Auto merge of #228 - rust-num:fix/num-macros, r=cuviper
Fix `num-macros` `FromPrimitive` implementation Current solution follow syntax proposed in rust-lang/rfcs#1681. Tracking issue rust-lang/rust#35900 Close #227 Code broken after change: - [ ] https://github.com/kdar/gameboy-rs - [ ] https://github.com/lemonrock/mbedtls - [ ] https://github.com/timorantalaiho/kelaa - [ ] https://github.com/dylanede/cef-rs - [ ] https://github.com/klutzy/aheui-llvm - [ ] https://github.com/pcwalton/rust-media - [ ] https://github.com/PistonDevelopers/hematite_server
This commit is contained in:
commit
019c136b8c
|
@ -5,6 +5,7 @@ set -ex
|
||||||
cargo bench --verbose
|
cargo bench --verbose
|
||||||
|
|
||||||
cargo test --verbose --manifest-path=macros/Cargo.toml
|
cargo test --verbose --manifest-path=macros/Cargo.toml
|
||||||
|
cargo test --verbose --manifest-path=derive/Cargo.toml
|
||||||
|
|
||||||
# Build test for the serde feature
|
# Build test for the serde feature
|
||||||
cargo build --verbose --features "serde"
|
cargo build --verbose --features "serde"
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
[package]
|
||||||
|
authors = ["The Rust Project Developers"]
|
||||||
|
description = "Numeric syntax extensions"
|
||||||
|
documentation = "http://rust-num.github.io/num"
|
||||||
|
homepage = "https://github.com/rust-num/num"
|
||||||
|
keywords = ["mathematics", "numerics"]
|
||||||
|
license = "MIT/Apache-2.0"
|
||||||
|
name = "num-derive"
|
||||||
|
repository = "https://github.com/rust-num/num"
|
||||||
|
version = "0.1.33"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
quote = "0.1.3"
|
||||||
|
syn = "0.7.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
compiletest_rs = "0.2.2"
|
||||||
|
|
||||||
|
[dev-dependencies.num]
|
||||||
|
path = ".."
|
||||||
|
version = "0.1"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["rustc-macro"]
|
||||||
|
name = "num_derive"
|
||||||
|
rustc-macro = true
|
||||||
|
test = false
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2012-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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![crate_type = "rustc-macro"]
|
||||||
|
#![feature(rustc_macro, rustc_macro_lib)]
|
||||||
|
|
||||||
|
extern crate syn;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate quote;
|
||||||
|
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 {
|
||||||
|
let source = input.to_string();
|
||||||
|
|
||||||
|
let ast = syn::parse_macro_input(&source).unwrap();
|
||||||
|
let name = &ast.ident;
|
||||||
|
|
||||||
|
let variants = match ast.body {
|
||||||
|
Enum(ref variants) => variants,
|
||||||
|
_ => {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
let tt = quote!(#idx => Some(#name::#ident));
|
||||||
|
idx += 1;
|
||||||
|
tt
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let res = quote! {
|
||||||
|
#ast
|
||||||
|
|
||||||
|
impl ::num::traits::FromPrimitive for #name {
|
||||||
|
fn from_i64(n: i64) -> Option<Self> {
|
||||||
|
Self::from_u64(n as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_u64(n: u64) -> Option<Self> {
|
||||||
|
match n {
|
||||||
|
#(variants,)*
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
res.to_string().parse().unwrap()
|
||||||
|
}
|
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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_derive;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, FromPrimitive)] //~ ERROR
|
||||||
|
struct Color {
|
||||||
|
r: u8,
|
||||||
|
g: u8,
|
||||||
|
b: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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_derive;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, FromPrimitive)] //~ ERROR
|
||||||
|
enum Color {
|
||||||
|
Rgb(u8, u8, u8),
|
||||||
|
Hsv(u8, u8, u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -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");
|
||||||
|
}
|
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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_derive;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, FromPrimitive)]
|
||||||
|
enum Color {}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_empty_enum() {
|
||||||
|
let v: [Option<Color>; 1] = [num::FromPrimitive::from_u64(0)];
|
||||||
|
|
||||||
|
assert_eq!(v, [None]);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
// 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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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_derive;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, FromPrimitive)]
|
||||||
|
enum Color {
|
||||||
|
Red,
|
||||||
|
Blue,
|
||||||
|
Green,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_from_primitive_for_trivial_case() {
|
||||||
|
let v: [Option<Color>; 4] = [num::FromPrimitive::from_u64(0),
|
||||||
|
num::FromPrimitive::from_u64(1),
|
||||||
|
num::FromPrimitive::from_u64(2),
|
||||||
|
num::FromPrimitive::from_u64(3)];
|
||||||
|
|
||||||
|
assert_eq!(v,
|
||||||
|
[Some(Color::Red), Some(Color::Blue), Some(Color::Green), None]);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
// 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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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_derive;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, FromPrimitive)]
|
||||||
|
enum Color {
|
||||||
|
Red,
|
||||||
|
Blue = 5,
|
||||||
|
Green,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_from_primitive_for_enum_with_custom_value() {
|
||||||
|
let v: [Option<Color>; 4] = [num::FromPrimitive::from_u64(0),
|
||||||
|
num::FromPrimitive::from_u64(5),
|
||||||
|
num::FromPrimitive::from_u64(6),
|
||||||
|
num::FromPrimitive::from_u64(3)];
|
||||||
|
|
||||||
|
assert_eq!(v,
|
||||||
|
[Some(Color::Red), Some(Color::Blue), Some(Color::Green), None]);
|
||||||
|
}
|
Loading…
Reference in New Issue