about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-11-19 01:54:19 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-11-19 19:25:20 +0300
commitcd2177f3de22f54d7e71eea1e270f4e424394fc7 (patch)
treefc14fa30678990db7f8974853af94ae72717c188
parentec547202b4fa11cd351b29d076391d2913364fc6 (diff)
downloadrust-cd2177f3de22f54d7e71eea1e270f4e424394fc7.tar.gz
rust-cd2177f3de22f54d7e71eea1e270f4e424394fc7.zip
expand: Stop derive expansion un unexpected targets early
Collect derive placeholders using `collect` instead of `push`
-rw-r--r--compiler/rustc_expand/src/expand.rs60
-rw-r--r--src/test/ui/issues/issue-36617.rs1
-rw-r--r--src/test/ui/issues/issue-36617.stderr10
-rw-r--r--src/test/ui/issues/issue-49934-errors.rs2
-rw-r--r--src/test/ui/issues/issue-49934-errors.stderr16
-rw-r--r--src/test/ui/malformed/issue-69341-malformed-derive-inert.rs1
-rw-r--r--src/test/ui/malformed/issue-69341-malformed-derive-inert.stderr10
-rw-r--r--src/test/ui/span/issue-43927-non-ADT-derive.rs3
-rw-r--r--src/test/ui/span/issue-43927-non-ADT-derive.stderr26
9 files changed, 41 insertions, 88 deletions
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 22334a63988..c2240aabd88 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::<Vec<_>>();
+                        (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 58f44f42524..1102f3c4640 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 586dcf2cea6..dc6ef169259 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 6fa5f01ffd9..bf95f8fa7e1 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 3befb38a208..71cd2d30342 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 24692f7cf52..1fd7cddc7c9 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 c4532a375a7..db40ce07530 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 89b8eba1e95..8f1599a5abc 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 b160a4e5877..85beac535c9 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`.