Skip to content

Commit fabede1

Browse files
committed
Add more tests for cross-crate hygiene
1 parent 1536d72 commit fabede1

18 files changed

+465
-0
lines changed
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#![feature(decl_macro)]
2+
3+
#[derive(Copy, Clone, PartialEq, Debug)]
4+
pub enum Field {
5+
RootCtxt,
6+
MacroCtxt,
7+
}
8+
9+
#[rustfmt::skip]
10+
macro x(
11+
$macro_name:ident,
12+
$macro2_name:ident,
13+
$type_name:ident,
14+
$field_name:ident,
15+
$const_name:ident
16+
) {
17+
#[derive(Copy, Clone)]
18+
pub struct $type_name {
19+
pub field: Field,
20+
pub $field_name: Field,
21+
}
22+
23+
pub const $const_name: $type_name =
24+
$type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt };
25+
26+
#[macro_export]
27+
macro_rules! $macro_name {
28+
(check_fields_of $e:expr) => {{
29+
let e = $e;
30+
assert_eq!(e.field, Field::MacroCtxt);
31+
assert_eq!(e.$field_name, Field::RootCtxt);
32+
}};
33+
(check_fields) => {{
34+
assert_eq!($const_name.field, Field::MacroCtxt);
35+
assert_eq!($const_name.$field_name, Field::RootCtxt);
36+
}};
37+
(construct) => {
38+
$type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt }
39+
};
40+
}
41+
42+
pub macro $macro2_name {
43+
(check_fields_of $e:expr) => {{
44+
let e = $e;
45+
assert_eq!(e.field, Field::MacroCtxt);
46+
assert_eq!(e.$field_name, Field::RootCtxt);
47+
}},
48+
(check_fields) => {{
49+
assert_eq!($const_name.field, Field::MacroCtxt);
50+
assert_eq!($const_name.$field_name, Field::RootCtxt);
51+
}},
52+
(construct) => {
53+
$type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt }
54+
}
55+
}
56+
}
57+
58+
x!(test_fields, test_fields2, MyStruct, field, MY_CONST);
59+
60+
pub fn check_fields(s: MyStruct) {
61+
test_fields!(check_fields_of s);
62+
}
63+
64+
pub fn check_fields_local() {
65+
test_fields!(check_fields);
66+
test_fields2!(check_fields);
67+
68+
let s1 = test_fields!(construct);
69+
test_fields!(check_fields_of s1);
70+
71+
let s2 = test_fields2!(construct);
72+
test_fields2!(check_fields_of s2);
73+
}
+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#![feature(decl_macro)]
2+
3+
#[derive(PartialEq, Eq, Debug)]
4+
pub enum Method {
5+
DefaultMacroCtxt,
6+
DefaultRootCtxt,
7+
OverrideMacroCtxt,
8+
OverrideRootCtxt,
9+
}
10+
11+
#[rustfmt::skip]
12+
macro x($macro_name:ident, $macro2_name:ident, $trait_name:ident, $method_name:ident) {
13+
pub trait $trait_name {
14+
fn method(&self) -> Method {
15+
Method::DefaultMacroCtxt
16+
}
17+
18+
fn $method_name(&self) -> Method {
19+
Method::DefaultRootCtxt
20+
}
21+
}
22+
23+
impl $trait_name for () {}
24+
impl $trait_name for bool {
25+
fn method(&self) -> Method {
26+
Method::OverrideMacroCtxt
27+
}
28+
29+
fn $method_name(&self) -> Method {
30+
Method::OverrideRootCtxt
31+
}
32+
}
33+
34+
#[macro_export]
35+
macro_rules! $macro_name {
36+
(check_resolutions) => {
37+
assert_eq!(().method(), Method::DefaultMacroCtxt);
38+
assert_eq!($trait_name::method(&()), Method::DefaultMacroCtxt);
39+
assert_eq!(().$method_name(), Method::DefaultRootCtxt);
40+
assert_eq!($trait_name::$method_name(&()), Method::DefaultRootCtxt);
41+
42+
assert_eq!(false.method(), Method::OverrideMacroCtxt);
43+
assert_eq!($trait_name::method(&false), Method::OverrideMacroCtxt);
44+
assert_eq!(false.$method_name(), Method::OverrideRootCtxt);
45+
assert_eq!($trait_name::$method_name(&false), Method::OverrideRootCtxt);
46+
47+
assert_eq!('a'.method(), Method::DefaultMacroCtxt);
48+
assert_eq!($trait_name::method(&'a'), Method::DefaultMacroCtxt);
49+
assert_eq!('a'.$method_name(), Method::DefaultRootCtxt);
50+
assert_eq!($trait_name::$method_name(&'a'), Method::DefaultRootCtxt);
51+
52+
assert_eq!(1i32.method(), Method::OverrideMacroCtxt);
53+
assert_eq!($trait_name::method(&1i32), Method::OverrideMacroCtxt);
54+
assert_eq!(1i32.$method_name(), Method::OverrideRootCtxt);
55+
assert_eq!($trait_name::$method_name(&1i32), Method::OverrideRootCtxt);
56+
57+
assert_eq!(1i64.method(), Method::OverrideMacroCtxt);
58+
assert_eq!($trait_name::method(&1i64), Method::OverrideMacroCtxt);
59+
assert_eq!(1i64.$method_name(), Method::OverrideRootCtxt);
60+
assert_eq!($trait_name::$method_name(&1i64), Method::OverrideRootCtxt);
61+
};
62+
(assert_no_override $v:expr) => {
63+
assert_eq!($v.method(), Method::DefaultMacroCtxt);
64+
assert_eq!($trait_name::method(&$v), Method::DefaultMacroCtxt);
65+
assert_eq!($v.$method_name(), Method::DefaultRootCtxt);
66+
assert_eq!($trait_name::$method_name(&$v), Method::DefaultRootCtxt);
67+
};
68+
(assert_override $v:expr) => {
69+
assert_eq!($v.method(), Method::OverrideMacroCtxt);
70+
assert_eq!($trait_name::method(&$v), Method::OverrideMacroCtxt);
71+
assert_eq!($v.$method_name(), Method::OverrideRootCtxt);
72+
assert_eq!($trait_name::$method_name(&$v), Method::OverrideRootCtxt);
73+
};
74+
(impl for $t:ty) => {
75+
impl $trait_name for $t {
76+
fn method(&self) -> Method {
77+
Method::OverrideMacroCtxt
78+
}
79+
80+
fn $method_name(&self) -> Method {
81+
Method::OverrideRootCtxt
82+
}
83+
}
84+
};
85+
}
86+
87+
pub macro $macro2_name {
88+
(check_resolutions) => {
89+
assert_eq!(().method(), Method::DefaultMacroCtxt);
90+
assert_eq!($trait_name::method(&()), Method::DefaultMacroCtxt);
91+
assert_eq!(().$method_name(), Method::DefaultRootCtxt);
92+
assert_eq!($trait_name::$method_name(&()), Method::DefaultRootCtxt);
93+
94+
assert_eq!(false.method(), Method::OverrideMacroCtxt);
95+
assert_eq!($trait_name::method(&false), Method::OverrideMacroCtxt);
96+
assert_eq!(false.$method_name(), Method::OverrideRootCtxt);
97+
assert_eq!($trait_name::$method_name(&false), Method::OverrideRootCtxt);
98+
99+
assert_eq!('a'.method(), Method::DefaultMacroCtxt);
100+
assert_eq!($trait_name::method(&'a'), Method::DefaultMacroCtxt);
101+
assert_eq!('a'.$method_name(), Method::DefaultRootCtxt);
102+
assert_eq!($trait_name::$method_name(&'a'), Method::DefaultRootCtxt);
103+
104+
assert_eq!(1i32.method(), Method::OverrideMacroCtxt);
105+
assert_eq!($trait_name::method(&1i32), Method::OverrideMacroCtxt);
106+
assert_eq!(1i32.$method_name(), Method::OverrideRootCtxt);
107+
assert_eq!($trait_name::$method_name(&1i32), Method::OverrideRootCtxt);
108+
109+
assert_eq!(1i64.method(), Method::OverrideMacroCtxt);
110+
assert_eq!($trait_name::method(&1i64), Method::OverrideMacroCtxt);
111+
assert_eq!(1i64.$method_name(), Method::OverrideRootCtxt);
112+
assert_eq!($trait_name::$method_name(&1i64), Method::OverrideRootCtxt);
113+
},
114+
(assert_no_override $v:expr) => {
115+
assert_eq!($v.method(), Method::DefaultMacroCtxt);
116+
assert_eq!($trait_name::method(&$v), Method::DefaultMacroCtxt);
117+
assert_eq!($v.$method_name(), Method::DefaultRootCtxt);
118+
assert_eq!($trait_name::$method_name(&$v), Method::DefaultRootCtxt);
119+
},
120+
(assert_override $v:expr) => {
121+
assert_eq!($v.method(), Method::OverrideMacroCtxt);
122+
assert_eq!($trait_name::method(&$v), Method::OverrideMacroCtxt);
123+
assert_eq!($v.$method_name(), Method::OverrideRootCtxt);
124+
assert_eq!($trait_name::$method_name(&$v), Method::OverrideRootCtxt);
125+
},
126+
(impl for $t:ty) => {
127+
impl $trait_name for $t {
128+
fn method(&self) -> Method {
129+
Method::OverrideMacroCtxt
130+
}
131+
132+
fn $method_name(&self) -> Method {
133+
Method::OverrideRootCtxt
134+
}
135+
}
136+
}
137+
}
138+
}
139+
140+
x!(test_trait, test_trait2, MyTrait, method);
141+
142+
impl MyTrait for char {}
143+
test_trait!(impl for i32);
144+
test_trait2!(impl for i64);
145+
146+
pub fn check_crate_local() {
147+
test_trait!(check_resolutions);
148+
test_trait2!(check_resolutions);
149+
}
150+
151+
// Check that any comparison of idents at monomorphization time is correct
152+
pub fn check_crate_local_generic<T: MyTrait, U: MyTrait>(t: T, u: U) {
153+
test_trait!(check_resolutions);
154+
test_trait2!(check_resolutions);
155+
156+
test_trait!(assert_no_override t);
157+
test_trait2!(assert_no_override t);
158+
test_trait!(assert_override u);
159+
test_trait2!(assert_override u);
160+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![feature(decl_macro)]
2+
3+
macro x() {
4+
pub struct MyStruct;
5+
}
6+
7+
x!();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(decl_macro)]
2+
3+
macro x($macro_name:ident) {
4+
#[macro_export]
5+
macro_rules! $macro_name {
6+
(define) => {
7+
pub struct MyStruct;
8+
};
9+
(create) => {
10+
MyStruct {}
11+
};
12+
}
13+
}
14+
15+
x!(my_struct);
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![feature(decl_macro)]
2+
3+
#[rustfmt::skip]
4+
macro x($macro_name:ident, $macro2_name:ident, $type_name:ident, $variant_name:ident) {
5+
#[repr(u8)]
6+
pub enum $type_name {
7+
Variant = 0,
8+
$variant_name = 1,
9+
}
10+
11+
#[macro_export]
12+
macro_rules! $macro_name {
13+
() => {{
14+
assert_eq!($type_name::Variant as u8, 0);
15+
assert_eq!($type_name::$variant_name as u8, 1);
16+
assert_eq!(<$type_name>::Variant as u8, 0);
17+
assert_eq!(<$type_name>::$variant_name as u8, 1);
18+
}};
19+
}
20+
21+
pub macro $macro2_name {
22+
() => {{
23+
assert_eq!($type_name::Variant as u8, 0);
24+
assert_eq!($type_name::$variant_name as u8, 1);
25+
assert_eq!(<$type_name>::Variant as u8, 0);
26+
assert_eq!(<$type_name>::$variant_name as u8, 1);
27+
}},
28+
}
29+
}
30+
31+
x!(test_variants, test_variants2, MyEnum, Variant);
32+
33+
pub fn check_variants() {
34+
test_variants!();
35+
test_variants2!();
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-pass
2+
// aux-build:use_by_macro.rs
3+
4+
#![feature(type_name_of_val)]
5+
extern crate use_by_macro;
6+
7+
use use_by_macro::*;
8+
9+
enum MyStruct {}
10+
my_struct!(define);
11+
12+
fn main() {
13+
let x = my_struct!(create);
14+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// run-pass
2+
// aux-build:fields.rs
3+
4+
extern crate fields;
5+
6+
use fields::*;
7+
8+
fn main() {
9+
check_fields_local();
10+
11+
test_fields!(check_fields);
12+
test_fields2!(check_fields);
13+
14+
let s1 = test_fields!(construct);
15+
check_fields(s1);
16+
test_fields!(check_fields_of s1);
17+
18+
let s2 = test_fields2!(construct);
19+
check_fields(s2);
20+
test_fields2!(check_fields_of s2);
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// aux-build:use_by_macro.rs
2+
3+
extern crate use_by_macro;
4+
5+
use use_by_macro::*;
6+
7+
mod m {
8+
use use_by_macro::*;
9+
10+
my_struct!(define);
11+
}
12+
13+
use m::*;
14+
15+
fn main() {
16+
let x = my_struct!(create);
17+
//~^ ERROR cannot find struct, variant or union type `MyStruct` in this scope
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0422]: cannot find struct, variant or union type `MyStruct` in this scope
2+
--> $DIR/cross-crate-glob-hygiene.rs:16:13
3+
|
4+
LL | let x = my_struct!(create);
5+
| ^^^^^^^^^^^^^^^^^^ not found in this scope
6+
|
7+
= note: this error originates in the macro `my_struct` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error: aborting due to previous error
10+
11+
For more information about this error, try `rustc --explain E0422`.
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// run-pass
2+
// aux-build:methods.rs
3+
4+
extern crate methods;
5+
6+
use methods::*;
7+
8+
struct A;
9+
struct B;
10+
struct C;
11+
12+
impl MyTrait for A {}
13+
test_trait!(impl for B);
14+
test_trait2!(impl for C);
15+
16+
fn main() {
17+
check_crate_local();
18+
check_crate_local_generic(A, B);
19+
check_crate_local_generic(A, C);
20+
21+
test_trait!(check_resolutions);
22+
test_trait2!(check_resolutions);
23+
test_trait!(assert_no_override A);
24+
test_trait2!(assert_no_override A);
25+
test_trait!(assert_override B);
26+
test_trait2!(assert_override B);
27+
test_trait!(assert_override C);
28+
test_trait2!(assert_override C);
29+
}

0 commit comments

Comments
 (0)