about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/expand.rs17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 1241e230b26..d64f3de8daa 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -240,6 +240,13 @@ impl Invocation {
             InvocationKind::Derive { ref path, .. } => path.span,
         }
     }
+
+    pub fn attr_id(&self) -> Option<ast::AttrId> {
+        match self.kind {
+            InvocationKind::Attr { attr: Some(ref attr), .. } => Some(attr.id),
+            _ => None,
+        }
+    }
 }
 
 pub struct MacroExpander<'a, 'b:'a> {
@@ -331,10 +338,20 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
 
             let scope =
                 if self.monotonic { invoc.expansion_data.mark } else { orig_expansion_data.mark };
+            let attr_id_before = invoc.attr_id();
             let ext = match self.cx.resolver.resolve_invoc(&mut invoc, scope, force) {
                 Ok(ext) => Some(ext),
                 Err(Determinacy::Determined) => None,
                 Err(Determinacy::Undetermined) => {
+                    // Sometimes attributes which we thought were invocations
+                    // end up being custom attributes for custom derives. If
+                    // that's the case our `invoc` will have changed out from
+                    // under us. If this is the case we're making progress so we
+                    // want to flag it as such, and we test this by looking if
+                    // the `attr_id()` method has been changing over time.
+                    if invoc.attr_id() != attr_id_before {
+                        progress = true;
+                    }
                     undetermined_invocations.push(invoc);
                     continue
                 }