From cd2177f3de22f54d7e71eea1e270f4e424394fc7 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 19 Nov 2020 01:54:19 +0300 Subject: [PATCH] expand: Stop derive expansion un unexpected targets early Collect derive placeholders using `collect` instead of `push` --- compiler/rustc_expand/src/expand.rs | 60 +++++++++++-------- src/test/ui/issues/issue-36617.rs | 1 - src/test/ui/issues/issue-36617.stderr | 10 +--- src/test/ui/issues/issue-49934-errors.rs | 2 - src/test/ui/issues/issue-49934-errors.stderr | 16 +---- .../issue-69341-malformed-derive-inert.rs | 1 - .../issue-69341-malformed-derive-inert.stderr | 10 +--- .../ui/span/issue-43927-non-ADT-derive.rs | 3 - .../ui/span/issue-43927-non-ADT-derive.stderr | 26 +------- 9 files changed, 41 insertions(+), 88 deletions(-) diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 22334a63988dc..c2240aabd884b 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -492,6 +492,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx.force_mode = force; // FIXME(jseyfried): Refactor out the following logic + let fragment_kind = invoc.fragment_kind; let (expanded_fragment, new_invocations) = match res { InvocationRes::Single(ext) => match self.expand_invoc(invoc, &ext.kind) { ExpandResult::Ready(fragment) => self.collect_invocations(fragment, &[]), @@ -512,36 +513,45 @@ impl<'a, 'b> MacroExpander<'a, 'b> { InvocationRes::DeriveContainer(_exts) => { // FIXME: Consider using the derive resolutions (`_exts`) immediately, // instead of enqueuing the derives to be resolved again later. - let (derives, item) = match invoc.kind { + let (derives, mut item) = match invoc.kind { InvocationKind::DeriveContainer { derives, item } => (derives, item), _ => unreachable!(), }; - if !item.derive_allowed() { + let (item, derive_placeholders) = if !item.derive_allowed() { self.error_derive_forbidden_on_non_adt(&derives, &item); - } + item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive))); + (item, Vec::new()) + } else { + let mut item = StripUnconfigured { + sess: self.cx.sess, + features: self.cx.ecfg.features, + } + .fully_configure(item); + item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive))); + + invocations.reserve(derives.len()); + let derive_placeholders = derives + .into_iter() + .map(|path| { + let expn_id = ExpnId::fresh(None); + invocations.push(( + Invocation { + kind: InvocationKind::Derive { path, item: item.clone() }, + fragment_kind, + expansion_data: ExpansionData { + id: expn_id, + ..self.cx.current_expansion.clone() + }, + }, + None, + )); + NodeId::placeholder_from_expn_id(expn_id) + }) + .collect::>(); + (item, derive_placeholders) + }; - let mut item = self.fully_configure(item); - item.visit_attrs(|attrs| attrs.retain(|a| !a.has_name(sym::derive))); - - let mut derive_placeholders = Vec::with_capacity(derives.len()); - invocations.reserve(derives.len()); - for path in derives { - let expn_id = ExpnId::fresh(None); - derive_placeholders.push(NodeId::placeholder_from_expn_id(expn_id)); - invocations.push(( - Invocation { - kind: InvocationKind::Derive { path, item: item.clone() }, - fragment_kind: invoc.fragment_kind, - expansion_data: ExpansionData { - id: expn_id, - ..invoc.expansion_data.clone() - }, - }, - None, - )); - } - let fragment = - invoc.fragment_kind.expect_from_annotatables(::std::iter::once(item)); + let fragment = fragment_kind.expect_from_annotatables(::std::iter::once(item)); self.collect_invocations(fragment, &derive_placeholders) } }; diff --git a/src/test/ui/issues/issue-36617.rs b/src/test/ui/issues/issue-36617.rs index 58f44f42524bc..1102f3c4640a1 100644 --- a/src/test/ui/issues/issue-36617.rs +++ b/src/test/ui/issues/issue-36617.rs @@ -1,5 +1,4 @@ #![derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions //~| ERROR cannot determine resolution for the derive macro `Copy` - //~| ERROR cannot determine resolution for the derive macro `Copy` fn main() {} diff --git a/src/test/ui/issues/issue-36617.stderr b/src/test/ui/issues/issue-36617.stderr index 586dcf2cea675..dc6ef16925913 100644 --- a/src/test/ui/issues/issue-36617.stderr +++ b/src/test/ui/issues/issue-36617.stderr @@ -12,14 +12,6 @@ LL | #![derive(Copy)] | = note: import resolution is stuck, try simplifying macro imports -error: cannot determine resolution for the derive macro `Copy` - --> $DIR/issue-36617.rs:1:11 - | -LL | #![derive(Copy)] - | ^^^^ - | - = note: import resolution is stuck, try simplifying macro imports - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0774`. diff --git a/src/test/ui/issues/issue-49934-errors.rs b/src/test/ui/issues/issue-49934-errors.rs index 6fa5f01ffd926..bf95f8fa7e1ec 100644 --- a/src/test/ui/issues/issue-49934-errors.rs +++ b/src/test/ui/issues/issue-49934-errors.rs @@ -1,10 +1,8 @@ fn foo<#[derive(Debug)] T>() { //~^ ERROR `derive` may only be applied to structs, enums and unions -//~| ERROR expected an inert attribute, found a derive macro match 0 { #[derive(Debug)] //~^ ERROR `derive` may only be applied to structs, enums and unions - //~| ERROR expected an inert attribute, found a derive macro _ => (), } } diff --git a/src/test/ui/issues/issue-49934-errors.stderr b/src/test/ui/issues/issue-49934-errors.stderr index 3befb38a20882..71cd2d3034243 100644 --- a/src/test/ui/issues/issue-49934-errors.stderr +++ b/src/test/ui/issues/issue-49934-errors.stderr @@ -4,24 +4,12 @@ error[E0774]: `derive` may only be applied to structs, enums and unions LL | fn foo<#[derive(Debug)] T>() { | ^^^^^^^^^^^^^^^^ -error: expected an inert attribute, found a derive macro - --> $DIR/issue-49934-errors.rs:1:17 - | -LL | fn foo<#[derive(Debug)] T>() { - | ^^^^^ - error[E0774]: `derive` may only be applied to structs, enums and unions - --> $DIR/issue-49934-errors.rs:5:9 + --> $DIR/issue-49934-errors.rs:4:9 | LL | #[derive(Debug)] | ^^^^^^^^^^^^^^^^ -error: expected an inert attribute, found a derive macro - --> $DIR/issue-49934-errors.rs:5:18 - | -LL | #[derive(Debug)] - | ^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0774`. diff --git a/src/test/ui/malformed/issue-69341-malformed-derive-inert.rs b/src/test/ui/malformed/issue-69341-malformed-derive-inert.rs index 24692f7cf52e1..1fd7cddc7c937 100644 --- a/src/test/ui/malformed/issue-69341-malformed-derive-inert.rs +++ b/src/test/ui/malformed/issue-69341-malformed-derive-inert.rs @@ -4,7 +4,6 @@ struct CLI { #[derive(parse())] //~^ ERROR traits in `#[derive(...)]` don't accept arguments //~| ERROR cannot find derive macro `parse` in this scope - //~| ERROR cannot find derive macro `parse` in this scope path: (), //~^ ERROR `derive` may only be applied to structs, enums and unions } diff --git a/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr b/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr index c4532a375a75e..db40ce0753045 100644 --- a/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr +++ b/src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr @@ -5,7 +5,7 @@ LL | #[derive(parse())] | ^^ help: remove the arguments error[E0774]: `derive` may only be applied to structs, enums and unions - --> $DIR/issue-69341-malformed-derive-inert.rs:8:5 + --> $DIR/issue-69341-malformed-derive-inert.rs:7:5 | LL | path: (), | ^^^^^^^^ @@ -16,12 +16,6 @@ error: cannot find derive macro `parse` in this scope LL | #[derive(parse())] | ^^^^^ -error: cannot find derive macro `parse` in this scope - --> $DIR/issue-69341-malformed-derive-inert.rs:4:14 - | -LL | #[derive(parse())] - | ^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0774`. diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.rs b/src/test/ui/span/issue-43927-non-ADT-derive.rs index 89b8eba1e95e7..8f1599a5abcb0 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.rs +++ b/src/test/ui/span/issue-43927-non-ADT-derive.rs @@ -5,9 +5,6 @@ //~| ERROR cannot determine resolution for the derive macro `Debug` //~| ERROR cannot determine resolution for the derive macro `PartialEq` //~| ERROR cannot determine resolution for the derive macro `Eq` -//~| ERROR cannot determine resolution for the derive macro `Debug` -//~| ERROR cannot determine resolution for the derive macro `PartialEq` -//~| ERROR cannot determine resolution for the derive macro `Eq` struct DerivedOn; fn main() {} diff --git a/src/test/ui/span/issue-43927-non-ADT-derive.stderr b/src/test/ui/span/issue-43927-non-ADT-derive.stderr index b160a4e5877d5..85beac535c965 100644 --- a/src/test/ui/span/issue-43927-non-ADT-derive.stderr +++ b/src/test/ui/span/issue-43927-non-ADT-derive.stderr @@ -28,30 +28,6 @@ LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! | = note: import resolution is stuck, try simplifying macro imports -error: cannot determine resolution for the derive macro `Eq` - --> $DIR/issue-43927-non-ADT-derive.rs:3:29 - | -LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! - | ^^ - | - = note: import resolution is stuck, try simplifying macro imports - -error: cannot determine resolution for the derive macro `PartialEq` - --> $DIR/issue-43927-non-ADT-derive.rs:3:18 - | -LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! - | ^^^^^^^^^ - | - = note: import resolution is stuck, try simplifying macro imports - -error: cannot determine resolution for the derive macro `Debug` - --> $DIR/issue-43927-non-ADT-derive.rs:3:11 - | -LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! - | ^^^^^ - | - = note: import resolution is stuck, try simplifying macro imports - -error: aborting due to 7 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0774`.