Skip to content

Commit 1fe1483

Browse files
authored
Rollup merge of rust-lang#148173 - tiif:fix-opaque-ice, r=BoxyUwU
Emit delayed bug during wfck for stranded opaque Fixes rust-lang/trait-system-refactor-initiative#235 ## Problem The fundamental issue here is ``OpaqueTypeCollector`` operates on ``rustc_middle::Ty``, but ``check_type_wf`` operates on HIR. Since [check_type_wf](https://github.com/rust-lang/rust/blob/2f7620a5ccfea7d59d1f500e2a2e59cf1c867a1b/compiler/rustc_hir_analysis/src/check/wfcheck.rs#L2262) operates on HIR, it can see the stranded opaque and tries to infer it's hidden type. But ``OpaqueTypeCollector`` operates on ``rustc_middle::Ty``, so the ``OpaqueTypeCollector`` can no longer see a stranded opaque, hence its hidden type could not be inferred. As a result, the tests ICE'ed at https://github.com/rust-lang/rust/blob/34a8c7368c84fc699fc83a8851a02f93fd655931/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs#L253 ## Proposed solution This PR detects stranded opaque types during wf check and emit a delayed bug for it. ## Alternative solution `@BoxyUwU` and I had considered rewriting ``OpaqueTypeCollector`` to be a HIR visitor instead of a ``rustc_middle::Ty`` visitor, but we believe a HIR-based ``OpaqueTypeCollector`` will not work and might not worth the cost of rewriting. ## Acknowledgement This PR is a joint effort with `@BoxyUwU` :3
2 parents bc1d727 + c797724 commit 1fe1483

File tree

3 files changed

+176
-0
lines changed

3 files changed

+176
-0
lines changed

compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,16 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
242242
owner_def_id: LocalDefId,
243243
opaque_types_from: DefiningScopeKind,
244244
) -> Ty<'tcx> {
245+
// When an opaque type is stranded, its hidden type cannot be inferred
246+
// so we should not continue.
247+
if !tcx.opaque_types_defined_by(owner_def_id).contains(&def_id) {
248+
let opaque_type_span = tcx.def_span(def_id);
249+
let guar = tcx
250+
.dcx()
251+
.span_delayed_bug(opaque_type_span, "cannot infer type for stranded opaque type");
252+
return Ty::new_error(tcx, guar);
253+
}
254+
245255
match opaque_types_from {
246256
DefiningScopeKind::HirTypeck => {
247257
let tables = tcx.typeck(owner_def_id);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//@ compile-flags: -Znext-solver
2+
#![feature(type_alias_impl_trait)]
3+
use std::future::Future;
4+
5+
// Test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/235
6+
7+
// These are cases where an opaque types become "stranded" due to
8+
// some errors. Make sure we don't ICE in either case.
9+
10+
// Case 1: `impl Send` is stranded
11+
fn foo() -> impl ?Future<Output = impl Send> {
12+
//~^ ERROR bound modifier `?` can only be applied to `Sized`
13+
//~| ERROR bound modifier `?` can only be applied to `Sized`
14+
()
15+
}
16+
17+
// Case 2: `Assoc = impl Trait` is stranded
18+
trait Trait {}
19+
impl Trait for i32 {}
20+
21+
fn produce() -> impl Trait<Assoc = impl Trait> {
22+
//~^ ERROR associated type `Assoc` not found for `Trait`
23+
//~| ERROR associated type `Assoc` not found for `Trait`
24+
16
25+
}
26+
27+
// Case 3: `impl Trait` is stranded
28+
fn ill_formed_string() -> String<impl Trait> {
29+
//~^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied
30+
String::from("a string")
31+
}
32+
33+
// Case 4: TAIT variant of Case 1 to 3
34+
type Foo = impl ?Future<Output = impl Send>;
35+
//~^ ERROR unconstrained opaque type
36+
//~| ERROR unconstrained opaque type
37+
//~| ERROR bound modifier `?` can only be applied to `Sized`
38+
//~| ERROR bound modifier `?` can only be applied to `Sized`
39+
40+
type Produce = impl Trait<Assoc = impl Trait>;
41+
//~^ ERROR unconstrained opaque type
42+
//~| ERROR unconstrained opaque type
43+
//~| ERROR associated type `Assoc` not found for `Trait`
44+
//~| ERROR associated type `Assoc` not found for `Trait`
45+
46+
type IllFormedString = String<impl Trait>;
47+
//~^ ERROR unconstrained opaque type
48+
//~| ERROR struct takes 0 generic arguments but 1 generic argument was supplied
49+
50+
fn main() {}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
error: bound modifier `?` can only be applied to `Sized`
2+
--> $DIR/stranded_opaque.rs:11:18
3+
|
4+
LL | fn foo() -> impl ?Future<Output = impl Send> {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error[E0220]: associated type `Assoc` not found for `Trait`
8+
--> $DIR/stranded_opaque.rs:21:28
9+
|
10+
LL | fn produce() -> impl Trait<Assoc = impl Trait> {
11+
| ^^^^^ associated type `Assoc` not found
12+
13+
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
14+
--> $DIR/stranded_opaque.rs:28:27
15+
|
16+
LL | fn ill_formed_string() -> String<impl Trait> {
17+
| ^^^^^^------------ help: remove the unnecessary generics
18+
| |
19+
| expected 0 generic arguments
20+
21+
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
22+
--> $DIR/stranded_opaque.rs:46:25
23+
|
24+
LL | type IllFormedString = String<impl Trait>;
25+
| ^^^^^^------------ help: remove the unnecessary generics
26+
| |
27+
| expected 0 generic arguments
28+
29+
error: bound modifier `?` can only be applied to `Sized`
30+
--> $DIR/stranded_opaque.rs:11:18
31+
|
32+
LL | fn foo() -> impl ?Future<Output = impl Send> {
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
|
35+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
36+
37+
error[E0220]: associated type `Assoc` not found for `Trait`
38+
--> $DIR/stranded_opaque.rs:21:28
39+
|
40+
LL | fn produce() -> impl Trait<Assoc = impl Trait> {
41+
| ^^^^^ associated type `Assoc` not found
42+
|
43+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
44+
45+
error: unconstrained opaque type
46+
--> $DIR/stranded_opaque.rs:34:12
47+
|
48+
LL | type Foo = impl ?Future<Output = impl Send>;
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50+
|
51+
= note: `Foo` must be used in combination with a concrete type within the same crate
52+
53+
error: bound modifier `?` can only be applied to `Sized`
54+
--> $DIR/stranded_opaque.rs:34:17
55+
|
56+
LL | type Foo = impl ?Future<Output = impl Send>;
57+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
58+
59+
error: bound modifier `?` can only be applied to `Sized`
60+
--> $DIR/stranded_opaque.rs:34:17
61+
|
62+
LL | type Foo = impl ?Future<Output = impl Send>;
63+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
64+
|
65+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
66+
67+
error: unconstrained opaque type
68+
--> $DIR/stranded_opaque.rs:34:34
69+
|
70+
LL | type Foo = impl ?Future<Output = impl Send>;
71+
| ^^^^^^^^^
72+
|
73+
= note: `Foo` must be used in combination with a concrete type within the same crate
74+
75+
error: unconstrained opaque type
76+
--> $DIR/stranded_opaque.rs:40:17
77+
|
78+
LL | type Produce = impl Trait<Assoc = impl Trait>;
79+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
80+
|
81+
= note: `Produce` must be used in combination with a concrete type within the same crate
82+
83+
error[E0220]: associated type `Assoc` not found for `Trait`
84+
--> $DIR/stranded_opaque.rs:40:28
85+
|
86+
LL | type Produce = impl Trait<Assoc = impl Trait>;
87+
| ^^^^^ associated type `Assoc` not found
88+
89+
error[E0220]: associated type `Assoc` not found for `Trait`
90+
--> $DIR/stranded_opaque.rs:40:28
91+
|
92+
LL | type Produce = impl Trait<Assoc = impl Trait>;
93+
| ^^^^^ associated type `Assoc` not found
94+
|
95+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
96+
97+
error: unconstrained opaque type
98+
--> $DIR/stranded_opaque.rs:40:36
99+
|
100+
LL | type Produce = impl Trait<Assoc = impl Trait>;
101+
| ^^^^^^^^^^
102+
|
103+
= note: `Produce` must be used in combination with a concrete type within the same crate
104+
105+
error: unconstrained opaque type
106+
--> $DIR/stranded_opaque.rs:46:32
107+
|
108+
LL | type IllFormedString = String<impl Trait>;
109+
| ^^^^^^^^^^
110+
|
111+
= note: `IllFormedString` must be used in combination with a concrete type within the same crate
112+
113+
error: aborting due to 15 previous errors
114+
115+
Some errors have detailed explanations: E0107, E0220.
116+
For more information about an error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)