Check hidden types for well formedness at the definition site instead of only at the opaque type itself

This commit is contained in:
Oli Scherer 2022-05-05 14:14:06 +00:00
parent 12d3f107c1
commit f667e952f8
32 changed files with 311 additions and 150 deletions

View File

@ -110,6 +110,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let remapped_type = infcx.infer_opaque_definition_from_instantiation( let remapped_type = infcx.infer_opaque_definition_from_instantiation(
opaque_type_key, opaque_type_key,
universal_concrete_type, universal_concrete_type,
origin,
); );
let ty = if check_opaque_type_parameter_valid( let ty = if check_opaque_type_parameter_valid(
infcx.tcx, infcx.tcx,

View File

@ -1,11 +1,15 @@
use crate::traits; use crate::traits;
use crate::traits::error_reporting::InferCtxtExt as _;
use crate::traits::TraitEngineExt as _;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::OpaqueTyOrigin;
use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic; use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
use rustc_infer::infer::InferCtxt; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt as _};
use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts};
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt}; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
pub trait InferCtxtExt<'tcx> { pub trait InferCtxtExt<'tcx> {
@ -13,6 +17,7 @@ pub trait InferCtxtExt<'tcx> {
&self, &self,
opaque_type_key: OpaqueTypeKey<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>,
instantiated_ty: OpaqueHiddenType<'tcx>, instantiated_ty: OpaqueHiddenType<'tcx>,
origin: OpaqueTyOrigin,
) -> Ty<'tcx>; ) -> Ty<'tcx>;
} }
@ -45,6 +50,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
&self, &self,
opaque_type_key: OpaqueTypeKey<'tcx>, opaque_type_key: OpaqueTypeKey<'tcx>,
instantiated_ty: OpaqueHiddenType<'tcx>, instantiated_ty: OpaqueHiddenType<'tcx>,
origin: OpaqueTyOrigin,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
if self.is_tainted_by_errors() { if self.is_tainted_by_errors() {
return self.tcx.ty_error(); return self.tcx.ty_error();
@ -76,7 +82,69 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
)); ));
debug!(?definition_ty); debug!(?definition_ty);
definition_ty // Only check this for TAIT. RPIT already supports `src/test/ui/impl-trait/nested-return-type2.rs`
// on stable and we'd break that.
if let OpaqueTyOrigin::TyAlias = origin {
// This logic duplicates most of `check_opaque_meets_bounds`.
// FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
let param_env = self.tcx.param_env(def_id);
let body_id = self.tcx.local_def_id_to_hir_id(def_id.as_local().unwrap());
self.tcx.infer_ctxt().enter(move |infcx| {
// Require the hidden type to be well-formed with only the generics of the opaque type.
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
// hidden type is well formed even without those bounds.
let predicate =
ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
.to_predicate(infcx.tcx);
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
// the bounds that the function supplies.
match infcx.register_hidden_type(
OpaqueTypeKey { def_id, substs: id_substs },
ObligationCause::misc(instantiated_ty.span, body_id),
param_env,
definition_ty,
origin,
) {
Ok(infer_ok) => {
for obligation in infer_ok.obligations {
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
}
}
Err(err) => {
infcx
.report_mismatched_types(
&ObligationCause::misc(instantiated_ty.span, body_id),
self.tcx.mk_opaque(def_id, id_substs),
definition_ty,
err,
)
.emit();
}
}
fulfillment_cx.register_predicate_obligation(
&infcx,
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate),
);
// Check that all obligations are satisfied by the implementation's
// version.
let errors = fulfillment_cx.select_all_or_error(&infcx);
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
if errors.is_empty() {
definition_ty
} else {
infcx.report_fulfillment_errors(&errors, None, false);
self.tcx.ty_error()
}
})
} else {
definition_ty
}
} }
} }

View File

