Change all run-pass hygiene tests to ui tests
Change some tests to `check-pass` that are only testing name resolution.
This commit is contained in:
parent
96234d5363
commit
03178f31c4
26 changed files with 14 additions and 21 deletions
9
src/test/ui/hygiene/auxiliary/legacy_interaction.rs
Normal file
9
src/test/ui/hygiene/auxiliary/legacy_interaction.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! m {
|
||||
() => {
|
||||
fn f() {} // (2)
|
||||
g(); // (1)
|
||||
}
|
||||
}
|
||||
1
src/test/ui/hygiene/auxiliary/my_crate.rs
Normal file
1
src/test/ui/hygiene/auxiliary/my_crate.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub fn f() {}
|
||||
27
src/test/ui/hygiene/auxiliary/unhygienic_example.rs
Normal file
27
src/test/ui/hygiene/auxiliary/unhygienic_example.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
extern crate my_crate;
|
||||
|
||||
pub fn g() {} // (a)
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unhygienic_macro {
|
||||
() => {
|
||||
// (1) unhygienic: depends on `my_crate` in the crate root at the invocation site.
|
||||
::my_crate::f();
|
||||
|
||||
// (2) unhygienic: defines `f` at the invocation site (in addition to the above point).
|
||||
use my_crate::f;
|
||||
f();
|
||||
|
||||
g(); // (3) unhygienic: `g` needs to be in scope at use site.
|
||||
|
||||
$crate::g(); // (4) hygienic: this always resolves to (a)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn test_unhygienic() {
|
||||
unhygienic_macro!();
|
||||
f(); // `f` was defined at the use site
|
||||
}
|
||||
28
src/test/ui/hygiene/auxiliary/xcrate.rs
Normal file
28
src/test/ui/hygiene/auxiliary/xcrate.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#![feature(decl_macro)]
|
||||
#![allow(unused)]
|
||||
|
||||
pub use bar::test;
|
||||
|
||||
extern crate std as foo;
|
||||
|
||||
pub fn f() {}
|
||||
use f as f2;
|
||||
|
||||
mod bar {
|
||||
pub fn g() {}
|
||||
use baz::h;
|
||||
|
||||
pub macro test() {
|
||||
use std::mem;
|
||||
use foo::cell;
|
||||
::f();
|
||||
::f2();
|
||||
g();
|
||||
h();
|
||||
::bar::h();
|
||||
}
|
||||
}
|
||||
|
||||
mod baz {
|
||||
pub fn h() {}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// Make sure `$crate` and `crate` work in for basic cases of nested macros.
|
||||
|
||||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
// check-pass
|
||||
// aux-build:intercrate.rs
|
||||
|
||||
#![feature(decl_macro, crate_in_paths)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
// FIXME: Investigate why expansion info for a single expansion id is reset from
|
||||
// `MacroBang(format_args)` to `MacroAttribute(derive(Clone))` (issue #52363).
|
||||
|
||||
fn main() {
|
||||
format_args!({ #[derive(Clone)] struct S; });
|
||||
//~^ ERROR format argument must be a string literal
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: format argument must be a string literal
|
||||
--> $DIR/expansion-info-reset.rs:5:18
|
||||
--> $DIR/expansion-info-reset.rs:2:18
|
||||
|
|
||||
LL | format_args!({ #[derive(Clone)] struct S; });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
14
src/test/ui/hygiene/hygiene-dodging-1.rs
Normal file
14
src/test/ui/hygiene/hygiene-dodging-1.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// run-pass
|
||||
#![allow(unused_must_use)]
|
||||
|
||||
mod x {
|
||||
pub fn g() -> usize {14}
|
||||
}
|
||||
|
||||
pub fn main(){
|
||||
// should *not* shadow the module x:
|
||||
let x = 9;
|
||||
// use it to avoid warnings:
|
||||
x+3;
|
||||
assert_eq!(x::g(),14);
|
||||
}
|
||||
114
src/test/ui/hygiene/hygiene.rs
Normal file
114
src/test/ui/hygiene/hygiene.rs
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
// run-pass
|
||||
#![allow(unused)]
|
||||
|
||||
fn f() {
|
||||
let x = 0;
|
||||
macro_rules! foo { () => {
|
||||
assert_eq!(x, 0);
|
||||
} }
|
||||
|
||||
let x = 1;
|
||||
foo!();
|
||||
}
|
||||
|
||||
fn g() {
|
||||
let x = 0;
|
||||
macro_rules! m { ($m1:ident, $m2:ident, $x:ident) => {
|
||||
macro_rules! $m1 { () => { ($x, x) } }
|
||||
let x = 1;
|
||||
macro_rules! $m2 { () => { ($x, x) } }
|
||||
} }
|
||||
|
||||
let x = 2;
|
||||
m!(m2, m3, x);
|
||||
|
||||
let x = 3;
|
||||
assert_eq!(m2!(), (2, 0));
|
||||
assert_eq!(m3!(), (2, 1));
|
||||
|
||||
let x = 4;
|
||||
m!(m4, m5, x);
|
||||
assert_eq!(m4!(), (4, 0));
|
||||
assert_eq!(m5!(), (4, 1));
|
||||
}
|
||||
|
||||
mod foo {
|
||||
macro_rules! m {
|
||||
($f:ident : |$x:ident| $e:expr) => {
|
||||
pub fn $f() -> (i32, i32) {
|
||||
let x = 0;
|
||||
let $x = 1;
|
||||
(x, $e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m!(f: |x| x + 10);
|
||||
}
|
||||
|
||||
fn interpolated_pattern() {
|
||||
let x = 0;
|
||||
macro_rules! m {
|
||||
($p:pat, $e:expr) => {
|
||||
let $p = 1;
|
||||
assert_eq!((x, $e), (0, 1));
|
||||
}
|
||||
}
|
||||
|
||||
m!(x, x);
|
||||
}
|
||||
|
||||
fn patterns_in_macro_generated_macros() {
|
||||
let x = 0;
|
||||
macro_rules! m {
|
||||
($a:expr, $b:expr) => {
|
||||
assert_eq!(x, 0);
|
||||
let x = $a;
|
||||
macro_rules! n {
|
||||
() => {
|
||||
(x, $b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let x = 1;
|
||||
m!(2, x);
|
||||
|
||||
let x = 3;
|
||||
assert_eq!(n!(), (2, 1));
|
||||
}
|
||||
|
||||
fn match_hygiene() {
|
||||
let x = 0;
|
||||
|
||||
macro_rules! m {
|
||||
($p:pat, $e:expr) => {
|
||||
for result in &[Ok(1), Err(1)] {
|
||||
match *result {
|
||||
$p => { assert_eq!(($e, x), (1, 0)); }
|
||||
Err(x) => { assert_eq!(($e, x), (2, 1)); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let x = 2;
|
||||
m!(Ok(x), x);
|
||||
}
|
||||
|
||||
fn label_hygiene() {
|
||||
'a: loop {
|
||||
macro_rules! m { () => { break 'a; } }
|
||||
m!();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
f();
|
||||
g();
|
||||
assert_eq!(foo::f(), (0, 11));
|
||||
interpolated_pattern();
|
||||
patterns_in_macro_generated_macros();
|
||||
match_hygiene();
|
||||
}
|
||||
75
src/test/ui/hygiene/hygienic-labels-in-let.rs
Normal file
75
src/test/ui/hygiene/hygienic-labels-in-let.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// run-pass
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
// Test that labels injected by macros do not break hygiene. This
|
||||
// checks cases where the macros invocations are under the rhs of a
|
||||
// let statement.
|
||||
|
||||
// Issue #24278: The label/lifetime shadowing checker from #24162
|
||||
// conservatively ignores hygiene, and thus issues warnings that are
|
||||
// both true- and false-positives for this test.
|
||||
|
||||
macro_rules! loop_x {
|
||||
($e: expr) => {
|
||||
// $e shouldn't be able to interact with this 'x
|
||||
'x: loop { $e }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! while_true {
|
||||
($e: expr) => {
|
||||
// $e shouldn't be able to interact with this 'x
|
||||
'x: while 1 + 1 == 2 { $e }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! run_once {
|
||||
($e: expr) => {
|
||||
// ditto
|
||||
'x: for _ in 0..1 { $e }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mut i = 0;
|
||||
|
||||
let j: isize = {
|
||||
'x: loop {
|
||||
// this 'x should refer to the outer loop, lexically
|
||||
loop_x!(break 'x);
|
||||
i += 1;
|
||||
}
|
||||
i + 1
|
||||
};
|
||||
assert_eq!(j, 1);
|
||||
|
||||
let k: isize = {
|
||||
'x: for _ in 0..1 {
|
||||
// ditto
|
||||
loop_x!(break 'x);
|
||||
i += 1;
|
||||
}
|
||||
i + 1
|
||||
};
|
||||
assert_eq!(k, 1);
|
||||
|
||||
let l: isize = {
|
||||
'x: for _ in 0..1 {
|
||||
// ditto
|
||||
while_true!(break 'x);
|
||||
i += 1;
|
||||
}
|
||||
i + 1
|
||||
};
|
||||
assert_eq!(l, 1);
|
||||
|
||||
let n: isize = {
|
||||
'x: for _ in 0..1 {
|
||||
// ditto
|
||||
run_once!(continue 'x);
|
||||
i += 1;
|
||||
}
|
||||
i + 1
|
||||
};
|
||||
assert_eq!(n, 1);
|
||||
}
|
||||
300
src/test/ui/hygiene/hygienic-labels-in-let.stderr
Normal file
300
src/test/ui/hygiene/hygienic-labels-in-let.stderr
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:15:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
LL | // this 'x should refer to the outer loop, lexically
|
||||
LL | loop_x!(break 'x);
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:47:9
|
||||
|
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:47:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:15:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | loop_x!(break 'x);
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:15:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| ^^
|
||||
| |
|
||||
| first declared here
|
||||
| lifetime 'x already in scope
|
||||
...
|
||||
LL | loop_x!(break 'x);
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:15:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
LL | // ditto
|
||||
LL | loop_x!(break 'x);
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:57:9
|
||||
|
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:57:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:57:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:57:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:22:9
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | while_true!(break 'x);
|
||||
| ---------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:22:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | while_true!(break 'x);
|
||||
| ---------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:22:9
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | while_true!(break 'x);
|
||||
| ---------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:22:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | while_true!(break 'x);
|
||||
| ---------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:22:9
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
LL | // ditto
|
||||
LL | while_true!(break 'x);
|
||||
| ---------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:67:9
|
||||
|
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:67:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:67:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:67:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:67:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:67:9
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:29:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:29:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:29:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:29:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:29:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:29:9
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels-in-let.rs:29:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
LL | // ditto
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
53
src/test/ui/hygiene/hygienic-labels.rs
Normal file
53
src/test/ui/hygiene/hygienic-labels.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// run-pass
|
||||
#![allow(unreachable_code)]
|
||||
// Test that labels injected by macros do not break hygiene.
|
||||
|
||||
// Issue #24278: The label/lifetime shadowing checker from #24162
|
||||
// conservatively ignores hygiene, and thus issues warnings that are
|
||||
// both true- and false-positives for this test.
|
||||
|
||||
macro_rules! loop_x {
|
||||
($e: expr) => {
|
||||
// $e shouldn't be able to interact with this 'x
|
||||
'x: loop { $e }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! run_once {
|
||||
($e: expr) => {
|
||||
// ditto
|
||||
'x: for _ in 0..1 { $e }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! while_x {
|
||||
($e: expr) => {
|
||||
// ditto
|
||||
'x: while 1 + 1 == 2 { $e }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
'x: for _ in 0..1 {
|
||||
// this 'x should refer to the outer loop, lexically
|
||||
loop_x!(break 'x);
|
||||
panic!("break doesn't act hygienically inside for loop");
|
||||
}
|
||||
|
||||
'x: loop {
|
||||
// ditto
|
||||
loop_x!(break 'x);
|
||||
panic!("break doesn't act hygienically inside infinite loop");
|
||||
}
|
||||
|
||||
'x: while 1 + 1 == 2 {
|
||||
while_x!(break 'x);
|
||||
panic!("break doesn't act hygienically inside infinite while loop");
|
||||
}
|
||||
|
||||
'x: for _ in 0..1 {
|
||||
// ditto
|
||||
run_once!(continue 'x);
|
||||
panic!("continue doesn't act hygienically inside for loop");
|
||||
}
|
||||
}
|
||||
299
src/test/ui/hygiene/hygienic-labels.stderr
Normal file
299
src/test/ui/hygiene/hygienic-labels.stderr
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:12:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
LL | // this 'x should refer to the outer loop, lexically
|
||||
LL | loop_x!(break 'x);
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:37:5
|
||||
|
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:37:5
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:12:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | loop_x!(break 'x);
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:12:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| ^^
|
||||
| |
|
||||
| first declared here
|
||||
| lifetime 'x already in scope
|
||||
...
|
||||
LL | loop_x!(break 'x);
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:12:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
LL | // ditto
|
||||
LL | loop_x!(break 'x);
|
||||
| ------------------ in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:43:5
|
||||
|
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:43:5
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:43:5
|
||||
|
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:43:5
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:26:9
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | while_x!(break 'x);
|
||||
| ------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:26:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | while_x!(break 'x);
|
||||
| ------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:26:9
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | while_x!(break 'x);
|
||||
| ------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:26:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | while_x!(break 'x);
|
||||
| ------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:26:9
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 {
|
||||
| -- first declared here
|
||||
LL | while_x!(break 'x);
|
||||
| ------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:48:5
|
||||
|
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:48:5
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:48:5
|
||||
|
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:48:5
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:48:5
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:48:5
|
||||
|
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| ^^ lifetime 'x already in scope
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:19:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:19:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:19:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: loop {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:19:9
|
||||
|
|
||||
LL | 'x: loop { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:19:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 {
|
||||
| -- first declared here
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:19:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: while 1 + 1 == 2 { $e }
|
||||
| -- first declared here
|
||||
...
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
warning: label name `'x` shadows a label name that is already in scope
|
||||
--> $DIR/hygienic-labels.rs:19:9
|
||||
|
|
||||
LL | 'x: for _ in 0..1 { $e }
|
||||
| ^^ lifetime 'x already in scope
|
||||
...
|
||||
LL | 'x: for _ in 0..1 {
|
||||
| -- first declared here
|
||||
LL | // ditto
|
||||
LL | run_once!(continue 'x);
|
||||
| ----------------------- in this macro invocation
|
||||
|
||||
17
src/test/ui/hygiene/issue-44128.rs
Normal file
17
src/test/ui/hygiene/issue-44128.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// check-pass
|
||||
#![allow(unused_must_use)]
|
||||
#![feature(decl_macro)]
|
||||
|
||||
pub macro create_struct($a:ident) {
|
||||
struct $a;
|
||||
impl Clone for $a {
|
||||
fn clone(&self) -> Self {
|
||||
$a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
create_struct!(Test);
|
||||
Test.clone();
|
||||
}
|
||||
17
src/test/ui/hygiene/issue-47311.rs
Normal file
17
src/test/ui/hygiene/issue-47311.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
#![allow(unused)]
|
||||
|
||||
macro m($S:ident, $x:ident) {
|
||||
$S { $x: 0 }
|
||||
}
|
||||
|
||||
mod foo {
|
||||
struct S { x: i32 }
|
||||
|
||||
fn f() { ::m!(S, x); }
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
21
src/test/ui/hygiene/issue-47312.rs
Normal file
21
src/test/ui/hygiene/issue-47312.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
#![allow(unused)]
|
||||
|
||||
mod foo {
|
||||
pub macro m($s:tt, $i:tt) {
|
||||
$s.$i
|
||||
}
|
||||
}
|
||||
|
||||
mod bar {
|
||||
struct S(i32);
|
||||
fn f() {
|
||||
let s = S(0);
|
||||
::foo::m!(s, 0);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
27
src/test/ui/hygiene/items.rs
Normal file
27
src/test/ui/hygiene/items.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
pub macro m($foo:ident, $f:ident, $e:expr) {
|
||||
mod foo {
|
||||
pub fn f() -> u32 { 0 }
|
||||
pub fn $f() -> u64 { 0 }
|
||||
}
|
||||
|
||||
mod $foo {
|
||||
pub fn f() -> i32 { 0 }
|
||||
pub fn $f() -> i64 { 0 }
|
||||
}
|
||||
|
||||
let _: u32 = foo::f();
|
||||
let _: u64 = foo::$f();
|
||||
let _: i32 = $foo::f();
|
||||
let _: i64 = $foo::$f();
|
||||
let _: i64 = $e;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
m!(foo, f, foo::f());
|
||||
let _: i64 = foo::f();
|
||||
}
|
||||
42
src/test/ui/hygiene/legacy_interaction.rs
Normal file
42
src/test/ui/hygiene/legacy_interaction.rs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// check-pass
|
||||
#![allow(dead_code)]
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
// aux-build:legacy_interaction.rs
|
||||
|
||||
#![feature(decl_macro)]
|
||||
#[allow(unused)]
|
||||
|
||||
extern crate legacy_interaction;
|
||||
// ^ defines
|
||||
// ```rust
|
||||
// macro_rules! m {
|
||||
// () => {
|
||||
// fn f() {} // (1)
|
||||
// g() // (2)
|
||||
// }
|
||||
// }
|
||||
// ```rust
|
||||
|
||||
mod def_site {
|
||||
// Unless this macro opts out of hygiene, it should resolve the same wherever it is invoked.
|
||||
pub macro m2() {
|
||||
::legacy_interaction::m!();
|
||||
f(); // This should resolve to (1)
|
||||
fn g() {} // We want (2) resolve to this, not to (4)
|
||||
}
|
||||
}
|
||||
|
||||
mod use_site {
|
||||
fn test() {
|
||||
fn f() -> bool { true } // (3)
|
||||
fn g() -> bool { true } // (4)
|
||||
|
||||
::def_site::m2!();
|
||||
|
||||
let _: bool = f(); // This should resolve to (3)
|
||||
let _: bool = g(); // This should resolve to (4)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
24
src/test/ui/hygiene/lexical.rs
Normal file
24
src/test/ui/hygiene/lexical.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
mod bar {
|
||||
mod baz {
|
||||
pub fn f() {}
|
||||
}
|
||||
|
||||
pub macro m($f:ident) {
|
||||
baz::f();
|
||||
let _: i32 = $f();
|
||||
{
|
||||
fn $f() -> u32 { 0 }
|
||||
let _: u32 = $f();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn f() -> i32 { 0 }
|
||||
bar::m!(f);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
// check-pass
|
||||
// aux-build:local_inner_macros.rs
|
||||
|
||||
extern crate local_inner_macros;
|
||||
|
|
|
|||
25
src/test/ui/hygiene/specialization.rs
Normal file
25
src/test/ui/hygiene/specialization.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// run-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
trait Tr {
|
||||
fn f(&self) -> &'static str {
|
||||
"This shouldn't happen"
|
||||
}
|
||||
}
|
||||
|
||||
pub macro m($t:ty) {
|
||||
impl Tr for $t {
|
||||
fn f(&self) -> &'static str {
|
||||
"Run me"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct S;
|
||||
m!(S);
|
||||
|
||||
fn main() {
|
||||
assert_eq!(S.f(), "Run me");
|
||||
}
|
||||
20
src/test/ui/hygiene/trait_items-2.rs
Normal file
20
src/test/ui/hygiene/trait_items-2.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
macro m($T:ident, $f:ident) {
|
||||
pub trait $T {
|
||||
fn f(&self) -> u32 { 0 }
|
||||
fn $f(&self) -> i32 { 0 }
|
||||
}
|
||||
impl $T for () {}
|
||||
|
||||
let _: u32 = ().f();
|
||||
let _: i32 = ().$f();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
m!(T, f);
|
||||
let _: i32 = ().f();
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
// check-pass
|
||||
// aux-build:transparent-basic.rs
|
||||
|
||||
#![feature(decl_macro, rustc_attrs)]
|
||||
|
|
|
|||
14
src/test/ui/hygiene/ty_params.rs
Normal file
14
src/test/ui/hygiene/ty_params.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
macro m($T:ident) {
|
||||
fn f<T, $T>(t: T, t2: $T) -> (T, $T) {
|
||||
(t, t2)
|
||||
}
|
||||
}
|
||||
|
||||
m!(T);
|
||||
|
||||
fn main() {}
|
||||
34
src/test/ui/hygiene/wrap_unhygienic_example.rs
Normal file
34
src/test/ui/hygiene/wrap_unhygienic_example.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// check-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
// aux-build:my_crate.rs
|
||||
// aux-build:unhygienic_example.rs
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
extern crate unhygienic_example;
|
||||
extern crate my_crate; // (b)
|
||||
|
||||
// Hygienic version of `unhygienic_macro`.
|
||||
pub macro hygienic_macro() {
|
||||
fn g() {} // (c)
|
||||
::unhygienic_example::unhygienic_macro!();
|
||||
// ^ Even though we invoke an unhygienic macro, `hygienic_macro` remains hygienic.
|
||||
// In the above expansion:
|
||||
// (1) `my_crate` always resolves to (b) regardless of invocation site.
|
||||
// (2) The defined function `f` is only usable inside this macro definition.
|
||||
// (3) `g` always resolves to (c) regardless of invocation site.
|
||||
// (4) `$crate::g` remains hygienic and continues to resolve to (a).
|
||||
|
||||
f();
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn test_hygienic_macro() {
|
||||
hygienic_macro!();
|
||||
|
||||
fn f() {} // (d) no conflict
|
||||
f(); // resolves to (d)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
12
src/test/ui/hygiene/xcrate.rs
Normal file
12
src/test/ui/hygiene/xcrate.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// run-pass
|
||||
// ignore-pretty pretty-printing is unhygienic
|
||||
|
||||
// aux-build:xcrate.rs
|
||||
|
||||
#![feature(decl_macro)]
|
||||
|
||||
extern crate xcrate;
|
||||
|
||||
fn main() {
|
||||
xcrate::test!();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue