Skip to content

Commit a19c16d

Browse files
committed
Add some tests for multistep coercion ICEs
1 parent ba51fc6 commit a19c16d

File tree

4 files changed

+565
-0
lines changed

4 files changed

+565
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//@ check-fail
2+
//@ known-bug: #148283
3+
4+
#![allow(static_mut_refs)]
5+
#![allow(dead_code)]
6+
use std::ops::Deref;
7+
8+
pub static mut ACTIONS: Vec<&'static str> = Vec::new();
9+
10+
pub struct Wrap<T: ?Sized>(T);
11+
12+
// Deref Chain: FinalType <- UnsizedArray <- IntWrapper <- ArrayWrapper <- TopType
13+
pub struct TopType;
14+
pub type ArrayWrapper = Wrap<[i32; 0]>;
15+
pub struct IntWrapper;
16+
pub type UnsizedArray = Wrap<[i32]>;
17+
pub struct FinalType;
18+
pub struct TopTypeNoTrait;
19+
20+
impl Deref for TopType {
21+
type Target = ArrayWrapper;
22+
fn deref(&self) -> &Self::Target {
23+
unsafe { ACTIONS.push("deref TopType->ArrayWrapper"); }
24+
&Wrap([])
25+
}
26+
}
27+
28+
impl Deref for ArrayWrapper {
29+
type Target = IntWrapper;
30+
fn deref(&self) -> &Self::Target {
31+
unsafe { ACTIONS.push("deref ArrayWrapper->IntWrapper"); }
32+
&IntWrapper
33+
}
34+
}
35+
36+
impl Deref for IntWrapper {
37+
type Target = UnsizedArray;
38+
fn deref(&self) -> &Self::Target {
39+
unsafe { ACTIONS.push("deref IntWrapper->UnsizedArray"); }
40+
&Wrap([])
41+
}
42+
}
43+
44+
impl Deref for UnsizedArray {
45+
type Target = FinalType;
46+
fn deref(&self) -> &Self::Target {
47+
unsafe { ACTIONS.push("deref UnsizedArray->FinalType"); }
48+
&FinalType
49+
}
50+
}
51+
52+
impl Deref for TopTypeNoTrait {
53+
type Target = ArrayWrapper;
54+
fn deref(&self) -> &Self::Target {
55+
unsafe { ACTIONS.push("deref TopTypeNoTrait->ArrayWrapper"); }
56+
&Wrap([])
57+
}
58+
}
59+
60+
trait Trait {
61+
fn self_ty(&self);
62+
63+
fn complete(&self) -> Vec<&'static str> {
64+
self.self_ty();
65+
let actions = unsafe { ACTIONS.clone() };
66+
unsafe { ACTIONS.clear() };
67+
actions
68+
}
69+
}
70+
71+
impl Trait for TopType {
72+
fn self_ty(&self) {
73+
unsafe { ACTIONS.push("self_ty TopType"); }
74+
}
75+
}
76+
77+
impl Trait for ArrayWrapper {
78+
fn self_ty(&self) {
79+
unsafe { ACTIONS.push("self_ty ArrayWrapper"); }
80+
}
81+
}
82+
83+
impl Trait for IntWrapper {
84+
fn self_ty(&self) {
85+
unsafe { ACTIONS.push("self_ty IntWrapper"); }
86+
}
87+
}
88+
89+
impl Trait for UnsizedArray {
90+
fn self_ty(&self) {
91+
unsafe { ACTIONS.push("self_ty UnsizedArray"); }
92+
}
93+
}
94+
95+
impl Trait for FinalType {
96+
fn self_ty(&self) {
97+
unsafe { ACTIONS.push("self_ty FinalType"); }
98+
}
99+
}
100+
101+
fn deref_to_dyn_direct() {
102+
let x = match 0 {
103+
0 => &TopTypeNoTrait as &TopTypeNoTrait,
104+
1 => &TopTypeNoTrait as &FinalType as &dyn Trait,
105+
_ => loop {},
106+
};
107+
}
108+
109+
fn main() {
110+
deref_to_dyn_direct();
111+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0277]: the trait bound `TopTypeNoTrait: Trait` is not satisfied
2+
--> $DIR/multistep-fail.rs:104:14
3+
|
4+
LL | 1 => &TopTypeNoTrait as &FinalType as &dyn Trait,
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
6+
|
7+
help: the trait `Trait` is not implemented for `TopTypeNoTrait`
8+
--> $DIR/multistep-fail.rs:18:1
9+
|
10+
LL | pub struct TopTypeNoTrait;
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
12+
= help: the following other types implement trait `Trait`:
13+
FinalType
14+
IntWrapper
15+
TopType
16+
Wrap<[i32; 0]>
17+
Wrap<[i32]>
18+
= note: required for the cast from `&TopTypeNoTrait` to `&dyn Trait`
19+
20+
error: aborting due to 1 previous error
21+
22+
For more information about this error, try `rustc --explain E0277`.

