Rollup merge of #148173 - tiif:fix-opaque-ice, r=BoxyUwU
Emit delayed bug during wfck for stranded opaque Fixes https://github.com/rust-lang/trait-system-refactor-initiative/issues/235 ## Problem The fundamental issue here is ``OpaqueTypeCollector`` operates on ``rustc_middle::Ty``, but ``check_type_wf`` operates on HIR. Since [check_type_wf](2f7620a5cc/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 at34a8c7368c/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
This commit is contained in:
@@ -242,6 +242,16 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
|
||||
owner_def_id: LocalDefId,
|
||||
opaque_types_from: DefiningScopeKind,
|
||||
) -> Ty<'tcx> {
|
||||
// When an opaque type is stranded, its hidden type cannot be inferred
|
||||
// so we should not continue.
|
||||
if !tcx.opaque_types_defined_by(owner_def_id).contains(&def_id) {
|
||||
let opaque_type_span = tcx.def_span(def_id);
|
||||
let guar = tcx
|
||||
.dcx()
|
||||
.span_delayed_bug(opaque_type_span, "cannot infer type for stranded opaque type");
|
||||
return Ty::new_error(tcx, guar);
|
||||
}
|
||||
|
||||
match opaque_types_from {
|
||||
DefiningScopeKind::HirTypeck => {
|
||||
let tables = tcx.typeck(owner_def_id);
|
||||
|
||||
50
tests/ui/traits/next-solver/opaques/stranded_opaque.rs
Normal file
50
tests/ui/traits/next-solver/opaques/stranded_opaque.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
//@ compile-flags: -Znext-solver
|
||||
#![feature(type_alias_impl_trait)]
|
||||
use std::future::Future;
|
||||
|
||||
// Test for https://github.com/rust-lang/trait-system-refactor-initiative/issues/235
|
||||
|
||||
// These are cases where an opaque types become "stranded" due to
|
||||
// some errors. Make sure we don't ICE in either case.
|
||||
|
||||
// Case 1: `impl Send` is stranded
|
||||
fn foo() -> impl ?Future<Output = impl Send> {
|
||||
//~^ ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
()
|
||||
}
|
||||
|
||||
// Case 2: `Assoc = impl Trait` is stranded
|
||||
trait Trait {}
|
||||
impl Trait for i32 {}
|
||||
|
||||
fn produce() -> impl Trait<Assoc = impl Trait> {
|
||||
//~^ ERROR associated type `Assoc` not found for `Trait`
|
||||
//~| ERROR associated type `Assoc` not found for `Trait`
|
||||
16
|
||||
}
|
||||
|
||||
// Case 3: `impl Trait` is stranded
|
||||
fn ill_formed_string() -> String<impl Trait> {
|
||||
//~^ ERROR struct takes 0 generic arguments but 1 generic argument was supplied
|
||||
String::from("a string")
|
||||
}
|
||||
|
||||
// Case 4: TAIT variant of Case 1 to 3
|
||||
type Foo = impl ?Future<Output = impl Send>;
|
||||
//~^ ERROR unconstrained opaque type
|
||||
//~| ERROR unconstrained opaque type
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
//~| ERROR bound modifier `?` can only be applied to `Sized`
|
||||
|
||||
type Produce = impl Trait<Assoc = impl Trait>;
|
||||
//~^ ERROR unconstrained opaque type
|
||||
//~| ERROR unconstrained opaque type
|
||||
//~| ERROR associated type `Assoc` not found for `Trait`
|
||||
//~| ERROR associated type `Assoc` not found for `Trait`
|
||||
|
||||
type IllFormedString = String<impl Trait>;
|
||||
//~^ ERROR unconstrained opaque type
|
||||
//~| ERROR struct takes 0 generic arguments but 1 generic argument was supplied
|
||||
|
||||
fn main() {}
|
||||
116
tests/ui/traits/next-solver/opaques/stranded_opaque.stderr
Normal file
116
tests/ui/traits/next-solver/opaques/stranded_opaque.stderr
Normal file
@@ -0,0 +1,116 @@
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/stranded_opaque.rs:11:18
|
||||
|
|
||||
LL | fn foo() -> impl ?Future<Output = impl Send> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0220]: associated type `Assoc` not found for `Trait`
|
||||
--> $DIR/stranded_opaque.rs:21:28
|
||||
|
|
||||
LL | fn produce() -> impl Trait<Assoc = impl Trait> {
|
||||
| ^^^^^ associated type `Assoc` not found
|
||||
|
||||
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
|
||||
--> $DIR/stranded_opaque.rs:28:27
|
||||
|
|
||||
LL | fn ill_formed_string() -> String<impl Trait> {
|
||||
| ^^^^^^------------ help: remove the unnecessary generics
|
||||
| |
|
||||
| expected 0 generic arguments
|
||||
|
||||
error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
|
||||
--> $DIR/stranded_opaque.rs:46:25
|
||||
|
|
||||
LL | type IllFormedString = String<impl Trait>;
|
||||
| ^^^^^^------------ help: remove the unnecessary generics
|
||||
| |
|
||||
| expected 0 generic arguments
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/stranded_opaque.rs:11:18
|
||||
|
|
||||
LL | fn foo() -> impl ?Future<Output = impl Send> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0220]: associated type `Assoc` not found for `Trait`
|
||||
--> $DIR/stranded_opaque.rs:21:28
|
||||
|
|
||||
LL | fn produce() -> impl Trait<Assoc = impl Trait> {
|
||||
| ^^^^^ associated type `Assoc` not found
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/stranded_opaque.rs:34:12
|
||||
|
|
||||
LL | type Foo = impl ?Future<Output = impl Send>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same crate
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/stranded_opaque.rs:34:17
|
||||
|
|
||||
LL | type Foo = impl ?Future<Output = impl Send>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: bound modifier `?` can only be applied to `Sized`
|
||||
--> $DIR/stranded_opaque.rs:34:17
|
||||
|
|
||||
LL | type Foo = impl ?Future<Output = impl Send>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/stranded_opaque.rs:34:34
|
||||
|
|
||||
LL | type Foo = impl ?Future<Output = impl Send>;
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same crate
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/stranded_opaque.rs:40:17
|
||||
|
|
||||
LL | type Produce = impl Trait<Assoc = impl Trait>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `Produce` must be used in combination with a concrete type within the same crate
|
||||
|
||||
error[E0220]: associated type `Assoc` not found for `Trait`
|
||||
--> $DIR/stranded_opaque.rs:40:28
|
||||
|
|
||||
LL | type Produce = impl Trait<Assoc = impl Trait>;
|
||||
| ^^^^^ associated type `Assoc` not found
|
||||
|
||||
error[E0220]: associated type `Assoc` not found for `Trait`
|
||||
--> $DIR/stranded_opaque.rs:40:28
|
||||
|
|
||||
LL | type Produce = impl Trait<Assoc = impl Trait>;
|
||||
| ^^^^^ associated type `Assoc` not found
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/stranded_opaque.rs:40:36
|
||||
|
|
||||
LL | type Produce = impl Trait<Assoc = impl Trait>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `Produce` must be used in combination with a concrete type within the same crate
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/stranded_opaque.rs:46:32
|
||||
|
|
||||
LL | type IllFormedString = String<impl Trait>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `IllFormedString` must be used in combination with a concrete type within the same crate
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0220.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
Reference in New Issue
Block a user