mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-16 10:35:22 +00:00
Restore the old behavior of $crate
in nested macro_rules
`$crate` is not resolved at def-site of a macro, but rather at "transitive def-site"
This commit is contained in:
parent
9f92fce77c
commit
b69d51162b
@ -1989,7 +1989,31 @@ impl<'a> Resolver<'a> {
|
||||
// When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
|
||||
// we don't want to pretend that the `macro_rules!` definition is in the `macro`
|
||||
// as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks.
|
||||
ctxt.marks().into_iter().rev().find(|m| m.transparency() != Transparency::Transparent)
|
||||
// FIXME: This is only a guess and it doesn't work correctly for `macro_rules!`
|
||||
// definitions actually produced by `macro` and `macro` definitions produced by
|
||||
// `macro_rules!`, but at least such configurations are not stable yet.
|
||||
ctxt = ctxt.modern_and_legacy();
|
||||
let mut iter = ctxt.marks().into_iter().rev().peekable();
|
||||
let mut result = None;
|
||||
// Find the last modern mark from the end if it exists.
|
||||
while let Some(&mark) = iter.peek() {
|
||||
if mark.transparency() == Transparency::Opaque {
|
||||
result = Some(mark);
|
||||
iter.next();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Then find the last legacy mark from the end if it exists.
|
||||
while let Some(&mark) = iter.peek() {
|
||||
if mark.transparency() == Transparency::SemiTransparent {
|
||||
result = Some(mark);
|
||||
iter.next();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
result
|
||||
} else {
|
||||
ctxt = ctxt.modern();
|
||||
ctxt.adjust(Mark::root())
|
||||
|
@ -22,6 +22,35 @@ pub mod foo {
|
||||
|
||||
pub struct SomeType;
|
||||
|
||||
pub macro uses_dollar_crate() {
|
||||
// `$crate`
|
||||
pub macro uses_dollar_crate_modern() {
|
||||
type Alias = $crate::SomeType;
|
||||
}
|
||||
|
||||
pub macro define_uses_dollar_crate_modern_nested($uses_dollar_crate_modern_nested: ident) {
|
||||
macro $uses_dollar_crate_modern_nested() {
|
||||
type AliasCrateModernNested = $crate::SomeType;
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! define_uses_dollar_crate_legacy_nested {
|
||||
() => {
|
||||
macro_rules! uses_dollar_crate_legacy_nested {
|
||||
() => {
|
||||
type AliasLegacyNested = $crate::SomeType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// `crate`
|
||||
pub macro uses_crate_modern() {
|
||||
type AliasCrate = crate::SomeType;
|
||||
}
|
||||
|
||||
pub macro define_uses_crate_modern_nested($uses_crate_modern_nested: ident) {
|
||||
macro $uses_crate_modern_nested() {
|
||||
type AliasCrateModernNested = crate::SomeType;
|
||||
}
|
||||
}
|
||||
|
@ -8,15 +8,28 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Make sure `$crate` works in `macro` macros.
|
||||
// Make sure `$crate` and `crate` work in for basic cases of nested macros.
|
||||
|
||||
// compile-pass
|
||||
// aux-build:intercrate.rs
|
||||
|
||||
#![feature(use_extern_macros)]
|
||||
#![feature(decl_macro, crate_in_paths)]
|
||||
|
||||
extern crate intercrate;
|
||||
|
||||
intercrate::uses_dollar_crate!();
|
||||
// `$crate`
|
||||
intercrate::uses_dollar_crate_modern!();
|
||||
|
||||
intercrate::define_uses_dollar_crate_modern_nested!(uses_dollar_crate_modern_nested);
|
||||
uses_dollar_crate_modern_nested!();
|
||||
|
||||
intercrate::define_uses_dollar_crate_legacy_nested!();
|
||||
uses_dollar_crate_legacy_nested!();
|
||||
|
||||
// `crate`
|
||||
intercrate::uses_crate_modern!();
|
||||
|
||||
intercrate::define_uses_crate_modern_nested!(uses_crate_modern_nested);
|
||||
uses_crate_modern_nested!();
|
||||
|
||||
fn main() {}
|
||||
|
Loading…
Reference in New Issue
Block a user