tests/ui/coercion/multistep.rs

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
//@ check-fail
2+
//@ known-bug: #148283
3+
//@ failure-status: 101
4+
//@ rustc-env:RUST_BACKTRACE=0
5+
6+
#![allow(static_mut_refs)]
7+
#![allow(dead_code)]
8+
use std::ops::Deref;
9+
10+
pub static mut ACTIONS: Vec<&'static str> = Vec::new();
11+
12+
pub struct Wrap<T: ?Sized>(T);
13+
14+
// Deref Chain: FinalType <- UnsizedArray <- IntWrapper <- ArrayWrapper <- TopType
15+
pub struct TopType;
16+
pub type ArrayWrapper = Wrap<[i32; 0]>;
17+
pub struct IntWrapper;
18+
pub type UnsizedArray = Wrap<[i32]>;
19+
pub struct FinalType;
20+
pub struct TopTypeNoTrait;
21+
22+
impl Deref for TopType {
23+
type Target = ArrayWrapper;
24+
fn deref(&self) -> &Self::Target {
25+
unsafe { ACTIONS.push("deref TopType->ArrayWrapper"); }
26+
&Wrap([])
27+
}
28+
}
29+
30+
impl Deref for ArrayWrapper {
31+
type Target = IntWrapper;
32+
fn deref(&self) -> &Self::Target {
33+
unsafe { ACTIONS.push("deref ArrayWrapper->IntWrapper"); }
34+
&IntWrapper
35+
}
36+
}
37+
38+
impl Deref for IntWrapper {
39+
type Target = UnsizedArray;
40+
fn deref(&self) -> &Self::Target {
41+
unsafe { ACTIONS.push("deref IntWrapper->UnsizedArray"); }
42+
&Wrap([])
43+
}
44+
}
45+
46+
impl Deref for UnsizedArray {
47+
type Target = FinalType;
48+
fn deref(&self) -> &Self::Target {
49+
unsafe { ACTIONS.push("deref UnsizedArray->FinalType"); }
50+
&FinalType
51+
}
52+
}
53+
54+
impl Deref for TopTypeNoTrait {
55+
type Target = ArrayWrapper;
56+
fn deref(&self) -> &Self::Target {
57+
unsafe { ACTIONS.push("deref TopTypeNoTrait->ArrayWrapper"); }
58+
&Wrap([])
59+
}
60+
}
61+
62+
trait Trait {
63+
fn self_ty(&self);
64+
65+
fn complete(&self) -> Vec<&'static str> {
66+
self.self_ty();
67+
let actions = unsafe { ACTIONS.clone() };
68+
unsafe { ACTIONS.clear() };
69+
actions
70+
}
71+
}
72+
73+
impl Trait for TopType {
74+
fn self_ty(&self) {
75+
unsafe { ACTIONS.push("self_ty TopType"); }
76+
}
77+
}
78+
79+
impl Trait for ArrayWrapper {
80+
fn self_ty(&self) {
81+
unsafe { ACTIONS.push("self_ty ArrayWrapper"); }
82+
}
83+
}
84+
85+
impl Trait for IntWrapper {
86+
fn self_ty(&self) {
87+
unsafe { ACTIONS.push("self_ty IntWrapper"); }
88+
}
89+
}
90+
91+
impl Trait for UnsizedArray {
92+
fn self_ty(&self) {
93+
unsafe { ACTIONS.push("self_ty UnsizedArray"); }
94+
}
95+
}
96+
97+
impl Trait for FinalType {
98+
fn self_ty(&self) {
99+
unsafe { ACTIONS.push("self_ty FinalType"); }
100+
}
101+
}
102+
103+
fn simple() {
104+
let x = match 0 {
105+
0 => &Wrap([]) as &ArrayWrapper,
106+
_ => &Wrap([]) as &UnsizedArray,
107+
};
108+
assert_eq!(x.complete(), vec!["self_ty UnsizedArray"]);
109+
}
110+
111+
fn long_chain() {
112+
let x = match 0 {
113+
0 => &TopType as &TopType,
114+
1 => &Wrap([]) as &ArrayWrapper,
115+
2 => &IntWrapper as &IntWrapper,
116+
3 => &Wrap([]) as &UnsizedArray,
117+
4 => &FinalType as &FinalType,
118+
_ => loop {},
119+
};
120+
assert_eq!(
121+
x.complete(),
122+
vec![
123+
"deref TopType->ArrayWrapper",
124+
"deref ArrayWrapper->IntWrapper",
125+
"deref IntWrapper->UnsizedArray",
126+
"deref UnsizedArray->FinalType",
127+
"self_ty FinalType",
128+
],
129+
);
130+
}
131+
132+
fn mixed_coercion() {
133+
let x = match 0 {
134+
0 => &TopType as &TopType,
135+
1 => &Wrap([]) as &ArrayWrapper,
136+
// IntWrapper arm removed
137+
2 => &Wrap([]) as &UnsizedArray,
138+
3 => &FinalType as &FinalType,
139+
_ => loop {},
140+
};
141+
assert_eq!(
142+
x.complete(),
143+
vec![
144+
"deref TopType->ArrayWrapper",
145+
"deref UnsizedArray->FinalType",
146+
"self_ty FinalType",
147+
]
148+
);
149+
}
150+
151+
fn order_dependence() {
152+
let a = match 0 {
153+
0 => &Wrap([]) as &ArrayWrapper,
154+
1 => &IntWrapper as &IntWrapper,
155+
2 => &Wrap([]) as &UnsizedArray,
156+
_ => loop {},
157+
};
158+
assert_eq!(
159+
a.complete(),
160+
vec![
161+
"deref ArrayWrapper->IntWrapper",
162+
"deref IntWrapper->UnsizedArray",
163+
"self_ty UnsizedArray",
164+
],
165+
);
166+
167+
unsafe { ACTIONS.clear() }
168+
let b = match 0 {
169+
0 => &Wrap([]) as &ArrayWrapper,
170+
1 => &Wrap([]) as &UnsizedArray,
171+
2 => &IntWrapper as &IntWrapper,
172+
_ => loop {},
173+
};
174+
assert_eq!(b.complete(), vec!["self_ty UnsizedArray"]);
175+
}
176+
177+
fn deref_to_dyn() {
178+
let x = match 0 {
179+
0 => &TopTypeNoTrait as &TopTypeNoTrait,
180+
1 => &TopTypeNoTrait as &FinalType,
181+
2 => &TopTypeNoTrait as &FinalType as &dyn Trait,
182+
_ => loop {},
183+
};
184+
assert_eq!(
185+
x.complete(),
186+
vec![
187+
"deref TopTypeNoTrait->ArrayWrapper",
188+
"deref ArrayWrapper->IntWrapper",
189+
"deref IntWrapper->UnsizedArray",
190+
"deref UnsizedArray->FinalType",
191+
"self_ty FinalType",
192+
],
193+
);
194+
}
195+
196+
fn main() {
197+
simple();
198+
long_chain();
199+
mixed_coercion();
200+
order_dependence();
201+
deref_to_dyn();
202+
}

0 commit comments

Comments
 (0)