/// #[feature(trivial_bounds)] is not enabled
TrivialBound,
+
+ /// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
+ OpaqueType,
}
impl ObligationCauseCode<'_> {
"consider constraining the associated type `{}` to `{}`",
values.found, values.expected,
);
- if !self.suggest_constraint(
+ if !(self.suggest_constraining_opaque_associated_type(
+ db,
+ &msg,
+ proj_ty,
+ values.expected,
+ ) || self.suggest_constraint(
db,
&msg,
body_owner_def_id,
proj_ty,
values.expected,
- ) {
+ )) {
db.help(&msg);
db.note(
"for more information, visit \
}
}
- if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
- // When the expected `impl Trait` is not defined in the current item, it will come from
- // a return type. This can occur when dealing with `TryStream` (#71035).
- if self.constrain_associated_type_structured_suggestion(
- db,
- self.def_span(def_id),
- &assoc,
- proj_ty.trait_ref_and_own_substs(self).1,
- values.found,
- &msg,
- ) {
- return;
- }
- }
+ self.suggest_constraining_opaque_associated_type(db, &msg, proj_ty, values.found);
if self.point_at_associated_type(db, body_owner_def_id, values.found) {
return;
}
}
+ /// When the expected `impl Trait` is not defined in the current item, it will come from
+ /// a return type. This can occur when dealing with `TryStream` (#71035).
+ fn suggest_constraining_opaque_associated_type(
+ self,
+ db: &mut DiagnosticBuilder<'_>,
+ msg: &str,
+ proj_ty: &ty::ProjectionTy<'tcx>,
+ ty: Ty<'tcx>,
+ ) -> bool {
+ let assoc = self.associated_item(proj_ty.item_def_id);
+ if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
+ self.constrain_associated_type_structured_suggestion(
+ db,
+ self.def_span(def_id),
+ &assoc,
+ proj_ty.trait_ref_and_own_substs(self).1,
+ ty,
+ &msg,
+ )
+ } else {
+ false
+ }
+ }
+
fn point_at_methods_that_satisfy_associated_type(
self,
db: &mut DiagnosticBuilder<'_>,
// This also instantiates nested instances of `impl Trait`.
let predicate = self.instantiate_opaque_types_in_map(predicate);
- let cause = traits::ObligationCause::new(span, self.body_id, traits::MiscObligation);
+ let cause = traits::ObligationCause::new(span, self.body_id, traits::OpaqueType);
// Require that the predicate holds for the concrete type.
debug!("instantiate_opaque_types: predicate={:?}", predicate);
ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::BindingObligation(_, _)
| ObligationCauseCode::ObjectCastObligation(_)
+ | ObligationCauseCode::OpaqueType
);
if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
| ObligationCauseCode::MethodReceiver
| ObligationCauseCode::ReturnNoExpression
| ObligationCauseCode::UnifyReceiver(..)
+ | ObligationCauseCode::OpaqueType
| ObligationCauseCode::MiscObligation => {}
ObligationCauseCode::SliceOrArrayElem => {
err.note("slice and array elements must have `Sized` type");
--> $DIR/impl-trait-return-missing-constraint.rs:25:13
|
LL | fn bar() -> impl Bar {
- | -------- the expected opaque type
+ | -------- the found opaque type
...
LL | fn baz() -> impl Bar<Item = i32> {
- | ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32`
+ | ^^^^^^^^^^^^^^^^^^^^ expected `i32`, found associated type
|
- = note: expected associated type `<impl Bar as Foo>::Item`
- found type `i32`
+ = note: expected type `i32`
+ found associated type `<impl Bar as Foo>::Item`
help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32`
|
LL | fn bar() -> impl Bar<Item = i32> {
--> $DIR/type-mismatch-signature-deduction.rs:5:13
|
LL | fn foo() -> impl Generator<Return = i32> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Result`, found `i32`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found enum `Result`
|
- = note: expected enum `Result<{integer}, _>`
- found type `i32`
+ = note: expected type `i32`
+ found enum `Result<{integer}, _>`
error: aborting due to 2 previous errors
--> $DIR/bound-normalization-fail.rs:27:32
|
LL | fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
|
- = note: expected type `()`
- found associated type `<T as impl_trait::Trait>::Assoc`
+ = note: expected associated type `<T as impl_trait::Trait>::Assoc`
+ found type `()`
help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
|
LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output=T::Assoc> {
--> $DIR/bound-normalization-fail.rs:43:41
|
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
|
- = note: expected type `()`
- found associated type `<T as lifetimes::Trait<'static>>::Assoc`
+ = note: expected associated type `<T as lifetimes::Trait<'static>>::Assoc`
+ found type `()`
help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
|
LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output=T::Assoc> {
|
= note: expected type `i32`
found associated type `<impl Foo as Leak>::T`
- = help: consider constraining the associated type `<impl Foo as Leak>::T` to `i32`
- = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
+help: consider constraining the associated type `<impl Foo as Leak>::T` to `i32`
+ |
+LL | fn hide<T: Foo>(x: T) -> impl Foo<T = i32> {
+ | ^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/equality2.rs:38:10
--> $DIR/issue-70877.rs:11:12
|
LL | type FooRet = impl std::fmt::Debug;
- | -------------------- the expected opaque type
+ | -------------------- the found opaque type
...
LL | type Foo = impl Iterator<Item = FooItem>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found enum `Option`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Option`, found opaque type
|
- = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>`
- found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
+ = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
+ found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>`
error: aborting due to previous error
--> $DIR/issue-70877.rs:11:12
|
LL | type FooRet = impl std::fmt::Debug;
- | -------------------- the expected opaque type
+ | -------------------- the found opaque type
...
LL | type Foo = impl Iterator<Item = FooItem>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found enum `Option`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Option`, found opaque type
|
- = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>`
- found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
+ = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
+ found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>`
error: aborting due to previous error
--> $DIR/issue-63279.rs:8:16
|
LL | type Closure = impl FnOnce();
- | ^^^^^^^^^^^^^ expected opaque type, found `()`
+ | ^^^^^^^^^^^^^ expected `()`, found opaque type
|
- = note: expected opaque type `impl FnOnce<()>`
- found unit type `()`
+ = note: expected unit type `()`
+ found opaque type `impl FnOnce<()>`
error: aborting due to previous error; 1 warning emitted
--> $DIR/issue-63279.rs:8:16
|
LL | type Closure = impl FnOnce();
- | ^^^^^^^^^^^^^ expected opaque type, found `()`
+ | ^^^^^^^^^^^^^ expected `()`, found opaque type
|
- = note: expected opaque type `impl FnOnce<()>`
- found unit type `()`
+ = note: expected unit type `()`
+ found opaque type `impl FnOnce<()>`
error: aborting due to 2 previous errors