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> {
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
}
--- /dev/null
+// Copyright 2018 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.
+
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::*;
+
+#[proc_macro_derive(A, attributes(b))]
+pub fn foo(_x: TokenStream) -> TokenStream {
+ TokenStream::new()
+}
--- /dev/null
+// Copyright 2018 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.
+
+// aux-build:derive-two-attrs.rs
+
+#![feature(use_extern_macros)]
+
+extern crate derive_two_attrs as foo;
+
+use foo::A;
+
+#[derive(A)]
+#[b]
+#[b]
+struct B;
+
+fn main() {}