From 03178f31c461af42bb61815cc206443c5842ebe0 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 14 Jul 2019 11:34:13 +0100 Subject: Change all run-pass hygiene tests to `ui` tests Change some tests to `check-pass` that are only testing name resolution. --- .../hygiene/auxiliary/legacy_interaction.rs | 10 - src/test/run-pass/hygiene/auxiliary/my_crate.rs | 2 - .../hygiene/auxiliary/unhygienic_example.rs | 28 -- src/test/run-pass/hygiene/auxiliary/xcrate.rs | 29 -- src/test/run-pass/hygiene/hygiene-dodging-1.rs | 14 - src/test/run-pass/hygiene/hygiene.rs | 114 -------- .../run-pass/hygiene/hygienic-labels-in-let.rs | 75 ------ .../run-pass/hygiene/hygienic-labels-in-let.stderr | 300 --------------------- src/test/run-pass/hygiene/hygienic-labels.rs | 53 ---- src/test/run-pass/hygiene/hygienic-labels.stderr | 299 -------------------- src/test/run-pass/hygiene/issue-44128.rs | 17 -- src/test/run-pass/hygiene/issue-47311.rs | 17 -- src/test/run-pass/hygiene/issue-47312.rs | 21 -- src/test/run-pass/hygiene/items.rs | 27 -- src/test/run-pass/hygiene/legacy_interaction.rs | 42 --- src/test/run-pass/hygiene/lexical.rs | 24 -- src/test/run-pass/hygiene/specialization.rs | 25 -- src/test/run-pass/hygiene/trait_items.rs | 20 -- src/test/run-pass/hygiene/ty_params.rs | 14 - .../run-pass/hygiene/wrap_unhygienic_example.rs | 34 --- src/test/run-pass/hygiene/xcrate.rs | 12 - .../ui/hygiene/auxiliary/legacy_interaction.rs | 9 + src/test/ui/hygiene/auxiliary/my_crate.rs | 1 + .../ui/hygiene/auxiliary/unhygienic_example.rs | 27 ++ src/test/ui/hygiene/auxiliary/xcrate.rs | 28 ++ src/test/ui/hygiene/dollar-crate-modern.rs | 2 +- src/test/ui/hygiene/expansion-info-reset.rs | 3 - src/test/ui/hygiene/expansion-info-reset.stderr | 2 +- src/test/ui/hygiene/hygiene-dodging-1.rs | 14 + src/test/ui/hygiene/hygiene.rs | 114 ++++++++ src/test/ui/hygiene/hygienic-labels-in-let.rs | 75 ++++++ src/test/ui/hygiene/hygienic-labels-in-let.stderr | 300 +++++++++++++++++++++ src/test/ui/hygiene/hygienic-labels.rs | 53 ++++ src/test/ui/hygiene/hygienic-labels.stderr | 299 ++++++++++++++++++++ src/test/ui/hygiene/issue-44128.rs | 17 ++ src/test/ui/hygiene/issue-47311.rs | 17 ++ src/test/ui/hygiene/issue-47312.rs | 21 ++ src/test/ui/hygiene/items.rs | 27 ++ src/test/ui/hygiene/legacy_interaction.rs | 42 +++ src/test/ui/hygiene/lexical.rs | 24 ++ src/test/ui/hygiene/local_inner_macros.rs | 2 +- src/test/ui/hygiene/specialization.rs | 25 ++ src/test/ui/hygiene/trait_items-2.rs | 20 ++ src/test/ui/hygiene/transparent-basic.rs | 2 +- src/test/ui/hygiene/ty_params.rs | 14 + src/test/ui/hygiene/wrap_unhygienic_example.rs | 34 +++ src/test/ui/hygiene/xcrate.rs | 12 + 47 files changed, 1177 insertions(+), 1184 deletions(-) delete mode 100644 src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs delete mode 100644 src/test/run-pass/hygiene/auxiliary/my_crate.rs delete mode 100644 src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs delete mode 100644 src/test/run-pass/hygiene/auxiliary/xcrate.rs delete mode 100644 src/test/run-pass/hygiene/hygiene-dodging-1.rs delete mode 100644 src/test/run-pass/hygiene/hygiene.rs delete mode 100644 src/test/run-pass/hygiene/hygienic-labels-in-let.rs delete mode 100644 src/test/run-pass/hygiene/hygienic-labels-in-let.stderr delete mode 100644 src/test/run-pass/hygiene/hygienic-labels.rs delete mode 100644 src/test/run-pass/hygiene/hygienic-labels.stderr delete mode 100644 src/test/run-pass/hygiene/issue-44128.rs delete mode 100644 src/test/run-pass/hygiene/issue-47311.rs delete mode 100644 src/test/run-pass/hygiene/issue-47312.rs delete mode 100644 src/test/run-pass/hygiene/items.rs delete mode 100644 src/test/run-pass/hygiene/legacy_interaction.rs delete mode 100644 src/test/run-pass/hygiene/lexical.rs delete mode 100644 src/test/run-pass/hygiene/specialization.rs delete mode 100644 src/test/run-pass/hygiene/trait_items.rs delete mode 100644 src/test/run-pass/hygiene/ty_params.rs delete mode 100644 src/test/run-pass/hygiene/wrap_unhygienic_example.rs delete mode 100644 src/test/run-pass/hygiene/xcrate.rs create mode 100644 src/test/ui/hygiene/auxiliary/legacy_interaction.rs create mode 100644 src/test/ui/hygiene/auxiliary/my_crate.rs create mode 100644 src/test/ui/hygiene/auxiliary/unhygienic_example.rs create mode 100644 src/test/ui/hygiene/auxiliary/xcrate.rs create mode 100644 src/test/ui/hygiene/hygiene-dodging-1.rs create mode 100644 src/test/ui/hygiene/hygiene.rs create mode 100644 src/test/ui/hygiene/hygienic-labels-in-let.rs create mode 100644 src/test/ui/hygiene/hygienic-labels-in-let.stderr create mode 100644 src/test/ui/hygiene/hygienic-labels.rs create mode 100644 src/test/ui/hygiene/hygienic-labels.stderr create mode 100644 src/test/ui/hygiene/issue-44128.rs create mode 100644 src/test/ui/hygiene/issue-47311.rs create mode 100644 src/test/ui/hygiene/issue-47312.rs create mode 100644 src/test/ui/hygiene/items.rs create mode 100644 src/test/ui/hygiene/legacy_interaction.rs create mode 100644 src/test/ui/hygiene/lexical.rs create mode 100644 src/test/ui/hygiene/specialization.rs create mode 100644 src/test/ui/hygiene/trait_items-2.rs create mode 100644 src/test/ui/hygiene/ty_params.rs create mode 100644 src/test/ui/hygiene/wrap_unhygienic_example.rs create mode 100644 src/test/ui/hygiene/xcrate.rs (limited to 'src') diff --git a/src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs b/src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs deleted file mode 100644 index 0774fbecac1..00000000000 --- a/src/test/run-pass/hygiene/auxiliary/legacy_interaction.rs +++ /dev/null @@ -1,10 +0,0 @@ -// run-pass -// ignore-pretty pretty-printing is unhygienic - -#[macro_export] -macro_rules! m { - () => { - fn f() {} // (2) - g(); // (1) - } -} diff --git a/src/test/run-pass/hygiene/auxiliary/my_crate.rs b/src/test/run-pass/hygiene/auxiliary/my_crate.rs deleted file mode 100644 index 5a7412e4bf5..00000000000 --- a/src/test/run-pass/hygiene/auxiliary/my_crate.rs +++ /dev/null @@ -1,2 +0,0 @@ -// run-pass -pub fn f() {} diff --git a/src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs b/src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs deleted file mode 100644 index 3f66748bf30..00000000000 --- a/src/test/run-pass/hygiene/auxiliary/unhygienic_example.rs +++ /dev/null @@ -1,28 +0,0 @@ -// run-pass -#![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 -} diff --git a/src/test/run-pass/hygiene/auxiliary/xcrate.rs b/src/test/run-pass/hygiene/auxiliary/xcrate.rs deleted file mode 100644 index 3862914d584..00000000000 --- a/src/test/run-pass/hygiene/auxiliary/xcrate.rs +++ /dev/null @@ -1,29 +0,0 @@ -// run-pass -#![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() {} -} diff --git a/src/test/run-pass/hygiene/hygiene-dodging-1.rs b/src/test/run-pass/hygiene/hygiene-dodging-1.rs deleted file mode 100644 index 69e47e82ba5..00000000000 --- a/src/test/run-pass/hygiene/hygiene-dodging-1.rs +++ /dev/null @@ -1,14 +0,0 @@ -// 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); -} diff --git a/src/test/run-pass/hygiene/hygiene.rs b/src/test/run-pass/hygiene/hygiene.rs deleted file mode 100644 index fb351cf0faf..00000000000 --- a/src/test/run-pass/hygiene/hygiene.rs +++ /dev/null @@ -1,114 +0,0 @@ -// 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(); -} diff --git a/src/test/run-pass/hygiene/hygienic-labels-in-let.rs b/src/test/run-pass/hygiene/hygienic-labels-in-let.rs deleted file mode 100644 index fb9523b547d..00000000000 --- a/src/test/run-pass/hygiene/hygienic-labels-in-let.rs +++ /dev/null @@ -1,75 +0,0 @@ -// 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); -} diff --git a/src/test/run-pass/hygiene/hygienic-labels-in-let.stderr b/src/test/run-pass/hygiene/hygienic-labels-in-let.stderr deleted file mode 100644 index 9c906749f8c..00000000000 --- a/src/test/run-pass/hygiene/hygienic-labels-in-let.stderr +++ /dev/null @@ -1,300 +0,0 @@ -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 - diff --git a/src/test/run-pass/hygiene/hygienic-labels.rs b/src/test/run-pass/hygiene/hygienic-labels.rs deleted file mode 100644 index a364dd9c887..00000000000 --- a/src/test/run-pass/hygiene/hygienic-labels.rs +++ /dev/null @@ -1,53 +0,0 @@ -// 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"); - } -} diff --git a/src/test/run-pass/hygiene/hygienic-labels.stderr b/src/test/run-pass/hygiene/hygienic-labels.stderr deleted file mode 100644 index d88dfce540e..00000000000 --- a/src/test/run-pass/hygiene/hygienic-labels.stderr +++ /dev/null @@ -1,299 +0,0 @@ -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 - diff --git a/src/test/run-pass/hygiene/issue-44128.rs b/src/test/run-pass/hygiene/issue-44128.rs deleted file mode 100644 index 23ced9ae530..00000000000 --- a/src/test/run-pass/hygiene/issue-44128.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-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(); -} diff --git a/src/test/run-pass/hygiene/issue-47311.rs b/src/test/run-pass/hygiene/issue-47311.rs deleted file mode 100644 index 856184fbc83..00000000000 --- a/src/test/run-pass/hygiene/issue-47311.rs +++ /dev/null @@ -1,17 +0,0 @@ -// run-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() {} diff --git a/src/test/run-pass/hygiene/issue-47312.rs b/src/test/run-pass/hygiene/issue-47312.rs deleted file mode 100644 index 88e7a028f92..00000000000 --- a/src/test/run-pass/hygiene/issue-47312.rs +++ /dev/null @@ -1,21 +0,0 @@ -// run-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() {} diff --git a/src/test/run-pass/hygiene/items.rs b/src/test/run-pass/hygiene/items.rs deleted file mode 100644 index cdc271386b7..00000000000 --- a/src/test/run-pass/hygiene/items.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-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(); -} diff --git a/src/test/run-pass/hygiene/legacy_interaction.rs b/src/test/run-pass/hygiene/legacy_interaction.rs deleted file mode 100644 index a5460a89f13..00000000000 --- a/src/test/run-pass/hygiene/legacy_interaction.rs +++ /dev/null @@ -1,42 +0,0 @@ -// run-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() {} diff --git a/src/test/run-pass/hygiene/lexical.rs b/src/test/run-pass/hygiene/lexical.rs deleted file mode 100644 index 20bda5508c8..00000000000 --- a/src/test/run-pass/hygiene/lexical.rs +++ /dev/null @@ -1,24 +0,0 @@ -// run-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); -} diff --git a/src/test/run-pass/hygiene/specialization.rs b/src/test/run-pass/hygiene/specialization.rs deleted file mode 100644 index 656aa880ad1..00000000000 --- a/src/test/run-pass/hygiene/specialization.rs +++ /dev/null @@ -1,25 +0,0 @@ -// 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"); -} diff --git a/src/test/run-pass/hygiene/trait_items.rs b/src/test/run-pass/hygiene/trait_items.rs deleted file mode 100644 index 680f228c986..00000000000 --- a/src/test/run-pass/hygiene/trait_items.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-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(); -} diff --git a/src/test/run-pass/hygiene/ty_params.rs b/src/test/run-pass/hygiene/ty_params.rs deleted file mode 100644 index dce4bd6489c..00000000000 --- a/src/test/run-pass/hygiene/ty_params.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass -// ignore-pretty pretty-printing is unhygienic - -#![feature(decl_macro)] - -macro m($T:ident) { - fn f(t: T, t2: $T) -> (T, $T) { - (t, t2) - } -} - -m!(T); - -fn main() {} diff --git a/src/test/run-pass/hygiene/wrap_unhygienic_example.rs b/src/test/run-pass/hygiene/wrap_unhygienic_example.rs deleted file mode 100644 index e0277e2bb74..00000000000 --- a/src/test/run-pass/hygiene/wrap_unhygienic_example.rs +++ /dev/null @@ -1,34 +0,0 @@ -// run-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() {} diff --git a/src/test/run-pass/hygiene/xcrate.rs b/src/test/run-pass/hygiene/xcrate.rs deleted file mode 100644 index 6981ce3f687..00000000000 --- a/src/test/run-pass/hygiene/xcrate.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -// ignore-pretty pretty-printing is unhygienic - -// aux-build:xcrate.rs - -#![feature(decl_macro)] - -extern crate xcrate; - -fn main() { - xcrate::test!(); -} diff --git a/src/test/ui/hygiene/auxiliary/legacy_interaction.rs b/src/test/ui/hygiene/auxiliary/legacy_interaction.rs new file mode 100644 index 00000000000..90d5243b74b --- /dev/null +++ b/src/test/ui/hygiene/auxiliary/legacy_interaction.rs @@ -0,0 +1,9 @@ +// ignore-pretty pretty-printing is unhygienic + +#[macro_export] +macro_rules! m { + () => { + fn f() {} // (2) + g(); // (1) + } +} diff --git a/src/test/ui/hygiene/auxiliary/my_crate.rs b/src/test/ui/hygiene/auxiliary/my_crate.rs new file mode 100644 index 00000000000..cdc6c27d800 --- /dev/null +++ b/src/test/ui/hygiene/auxiliary/my_crate.rs @@ -0,0 +1 @@ +pub fn f() {} diff --git a/src/test/ui/hygiene/auxiliary/unhygienic_example.rs b/src/test/ui/hygiene/auxiliary/unhygienic_example.rs new file mode 100644 index 00000000000..8e6e8f9b32f --- /dev/null +++ b/src/test/ui/hygiene/auxiliary/unhygienic_example.rs @@ -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 +} diff --git a/src/test/ui/hygiene/auxiliary/xcrate.rs b/src/test/ui/hygiene/auxiliary/xcrate.rs new file mode 100644 index 00000000000..f5a911f57df --- /dev/null +++ b/src/test/ui/hygiene/auxiliary/xcrate.rs @@ -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() {} +} diff --git a/src/test/ui/hygiene/dollar-crate-modern.rs b/src/test/ui/hygiene/dollar-crate-modern.rs index 9c25e138d2c..a432fb6eee1 100644 --- a/src/test/ui/hygiene/dollar-crate-modern.rs +++ b/src/test/ui/hygiene/dollar-crate-modern.rs @@ -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)] diff --git a/src/test/ui/hygiene/expansion-info-reset.rs b/src/test/ui/hygiene/expansion-info-reset.rs index 5c384c4ada9..fa5f712121d 100644 --- a/src/test/ui/hygiene/expansion-info-reset.rs +++ b/src/test/ui/hygiene/expansion-info-reset.rs @@ -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 diff --git a/src/test/ui/hygiene/expansion-info-reset.stderr b/src/test/ui/hygiene/expansion-info-reset.stderr index 9dd954b16cd..d8b602ce1c6 100644 --- a/src/test/ui/hygiene/expansion-info-reset.stderr +++ b/src/test/ui/hygiene/expansion-info-reset.stderr @@ -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; }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/hygiene/hygiene-dodging-1.rs b/src/test/ui/hygiene/hygiene-dodging-1.rs new file mode 100644 index 00000000000..69e47e82ba5 --- /dev/null +++ b/src/test/ui/hygiene/hygiene-dodging-1.rs @@ -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); +} diff --git a/src/test/ui/hygiene/hygiene.rs b/src/test/ui/hygiene/hygiene.rs new file mode 100644 index 00000000000..fb351cf0faf --- /dev/null +++ b/src/test/ui/hygiene/hygiene.rs @@ -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(); +} diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.rs b/src/test/ui/hygiene/hygienic-labels-in-let.rs new file mode 100644 index 00000000000..fb9523b547d --- /dev/null +++ b/src/test/ui/hygiene/hygienic-labels-in-let.rs @@ -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); +} diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.stderr b/src/test/ui/hygiene/hygienic-labels-in-let.stderr new file mode 100644 index 00000000000..9c906749f8c --- /dev/null +++ b/src/test/ui/hygiene/hygienic-labels-in-let.stderr @@ -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 + diff --git a/src/test/ui/hygiene/hygienic-labels.rs b/src/test/ui/hygiene/hygienic-labels.rs new file mode 100644 index 00000000000..a364dd9c887 --- /dev/null +++ b/src/test/ui/hygiene/hygienic-labels.rs @@ -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"); + } +} diff --git a/src/test/ui/hygiene/hygienic-labels.stderr b/src/test/ui/hygiene/hygienic-labels.stderr new file mode 100644 index 00000000000..d88dfce540e --- /dev/null +++ b/src/test/ui/hygiene/hygienic-labels.stderr @@ -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 + diff --git a/src/test/ui/hygiene/issue-44128.rs b/src/test/ui/hygiene/issue-44128.rs new file mode 100644 index 00000000000..5e03bdb8c5b --- /dev/null +++ b/src/test/ui/hygiene/issue-44128.rs @@ -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(); +} diff --git a/src/test/ui/hygiene/issue-47311.rs b/src/test/ui/hygiene/issue-47311.rs new file mode 100644 index 00000000000..5c2379a8aba --- /dev/null +++ b/src/test/ui/hygiene/issue-47311.rs @@ -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() {} diff --git a/src/test/ui/hygiene/issue-47312.rs b/src/test/ui/hygiene/issue-47312.rs new file mode 100644 index 00000000000..bbcb3a7f393 --- /dev/null +++ b/src/test/ui/hygiene/issue-47312.rs @@ -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() {} diff --git a/src/test/ui/hygiene/items.rs b/src/test/ui/hygiene/items.rs new file mode 100644 index 00000000000..1c625a9728c --- /dev/null +++ b/src/test/ui/hygiene/items.rs @@ -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(); +} diff --git a/src/test/ui/hygiene/legacy_interaction.rs b/src/test/ui/hygiene/legacy_interaction.rs new file mode 100644 index 00000000000..52008eed515 --- /dev/null +++ b/src/test/ui/hygiene/legacy_interaction.rs @@ -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() {} diff --git a/src/test/ui/hygiene/lexical.rs b/src/test/ui/hygiene/lexical.rs new file mode 100644 index 00000000000..3d25c720989 --- /dev/null +++ b/src/test/ui/hygiene/lexical.rs @@ -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); +} diff --git a/src/test/ui/hygiene/local_inner_macros.rs b/src/test/ui/hygiene/local_inner_macros.rs index f361e3d5d49..71ffcac40d3 100644 --- a/src/test/ui/hygiene/local_inner_macros.rs +++ b/src/test/ui/hygiene/local_inner_macros.rs @@ -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; diff --git a/src/test/ui/hygiene/specialization.rs b/src/test/ui/hygiene/specialization.rs new file mode 100644 index 00000000000..656aa880ad1 --- /dev/null +++ b/src/test/ui/hygiene/specialization.rs @@ -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"); +} diff --git a/src/test/ui/hygiene/trait_items-2.rs b/src/test/ui/hygiene/trait_items-2.rs new file mode 100644 index 00000000000..39edfc37d69 --- /dev/null +++ b/src/test/ui/hygiene/trait_items-2.rs @@ -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(); +} diff --git a/src/test/ui/hygiene/transparent-basic.rs b/src/test/ui/hygiene/transparent-basic.rs index 69dfc524989..bfa1713e4ed 100644 --- a/src/test/ui/hygiene/transparent-basic.rs +++ b/src/test/ui/hygiene/transparent-basic.rs @@ -1,4 +1,4 @@ -// build-pass (FIXME(62277): could be check-pass?) +// check-pass // aux-build:transparent-basic.rs #![feature(decl_macro, rustc_attrs)] diff --git a/src/test/ui/hygiene/ty_params.rs b/src/test/ui/hygiene/ty_params.rs new file mode 100644 index 00000000000..b296bfe5988 --- /dev/null +++ b/src/test/ui/hygiene/ty_params.rs @@ -0,0 +1,14 @@ +// check-pass +// ignore-pretty pretty-printing is unhygienic + +#![feature(decl_macro)] + +macro m($T:ident) { + fn f(t: T, t2: $T) -> (T, $T) { + (t, t2) + } +} + +m!(T); + +fn main() {} diff --git a/src/test/ui/hygiene/wrap_unhygienic_example.rs b/src/test/ui/hygiene/wrap_unhygienic_example.rs new file mode 100644 index 00000000000..50c6b35ab18 --- /dev/null +++ b/src/test/ui/hygiene/wrap_unhygienic_example.rs @@ -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() {} diff --git a/src/test/ui/hygiene/xcrate.rs b/src/test/ui/hygiene/xcrate.rs new file mode 100644 index 00000000000..6981ce3f687 --- /dev/null +++ b/src/test/ui/hygiene/xcrate.rs @@ -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!(); +} -- cgit 1.4.1-3-g733a5 From a4a7bb9a3f72505efb6ca9856af45287c8685d5e Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Mon, 15 Jul 2019 22:26:45 +0100 Subject: Make pretty-expanded-hygiene a `ui` test `normalize-stdout-test` removes the need for Make, and it can be updated with `--bless` this way --- .../pretty-expanded-hygiene/Makefile | 21 --------------------- .../pretty-expanded-hygiene/input.pp.rs | 9 --------- .../pretty-expanded-hygiene/input.rs | 14 -------------- src/test/ui/hygiene/unpretty-debug.rs | 20 ++++++++++++++++++++ src/test/ui/hygiene/unpretty-debug.stdout | 15 +++++++++++++++ 5 files changed, 35 insertions(+), 44 deletions(-) delete mode 100644 src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile delete mode 100644 src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs delete mode 100644 src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs create mode 100644 src/test/ui/hygiene/unpretty-debug.rs create mode 100644 src/test/ui/hygiene/unpretty-debug.stdout (limited to 'src') diff --git a/src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile b/src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile deleted file mode 100644 index 136d7643ade..00000000000 --- a/src/test/run-make-fulldeps/pretty-expanded-hygiene/Makefile +++ /dev/null @@ -1,21 +0,0 @@ --include ../tools.mk - -REPLACEMENT := s/[0-9][0-9]*\#[0-9][0-9]*/$(shell date)/g - -all: - $(RUSTC) -o $(TMPDIR)/input.out -Z unstable-options \ - --pretty expanded,hygiene input.rs - - # the name/ctxt numbers are very internals-dependent and thus - # change relatively frequently, and testing for their exact values - # them will fail annoyingly, so we just check their positions - # (using a non-constant replacement like this will make it less - # likely the compiler matches whatever other dummy value we - # choose). - # - # (These need to be out-of-place because OSX/BSD & GNU sed - # differ.) - sed "$(REPLACEMENT)" input.pp.rs > $(TMPDIR)/input.pp.rs - sed "$(REPLACEMENT)" $(TMPDIR)/input.out > $(TMPDIR)/input.out.replaced - - diff -u $(TMPDIR)/input.out.replaced $(TMPDIR)/input.pp.rs diff --git a/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs deleted file mode 100644 index 570dece023d..00000000000 --- a/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.pp.rs +++ /dev/null @@ -1,9 +0,0 @@ -// minimal junk -#![feature /* 0#0 */(no_core)] -#![no_core /* 0#0 */] - -macro_rules! foo /* 0#0 */ { ($ x : ident) => { y + $ x } } - -fn bar /* 0#0 */() { let x /* 0#0 */ = 1; y /* 0#1 */ + x /* 0#0 */ } - -fn y /* 0#0 */() { } diff --git a/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs b/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs deleted file mode 100644 index ed3b48dbdc1..00000000000 --- a/src/test/run-make-fulldeps/pretty-expanded-hygiene/input.rs +++ /dev/null @@ -1,14 +0,0 @@ -// minimal junk -#![feature(no_core)] -#![no_core] - -macro_rules! foo { - ($x: ident) => { y + $x } -} - -fn bar() { - let x = 1; - foo!(x) -} - -fn y() {} diff --git a/src/test/ui/hygiene/unpretty-debug.rs b/src/test/ui/hygiene/unpretty-debug.rs new file mode 100644 index 00000000000..6e936bb3d83 --- /dev/null +++ b/src/test/ui/hygiene/unpretty-debug.rs @@ -0,0 +1,20 @@ +// check-pass +// compile-flags: -Zunpretty=expanded,hygiene + +// Don't break whenever Symbol numbering changes +// normalize-stdout-test "\d+#" -> "0#" + +// minimal junk +#![feature(no_core)] +#![no_core] + +macro_rules! foo { + ($x: ident) => { y + $x } +} + +fn bar() { + let x = 1; + foo!(x) +} + +fn y() {} diff --git a/src/test/ui/hygiene/unpretty-debug.stdout b/src/test/ui/hygiene/unpretty-debug.stdout new file mode 100644 index 00000000000..beac4c17abf --- /dev/null +++ b/src/test/ui/hygiene/unpretty-debug.stdout @@ -0,0 +1,15 @@ +// check-pass +// compile-flags: -Zunpretty=expanded,hygiene + +// Don't break whenever Symbol numbering changes +// normalize-stdout-test "\d+#" -> "0#" + +// minimal junk +#![feature /* 0#0 */(no_core)] +#![no_core /* 0#0 */] + +macro_rules! foo /* 0#0 */ { ($ x : ident) => { y + $ x } } + +fn bar /* 0#0 */() { let x /* 0#0 */ = 1; y /* 0#1 */ + x /* 0#0 */ } + +fn y /* 0#0 */() { } -- cgit 1.4.1-3-g733a5