@ -4,10 +4,10 @@
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
type X<T> = impl Clone; type X<T> = impl Clone;
//~^ ERROR the trait bound `T: Clone` is not satisfied
fn f<T: Clone>(t: T) -> X<T> { fn f<T: Clone>(t: T) -> X<T> {
t t
//~^ ERROR the trait bound `T: Clone` is not satisfied
} }
fn g<T>(o: Option<X<T>>) -> Option<X<T>> { fn g<T>(o: Option<X<T>>) -> Option<X<T>> {

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `T: Clone` is not satisfied error[E0277]: the trait bound `T: Clone` is not satisfied
--> $DIR/bounds-are-checked-2.rs:6:13 --> $DIR/bounds-are-checked-2.rs:9:5
| |
LL | type X<T> = impl Clone; LL | t
| ^^^^^^^^^^ the trait `Clone` is not implemented for `T` | ^ the trait `Clone` is not implemented for `T`
| |
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
| |

View File

@ -15,6 +15,7 @@ type TwoConsts<const X: usize, const Y: usize> = impl Debug;
fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> { fn one_ty<T: Debug>(t: T) -> TwoTys<T, T> {
t t
//~^ ERROR non-defining opaque type use in defining scope //~^ ERROR non-defining opaque type use in defining scope
//~| ERROR `U` doesn't implement `Debug`
} }
fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> { fn one_lifetime<'a>(t: &'a u32) -> TwoLifetimes<'a, 'a> {

View File

@ -1,3 +1,14 @@
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use.rs:16:5
|
LL | t
| ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
help: consider restricting type parameter `U`
|
LL | type TwoTys<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: non-defining opaque type use in defining scope error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:16:5 --> $DIR/generic_duplicate_param_use.rs:16:5
| |
@ -11,7 +22,7 @@ LL | type TwoTys<T, U> = impl Debug;
| ^ ^ | ^ ^
error: non-defining opaque type use in defining scope error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:21:5 --> $DIR/generic_duplicate_param_use.rs:22:5
| |
LL | t LL | t
| ^ | ^
@ -23,7 +34,7 @@ LL | type TwoLifetimes<'a, 'b> = impl Debug;
| ^^ ^^ | ^^ ^^
error: non-defining opaque type use in defining scope error: non-defining opaque type use in defining scope
--> $DIR/generic_duplicate_param_use.rs:26:5 --> $DIR/generic_duplicate_param_use.rs:27:5
| |
LL | t LL | t
| ^ | ^
@ -34,5 +45,6 @@ note: constant used multiple times
LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug; LL | type TwoConsts<const X: usize, const Y: usize> = impl Debug;
| ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
error: aborting due to 3 previous errors error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -6,8 +6,8 @@ fn main() {}
// test that unused generic parameters are ok // test that unused generic parameters are ok
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
//~^ ERROR `T` doesn't implement `Debug`
fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
t t
//~^ ERROR `T` doesn't implement `Debug`
} }

View File

@ -1,8 +1,8 @@
error[E0277]: `T` doesn't implement `Debug` error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use2.rs:8:18 --> $DIR/generic_duplicate_param_use2.rs:11:5
| |
LL | type Two<T, U> = impl Debug; LL | t
| ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
| |

View File

@ -6,13 +6,13 @@ fn main() {}
// test that unused generic parameters are ok // test that unused generic parameters are ok
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
//~^ ERROR `T` doesn't implement `Debug`
fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> { fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
t t
//~^ ERROR `T` doesn't implement `Debug`
} }
fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> { fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
u u
//~^ ERROR concrete type differs from previous defining opaque type use //~^ ERROR `U` doesn't implement `Debug`
} }

View File

@ -1,26 +1,25 @@
error: concrete type differs from previous defining opaque type use error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use3.rs:16:5 --> $DIR/generic_duplicate_param_use3.rs:11:5
|
LL | u
| ^ expected `T`, got `U`
|
note: previous use here
--> $DIR/generic_duplicate_param_use3.rs:12:5
| |
LL | t LL | t
| ^ | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use3.rs:8:18
|
LL | type Two<T, U> = impl Debug;
| ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
| |
LL | type Two<T: std::fmt::Debug, U> = impl Debug; LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++ | +++++++++++++++++
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use3.rs:16:5
|
LL | u
| ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -6,8 +6,8 @@ fn main() {}
// test that unused generic parameters are ok // test that unused generic parameters are ok
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
//~^ ERROR `U` doesn't implement `Debug`
fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> { fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
u u
//~^ ERROR `U` doesn't implement `Debug`
} }

View File

@ -1,8 +1,8 @@
error[E0277]: `U` doesn't implement `Debug` error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use4.rs:8:18 --> $DIR/generic_duplicate_param_use4.rs:11:5
| |
LL | type Two<T, U> = impl Debug; LL | u
| ^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
help: consider restricting type parameter `U` help: consider restricting type parameter `U`
| |

View File

