Skip to content

Commit ce322ee

Browse files
committed
rustc: Fix proc_macro expansions on trait methods
This commit fixes procedural macro attributes being attached to trait methods, ensuring that they get resolved and expanded as other procedural macro attributes. The bug here was that `current_module` on the resolver was accidentally set to be a trait when it's otherwise only ever expecting a `mod`/block module. The actual fix here came from @jseyfried, I'm just helping to land it in the compiler! Closes #42493
1 parent ba65645 commit ce322ee

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

src/librustc_resolve/macros.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,8 @@ impl<'a> Resolver<'a> {
402402
let ast::Path { ref segments, span } = *path;
403403
let path: Vec<_> = segments.iter().map(|seg| respan(seg.span, seg.identifier)).collect();
404404
let invocation = self.invocations[&scope];
405-
self.current_module = invocation.module.get();
405+
let module = invocation.module.get();
406+
self.current_module = if module.is_trait() { module.parent.unwrap() } else { module };
406407

407408
if path.len() > 1 {
408409
if !self.use_extern_macros && self.gated_errors.insert(span) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// aux-build:attr-on-trait.rs
12+
13+
#![feature(proc_macro)]
14+
15+
extern crate attr_on_trait;
16+
17+
trait Foo {
18+
#[attr_on_trait::foo]
19+
fn foo() {}
20+
}
21+
22+
impl Foo for i32 {
23+
fn foo(&self) {}
24+
}
25+
26+
fn main() {
27+
3i32.foo();
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// no-prefer-dynamic
12+
13+
#![feature(proc_macro)]
14+
#![crate_type = "proc-macro"]
15+
16+
extern crate proc_macro;
17+
18+
use proc_macro::TokenStream;
19+
20+
#[proc_macro_attribute]
21+
pub fn foo(attr: TokenStream, item: TokenStream) -> TokenStream {
22+
drop(attr);
23+
assert_eq!(item.to_string(), "fn foo() { }");
24+
"fn foo(&self);".parse().unwrap()
25+
}

0 commit comments

Comments
 (0)