resolve: Model shadowing restriction for macro_rules after modern macros
This is a regression for legacy macros that will be fixed in the next commit
This commit is contained in:
parent
83a51deef5
commit
f34ac26114
4 changed files with 45 additions and 28 deletions
|
@ -46,7 +46,6 @@ use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::small_vec::ExpectOne;
|
use rustc_data_structures::small_vec::ExpectOne;
|
||||||
|
|
||||||
crate struct FromPrelude(bool);
|
crate struct FromPrelude(bool);
|
||||||
crate struct FromExpansion(bool);
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct InvocationData<'a> {
|
pub struct InvocationData<'a> {
|
||||||
|
@ -481,7 +480,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, path[0], false);
|
let legacy_resolution = self.resolve_legacy_scope(&invocation.legacy_scope, path[0], false);
|
||||||
let result = if let Some((legacy_binding, _)) = legacy_resolution {
|
let result = if let Some(legacy_binding) = legacy_resolution {
|
||||||
Ok(legacy_binding.def())
|
Ok(legacy_binding.def())
|
||||||
} else {
|
} else {
|
||||||
match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, force,
|
match self.resolve_lexical_macro_path_segment(path[0], MacroNS, false, force,
|
||||||
|
@ -788,7 +787,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
scope: &'a Cell<LegacyScope<'a>>,
|
scope: &'a Cell<LegacyScope<'a>>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
record_used: bool)
|
record_used: bool)
|
||||||
-> Option<(&'a NameBinding<'a>, FromExpansion)> {
|
-> Option<&'a NameBinding<'a>> {
|
||||||
let ident = ident.modern();
|
let ident = ident.modern();
|
||||||
|
|
||||||
// Names from inner scope that can't shadow names from outer scopes, e.g.
|
// Names from inner scope that can't shadow names from outer scopes, e.g.
|
||||||
|
@ -798,15 +797,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
// // the outer `mac` and we have and ambiguity error
|
// // the outer `mac` and we have and ambiguity error
|
||||||
// mac!();
|
// mac!();
|
||||||
// }
|
// }
|
||||||
let mut potentially_ambiguous_result: Option<(&NameBinding, FromExpansion)> = None;
|
let mut potentially_ambiguous_result: Option<&NameBinding> = None;
|
||||||
|
|
||||||
// Go through all the scopes and try to resolve the name.
|
// Go through all the scopes and try to resolve the name.
|
||||||
let mut where_to_resolve = scope;
|
let mut where_to_resolve = scope;
|
||||||
let mut relative_depth = 0u32;
|
|
||||||
loop {
|
loop {
|
||||||
let result = match where_to_resolve.get() {
|
let result = match where_to_resolve.get() {
|
||||||
LegacyScope::Binding(legacy_binding) => if ident == legacy_binding.ident {
|
LegacyScope::Binding(legacy_binding) => if ident == legacy_binding.ident {
|
||||||
Some((legacy_binding.binding, FromExpansion(relative_depth > 0)))
|
Some(legacy_binding.binding)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -816,16 +814,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
macro_rules! continue_search { () => {
|
macro_rules! continue_search { () => {
|
||||||
where_to_resolve = match where_to_resolve.get() {
|
where_to_resolve = match where_to_resolve.get() {
|
||||||
LegacyScope::Binding(binding) => &binding.parent,
|
LegacyScope::Binding(binding) => &binding.parent,
|
||||||
LegacyScope::Invocation(invocation) => {
|
LegacyScope::Invocation(invocation) => &invocation.legacy_scope,
|
||||||
relative_depth = relative_depth.saturating_sub(1);
|
|
||||||
&invocation.legacy_scope
|
|
||||||
}
|
|
||||||
LegacyScope::Expansion(invocation) => match invocation.expansion.get() {
|
LegacyScope::Expansion(invocation) => match invocation.expansion.get() {
|
||||||
LegacyScope::Empty => &invocation.legacy_scope,
|
LegacyScope::Empty => &invocation.legacy_scope,
|
||||||
LegacyScope::Binding(..) | LegacyScope::Expansion(..) => {
|
LegacyScope::Binding(..) |
|
||||||
relative_depth += 1;
|
LegacyScope::Expansion(..) => &invocation.expansion,
|
||||||
&invocation.expansion
|
|
||||||
}
|
|
||||||
LegacyScope::Invocation(..) => {
|
LegacyScope::Invocation(..) => {
|
||||||
where_to_resolve.set(invocation.legacy_scope.get());
|
where_to_resolve.set(invocation.legacy_scope.get());
|
||||||
where_to_resolve
|
where_to_resolve
|
||||||
|
@ -847,12 +840,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
// Push an ambiguity error for later reporting and
|
// Push an ambiguity error for later reporting and
|
||||||
// return something for better recovery.
|
// return something for better recovery.
|
||||||
if let Some(previous_result) = potentially_ambiguous_result {
|
if let Some(previous_result) = potentially_ambiguous_result {
|
||||||
if result.0.def() != previous_result.0.def() {
|
if result.def() != previous_result.def() {
|
||||||
self.ambiguity_errors.push(AmbiguityError {
|
self.ambiguity_errors.push(AmbiguityError {
|
||||||
span: ident.span,
|
span: ident.span,
|
||||||
name: ident.name,
|
name: ident.name,
|
||||||
b1: previous_result.0,
|
b1: previous_result,
|
||||||
b2: result.0,
|
b2: result,
|
||||||
});
|
});
|
||||||
return Some(previous_result);
|
return Some(previous_result);
|
||||||
}
|
}
|
||||||
|
@ -861,7 +854,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
// Found a solution that's not an ambiguity yet, but is "suspicious" and
|
// Found a solution that's not an ambiguity yet, but is "suspicious" and
|
||||||
// can participate in ambiguities later on.
|
// can participate in ambiguities later on.
|
||||||
// Remember it and go search for other solutions in outer scopes.
|
// Remember it and go search for other solutions in outer scopes.
|
||||||
if (result.1).0 {
|
if result.expansion != Mark::root() {
|
||||||
potentially_ambiguous_result = Some(result);
|
potentially_ambiguous_result = Some(result);
|
||||||
|
|
||||||
continue_search!();
|
continue_search!();
|
||||||
|
@ -933,16 +926,16 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
self.suggest_macro_name(&ident.as_str(), kind, &mut err, span);
|
self.suggest_macro_name(&ident.as_str(), kind, &mut err, span);
|
||||||
err.emit();
|
err.emit();
|
||||||
},
|
},
|
||||||
(Some((legacy_binding, FromExpansion(_))), Ok((binding, FromPrelude(false)))) |
|
(Some(legacy_binding), Ok((binding, FromPrelude(from_prelude))))
|
||||||
(Some((legacy_binding, FromExpansion(true))), Ok((binding, FromPrelude(true)))) => {
|
if !from_prelude || legacy_binding.expansion != Mark::root() => {
|
||||||
if legacy_binding.def_ignoring_ambiguity() != binding.def_ignoring_ambiguity() {
|
if legacy_binding.def_ignoring_ambiguity() != binding.def_ignoring_ambiguity() {
|
||||||
self.report_ambiguity_error(ident.name, span, legacy_binding, binding);
|
self.report_ambiguity_error(ident.name, span, legacy_binding, binding);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// OK, non-macro-expanded legacy wins over macro prelude even if defs are different
|
// OK, non-macro-expanded legacy wins over prelude even if defs are different
|
||||||
(Some((legacy_binding, FromExpansion(false))), Ok((_, FromPrelude(true)))) |
|
(Some(legacy_binding), Ok(_)) |
|
||||||
// OK, unambiguous resolution
|
// OK, unambiguous resolution
|
||||||
(Some((legacy_binding, _)), Err(_)) => {
|
(Some(legacy_binding), Err(_)) => {
|
||||||
check_consistency(self, legacy_binding.def());
|
check_consistency(self, legacy_binding.def());
|
||||||
}
|
}
|
||||||
// OK, unambiguous resolution
|
// OK, unambiguous resolution
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#![allow(nonstandard_style)]
|
#![allow(nonstandard_style)]
|
||||||
|
|
||||||
macro_rules! cfg_if {
|
macro_rules! cfg_if2 {
|
||||||
( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
|
( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
|
||||||
( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* )
|
( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* )
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ extern "C" {
|
||||||
pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
|
pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if2! {
|
||||||
if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] {
|
if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] {
|
||||||
// Not ARM EHABI
|
// Not ARM EHABI
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -238,4 +238,4 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
|
||||||
_Unwind_SjLj_RaiseException(exc)
|
_Unwind_SjLj_RaiseException(exc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // cfg_if!
|
} // cfg_if2!
|
||||||
|
|
|
@ -28,7 +28,7 @@ foo!(); //~ ERROR `foo` is ambiguous
|
||||||
|
|
||||||
macro_rules! m2 { () => {
|
macro_rules! m2 { () => {
|
||||||
macro_rules! foo { () => {} }
|
macro_rules! foo { () => {} }
|
||||||
foo!();
|
foo!(); //~ ERROR `foo` is ambiguous
|
||||||
}}
|
}}
|
||||||
m2!();
|
m2!();
|
||||||
//^ Since `foo` is not used outside this expansion, it is not a shadowing error.
|
//^ Since `foo` is not used outside this expansion, it is not a shadowing error.
|
||||||
|
|
|
@ -30,6 +30,30 @@ LL | macro_rules! foo { () => {} }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: macro-expanded macros do not shadow
|
= note: macro-expanded macros do not shadow
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error[E0659]: `foo` is ambiguous
|
||||||
|
--> $DIR/macro-shadowing.rs:31:5
|
||||||
|
|
|
||||||
|
LL | foo!(); //~ ERROR `foo` is ambiguous
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
note: `foo` could refer to the name defined here
|
||||||
|
--> $DIR/macro-shadowing.rs:30:5
|
||||||
|
|
|
||||||
|
LL | macro_rules! foo { () => {} }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | m2!();
|
||||||
|
| ------ in this macro invocation
|
||||||
|
note: `foo` could also refer to the name defined here
|
||||||
|
--> $DIR/macro-shadowing.rs:20:5
|
||||||
|
|
|
||||||
|
LL | macro_rules! foo { () => {} }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
...
|
||||||
|
LL | m1!();
|
||||||
|
| ------ in this macro invocation
|
||||||
|
= note: macro-expanded macros do not shadow
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0659`.
|
For more information about this error, try `rustc --explain E0659`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue