diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index 096f6dfd5d8d8..5c4ace246b1b8 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -158,12 +158,13 @@ pub fn expand_derive(cx: &mut ExtCtxt, traits.retain(|titem| { let tword = titem.word().unwrap(); let tname = tword.name(); + let legacy_name = Symbol::intern(&format!("derive_{}", tname)); - if is_builtin_trait(tname) || { - let derive_mode = ast::Path::from_ident(titem.span, ast::Ident::with_empty_ctxt(tname)); - cx.resolver.resolve_macro(cx.current_expansion.mark, &derive_mode, false).map(|ext| { - if let SyntaxExtension::CustomDerive(_) = *ext { true } else { false } - }).unwrap_or(false) + // Skip macros that are builtin derives, and don't resolve as legacy derives. + if is_builtin_trait(tname) || !{ + let derive_mode = ast::Path::from_ident(titem.span, + ast::Ident::with_empty_ctxt(legacy_name)); + cx.resolver.resolve_macro(cx.current_expansion.mark, &derive_mode, false).is_ok() } { return true; } @@ -175,11 +176,10 @@ pub fn expand_derive(cx: &mut ExtCtxt, feature_gate::GateIssue::Language, feature_gate::EXPLAIN_CUSTOM_DERIVE); } else { - let name = Symbol::intern(&format!("derive_{}", tname)); - if !cx.resolver.is_whitelisted_legacy_custom_derive(name) { + if !cx.resolver.is_whitelisted_legacy_custom_derive(legacy_name) { cx.span_warn(titem.span, feature_gate::EXPLAIN_DEPR_CUSTOM_DERIVE); } - let mitem = cx.meta_word(titem.span, name); + let mitem = cx.meta_word(titem.span, legacy_name); new_attributes.push(cx.attribute(mitem.span, mitem)); } false @@ -222,7 +222,6 @@ pub fn expand_derive(cx: &mut ExtCtxt, if let Some((i, titem)) = macros_11_derive { let tname = ast::Ident::with_empty_ctxt(titem.name().unwrap()); let path = ast::Path::from_ident(titem.span, tname); - let ext = cx.resolver.resolve_macro(cx.current_expansion.mark, &path, false).unwrap(); traits.remove(i); if traits.len() > 0 { @@ -248,11 +247,14 @@ pub fn expand_derive(cx: &mut ExtCtxt, ..mitem.span }; - if let SyntaxExtension::CustomDerive(ref ext) = *ext { - return ext.expand(cx, span, &mitem, item); - } else { - unreachable!() + if let Ok(ext) = cx.resolver.resolve_macro(cx.current_expansion.mark, &path, false) { + if let SyntaxExtension::CustomDerive(ref ext) = *ext { + return ext.expand(cx, span, &mitem, item); + } } + + cx.span_err(span, &format!("cannot find derive macro `{}` in this scope", tname)); + return vec![item]; } // Ok, at this point we know that there are no old-style `#[derive_Foo]` nor diff --git a/src/test/compile-fail/deriving-meta-unknown-trait.rs b/src/test/compile-fail/deriving-meta-unknown-trait.rs index 596cc1e7d5816..d388ece084417 100644 --- a/src/test/compile-fail/deriving-meta-unknown-trait.rs +++ b/src/test/compile-fail/deriving-meta-unknown-trait.rs @@ -11,7 +11,7 @@ // ignore-tidy-linelength #[derive(Eqr)] -//~^ ERROR `#[derive]` for custom traits is not stable enough for use. It is deprecated and will be removed in v1.15 (see issue #29644) +//~^ ERROR cannot find derive macro `Eqr` in this scope struct Foo; pub fn main() {} diff --git a/src/test/compile-fail/deriving-primitive.rs b/src/test/compile-fail/deriving-primitive.rs index be822a173ab58..97a39a46c19a8 100644 --- a/src/test/compile-fail/deriving-primitive.rs +++ b/src/test/compile-fail/deriving-primitive.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#[derive(FromPrimitive)] //~ERROR `#[derive]` for custom traits is not stable +#[derive(FromPrimitive)] //~ERROR cannot find derive macro `FromPrimitive` in this scope enum Foo {} fn main() {} diff --git a/src/test/pretty/attr-variant-data.rs b/src/test/pretty/attr-variant-data.rs deleted file mode 100644 index 1ffacaa9f5a5d..0000000000000 --- a/src/test/pretty/attr-variant-data.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2012 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. - -// pp-exact -// Testing that both the inner item and next outer item are -// preserved, and that the first outer item parsed in main is not -// accidentally carried over to each inner function - -#![feature(custom_attribute)] -#![feature(custom_derive)] - -#[derive(Serialize, Deserialize)] -struct X; - -#[derive(Serialize, Deserialize)] -struct WithRef<'a, T: 'a> { - #[serde(skip_deserializing)] - t: Option<&'a T>, - #[serde(serialize_with = "ser_x", deserialize_with = "de_x")] - x: X, -} - -#[derive(Serialize, Deserialize)] -enum EnumWith { - Unit, - Newtype( - #[serde(serialize_with = "ser_x", deserialize_with = "de_x")] - X), - Tuple(T, - #[serde(serialize_with = "ser_x", deserialize_with = "de_x")] - X), - Struct { - t: T, - #[serde(serialize_with = "ser_x", deserialize_with = "de_x")] - x: X, - }, -} - -#[derive(Serialize, Deserialize)] -struct Tuple(T, - #[serde(serialize_with = "ser_x", deserialize_with = "de_x")] - X); - -fn main() { }