@ -6,14 +6,15 @@ fn main() {}
// test that unused generic parameters are ok // test that unused generic parameters are ok
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
//~^ ERROR `T` doesn't implement `Debug`
//~| ERROR `U` doesn't implement `Debug`
fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> { fn two<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, u) (t, u)
//~^ ERROR `T` doesn't implement `Debug`
//~| ERROR `U` doesn't implement `Debug`
} }
fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> { fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(u, t) (u, t)
//~^ concrete type differs from previous //~^ ERROR `T` doesn't implement `Debug`
//~| ERROR `U` doesn't implement `Debug`
} }

View File

@ -1,20 +1,8 @@
error: concrete type differs from previous defining opaque type use error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:17:5 --> $DIR/generic_duplicate_param_use5.rs:11:5
|
LL | (u, t)
| ^^^^^^ expected `(T, U)`, got `(U, T)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use5.rs:13:5
| |
LL | (t, u) LL | (t, u)
| ^^^^^^ | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:8:18
|
LL | type Two<T, U> = impl Debug;
| ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
= note: required because of the requirements on the impl of `Debug` for `(T, U)` = note: required because of the requirements on the impl of `Debug` for `(T, U)`
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
@ -23,10 +11,10 @@ LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++ | +++++++++++++++++
error[E0277]: `U` doesn't implement `Debug` error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:8:18 --> $DIR/generic_duplicate_param_use5.rs:11:5
| |
LL | type Two<T, U> = impl Debug; LL | (t, u)
| ^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
= note: required because of the requirements on the impl of `Debug` for `(T, U)` = note: required because of the requirements on the impl of `Debug` for `(T, U)`
help: consider restricting type parameter `U` help: consider restricting type parameter `U`
@ -34,6 +22,30 @@ help: consider restricting type parameter `U`
LL | type Two<T, U: std::fmt::Debug> = impl Debug; LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++ | +++++++++++++++++
error: aborting due to 3 previous errors error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:17:5
|
LL | (u, t)
| ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required because of the requirements on the impl of `Debug` for `(U, T)`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use5.rs:17:5
|
LL | (u, t)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required because of the requirements on the impl of `Debug` for `(U, T)`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -6,13 +6,14 @@ fn main() {}
// test that unused generic parameters are ok // test that unused generic parameters are ok
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
//~^ ERROR `T` doesn't implement `Debug`
fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> { fn two<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, t) (t, t)
//~^ ERROR `T` doesn't implement `Debug`
} }
fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> { fn three<T: Copy + Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(u, t) (u, t)
//~^ ERROR concrete type differs from previous //~^ ERROR `T` doesn't implement `Debug`
//~| ERROR `U` doesn't implement `Debug`
} }

View File

@ -1,20 +1,8 @@
error: concrete type differs from previous defining opaque type use error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use6.rs:16:5 --> $DIR/generic_duplicate_param_use6.rs:11:5
|
LL | (u, t)
| ^^^^^^ expected `(T, T)`, got `(U, T)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use6.rs:12:5
| |
LL | (t, t) LL | (t, t)
| ^^^^^^ | ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use6.rs:8:18
|
LL | type Two<T, U> = impl Debug;
| ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
= note: required because of the requirements on the impl of `Debug` for `(T, T)` = note: required because of the requirements on the impl of `Debug` for `(T, T)`
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
@ -22,6 +10,30 @@ help: consider restricting type parameter `T`
LL | type Two<T: std::fmt::Debug, U> = impl Debug; LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++ | +++++++++++++++++
error: aborting due to 2 previous errors error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use6.rs:16:5
|
LL | (u, t)
| ^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required because of the requirements on the impl of `Debug` for `(U, T)`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use6.rs:16:5
|
LL | (u, t)
| ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required because of the requirements on the impl of `Debug` for `(U, T)`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -5,13 +5,13 @@ use std::fmt::Debug;
fn main() {} fn main() {}
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
//~^ ERROR `T` doesn't implement `Debug`
fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> { fn two<T: Debug, U: Debug>(t: T, _: U) -> Two<T, U> {
(t, 4u32) (t, 4u32)
//~^ ERROR `T` doesn't implement `Debug`
} }
fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> { fn three<T: Debug, U: Debug>(_: T, u: U) -> Two<T, U> {
(u, 4u32) (u, 4u32)
//~^ concrete type differs from previous //~^ ERROR `U` doesn't implement `Debug`
} }

View File

