Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
50 changes: 50 additions & 0 deletions tests/ui/traits/next-solver/opaques/stranded_opaque.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 116 additions & 0 deletions tests/ui/traits/next-solver/opaques/stranded_opaque.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Loading