diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 2fa2563..61e25c6 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -14,6 +14,7 @@ quote = "0.1.3" syn = "0.6.0" [dev-dependencies] +compiletest_rs = "0.2.2" [dev-dependencies.num] path = ".." diff --git a/macros/src/lib.rs b/macros/src/lib.rs index d85218c..3283bb0 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -19,6 +19,7 @@ extern crate rustc_macro; use rustc_macro::TokenStream; use syn::Body::Enum; +use syn::VariantData::Unit; #[rustc_macro_derive(FromPrimitive)] pub fn from_primitive(input: TokenStream) -> TokenStream { @@ -29,13 +30,22 @@ pub fn from_primitive(input: TokenStream) -> TokenStream { let variants = match ast.body { Enum(ref variants) => variants, - _ => panic!("`FromPrimitive` can be applied only to the enums, {} is not an enum", name), + _ => { + panic!("`FromPrimitive` can be applied only to the enums, {} is not an enum", + name) + } }; let mut idx = 0; let variants: Vec<_> = variants.iter() .map(|variant| { let ident = &variant.ident; + match variant.data { + Unit => (), + _ => { + panic!("`FromPrimitive` can be applied only to unitary enums, {}::{} is either struct or tuple", name, ident) + }, + } if let Some(val) = variant.discriminant { idx = val.value; } diff --git a/macros/tests/compile-fail/derive_on_struct.rs b/macros/tests/compile-fail/derive_on_struct.rs new file mode 100644 index 0000000..1f21081 --- /dev/null +++ b/macros/tests/compile-fail/derive_on_struct.rs @@ -0,0 +1,25 @@ + +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_macro)] + +extern crate num; +#[macro_use] +extern crate num_macros; + +#[derive(Debug, PartialEq, FromPrimitive)] //~ ERROR +struct Color { + r: u8, + g: u8, + b: u8, +} + +fn main() {} diff --git a/macros/tests/compile-fail/enum_with_associated_data.rs b/macros/tests/compile-fail/enum_with_associated_data.rs new file mode 100644 index 0000000..0fef268 --- /dev/null +++ b/macros/tests/compile-fail/enum_with_associated_data.rs @@ -0,0 +1,24 @@ + +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_macro)] + +extern crate num; +#[macro_use] +extern crate num_macros; + +#[derive(Debug, PartialEq, FromPrimitive)] //~ ERROR +enum Color { + Rgb(u8, u8, u8), + Hsv(u8, u8, u8), +} + +fn main() {} diff --git a/macros/tests/compiletest.rs b/macros/tests/compiletest.rs new file mode 100644 index 0000000..27c212b --- /dev/null +++ b/macros/tests/compiletest.rs @@ -0,0 +1,25 @@ +extern crate compiletest_rs as compiletest; + +use std::path::PathBuf; +use std::env::var; + +fn run_mode(mode: &'static str) { + let mut config = compiletest::default_config(); + + let cfg_mode = mode.parse().ok().expect("Invalid mode"); + + config.target_rustcflags = Some("-L target/debug/ -L target/debug/deps/".to_owned()); + if let Ok(name) = var::<&str>("TESTNAME") { + let s : String = name.to_owned(); + config.filter = Some(s) + } + config.mode = cfg_mode; + config.src_base = PathBuf::from(format!("tests/{}", mode)); + + compiletest::run_tests(&config); +} + +#[test] +fn compile_test() { + run_mode("compile-fail"); +} diff --git a/macros/tests/empty_enum.rs b/macros/tests/empty_enum.rs new file mode 100644 index 0000000..3a3d55a --- /dev/null +++ b/macros/tests/empty_enum.rs @@ -0,0 +1,26 @@ + +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rustc_macro)] + +extern crate num; +#[macro_use] +extern crate num_macros; + +#[derive(Debug, PartialEq, FromPrimitive)] +enum Color {} + +#[test] +fn test_empty_enum() { + let v: [Option; 1] = [num::FromPrimitive::from_u64(0)]; + + assert_eq!(v, [None]); +}