@ -1,20 +1,8 @@
error: concrete type differs from previous defining opaque type use error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use8.rs:15:5 --> $DIR/generic_duplicate_param_use8.rs:10:5
|
LL | (u, 4u32)
| ^^^^^^^^^ expected `(T, u32)`, got `(U, u32)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use8.rs:11:5
| |
LL | (t, 4u32) LL | (t, 4u32)
| ^^^^^^^^^ | ^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use8.rs:7:18
|
LL | type Two<T, U> = impl Debug;
| ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
= note: required because of the requirements on the impl of `Debug` for `(T, u32)` = note: required because of the requirements on the impl of `Debug` for `(T, u32)`
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
@ -22,6 +10,18 @@ help: consider restricting type parameter `T`
LL | type Two<T: std::fmt::Debug, U> = impl Debug; LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++ | +++++++++++++++++
error[E0277]: `U` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use8.rs:15:5
|
LL | (u, 4u32)
| ^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required because of the requirements on the impl of `Debug` for `(U, u32)`
help: consider restricting type parameter `U`
|
LL | type Two<T, U: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -5,9 +5,6 @@ use std::fmt::Debug;
fn main() {} fn main() {}
type Two<A, B> = impl Debug; type Two<A, B> = impl Debug;
//~^ ERROR the trait bound `A: Foo` is not satisfied
//~| ERROR `A` doesn't implement `Debug`
//~| ERROR `B` doesn't implement `Debug`
trait Foo { trait Foo {
type Bar: Debug; type Bar: Debug;
@ -16,8 +13,13 @@ trait Foo {
fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> { fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, u, T::BAR) (t, u, T::BAR)
//~^ ERROR the trait bound `A: Foo` is not satisfied
//~| ERROR `A` doesn't implement `Debug`
//~| ERROR `B` doesn't implement `Debug`
} }
fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> { fn three<T: Debug, U: Debug>(t: T, u: U) -> Two<T, U> {
(t, u, 42) //~ ERROR concrete type differs from previous (t, u, 42)
//~^ ERROR `A` doesn't implement `Debug`
//~| ERROR `B` doesn't implement `Debug`
} }

View File

@ -1,20 +1,8 @@
error: concrete type differs from previous defining opaque type use error[E0277]: the trait bound `A: Foo` is not satisfied
--> $DIR/generic_duplicate_param_use9.rs:22:5 --> $DIR/generic_duplicate_param_use9.rs:15:5
|
LL | (t, u, 42)
| ^^^^^^^^^^ expected `(A, B, <A as Foo>::Bar)`, got `(A, B, i32)`
|
note: previous use here
--> $DIR/generic_duplicate_param_use9.rs:18:5
| |
LL | (t, u, T::BAR) LL | (t, u, T::BAR)
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
error[E0277]: the trait bound `A: Foo` is not satisfied
--> $DIR/generic_duplicate_param_use9.rs:7:18
|
LL | type Two<A, B> = impl Debug;
| ^^^^^^^^^^ the trait `Foo` is not implemented for `A`
| |
help: consider restricting type parameter `A` help: consider restricting type parameter `A`
| |
@ -22,10 +10,10 @@ LL | type Two<A: Foo, B> = impl Debug;
| +++++ | +++++
error[E0277]: `A` doesn't implement `Debug` error[E0277]: `A` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use9.rs:7:18 --> $DIR/generic_duplicate_param_use9.rs:15:5
| |
LL | type Two<A, B> = impl Debug; LL | (t, u, T::BAR)
| ^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
= note: required because of the requirements on the impl of `Debug` for `(A, B, _)` = note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
help: consider restricting type parameter `A` help: consider restricting type parameter `A`
@ -34,10 +22,10 @@ LL | type Two<A: std::fmt::Debug, B> = impl Debug;
| +++++++++++++++++ | +++++++++++++++++
error[E0277]: `B` doesn't implement `Debug` error[E0277]: `B` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use9.rs:7:18 --> $DIR/generic_duplicate_param_use9.rs:15:5
| |
LL | type Two<A, B> = impl Debug; LL | (t, u, T::BAR)
| ^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug` | ^^^^^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
= note: required because of the requirements on the impl of `Debug` for `(A, B, _)` = note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
help: consider restricting type parameter `B` help: consider restricting type parameter `B`
@ -45,6 +33,30 @@ help: consider restricting type parameter `B`
LL | type Two<A, B: std::fmt::Debug> = impl Debug; LL | type Two<A, B: std::fmt::Debug> = impl Debug;
| +++++++++++++++++ | +++++++++++++++++
error: aborting due to 4 previous errors error[E0277]: `A` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use9.rs:22:5
|
LL | (t, u, 42)
| ^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required because of the requirements on the impl of `Debug` for `(A, B, i32)`
help: consider restricting type parameter `A`
|
LL | type Two<A: std::fmt::Debug, B> = impl Debug;
| +++++++++++++++++
error[E0277]: `B` doesn't implement `Debug`
--> $DIR/generic_duplicate_param_use9.rs:22:5
|
LL | (t, u, 42)
| ^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required because of the requirements on the impl of `Debug` for `(A, B, i32)`
help: consider restricting type parameter `B`
|
LL | type Two<A, B: std::fmt::Debug> = impl Debug;
| +++++++++++++++++
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -1,11 +1,11 @@
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
type Foo<T> = impl Default; type Foo<T> = impl Default;
//~^ ERROR: the trait bound `T: Default` is not satisfied
#[allow(unused)] #[allow(unused)]
fn foo<T: Default>(t: T) -> Foo<T> { fn foo<T: Default>(t: T) -> Foo<T> {
t t
//~^ ERROR: the trait bound `T: Default` is not satisfied
} }
struct NotDefault; struct NotDefault;

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `T: Default` is not satisfied error[E0277]: the trait bound `T: Default` is not satisfied
--> $DIR/issue-52843.rs:3:15 --> $DIR/issue-52843.rs:7:5
| |
LL | type Foo<T> = impl Default; LL | t
| ^^^^^^^^^^^^ the trait `Default` is not implemented for `T` | ^ the trait `Default` is not implemented for `T`
| |
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
| |

