summaryrefslogtreecommitdiffstats
path: root/src/test/ui/hygiene/auxiliary
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/hygiene/auxiliary')
-rw-r--r--src/test/ui/hygiene/auxiliary/codegen-attrs.rs10
-rw-r--r--src/test/ui/hygiene/auxiliary/def-site-async-await.rs7
-rw-r--r--src/test/ui/hygiene/auxiliary/fields.rs73
-rw-r--r--src/test/ui/hygiene/auxiliary/intercrate.rs46
-rw-r--r--src/test/ui/hygiene/auxiliary/legacy_interaction.rs9
-rw-r--r--src/test/ui/hygiene/auxiliary/local_inner_macros.rs19
-rw-r--r--src/test/ui/hygiene/auxiliary/methods.rs160
-rw-r--r--src/test/ui/hygiene/auxiliary/my_crate.rs1
-rw-r--r--src/test/ui/hygiene/auxiliary/needs_hygiene.rs5
-rw-r--r--src/test/ui/hygiene/auxiliary/nested-dollar-crate.rs14
-rw-r--r--src/test/ui/hygiene/auxiliary/not-libstd.rs1
-rw-r--r--src/test/ui/hygiene/auxiliary/opaque-hygiene.rs21
-rw-r--r--src/test/ui/hygiene/auxiliary/pub_hygiene.rs7
-rw-r--r--src/test/ui/hygiene/auxiliary/stdlib-prelude.rs3
-rw-r--r--src/test/ui/hygiene/auxiliary/transparent-basic.rs6
-rw-r--r--src/test/ui/hygiene/auxiliary/unhygienic_example.rs27
-rw-r--r--src/test/ui/hygiene/auxiliary/use_by_macro.rs15
-rw-r--r--src/test/ui/hygiene/auxiliary/variants.rs36
-rw-r--r--src/test/ui/hygiene/auxiliary/xcrate.rs28
19 files changed, 488 insertions, 0 deletions
diff --git a/src/test/ui/hygiene/auxiliary/codegen-attrs.rs b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs
new file mode 100644
index 000000000..74afedbeb
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/codegen-attrs.rs
@@ -0,0 +1,10 @@
+#![feature(decl_macro)]
+
+macro m($f:ident) {
+ #[export_name = "export_function_name"]
+ pub fn $f() -> i32 {
+ 2
+ }
+}
+
+m!(rust_function_name);
diff --git a/src/test/ui/hygiene/auxiliary/def-site-async-await.rs b/src/test/ui/hygiene/auxiliary/def-site-async-await.rs
new file mode 100644
index 000000000..f7e9b8013
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/def-site-async-await.rs
@@ -0,0 +1,7 @@
+// edition:2018
+
+extern crate opaque_hygiene;
+
+pub async fn serve() {
+ opaque_hygiene::make_it!();
+}
diff --git a/src/test/ui/hygiene/auxiliary/fields.rs b/src/test/ui/hygiene/auxiliary/fields.rs
new file mode 100644
index 000000000..733d11a9e
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/fields.rs
@@ -0,0 +1,73 @@
+#![feature(decl_macro)]
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum Field {
+ RootCtxt,
+ MacroCtxt,
+}
+
+#[rustfmt::skip]
+macro x(
+ $macro_name:ident,
+ $macro2_name:ident,
+ $type_name:ident,
+ $field_name:ident,
+ $const_name:ident
+) {
+ #[derive(Copy, Clone)]
+ pub struct $type_name {
+ pub field: Field,
+ pub $field_name: Field,
+ }
+
+ pub const $const_name: $type_name =
+ $type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt };
+
+ #[macro_export]
+ macro_rules! $macro_name {
+ (check_fields_of $e:expr) => {{
+ let e = $e;
+ assert_eq!(e.field, Field::MacroCtxt);
+ assert_eq!(e.$field_name, Field::RootCtxt);
+ }};
+ (check_fields) => {{
+ assert_eq!($const_name.field, Field::MacroCtxt);
+ assert_eq!($const_name.$field_name, Field::RootCtxt);
+ }};
+ (construct) => {
+ $type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt }
+ };
+ }
+
+ pub macro $macro2_name {
+ (check_fields_of $e:expr) => {{
+ let e = $e;
+ assert_eq!(e.field, Field::MacroCtxt);
+ assert_eq!(e.$field_name, Field::RootCtxt);
+ }},
+ (check_fields) => {{
+ assert_eq!($const_name.field, Field::MacroCtxt);
+ assert_eq!($const_name.$field_name, Field::RootCtxt);
+ }},
+ (construct) => {
+ $type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt }
+ }
+ }
+}
+
+x!(test_fields, test_fields2, MyStruct, field, MY_CONST);
+
+pub fn check_fields(s: MyStruct) {
+ test_fields!(check_fields_of s);
+}
+
+pub fn check_fields_local() {
+ test_fields!(check_fields);
+ test_fields2!(check_fields);
+
+ let s1 = test_fields!(construct);
+ test_fields!(check_fields_of s1);
+
+ let s2 = test_fields2!(construct);
+ test_fields2!(check_fields_of s2);
+}
diff --git a/src/test/ui/hygiene/auxiliary/intercrate.rs b/src/test/ui/hygiene/auxiliary/intercrate.rs
new file mode 100644
index 000000000..068535885
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/intercrate.rs
@@ -0,0 +1,46 @@
+#![feature(decl_macro)]
+
+pub mod foo {
+ pub use self::bar::m;
+ mod bar {
+ fn f() -> u32 { 1 }
+ pub macro m() {
+ f()
+ }
+ }
+}
+
+pub struct SomeType;
+
+// `$crate`
+pub macro uses_dollar_crate_modern() {
+ type Alias = $crate::SomeType;
+}
+
+pub macro define_uses_dollar_crate_modern_nested($uses_dollar_crate_modern_nested: ident) {
+ macro $uses_dollar_crate_modern_nested() {
+ type AliasCrateModernNested = $crate::SomeType;
+ }
+}
+
+#[macro_export]
+macro_rules! define_uses_dollar_crate_legacy_nested {
+ () => {
+ macro_rules! uses_dollar_crate_legacy_nested {
+ () => {
+ type AliasLegacyNested = $crate::SomeType;
+ }
+ }
+ }
+}
+
+// `crate`
+pub macro uses_crate_modern() {
+ type AliasCrate = crate::SomeType;
+}
+
+pub macro define_uses_crate_modern_nested($uses_crate_modern_nested: ident) {
+ macro $uses_crate_modern_nested() {
+ type AliasCrateModernNested = crate::SomeType;
+ }
+}
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 000000000..90d5243b7
--- /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/local_inner_macros.rs b/src/test/ui/hygiene/auxiliary/local_inner_macros.rs
new file mode 100644
index 000000000..4296ae2fd
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/local_inner_macros.rs
@@ -0,0 +1,19 @@
+#[macro_export]
+macro_rules! helper1 {
+ () => ( struct S; )
+}
+
+#[macro_export(local_inner_macros)]
+macro_rules! helper2 {
+ () => ( helper1!(); )
+}
+
+#[macro_export(local_inner_macros)]
+macro_rules! public_macro {
+ () => ( helper2!(); )
+}
+
+#[macro_export(local_inner_macros)]
+macro_rules! public_macro_dynamic {
+ ($helper: ident) => ( $helper!(); )
+}
diff --git a/src/test/ui/hygiene/auxiliary/methods.rs b/src/test/ui/hygiene/auxiliary/methods.rs
new file mode 100644
index 000000000..23b9c61cf
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/methods.rs
@@ -0,0 +1,160 @@
+#![feature(decl_macro)]
+
+#[derive(PartialEq, Eq, Debug)]
+pub enum Method {
+ DefaultMacroCtxt,
+ DefaultRootCtxt,
+ OverrideMacroCtxt,
+ OverrideRootCtxt,
+}
+
+#[rustfmt::skip]
+macro x($macro_name:ident, $macro2_name:ident, $trait_name:ident, $method_name:ident) {
+ pub trait $trait_name {
+ fn method(&self) -> Method {
+ Method::DefaultMacroCtxt
+ }
+
+ fn $method_name(&self) -> Method {
+ Method::DefaultRootCtxt
+ }
+ }
+
+ impl $trait_name for () {}
+ impl $trait_name for bool {
+ fn method(&self) -> Method {
+ Method::OverrideMacroCtxt
+ }
+
+ fn $method_name(&self) -> Method {
+ Method::OverrideRootCtxt
+ }
+ }
+
+ #[macro_export]
+ macro_rules! $macro_name {
+ (check_resolutions) => {
+ assert_eq!(().method(), Method::DefaultMacroCtxt);
+ assert_eq!($trait_name::method(&()), Method::DefaultMacroCtxt);
+ assert_eq!(().$method_name(), Method::DefaultRootCtxt);
+ assert_eq!($trait_name::$method_name(&()), Method::DefaultRootCtxt);
+
+ assert_eq!(false.method(), Method::OverrideMacroCtxt);
+ assert_eq!($trait_name::method(&false), Method::OverrideMacroCtxt);
+ assert_eq!(false.$method_name(), Method::OverrideRootCtxt);
+ assert_eq!($trait_name::$method_name(&false), Method::OverrideRootCtxt);
+
+ assert_eq!('a'.method(), Method::DefaultMacroCtxt);
+ assert_eq!($trait_name::method(&'a'), Method::DefaultMacroCtxt);
+ assert_eq!('a'.$method_name(), Method::DefaultRootCtxt);
+ assert_eq!($trait_name::$method_name(&'a'), Method::DefaultRootCtxt);
+
+ assert_eq!(1i32.method(), Method::OverrideMacroCtxt);
+ assert_eq!($trait_name::method(&1i32), Method::OverrideMacroCtxt);
+ assert_eq!(1i32.$method_name(), Method::OverrideRootCtxt);
+ assert_eq!($trait_name::$method_name(&1i32), Method::OverrideRootCtxt);
+
+ assert_eq!(1i64.method(), Method::OverrideMacroCtxt);
+ assert_eq!($trait_name::method(&1i64), Method::OverrideMacroCtxt);
+ assert_eq!(1i64.$method_name(), Method::OverrideRootCtxt);
+ assert_eq!($trait_name::$method_name(&1i64), Method::OverrideRootCtxt);
+ };
+ (assert_no_override $v:expr) => {
+ assert_eq!($v.method(), Method::DefaultMacroCtxt);
+ assert_eq!($trait_name::method(&$v), Method::DefaultMacroCtxt);
+ assert_eq!($v.$method_name(), Method::DefaultRootCtxt);
+ assert_eq!($trait_name::$method_name(&$v), Method::DefaultRootCtxt);
+ };
+ (assert_override $v:expr) => {
+ assert_eq!($v.method(), Method::OverrideMacroCtxt);
+ assert_eq!($trait_name::method(&$v), Method::OverrideMacroCtxt);
+ assert_eq!($v.$method_name(), Method::OverrideRootCtxt);
+ assert_eq!($trait_name::$method_name(&$v), Method::OverrideRootCtxt);
+ };
+ (impl for $t:ty) => {
+ impl $trait_name for $t {
+ fn method(&self) -> Method {
+ Method::OverrideMacroCtxt
+ }
+
+ fn $method_name(&self) -> Method {
+ Method::OverrideRootCtxt
+ }
+ }
+ };
+ }
+
+ pub macro $macro2_name {
+ (check_resolutions) => {
+ assert_eq!(().method(), Method::DefaultMacroCtxt);
+ assert_eq!($trait_name::method(&()), Method::DefaultMacroCtxt);
+ assert_eq!(().$method_name(), Method::DefaultRootCtxt);
+ assert_eq!($trait_name::$method_name(&()), Method::DefaultRootCtxt);
+
+ assert_eq!(false.method(), Method::OverrideMacroCtxt);
+ assert_eq!($trait_name::method(&false), Method::OverrideMacroCtxt);
+ assert_eq!(false.$method_name(), Method::OverrideRootCtxt);
+ assert_eq!($trait_name::$method_name(&false), Method::OverrideRootCtxt);
+
+ assert_eq!('a'.method(), Method::DefaultMacroCtxt);
+ assert_eq!($trait_name::method(&'a'), Method::DefaultMacroCtxt);
+ assert_eq!('a'.$method_name(), Method::DefaultRootCtxt);
+ assert_eq!($trait_name::$method_name(&'a'), Method::DefaultRootCtxt);
+
+ assert_eq!(1i32.method(), Method::OverrideMacroCtxt);
+ assert_eq!($trait_name::method(&1i32), Method::OverrideMacroCtxt);
+ assert_eq!(1i32.$method_name(), Method::OverrideRootCtxt);
+ assert_eq!($trait_name::$method_name(&1i32), Method::OverrideRootCtxt);
+
+ assert_eq!(1i64.method(), Method::OverrideMacroCtxt);
+ assert_eq!($trait_name::method(&1i64), Method::OverrideMacroCtxt);
+ assert_eq!(1i64.$method_name(), Method::OverrideRootCtxt);
+ assert_eq!($trait_name::$method_name(&1i64), Method::OverrideRootCtxt);
+ },
+ (assert_no_override $v:expr) => {
+ assert_eq!($v.method(), Method::DefaultMacroCtxt);
+ assert_eq!($trait_name::method(&$v), Method::DefaultMacroCtxt);
+ assert_eq!($v.$method_name(), Method::DefaultRootCtxt);
+ assert_eq!($trait_name::$method_name(&$v), Method::DefaultRootCtxt);
+ },
+ (assert_override $v:expr) => {
+ assert_eq!($v.method(), Method::OverrideMacroCtxt);
+ assert_eq!($trait_name::method(&$v), Method::OverrideMacroCtxt);
+ assert_eq!($v.$method_name(), Method::OverrideRootCtxt);
+ assert_eq!($trait_name::$method_name(&$v), Method::OverrideRootCtxt);
+ },
+ (impl for $t:ty) => {
+ impl $trait_name for $t {
+ fn method(&self) -> Method {
+ Method::OverrideMacroCtxt
+ }
+
+ fn $method_name(&self) -> Method {
+ Method::OverrideRootCtxt
+ }
+ }
+ }
+ }
+}
+
+x!(test_trait, test_trait2, MyTrait, method);
+
+impl MyTrait for char {}
+test_trait!(impl for i32);
+test_trait2!(impl for i64);
+
+pub fn check_crate_local() {
+ test_trait!(check_resolutions);
+ test_trait2!(check_resolutions);
+}
+
+// Check that any comparison of idents at monomorphization time is correct
+pub fn check_crate_local_generic<T: MyTrait, U: MyTrait>(t: T, u: U) {
+ test_trait!(check_resolutions);
+ test_trait2!(check_resolutions);
+
+ test_trait!(assert_no_override t);
+ test_trait2!(assert_no_override t);
+ test_trait!(assert_override u);
+ test_trait2!(assert_override u);
+}
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 000000000..cdc6c27d8
--- /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/needs_hygiene.rs b/src/test/ui/hygiene/auxiliary/needs_hygiene.rs
new file mode 100644
index 000000000..3df6450fd
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/needs_hygiene.rs
@@ -0,0 +1,5 @@
+#![feature(decl_macro)]
+macro x() { struct MyStruct; }
+
+x!();
+x!();
diff --git a/src/test/ui/hygiene/auxiliary/nested-dollar-crate.rs b/src/test/ui/hygiene/auxiliary/nested-dollar-crate.rs
new file mode 100644
index 000000000..e5caa0f9c
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/nested-dollar-crate.rs
@@ -0,0 +1,14 @@
+pub const IN_DEF_CRATE: &str = "In def crate!";
+
+macro_rules! make_it {
+ () => {
+ #[macro_export]
+ macro_rules! inner {
+ () => {
+ $crate::IN_DEF_CRATE
+ }
+ }
+ }
+}
+
+make_it!();
diff --git a/src/test/ui/hygiene/auxiliary/not-libstd.rs b/src/test/ui/hygiene/auxiliary/not-libstd.rs
new file mode 100644
index 000000000..babba293d
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/not-libstd.rs
@@ -0,0 +1 @@
+pub fn not_in_lib_std() {}
diff --git a/src/test/ui/hygiene/auxiliary/opaque-hygiene.rs b/src/test/ui/hygiene/auxiliary/opaque-hygiene.rs
new file mode 100644
index 000000000..7730f91bd
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/opaque-hygiene.rs
@@ -0,0 +1,21 @@
+// force-host
+// no-prefer-dynamic
+
+#![feature(proc_macro_quote)]
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::{TokenStream, quote};
+
+#[proc_macro]
+pub fn make_it(input: TokenStream) -> TokenStream {
+ // `quote!` applies def-site hygiene
+ quote! {
+ trait Foo {
+ fn my_fn(&self) {}
+ }
+
+ impl<T> Foo for T {}
+ "a".my_fn();
+ }
+}
diff --git a/src/test/ui/hygiene/auxiliary/pub_hygiene.rs b/src/test/ui/hygiene/auxiliary/pub_hygiene.rs
new file mode 100644
index 000000000..47e76a629
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/pub_hygiene.rs
@@ -0,0 +1,7 @@
+#![feature(decl_macro)]
+
+macro x() {
+ pub struct MyStruct;
+}
+
+x!();
diff --git a/src/test/ui/hygiene/auxiliary/stdlib-prelude.rs b/src/test/ui/hygiene/auxiliary/stdlib-prelude.rs
new file mode 100644
index 000000000..81b0b7faa
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/stdlib-prelude.rs
@@ -0,0 +1,3 @@
+#![feature(decl_macro)]
+
+pub macro stdlib_macro() {}
diff --git a/src/test/ui/hygiene/auxiliary/transparent-basic.rs b/src/test/ui/hygiene/auxiliary/transparent-basic.rs
new file mode 100644
index 000000000..37de27ee8
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/transparent-basic.rs
@@ -0,0 +1,6 @@
+#![feature(decl_macro, rustc_attrs)]
+
+#[rustc_macro_transparency = "transparent"]
+pub macro dollar_crate() {
+ let s = $crate::S;
+}
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 000000000..8e6e8f9b3
--- /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/use_by_macro.rs b/src/test/ui/hygiene/auxiliary/use_by_macro.rs
new file mode 100644
index 000000000..791cf0358
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/use_by_macro.rs
@@ -0,0 +1,15 @@
+#![feature(decl_macro)]
+
+macro x($macro_name:ident) {
+ #[macro_export]
+ macro_rules! $macro_name {
+ (define) => {
+ pub struct MyStruct;
+ };
+ (create) => {
+ MyStruct {}
+ };
+ }
+}
+
+x!(my_struct);
diff --git a/src/test/ui/hygiene/auxiliary/variants.rs b/src/test/ui/hygiene/auxiliary/variants.rs
new file mode 100644
index 000000000..dbfcce17d
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/variants.rs
@@ -0,0 +1,36 @@
+#![feature(decl_macro)]
+
+#[rustfmt::skip]
+macro x($macro_name:ident, $macro2_name:ident, $type_name:ident, $variant_name:ident) {
+ #[repr(u8)]
+ pub enum $type_name {
+ Variant = 0,
+ $variant_name = 1,
+ }
+
+ #[macro_export]
+ macro_rules! $macro_name {
+ () => {{
+ assert_eq!($type_name::Variant as u8, 0);
+ assert_eq!($type_name::$variant_name as u8, 1);
+ assert_eq!(<$type_name>::Variant as u8, 0);
+ assert_eq!(<$type_name>::$variant_name as u8, 1);
+ }};
+ }
+
+ pub macro $macro2_name {
+ () => {{
+ assert_eq!($type_name::Variant as u8, 0);
+ assert_eq!($type_name::$variant_name as u8, 1);
+ assert_eq!(<$type_name>::Variant as u8, 0);
+ assert_eq!(<$type_name>::$variant_name as u8, 1);
+ }},
+ }
+}
+
+x!(test_variants, test_variants2, MyEnum, Variant);
+
+pub fn check_variants() {
+ test_variants!();
+ test_variants2!();
+}
diff --git a/src/test/ui/hygiene/auxiliary/xcrate.rs b/src/test/ui/hygiene/auxiliary/xcrate.rs
new file mode 100644
index 000000000..f5a911f57
--- /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() {}
+}