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:
Matthew Jasper 2019-07-14 11:34:13 +01:00
parent 96234d5363
commit 03178f31c4
26 changed files with 14 additions and 21 deletions

View file

@ -0,0 +1,9 @@
// ignore-pretty pretty-printing is unhygienic
#[macro_export]
macro_rules! m {
() => {
fn f() {} // (2)
g(); // (1)
}
}

View file

@ -0,0 +1 @@
pub fn f() {}

View 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
}

View 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() {}
}

View file

@ -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)]

View file

@ -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

View file

@ -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; });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View 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);
}

View 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();
}

View 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);
}

View 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

View 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");
}
}

View 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

View 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();
}

View 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() {}

View 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() {}

View 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();
}

View 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() {}

View 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);
}

View file

@ -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;

View 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");
}

View 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();
}

View file

@ -1,4 +1,4 @@
// build-pass (FIXME(62277): could be check-pass?)
// check-pass
// aux-build:transparent-basic.rs
#![feature(decl_macro, rustc_attrs)]

View 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() {}

View 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() {}

View 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!();
}