]> git.lizzy.rs Git - rust.git/commitdiff
Add more tests for cross-crate hygiene
authorMatthew Jasper <mjjasper1@gmail.com>
Sat, 23 Oct 2021 11:06:58 +0000 (12:06 +0100)
committerMatthew Jasper <mjjasper1@gmail.com>
Sun, 24 Oct 2021 11:31:42 +0000 (12:31 +0100)
19 files changed:
src/test/ui/hygiene/auxiliary/fields.rs [new file with mode: 0644]
src/test/ui/hygiene/auxiliary/methods.rs [new file with mode: 0644]
src/test/ui/hygiene/auxiliary/pub_hygiene.rs [new file with mode: 0644]
src/test/ui/hygiene/auxiliary/use_by_macro.rs [new file with mode: 0644]
src/test/ui/hygiene/auxiliary/variants.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-define-and-use.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-fields.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-glob-hygiene.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-glob-hygiene.stderr [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-methods.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-name-collision.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-name-hiding-2.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-name-hiding-2.stderr [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-name-hiding.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-name-hiding.stderr [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-redefine.rs [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-redefine.stderr [new file with mode: 0644]
src/test/ui/hygiene/cross-crate-variants.rs [new file with mode: 0644]
src/test/ui/hygiene/cross_crate_hygiene.rs [deleted file]

diff --git a/src/test/ui/hygiene/auxiliary/fields.rs b/src/test/ui/hygiene/auxiliary/fields.rs
new file mode 100644 (file)
index 0000000..733d11a
--- /dev/null
@@ -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/methods.rs b/src/test/ui/hygiene/auxiliary/methods.rs
new file mode 100644 (file)
index 0000000..23b9c61
--- /dev/null
@@ -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/pub_hygiene.rs b/src/test/ui/hygiene/auxiliary/pub_hygiene.rs
new file mode 100644 (file)
index 0000000..47e76a6
--- /dev/null
@@ -0,0 +1,7 @@
+#![feature(decl_macro)]
+
+macro x() {
+    pub struct MyStruct;
+}
+
+x!();
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 (file)
index 0000000..791cf03
--- /dev/null
@@ -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 (file)
index 0000000..dbfcce1
--- /dev/null
@@ -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/cross-crate-define-and-use.rs b/src/test/ui/hygiene/cross-crate-define-and-use.rs
new file mode 100644 (file)
index 0000000..9bb8d80
--- /dev/null
@@ -0,0 +1,14 @@
+// check-pass
+// aux-build:use_by_macro.rs
+
+#![feature(type_name_of_val)]
+extern crate use_by_macro;
+
+use use_by_macro::*;
+
+enum MyStruct {}
+my_struct!(define);
+
+fn main() {
+    let x = my_struct!(create);
+}
diff --git a/src/test/ui/hygiene/cross-crate-fields.rs b/src/test/ui/hygiene/cross-crate-fields.rs
new file mode 100644 (file)
index 0000000..96ed412
--- /dev/null
@@ -0,0 +1,21 @@
+// run-pass
+// aux-build:fields.rs
+
+extern crate fields;
+
+use fields::*;
+
+fn main() {
+    check_fields_local();
+
+    test_fields!(check_fields);
+    test_fields2!(check_fields);
+
+    let s1 = test_fields!(construct);
+    check_fields(s1);
+    test_fields!(check_fields_of s1);
+
+    let s2 = test_fields2!(construct);
+    check_fields(s2);
+    test_fields2!(check_fields_of s2);
+}
diff --git a/src/test/ui/hygiene/cross-crate-glob-hygiene.rs b/src/test/ui/hygiene/cross-crate-glob-hygiene.rs
new file mode 100644 (file)
index 0000000..ebd632d
--- /dev/null
@@ -0,0 +1,18 @@
+// aux-build:use_by_macro.rs
+
+extern crate use_by_macro;
+
+use use_by_macro::*;
+
+mod m {
+    use use_by_macro::*;
+
+    my_struct!(define);
+}
+
+use m::*;
+
+fn main() {
+    let x = my_struct!(create);
+    //~^ ERROR cannot find struct, variant or union type `MyStruct` in this scope
+}
diff --git a/src/test/ui/hygiene/cross-crate-glob-hygiene.stderr b/src/test/ui/hygiene/cross-crate-glob-hygiene.stderr
new file mode 100644 (file)
index 0000000..8f8ed83
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope
+  --> $DIR/cross-crate-glob-hygiene.rs:16:13
+   |
+LL |     let x = my_struct!(create);
+   |             ^^^^^^^^^^^^^^^^^^ not found in this scope
+   |
+   = note: this error originates in the macro `my_struct` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0422`.
diff --git a/src/test/ui/hygiene/cross-crate-methods.rs b/src/test/ui/hygiene/cross-crate-methods.rs
new file mode 100644 (file)
index 0000000..f27ad89
--- /dev/null
@@ -0,0 +1,29 @@
+// run-pass
+// aux-build:methods.rs
+
+extern crate methods;
+
+use methods::*;
+
+struct A;
+struct B;
+struct C;
+
+impl MyTrait for A {}
+test_trait!(impl for B);
+test_trait2!(impl for C);
+
+fn main() {
+    check_crate_local();
+    check_crate_local_generic(A, B);
+    check_crate_local_generic(A, C);
+
+    test_trait!(check_resolutions);
+    test_trait2!(check_resolutions);
+    test_trait!(assert_no_override A);
+    test_trait2!(assert_no_override A);
+    test_trait!(assert_override B);
+    test_trait2!(assert_override B);
+    test_trait!(assert_override C);
+    test_trait2!(assert_override C);
+}
diff --git a/src/test/ui/hygiene/cross-crate-name-collision.rs b/src/test/ui/hygiene/cross-crate-name-collision.rs
new file mode 100644 (file)
index 0000000..7574296
--- /dev/null
@@ -0,0 +1,8 @@
+// check-pass
+// aux-build:needs_hygiene.rs
+
+extern crate needs_hygiene;
+
+use needs_hygiene::*;
+
+fn main() {}
diff --git a/src/test/ui/hygiene/cross-crate-name-hiding-2.rs b/src/test/ui/hygiene/cross-crate-name-hiding-2.rs
new file mode 100644 (file)
index 0000000..8d416b0
--- /dev/null
@@ -0,0 +1,12 @@
+// aux-build:use_by_macro.rs
+
+extern crate use_by_macro;
+
+use use_by_macro::*;
+
+my_struct!(define);
+
+fn main() {
+    let x = MyStruct {};
+    //~^ ERROR cannot find struct, variant or union type `MyStruct` in this scope
+}
diff --git a/src/test/ui/hygiene/cross-crate-name-hiding-2.stderr b/src/test/ui/hygiene/cross-crate-name-hiding-2.stderr
new file mode 100644 (file)
index 0000000..1a7e490
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope
+  --> $DIR/cross-crate-name-hiding-2.rs:10:13
+   |
+LL |     let x = MyStruct {};
+   |             ^^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0422`.
diff --git a/src/test/ui/hygiene/cross-crate-name-hiding.rs b/src/test/ui/hygiene/cross-crate-name-hiding.rs
new file mode 100644 (file)
index 0000000..87d011d
--- /dev/null
@@ -0,0 +1,10 @@
+// aux-build:pub_hygiene.rs
+
+extern crate pub_hygiene;
+
+use pub_hygiene::*;
+
+fn main() {
+    let x = MyStruct {};
+    //~^ ERROR cannot find struct, variant or union type `MyStruct` in this scope
+}
diff --git a/src/test/ui/hygiene/cross-crate-name-hiding.stderr b/src/test/ui/hygiene/cross-crate-name-hiding.stderr
new file mode 100644 (file)
index 0000000..149d7ee
--- /dev/null
@@ -0,0 +1,9 @@
+error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope
+  --> $DIR/cross-crate-name-hiding.rs:8:13
+   |
+LL |     let x = MyStruct {};
+   |             ^^^^^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0422`.
diff --git a/src/test/ui/hygiene/cross-crate-redefine.rs b/src/test/ui/hygiene/cross-crate-redefine.rs
new file mode 100644 (file)
index 0000000..c79a6be
--- /dev/null
@@ -0,0 +1,11 @@
+// aux-build:use_by_macro.rs
+
+extern crate use_by_macro;
+
+use use_by_macro::*;
+
+my_struct!(define);
+//~^ ERROR the name `MyStruct` is defined multiple times
+my_struct!(define);
+
+fn main() {}
diff --git a/src/test/ui/hygiene/cross-crate-redefine.stderr b/src/test/ui/hygiene/cross-crate-redefine.stderr
new file mode 100644 (file)
index 0000000..6d0c951
--- /dev/null
@@ -0,0 +1,15 @@
+error[E0428]: the name `MyStruct` is defined multiple times
+  --> $DIR/cross-crate-redefine.rs:7:1
+   |
+LL | my_struct!(define);
+   | ^^^^^^^^^^^^^^^^^^ `MyStruct` redefined here
+LL |
+LL | my_struct!(define);
+   | ------------------ previous definition of the type `MyStruct` here
+   |
+   = note: `MyStruct` must be defined only once in the type namespace of this module
+   = note: this error originates in the macro `my_struct` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/ui/hygiene/cross-crate-variants.rs b/src/test/ui/hygiene/cross-crate-variants.rs
new file mode 100644 (file)
index 0000000..6c5671f
--- /dev/null
@@ -0,0 +1,15 @@
+// run-pass
+// aux-build:variants.rs
+
+extern crate variants;
+
+use variants::*;
+
+fn main() {
+    check_variants();
+
+    test_variants!();
+    test_variants2!();
+
+    assert_eq!(MyEnum::Variant as u8, 1);
+}
diff --git a/src/test/ui/hygiene/cross_crate_hygiene.rs b/src/test/ui/hygiene/cross_crate_hygiene.rs
deleted file mode 100644 (file)
index 7574296..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// check-pass
-// aux-build:needs_hygiene.rs
-
-extern crate needs_hygiene;
-
-use needs_hygiene::*;
-
-fn main() {}