-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #64694 - petrochenkov:reshelp, r=matthewjasper
Fully integrate derive helpers into name resolution ```rust #[derive(Foo)] #[foo_helper] // already goes through name resolution struct S { #[foo_helper] // goes through name resolution after this PR field: u8 } ``` How name resolution normally works: - We have an identifier we need to resolve, take its location (in some sense) and look what names are in scope in that location. How derive helper attributes are "resolved" (before this PR): - After resolving the derive `Foo` we visit the derive's input (`struct S { ... } `) as a piece of AST and mark attributes textually matching one of the derive's helper attributes (`foo_helper`) as "known", so they never go through name resolution. This PR changes the rules for derive helpers, so they are not proactively marked as known (which is a big hack ignoring any ambiguities or hygiene), but go through regular name resolution instead. This change was previously blocked by attributes not being resolved in some positions at all (fixed in #63468). "Where exactly are derive helpers in scope?" is an interesting question, and I need some feedback from proc macro authors to answer it, see the post below (#64694 (comment)).
- Loading branch information
Showing
8 changed files
with
195 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
src/test/ui/proc-macro/auxiliary/derive-helper-shadowing.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// force-host | ||
// no-prefer-dynamic | ||
|
||
#![crate_type = "proc-macro"] | ||
|
||
extern crate proc_macro; | ||
use proc_macro::*; | ||
|
||
#[proc_macro_derive(GenHelperUse)] | ||
pub fn derive_a(_: TokenStream) -> TokenStream { | ||
" | ||
#[empty_helper] | ||
struct Uwu; | ||
".parse().unwrap() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,54 @@ | ||
// edition:2018 | ||
// aux-build:test-macros.rs | ||
// aux-build:derive-helper-shadowing.rs | ||
|
||
#[macro_use] | ||
extern crate test_macros; | ||
#[macro_use] | ||
extern crate derive_helper_shadowing; | ||
|
||
use test_macros::empty_attr as empty_helper; | ||
|
||
macro_rules! gen_helper_use { | ||
() => { | ||
#[empty_helper] //~ ERROR cannot find attribute `empty_helper` in this scope | ||
struct W; | ||
} | ||
} | ||
|
||
#[empty_helper] //~ ERROR `empty_helper` is ambiguous | ||
#[derive(Empty)] | ||
struct S { | ||
// FIXME No ambiguity, attributes in non-macro positions are not resolved properly | ||
#[empty_helper] | ||
#[empty_helper] //~ ERROR `empty_helper` is ambiguous | ||
field: [u8; { | ||
// FIXME No ambiguity, derive helpers are not put into scope for non-attributes | ||
use empty_helper; | ||
use empty_helper; //~ ERROR `empty_helper` is ambiguous | ||
|
||
// FIXME No ambiguity, derive helpers are not put into scope for inner items | ||
#[empty_helper] | ||
#[empty_helper] //~ ERROR `empty_helper` is ambiguous | ||
struct U; | ||
|
||
mod inner { | ||
// FIXME No ambiguity, attributes in non-macro positions are not resolved properly | ||
// OK, no ambiguity, the non-helper attribute is not in scope here, only the helper. | ||
#[empty_helper] | ||
struct V; | ||
|
||
gen_helper_use!(); | ||
|
||
#[derive(GenHelperUse)] //~ ERROR cannot find attribute `empty_helper` in this scope | ||
struct Owo; | ||
|
||
use empty_helper as renamed; | ||
#[renamed] //~ ERROR cannot use a derive helper attribute through an import | ||
struct Wow; | ||
} | ||
|
||
0 | ||
}] | ||
} | ||
|
||
// OK, no ambiguity, only the non-helper attribute is in scope. | ||
#[empty_helper] | ||
struct Z; | ||
|
||
fn main() { | ||
let s = S { field: [] }; | ||
} |
Oops, something went wrong.