Skip to content

Commit

Permalink
Avoid opaque type not constrained errors in the presence of other e…
Browse files Browse the repository at this point in the history
…rrors
  • Loading branch information
oli-obk committed Dec 4, 2024
1 parent ec3424a commit 5967ec9
Show file tree
Hide file tree
Showing 23 changed files with 72 additions and 153 deletions.
14 changes: 12 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,18 @@ impl TaitConstraintLocator<'_> {
constrained = true;

if !opaque_types_defined_by.contains(&self.def_id) {
self.tcx.dcx().emit_err(TaitForwardCompat {
let guar = self.tcx.dcx().emit_err(TaitForwardCompat {
span: hidden_type.span,
item_span: self
.tcx
.def_ident_span(item_def_id)
.unwrap_or_else(|| self.tcx.def_span(item_def_id)),
});
// Avoid "opaque type not constrained" errors on the opaque itself.
self.found = Some(ty::OpaqueHiddenType {
span: DUMMY_SP,
ty: Ty::new_error(self.tcx, guar),
});
}
let concrete_type =
self.tcx.erase_regions(hidden_type.remap_generic_params_to_declaration_params(
Expand All @@ -248,14 +253,19 @@ impl TaitConstraintLocator<'_> {
if !constrained {
debug!("no constraints in typeck results");
if opaque_types_defined_by.contains(&self.def_id) {
self.tcx.dcx().emit_err(TaitForwardCompat2 {
let guar = self.tcx.dcx().emit_err(TaitForwardCompat2 {
span: self
.tcx
.def_ident_span(item_def_id)
.unwrap_or_else(|| self.tcx.def_span(item_def_id)),
opaque_type_span: self.tcx.def_span(self.def_id),
opaque_type: self.tcx.def_path_str(self.def_id),
});
// Avoid "opaque type not constrained" errors on the opaque itself.
self.found = Some(ty::OpaqueHiddenType {
span: DUMMY_SP,
ty: Ty::new_error(self.tcx, guar),
});
}
return;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0284]: type annotations needed: cannot satisfy `Foo == _`
--> $DIR/norm-before-method-resolution-opaque-type.rs:16:19
--> $DIR/norm-before-method-resolution-opaque-type.rs:15:19
|
LL | fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X
| ^ cannot satisfy `Foo == _`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: item does not constrain `Foo::{opaque#0}`, but has it in its signature
--> $DIR/norm-before-method-resolution-opaque-type.rs:16:4
--> $DIR/norm-before-method-resolution-opaque-type.rs:15:4
|
LL | fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X
| ^^^^^^^^^^^
Expand All @@ -11,16 +11,8 @@ note: this opaque type is in the signature
LL | type Foo = impl Sized;
| ^^^^^^^^^^

error: unconstrained opaque type
--> $DIR/norm-before-method-resolution-opaque-type.rs:13:12
|
LL | type Foo = impl Sized;
| ^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same module

error[E0507]: cannot move out of `*x` which is behind a shared reference
--> $DIR/norm-before-method-resolution-opaque-type.rs:23:13
--> $DIR/norm-before-method-resolution-opaque-type.rs:22:13
|
LL | let x = *x;
| ^^ move occurs because `*x` has type `<X as Trait<'_>>::Out<Foo>`, which does not implement the `Copy` trait
Expand All @@ -31,6 +23,6 @@ LL - let x = *x;
LL + let x = x;
|

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0507`.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ impl<'a, T> Trait<'a> for T {
}

type Foo = impl Sized;
//[old]~^ ERROR: unconstrained opaque type

fn weird_bound<X>(x: &<X as Trait<'static>>::Out<Foo>) -> X
//[old]~^ ERROR: item does not constrain
Expand Down
23 changes: 9 additions & 14 deletions tests/ui/impl-trait/issues/issue-86800.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,28 @@

use std::future::Future;

struct Connection {
}
struct Connection {}

trait Transaction {
}
trait Transaction {}

struct TestTransaction<'conn> {
conn: &'conn Connection
conn: &'conn Connection,
}

impl<'conn> Transaction for TestTransaction<'conn> {
}
impl<'conn> Transaction for TestTransaction<'conn> {}

struct Context {
}
struct Context {}

type TransactionResult<O> = Result<O, ()>;

type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
//~^ ERROR unconstrained opaque type

fn execute_transaction_fut<'f, F, O>(
//~^ ERROR: item does not constrain
f: F,
) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
where
F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f
F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f,
{
f
//~^ ERROR expected generic lifetime parameter, found `'_`
Expand All @@ -39,9 +34,9 @@ where
impl Context {
async fn do_transaction<O>(
//~^ ERROR: item does not constrain
&self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>
) -> TransactionResult<O>
{
&self,
f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>,
) -> TransactionResult<O> {
//~^ ERROR expected generic lifetime parameter, found `'_`
//~| ERROR: item does not constrain
let mut conn = Connection {};
Expand Down
32 changes: 13 additions & 19 deletions tests/ui/impl-trait/issues/issue-86800.stderr
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
--> $DIR/issue-86800.rs:28:4
--> $DIR/issue-86800.rs:23:4
|
LL | fn execute_transaction_fut<'f, F, O>(
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/issue-86800.rs:25:34
--> $DIR/issue-86800.rs:21:34
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
--> $DIR/issue-86800.rs:40:14
--> $DIR/issue-86800.rs:35:14
|
LL | async fn do_transaction<O>(
| ^^^^^^^^^^^^^^
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/issue-86800.rs:25:34
--> $DIR/issue-86800.rs:21:34
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: item does not constrain `TransactionFuture::{opaque#0}`, but has it in its signature
--> $DIR/issue-86800.rs:44:5
--> $DIR/issue-86800.rs:39:31
|
LL | / {
LL | ) -> TransactionResult<O> {
| _______________________________^
LL | |
LL | |
LL | | let mut conn = Connection {};
Expand All @@ -38,21 +39,13 @@ LL | | }
|
= note: consider moving the opaque type's declaration and defining uses into a separate module
note: this opaque type is in the signature
--> $DIR/issue-86800.rs:25:34
--> $DIR/issue-86800.rs:21:34
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: unconstrained opaque type
--> $DIR/issue-86800.rs:25:34
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `TransactionFuture` must be used in combination with a concrete type within the same module

error[E0792]: expected generic lifetime parameter, found `'_`
--> $DIR/issue-86800.rs:35:5
--> $DIR/issue-86800.rs:30:5
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
| --- this generic parameter must be used with a generic lifetime parameter
Expand All @@ -61,12 +54,13 @@ LL | f
| ^

error[E0792]: expected generic lifetime parameter, found `'_`
--> $DIR/issue-86800.rs:44:5
--> $DIR/issue-86800.rs:39:31
|
LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>;
| --- this generic parameter must be used with a generic lifetime parameter
...
LL | / {
LL | ) -> TransactionResult<O> {
| _______________________________^
LL | |
LL | |
LL | | let mut conn = Connection {};
Expand All @@ -75,6 +69,6 @@ LL | | f(&mut transaction).await
LL | | }
| |_____^

error: aborting due to 6 previous errors
error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0792`.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

mod a {
type Foo = impl PartialEq<(Foo, i32)>;
//~^ ERROR: unconstrained opaque type

struct Bar;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0053]: method `eq` has an incompatible type for trait
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:30
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:9:30
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| -------------------------- the found opaque type
Expand All @@ -15,7 +15,7 @@ LL | fn eq(&self, _other: &(a::Bar, i32)) -> bool {
| ~~~~~~~~~~~~~~

error: item does not constrain `a::Foo::{opaque#0}`, but has it in its signature
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:10:12
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:9:12
|
LL | fn eq(&self, _other: &(Foo, i32)) -> bool {
| ^^
Expand All @@ -27,16 +27,8 @@ note: this opaque type is in the signature
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: unconstrained opaque type
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same module

error[E0053]: method `eq` has an incompatible type for trait
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:30
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:30
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| -------------------------- the expected opaque type
Expand All @@ -47,7 +39,7 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
= note: expected signature `fn(&b::Bar, &(b::Foo, _)) -> _`
found signature `fn(&b::Bar, &(b::Bar, _)) -> _`
note: this item must have the opaque type in its signature in order to be able to register hidden types
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:25:12
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:12
|
LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
| ^^
Expand All @@ -57,13 +49,13 @@ LL | fn eq(&self, _other: &(b::Foo, i32)) -> bool {
| ~~~~~~~~~~~~~~

error: unconstrained opaque type
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:19:16
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:18:16
|
LL | type Foo = impl PartialEq<(Foo, i32)>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `Foo` must be used in combination with a concrete type within the same module

error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0053`.
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ note: this opaque type is in the signature
LL | type A = impl Foo;
| ^^^^^^^^

error: unconstrained opaque type
--> $DIR/two_tait_defining_each_other2.rs:6:10
|
LL | type A = impl Foo;
| ^^^^^^^^
|
= note: `A` must be used in combination with a concrete type within the same module

error: opaque type's hidden type cannot be another opaque type from the same scope
--> $DIR/two_tait_defining_each_other2.rs:14:5
|
Expand All @@ -36,5 +28,5 @@ note: opaque type being used as hidden type
LL | type A = impl Foo;
| ^^^^^^^^

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

2 changes: 1 addition & 1 deletion tests/ui/impl-trait/two_tait_defining_each_other2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//@[next] compile-flags: -Znext-solver
#![feature(type_alias_impl_trait)]

type A = impl Foo; //[current]~ ERROR unconstrained opaque type
type A = impl Foo;
type B = impl Foo;

trait Foo {}
Expand Down
1 change: 0 additions & 1 deletion tests/ui/self/arbitrary-self-opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
struct Foo;

type Bar = impl Sized;
//~^ ERROR unconstrained opaque type

impl Foo {
fn foo(self: Bar) {}
Expand Down
14 changes: 3 additions & 11 deletions tests/ui/self/arbitrary-self-opaque.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0307]: invalid `self` parameter type: `Bar`
--> $DIR/arbitrary-self-opaque.rs:8:18
--> $DIR/arbitrary-self-opaque.rs:7:18
|
LL | fn foo(self: Bar) {}
| ^^^
Expand All @@ -8,7 +8,7 @@ LL | fn foo(self: Bar) {}
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)

error: item does not constrain `Bar::{opaque#0}`, but has it in its signature
--> $DIR/arbitrary-self-opaque.rs:8:8
--> $DIR/arbitrary-self-opaque.rs:7:8
|
LL | fn foo(self: Bar) {}
| ^^^
Expand All @@ -20,14 +20,6 @@ note: this opaque type is in the signature
LL | type Bar = impl Sized;
| ^^^^^^^^^^

error: unconstrained opaque type
--> $DIR/arbitrary-self-opaque.rs:4:12
|
LL | type Bar = impl Sized;
| ^^^^^^^^^^
|
= note: `Bar` must be used in combination with a concrete type within the same module

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0307`.
1 change: 0 additions & 1 deletion tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#![feature(type_alias_impl_trait)]
trait Trait<T> {}
type Alias<'a, U> = impl Trait<U>;
//~^ ERROR unconstrained opaque type

pub enum UninhabitedVariants {
Tuple(Alias),
Expand Down
Loading

0 comments on commit 5967ec9

Please sign in to comment.