View File

@ -19,6 +19,7 @@ where
fn iter_bits(self, n: u8) -> Self::BitsIter { fn iter_bits(self, n: u8) -> Self::BitsIter {
(0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
//~^ ERROR non-defining opaque type use in defining scope //~^ ERROR non-defining opaque type use in defining scope
//~| ERROR type mismatch resolving
} }
} }

View File

@ -1,3 +1,16 @@
error[E0271]: type mismatch resolving `<[closure@$DIR/issue-60564.rs:20:28: 20:100] as FnOnce<(u8,)>>::Output == I`
--> $DIR/issue-60564.rs:20:9
|
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
| - this type parameter
...
LL | (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found type parameter `I`
|
= note: expected type `u8`
found type parameter `I`
= note: required because of the requirements on the impl of `Iterator` for `Map<Rev<std::ops::Range<u8>>, [closure@$DIR/issue-60564.rs:20:28: 20:100]>`
error: non-defining opaque type use in defining scope error: non-defining opaque type use in defining scope
--> $DIR/issue-60564.rs:20:9 --> $DIR/issue-60564.rs:20:9
| |
@ -10,5 +23,6 @@ note: used non-generic type `u8` for generic parameter
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>; LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
| ^ | ^
error: aborting due to previous error error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0271`.

View File

@ -8,6 +8,7 @@ type Alias<'a, U> = impl Trait<U>;
fn f<'a>() -> Alias<'a, ()> {} fn f<'a>() -> Alias<'a, ()> {}
//~^ ERROR non-defining opaque type use in defining scope //~^ ERROR non-defining opaque type use in defining scope
//~| ERROR the trait bound `(): Trait<U>` is not satisfied
fn main() {} fn main() {}

View File

@ -1,3 +1,14 @@
error[E0277]: the trait bound `(): Trait<U>` is not satisfied
--> $DIR/issue-68368-non-defining-use.rs:9:29
|
LL | fn f<'a>() -> Alias<'a, ()> {}
| ^^ the trait `Trait<U>` is not implemented for `()`
|
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
LL | type Alias<'a, U> = impl Trait<U> where (): Trait<U>;
| ++++++++++++++++++
error: non-defining opaque type use in defining scope error: non-defining opaque type use in defining scope
--> $DIR/issue-68368-non-defining-use.rs:9:29 --> $DIR/issue-68368-non-defining-use.rs:9:29
| |
@ -10,5 +21,6 @@ note: used non-generic type `()` for generic parameter
LL | type Alias<'a, U> = impl Trait<U>; LL | type Alias<'a, U> = impl Trait<U>;
| ^ | ^
error: aborting due to previous error error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -5,7 +5,6 @@
use std::future::Future; use std::future::Future;
type G<'a, T> = impl Future<Output = ()>; type G<'a, T> = impl Future<Output = ()>;
//~^ ERROR: the trait bound `T: Trait` is not satisfied
trait Trait { trait Trait {
type F: Future<Output = ()>; type F: Future<Output = ()>;
@ -17,6 +16,7 @@ trait Trait {
Self: Sized, Self: Sized,
{ {
async move { self.f().await } async move { self.f().await }
//~^ ERROR: the trait bound `T: Trait` is not satisfied
} }
} }

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `T: Trait` is not satisfied error[E0277]: the trait bound `T: Trait` is not satisfied
--> $DIR/issue-89686.rs:7:17 --> $DIR/issue-89686.rs:18:9
| |
LL | type G<'a, T> = impl Future<Output = ()>; LL | async move { self.f().await }
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
| |
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
| |

View File

@ -5,10 +5,10 @@ use std::fmt::Debug;
fn main() {} fn main() {}
type Two<T, U> = impl Debug; type Two<T, U> = impl Debug;
//~^ ERROR `T` doesn't implement `Debug`
fn three<T: Debug, U>(t: T) -> Two<T, U> { fn three<T: Debug, U>(t: T) -> Two<T, U> {
(t, 5i8) (t, 5i8)
//~^ ERROR `T` doesn't implement `Debug`
} }
trait Bar { trait Bar {
@ -23,7 +23,8 @@ impl Bar for u32 {
fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> { fn four<T: Debug, U: Bar>(t: T) -> Two<T, U> {
(t, <U as Bar>::FOO) (t, <U as Bar>::FOO)
//~^ ERROR concrete type differs from previous //~^ ERROR `U: Bar` is not satisfied
//~| ERROR `T` doesn't implement `Debug`
} }
fn is_sync<T: Sync>() {} fn is_sync<T: Sync>() {}

View File

@ -1,20 +1,8 @@
error: concrete type differs from previous defining opaque type use error[E0277]: `T` doesn't implement `Debug`
--> $DIR/not_a_defining_use.rs:25:5 --> $DIR/not_a_defining_use.rs:10:5
|
LL | (t, <U as Bar>::FOO)
| ^^^^^^^^^^^^^^^^^^^^ expected `(T, i8)`, got `(T, <U as Bar>::Blub)`
|
note: previous use here
--> $DIR/not_a_defining_use.rs:11:5
| |
LL | (t, 5i8) LL | (t, 5i8)
| ^^^^^^^^ | ^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/not_a_defining_use.rs:7:18
|
LL | type Two<T, U> = impl Debug;
| ^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
| |
= note: required because of the requirements on the impl of `Debug` for `(T, i8)` = note: required because of the requirements on the impl of `Debug` for `(T, i8)`
help: consider restricting type parameter `T` help: consider restricting type parameter `T`
@ -22,6 +10,29 @@ help: consider restricting type parameter `T`
LL | type Two<T: std::fmt::Debug, U> = impl Debug; LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++ | +++++++++++++++++
error: aborting due to 2 previous errors error[E0277]: the trait bound `U: Bar` is not satisfied
--> $DIR/not_a_defining_use.rs:25:5
|
LL | (t, <U as Bar>::FOO)
| ^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `U`
|
help: consider restricting type parameter `U`
|
LL | type Two<T, U: Bar> = impl Debug;
| +++++
error[E0277]: `T` doesn't implement `Debug`
--> $DIR/not_a_defining_use.rs:25:5
|
LL | (t, <U as Bar>::FOO)
| ^^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= note: required because of the requirements on the impl of `Debug` for `(T, _)`
help: consider restricting type parameter `T`
|
LL | type Two<T: std::fmt::Debug, U> = impl Debug;
| +++++++++++++++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`. For more information about this error, try `rustc --explain E0277`.

View File

@ -17,10 +17,10 @@ impl<X: Trait> ProofForConversion<X> for () {
} }
type Converter<T> = impl ProofForConversion<T>; type Converter<T> = impl ProofForConversion<T>;
//~^ ERROR the trait bound `T: Trait` is not satisfied
fn _defining_use<T: Trait>() -> Converter<T> { fn _defining_use<T: Trait>() -> Converter<T> {
() ()
//~^ ERROR the trait bound `T: Trait` is not satisfied
} }

View File

@ -1,8 +1,8 @@
error[E0277]: the trait bound `T: Trait` is not satisfied error[E0277]: the trait bound `T: Trait` is not satisfied
--> $DIR/underconstrained_generic.rs:19:21 --> $DIR/underconstrained_generic.rs:22:5
| |
LL | type Converter<T> = impl ProofForConversion<T>; LL | ()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` | ^^ the trait `Trait` is not implemented for `T`
| |
note: required because of the requirements on the impl of `ProofForConversion<T>` for `()` note: required because of the requirements on the impl of `ProofForConversion<T>` for `()`
--> $DIR/underconstrained_generic.rs:13:16 --> $DIR/underconstrained_generic.rs:13:16