Auto merge of #31400 - durka:civilized-deriving, r=alexcrichton

You can `#[derive(FromPrimitive)]`, but it [fails later in the compile](https://play.rust-lang.org/?gist=82cb8ad2fac49e3fe472&version=stable) due to hardcoding `std::num::FromPrimitive` which [was removed](eeb94886ad) (for some reason Github doesn't show `FromPrimitive` in the diff, but `git show` does).

Anyway, this PR removes the code. I didn't mark it as a breaking change, even though [this extremely contrived code using highly unstable features](https://play.rust-lang.org/?gist=1e1b1bbff962837b228a&version=nightly) is broken by it -- should I?
This commit is contained in:
bors 2016-02-05 15:11:45 +00:00
commit 98422e8c15
3 changed files with 4 additions and 168 deletions

View File

@ -63,7 +63,6 @@ pub mod decodable;
pub mod hash;
pub mod debug;
pub mod default;
pub mod primitive;
#[path="cmp/partial_eq.rs"]
pub mod partial_eq;
@ -178,8 +177,6 @@ derive_traits! {
"Default" => default::expand_deriving_default,
"FromPrimitive" => primitive::expand_deriving_from_primitive,
"Send" => bounds::expand_deriving_unsafe_bound,
"Sync" => bounds::expand_deriving_unsafe_bound,
"Copy" => bounds::expand_deriving_copy,

View File

@ -1,142 +0,0 @@
// Copyright 2012-2013 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.
use deriving::generic::*;
use deriving::generic::ty::*;
use syntax::ast::{MetaItem, Expr};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
span: Span,
mitem: &MetaItem,
item: &Annotatable,
push: &mut FnMut(Annotatable))
{
let inline = cx.meta_word(span, InternedString::new("inline"));
let attrs = vec!(cx.attribute(span, inline));
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: path_std!(cx, core::num::FromPrimitive),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
is_unsafe: false,
methods: vec!(
MethodDef {
name: "from_i64",
generics: LifetimeBounds::empty(),
explicit_self: None,
args: vec!(Literal(path_local!(i64))),
ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
None,
vec!(Box::new(Self_)),
true)),
// #[inline] liable to cause code-bloat
attributes: attrs.clone(),
is_unsafe: false,
combine_substructure: combine_substructure(Box::new(|c, s, sub| {
cs_from("i64", c, s, sub)
})),
},
MethodDef {
name: "from_u64",
generics: LifetimeBounds::empty(),
explicit_self: None,
args: vec!(Literal(path_local!(u64))),
ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
None,
vec!(Box::new(Self_)),
true)),
// #[inline] liable to cause code-bloat
attributes: attrs,
is_unsafe: false,
combine_substructure: combine_substructure(Box::new(|c, s, sub| {
cs_from("u64", c, s, sub)
})),
}
),
associated_types: Vec::new(),
};
trait_def.expand(cx, mitem, item, push)
}
fn cs_from(name: &str, cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
let n = match (substr.nonself_args.len(), substr.nonself_args.get(0)) {
(1, Some(o_f)) => o_f,
_ => cx.span_bug(trait_span, "incorrect number of arguments in `derive(FromPrimitive)`")
};
match *substr.fields {
StaticStruct(..) => {
cx.span_err(trait_span, "`FromPrimitive` cannot be derived for structs");
return cx.expr_fail(trait_span, InternedString::new(""));
}
StaticEnum(enum_def, _) => {
if enum_def.variants.is_empty() {
cx.span_err(trait_span,
"`FromPrimitive` cannot be derived for enums with no variants");
return cx.expr_fail(trait_span, InternedString::new(""));
}
let mut arms = Vec::new();
for variant in &enum_def.variants {
let def = &variant.node.data;
if !def.is_unit() {
cx.span_err(trait_span, "`FromPrimitive` cannot be derived \
for enums with non-unit variants");
return cx.expr_fail(trait_span,
InternedString::new(""));
}
let span = variant.span;
// expr for `$n == $variant as $name`
let path = cx.path(span, vec![substr.type_ident, variant.node.name]);
let variant = cx.expr_path(path);
let ty = cx.ty_ident(span, cx.ident_of(name));
let cast = cx.expr_cast(span, variant.clone(), ty);
let guard = cx.expr_binary(span, ast::BiEq, n.clone(), cast);
// expr for `Some($variant)`
let body = cx.expr_some(span, variant);
// arm for `_ if $guard => $body`
let arm = ast::Arm {
attrs: vec!(),
pats: vec!(cx.pat_wild(span)),
guard: Some(guard),
body: body,
};
arms.push(arm);
}
// arm for `_ => None`
let arm = ast::Arm {
attrs: vec!(),
pats: vec!(cx.pat_wild(trait_span)),
guard: None,
body: cx.expr_none(trait_span),
};
arms.push(arm);
cx.expr_match(trait_span, n.clone(), arms)
}
_ => cx.span_bug(trait_span, "expected StaticEnum in derive(FromPrimitive)")
}
}

View File

@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -8,27 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::num::FromPrimitive;
use std::isize;
#[derive(FromPrimitive)] //~ERROR `#[derive]` for custom traits is not stable
enum Foo {}
#[derive(FromPrimitive)]
struct A { x: isize }
//~^^ ERROR `FromPrimitive` cannot be derived for structs
//~^^^ ERROR `FromPrimitive` cannot be derived for structs
fn main() {}
#[derive(FromPrimitive)]
struct B(isize);
//~^^ ERROR `FromPrimitive` cannot be derived for structs
//~^^^ ERROR `FromPrimitive` cannot be derived for structs
#[derive(FromPrimitive)]
enum C { Foo(isize), Bar(usize) }
//~^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
//~^^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
#[derive(FromPrimitive)]
enum D { Baz { x: isize } }
//~^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
//~^^^ ERROR `FromPrimitive` cannot be derived for enums with non-unit variants
pub fn main() {}