mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
resolve: Relax shadowing restriction on macro-expanded macros
... for both legacy and modern macros. Fix previously introduced regressions, add tests.
This commit is contained in:
parent
27235698f5
commit
c057d579ab
@ -1274,9 +1274,18 @@ impl<'a> NameBinding<'a> {
|
||||
// expansion round `max(invoc_id, binding)` when they both emerged from macros.
|
||||
// Then this function returns `true` if `self` may emerge from a macro *after* that
|
||||
// in some later round and screw up our previously found resolution.
|
||||
fn may_appear_after(&self, _invoc_id: Mark, _binding: &NameBinding) -> bool {
|
||||
// FIXME: This is a very conservative estimation.
|
||||
self.expansion != Mark::root()
|
||||
fn may_appear_after(&self, invoc_id: Mark, binding: &NameBinding) -> bool {
|
||||
// self > max(invoc_id, binding) => !(self <= invoc_id || self <= binding)
|
||||
// Expansions are partially ordered, so "may appear after" is an inversion of
|
||||
// "certainly appears before or simultaneously" and includes unordered cases.
|
||||
let self_parent_expansion = self.expansion;
|
||||
let other_parent_expansion = binding.expansion;
|
||||
let invoc_parent_expansion = invoc_id.parent();
|
||||
let certainly_before_other_or_simultaneously =
|
||||
other_parent_expansion.is_descendant_of(self_parent_expansion);
|
||||
let certainly_before_invoc_or_simultaneously =
|
||||
invoc_parent_expansion.is_descendant_of(self_parent_expansion);
|
||||
!(certainly_before_other_or_simultaneously || certainly_before_invoc_or_simultaneously)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#![allow(nonstandard_style)]
|
||||
|
||||
macro_rules! cfg_if2 {
|
||||
macro_rules! cfg_if {
|
||||
( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) =>
|
||||
( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* )
|
||||
}
|
||||
@ -92,7 +92,7 @@ extern "C" {
|
||||
pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr;
|
||||
}
|
||||
|
||||
cfg_if2! {
|
||||
cfg_if! {
|
||||
if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] {
|
||||
// Not ARM EHABI
|
||||
#[repr(C)]
|
||||
@ -238,4 +238,4 @@ if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] {
|
||||
_Unwind_SjLj_RaiseException(exc)
|
||||
}
|
||||
}
|
||||
} // cfg_if2!
|
||||
} // cfg_if!
|
||||
|
@ -17,3 +17,8 @@ macro_rules! mac {
|
||||
macro_rules! inline {
|
||||
() => ()
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! from_prelude {
|
||||
() => ()
|
||||
}
|
||||
|
35
src/test/ui/macros/macro-shadowing-relaxed.rs
Normal file
35
src/test/ui/macros/macro-shadowing-relaxed.rs
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// compile-pass
|
||||
// aux-build:macro-in-other-crate.rs
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
macro_rules! my_include {() => {
|
||||
// Outer
|
||||
macro m() {}
|
||||
#[macro_use(from_prelude)] extern crate macro_in_other_crate;
|
||||
|
||||
fn inner() {
|
||||
// Inner
|
||||
macro m() {}
|
||||
macro_rules! from_prelude { () => {} }
|
||||
|
||||
// OK, both `m` and `from_prelude` are macro-expanded,
|
||||
// but no more macro-expanded than their counterpart from outer scope.
|
||||
m!();
|
||||
from_prelude!();
|
||||
}
|
||||
}}
|
||||
|
||||
my_include!();
|
||||
|
||||
fn main() {}
|
@ -28,7 +28,7 @@ foo!(); //~ ERROR `foo` is ambiguous
|
||||
|
||||
macro_rules! m2 { () => {
|
||||
macro_rules! foo { () => {} }
|
||||
foo!(); //~ ERROR `foo` is ambiguous
|
||||
foo!();
|
||||
}}
|
||||
m2!();
|
||||
//^ Since `foo` is not used outside this expansion, it is not a shadowing error.
|
||||
|
@ -30,30 +30,6 @@ LL | macro_rules! foo { () => {} }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: macro-expanded macros do not shadow
|
||||
|
||||
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
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0659`.
|
||||
|
Loading…
Reference in New Issue
Block a user