Auto merge of #85499 - jackh726:assoc-type-norm-rebase, r=nikomatsakis

Normalize projections under binders

Fixes #70243
Fixes #70120
Fixes #62529
Fixes #87219

Issues to followup on after (probably fixed, but no test added here):
#76956
#56556
#79207
#85636

r? `@nikomatsakis`
This commit is contained in:
bors 2021-08-25 20:08:00 +00:00
commit 0afc20860e
55 changed files with 813 additions and 393 deletions

View file

@ -2483,10 +2483,9 @@ impl<'tcx> ty::Instance<'tcx> {
// `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping
// track of a polymorphization `ParamEnv` to allow normalizing later.
let mut sig = match *ty.kind() {
ty::FnDef(def_id, substs) if tcx.sess.opts.debugging_opts.polymorphize => tcx
ty::FnDef(def_id, substs) => tcx
.normalize_erasing_regions(tcx.param_env(def_id), tcx.fn_sig(def_id))
.subst(tcx, substs),
ty::FnDef(def_id, substs) => tcx.fn_sig(def_id).subst(tcx, substs),
_ => unreachable!(),
};

View file

@ -9,7 +9,9 @@
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_middle::mir::*;
use rustc_middle::ty::Ty;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{self, Ty};
use rustc_trait_selection::traits::query::normalize::AtExt;
use rustc_index::vec::Idx;
use rustc_span::Span;
@ -162,17 +164,49 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span) {
debug!("equate_normalized_input_or_output(a={:?}, b={:?})", a, b);
if let Err(terr) =
if let Err(_) =
self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation)
{
span_mirbug!(
self,
Location::START,
"equate_normalized_input_or_output: `{:?}=={:?}` failed with `{:?}`",
a,
b,
terr
);
// FIXME(jackh726): This is a hack. It's somewhat like
// `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd
// like to normalize *before* inserting into `local_decls`, but
// doing so ends up causing some other trouble.
let b = match self
.infcx
.at(&ObligationCause::dummy(), ty::ParamEnv::empty())
.normalize(b)
{
Ok(n) => {
debug!("equate_inputs_and_outputs: {:?}", n);
if n.obligations.iter().all(|o| {
matches!(
o.predicate.kind().skip_binder(),
ty::PredicateKind::RegionOutlives(_)
| ty::PredicateKind::TypeOutlives(_)
)
}) {
n.value
} else {
b
}
}
Err(_) => {
debug!("equate_inputs_and_outputs: NoSolution");
b
}
};
if let Err(terr) =
self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation)
{
span_mirbug!(
self,
Location::START,
"equate_normalized_input_or_output: `{:?}=={:?}` failed with `{:?}`",
a,
b,
terr
);
}
}
}
}

View file

@ -1053,6 +1053,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
);
for user_annotation in self.user_type_annotations {
let CanonicalUserTypeAnnotation { span, ref user_ty, inferred_ty } = *user_annotation;
let inferred_ty = self.normalize(inferred_ty, Locations::All(span));
let annotation = self.instantiate_canonical_with_fresh_inference_vars(span, user_ty);
match annotation {
UserType::Ty(mut ty) => {

View file

@ -362,25 +362,40 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
if !needs_normalization(&ty, self.param_env.reveal()) {
return ty;
}
// We don't want to normalize associated types that occur inside of region
// binders, because they may contain bound regions, and we can't cope with that.
//
// Example:
//
// for<'a> fn(<T as Foo<&'a>>::A)
//
// Instead of normalizing `<T as Foo<&'a>>::A` here, we'll
// normalize it when we instantiate those bound regions (which
// should occur eventually).
let ty = ty.super_fold_with(self);
// We try to be a little clever here as a performance optimization in
// cases where there are nested projections under binders.
// For example:
// ```
// for<'a> fn(<T as Foo>::One<'a, Box<dyn Bar<'a, Item=<T as Foo>::Two<'a>>>>)
// ```
// We normalize the substs on the projection before the projecting, but
// if we're naive, we'll
// replace bound vars on inner, project inner, replace placeholders on inner,
// replace bound vars on outer, project outer, replace placeholders on outer
//
// However, if we're a bit more clever, we can replace the bound vars
// on the entire type before normalizing nested projections, meaning we
// replace bound vars on outer, project inner,
// project outer, replace placeholders on outer
//
// This is possible because the inner `'a` will already be a placeholder
// when we need to normalize the inner projection
//
// On the other hand, this does add a bit of complexity, since we only
// replace bound vars if the current type is a `Projection` and we need
// to make sure we don't forget to fold the substs regardless.
match *ty.kind() {
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
ty::Opaque(def_id, substs) => {
// Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty,
Reveal::UserFacing => ty.super_fold_with(self),
Reveal::All => {
// N.b. there is an assumption here all this code can handle
// escaping bound vars.
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
let obligation = Obligation::with_depth(
@ -392,6 +407,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
self.selcx.infcx().report_overflow_error(&obligation, true);
}
let substs = substs.super_fold_with(self);
let generic_ty = self.tcx().type_of(def_id);
let concrete_ty = generic_ty.subst(self.tcx(), substs);
self.depth += 1;
@ -403,18 +419,13 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
}
ty::Projection(data) if !data.has_escaping_bound_vars() => {
// This is kind of hacky -- we need to be able to
// handle normalization within binders because
// otherwise we wind up a need to normalize when doing
// trait matching (since you can have a trait
// obligation like `for<'a> T::B: Fn(&'a i32)`), but
// we can't normalize with bound regions in scope. So
// far now we just ignore binders but only normalize
// if all bound regions are gone (and then we still
// have to renormalize whenever we instantiate a
// binder). It would be better to normalize in a
// binding-aware fashion.
// This branch is *mostly* just an optimization: when we don't
// have escaping bound vars, we don't need to replace them with
// placeholders (see branch below). *Also*, we know that we can
// register an obligation to *later* project, since we know
// there won't be bound vars there.
let data = data.super_fold_with(self);
let normalized_ty = normalize_projection_type(
self.selcx,
self.param_env,
@ -433,22 +444,23 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
normalized_ty
}
ty::Projection(data) if !data.trait_ref(self.tcx()).has_escaping_bound_vars() => {
// Okay, so you thought the previous branch was hacky. Well, to
// extend upon this, when the *trait ref* doesn't have escaping
// bound vars, but the associated item *does* (can only occur
// with GATs), then we might still be able to project the type.
// For this, we temporarily replace the bound vars with
// placeholders. Note though, that in the case that we still
// can't project for whatever reason (e.g. self type isn't
// known enough), we *can't* register an obligation and return
// an inference variable (since then that obligation would have
// bound vars and that's a can of worms). Instead, we just
// give up and fall back to pretending like we never tried!
ty::Projection(data) => {
// If there are escaping bound vars, we temporarily replace the
// bound vars with placeholders. Note though, that in the case
// that we still can't project for whatever reason (e.g. self
// type isn't known enough), we *can't* register an obligation
// and return an inference variable (since then that obligation
// would have bound vars and that's a can of worms). Instead,
// we just give up and fall back to pretending like we never tried!
//
// Note: this isn't necessarily the final approach here; we may
// want to figure out how to register obligations with escaping vars
// or handle this some other way.
let infcx = self.selcx.infcx();
let (data, mapped_regions, mapped_types, mapped_consts) =
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
let data = data.super_fold_with(self);
let normalized_ty = opt_normalize_projection_type(
self.selcx,
self.param_env,
@ -459,16 +471,18 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
)
.ok()
.flatten()
.unwrap_or_else(|| ty);
.map(|normalized_ty| {
PlaceholderReplacer::replace_placeholders(
infcx,
mapped_regions,
mapped_types,
mapped_consts,
&self.universes,
normalized_ty,
)
})
.unwrap_or_else(|| ty.super_fold_with(self));
let normalized_ty = PlaceholderReplacer::replace_placeholders(
infcx,
mapped_regions,
mapped_types,
mapped_consts,
&self.universes,
normalized_ty,
);
debug!(
?self.depth,
?ty,
@ -479,7 +493,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
normalized_ty
}
_ => ty,
_ => ty.super_fold_with(self),
}
}
@ -908,6 +922,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
// an impl, where-clause etc) and hence we must
// re-normalize it
let projected_ty = selcx.infcx().resolve_vars_if_possible(projected_ty);
debug!(?projected_ty, ?depth, ?projected_obligations);
let result = if projected_ty.has_projections() {

View file

@ -14,7 +14,9 @@ use rustc_infer::traits::Normalized;
use rustc_middle::mir;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
use std::ops::ControlFlow;
use super::NoSolution;
@ -65,6 +67,24 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
universes: vec![],
};
// This is actually a consequence by the way `normalize_erasing_regions` works currently.
// Because it needs to call the `normalize_generic_arg_after_erasing_regions`, it folds
// through tys and consts in a `TypeFoldable`. Importantly, it skips binders, leaving us
// with trying to normalize with escaping bound vars.
//
// Here, we just add the universes that we *would* have created had we passed through the binders.
//
// We *could* replace escaping bound vars eagerly here, but it doesn't seem really necessary.
// The rest of the code is already set up to be lazy about replacing bound vars,
// and only when we actually have to normalize.
if value.has_escaping_bound_vars() {
let mut max_visitor =
MaxEscapingBoundVarVisitor { outer_index: ty::INNERMOST, escaping: 0 };
value.visit_with(&mut max_visitor);
if max_visitor.escaping > 0 {
normalizer.universes.extend((0..max_visitor.escaping).map(|_| None));
}
}
let result = value.fold_with(&mut normalizer);
info!(
"normalize::<{}>: result={:?} with {} obligations",
@ -85,6 +105,58 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
}
}
/// Visitor to find the maximum escaping bound var
struct MaxEscapingBoundVarVisitor {
// The index which would count as escaping
outer_index: ty::DebruijnIndex,
escaping: usize,
}
impl<'tcx> TypeVisitor<'tcx> for MaxEscapingBoundVarVisitor {
fn visit_binder<T: TypeFoldable<'tcx>>(
&mut self,
t: &ty::Binder<'tcx, T>,
) -> ControlFlow<Self::BreakTy> {
self.outer_index.shift_in(1);
let result = t.super_visit_with(self);
self.outer_index.shift_out(1);
result
}
#[inline]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if t.outer_exclusive_binder() > self.outer_index {
self.escaping = self
.escaping
.max(t.outer_exclusive_binder().as_usize() - self.outer_index.as_usize());
}
ControlFlow::CONTINUE
}
#[inline]
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
match *r {
ty::ReLateBound(debruijn, _) if debruijn > self.outer_index => {
self.escaping =
self.escaping.max(debruijn.as_usize() - self.outer_index.as_usize());
}
_ => {}
}
ControlFlow::CONTINUE
}
fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
match ct.val {
ty::ConstKind::Bound(debruijn, _) if debruijn >= self.outer_index => {
self.escaping =
self.escaping.max(debruijn.as_usize() - self.outer_index.as_usize());
ControlFlow::CONTINUE
}
_ => ct.super_visit_with(self),
}
}
}
struct QueryNormalizer<'cx, 'tcx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
cause: &'cx ObligationCause<'tcx>,
@ -121,14 +193,21 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
return ty;
}
let ty = ty.super_fold_with(self);
// See note in `rustc_trait_selection::traits::project` about why we
// wait to fold the substs.
// Wrap this in a closure so we don't accidentally return from the outer function
let res = (|| match *ty.kind() {
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
ty::Opaque(def_id, substs) => {
// Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty,
Reveal::UserFacing => ty.super_fold_with(self),
Reveal::All => {
// N.b. there is an assumption here all this code can handle
// escaping bound vars.
let substs = substs.super_fold_with(self);
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.anon_depth) {
let obligation = Obligation::with_depth(
@ -161,19 +240,11 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
}
ty::Projection(data) if !data.has_escaping_bound_vars() => {
// This is kind of hacky -- we need to be able to
// handle normalization within binders because
// otherwise we wind up a need to normalize when doing
// trait matching (since you can have a trait
// obligation like `for<'a> T::B: Fn(&'a i32)`), but
// we can't normalize with bound regions in scope. So
// far now we just ignore binders but only normalize
// if all bound regions are gone (and then we still
// have to renormalize whenever we instantiate a
// binder). It would be better to normalize in a
// binding-aware fashion.
// This branch is just an optimization: when we don't have escaping bound vars,
// we don't need to replace them with placeholders (see branch below).
let tcx = self.infcx.tcx;
let data = data.super_fold_with(self);
let mut orig_values = OriginalQueryValues::default();
// HACK(matthewjasper) `'static` is special-cased in selection,
@ -188,7 +259,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
// We don't expect ambiguity.
if result.is_ambiguous() {
self.error = true;
return ty;
return ty.super_fold_with(self);
}
match self.infcx.instantiate_query_response_and_region_obligations(
@ -206,34 +277,21 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
Err(_) => {
self.error = true;
ty
ty.super_fold_with(self)
}
}
}
Err(NoSolution) => {
self.error = true;
ty
ty.super_fold_with(self)
}
}
}
ty::Projection(data) if !data.trait_ref(self.infcx.tcx).has_escaping_bound_vars() => {
ty::Projection(data) => {
// See note in `rustc_trait_selection::traits::project`
// One other point mentioning: In `traits::project`, if a
// projection can't be normalized, we return an inference variable
// and register an obligation to later resolve that. Here, the query
// will just return ambiguity. In both cases, the effect is the same: we only want
// to return `ty` because there are bound vars that we aren't yet handling in a more
// complete way.
// `BoundVarReplacer` can't handle escaping bound vars. Ideally, we want this before even calling
// `QueryNormalizer`, but some const-generics tests pass escaping bound vars.
// Also, use `ty` so we get that sweet `outer_exclusive_binder` optimization
assert!(!ty.has_vars_bound_at_or_above(ty::DebruijnIndex::from_usize(
self.universes.len()
)));
let tcx = self.infcx.tcx;
let infcx = self.infcx;
let (data, mapped_regions, mapped_types, mapped_consts) =
@ -252,12 +310,12 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
debug!("QueryNormalizer: c_data = {:#?}", c_data);
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
let normalized_ty = match tcx.normalize_projection_ty(c_data) {
match tcx.normalize_projection_ty(c_data) {
Ok(result) => {
// We don't expect ambiguity.
if result.is_ambiguous() {
self.error = true;
return ty;
return ty.super_fold_with(self);
}
match self.infcx.instantiate_query_response_and_region_obligations(
self.cause,
@ -269,30 +327,29 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
debug!("QueryNormalizer: result = {:#?}", result);
debug!("QueryNormalizer: obligations = {:#?}", obligations);
self.obligations.extend(obligations);
result.normalized_ty
crate::traits::project::PlaceholderReplacer::replace_placeholders(
infcx,
mapped_regions,
mapped_types,
mapped_consts,
&self.universes,
result.normalized_ty,
)
}
Err(_) => {
self.error = true;
ty
ty.super_fold_with(self)
}
}
}
Err(NoSolution) => {
self.error = true;
ty
ty.super_fold_with(self)
}
};
crate::traits::project::PlaceholderReplacer::replace_placeholders(
infcx,
mapped_regions,
mapped_types,
mapped_consts,
&self.universes,
normalized_ty,
)
}
}
_ => ty,
_ => ty.super_fold_with(self),
})();
self.cache.insert(ty, res);
res

View file

@ -796,6 +796,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
//! into a closure or a `proc`.
let b = self.shallow_resolve(b);
let InferOk { value: b, mut obligations } =
self.normalize_associated_types_in_as_infer_ok(self.cause.span, b);
debug!("coerce_from_fn_item(a={:?}, b={:?})", a, b);
match b.kind() {
@ -815,8 +817,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
}
}
let InferOk { value: a_sig, mut obligations } =
let InferOk { value: a_sig, obligations: o1 } =
self.normalize_associated_types_in_as_infer_ok(self.cause.span, a_sig);
obligations.extend(o1);
let a_fn_pointer = self.tcx.mk_fn_ptr(a_sig);
let InferOk { value, obligations: o2 } = self.coerce_from_safe_fn(

View file

@ -1,3 +1,5 @@
// check-pass
#![feature(associated_type_bounds)]
trait TraitA<'a> {
@ -34,6 +36,4 @@ where
fn main() {
foo::<Z>();
//~^ ERROR: the trait bound `for<'a, 'b> <Z as TraitA<'a>>::AsA: TraitB<'a, 'b>` is not satisfied
//~| ERROR: the trait bound `for<'a, 'b, 'c> <<Z as TraitA<'a>>::AsA as TraitB<'a, 'b>>::AsB: TraitC<'a, 'b, 'c>` is not satisfied
}

View file

@ -1,33 +0,0 @@
error[E0277]: the trait bound `for<'a, 'b> <Z as TraitA<'a>>::AsA: TraitB<'a, 'b>` is not satisfied
--> $DIR/issue-83017.rs:36:5
|
LL | foo::<Z>();
| ^^^^^^^^ the trait `for<'a, 'b> TraitB<'a, 'b>` is not implemented for `<Z as TraitA<'a>>::AsA`
|
note: required by a bound in `foo`
--> $DIR/issue-83017.rs:31:32
|
LL | fn foo<T>()
| --- required by a bound in this
LL | where
LL | for<'a> T: TraitA<'a, AsA: for<'b> TraitB<'a, 'b, AsB: for<'c> TraitC<'a, 'b, 'c>>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
error[E0277]: the trait bound `for<'a, 'b, 'c> <<Z as TraitA<'a>>::AsA as TraitB<'a, 'b>>::AsB: TraitC<'a, 'b, 'c>` is not satisfied
--> $DIR/issue-83017.rs:36:5
|
LL | foo::<Z>();
| ^^^^^^^^ the trait `for<'a, 'b, 'c> TraitC<'a, 'b, 'c>` is not implemented for `<<Z as TraitA<'a>>::AsA as TraitB<'a, 'b>>::AsB`
|
note: required by a bound in `foo`
--> $DIR/issue-83017.rs:31:60
|
LL | fn foo<T>()
| --- required by a bound in this
LL | where
LL | for<'a> T: TraitA<'a, AsA: for<'b> TraitB<'a, 'b, AsB: for<'c> TraitC<'a, 'b, 'c>>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | foo(());
| ^^^^^^^ one type is more general than the other
|
= note: expected type `&'a ()`
found reference `&()`
= note: expected reference `&'a ()`
found reference `&()`
error: aborting due to previous error

View file

@ -4,8 +4,8 @@ error[E0308]: mismatched types
LL | foo(());
| ^^^ lifetime mismatch
|
= note: expected type `&'a ()`
found type `&()`
= note: expected reference `&'a ()`
found type `&()`
note: the lifetime requirement is introduced here
--> $DIR/higher-ranked-projection.rs:15:33
|

View file

@ -10,7 +10,7 @@ where
impl X<'_> for i32 {
type U = str;
//~^ ERROR the trait bound `for<'b> <i32 as X<'b>>::U: Clone`
//~^ ERROR the trait bound `str: Clone`
}
fn main() {

View file

@ -1,11 +1,9 @@
error[E0277]: the trait bound `for<'b> <i32 as X<'b>>::U: Clone` is not satisfied
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-1.rs:12:14
|
LL | type U = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<i32 as X<'b>>::U`
| ^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-1.rs:3:33
|

View file

@ -8,14 +8,13 @@ where
}
}
impl X<'_> for u32
impl X<'_> for u32 //~ overflow evaluating the requirement `for<'b> u32: X<'b>`
where
for<'b> <Self as X<'b>>::U: Clone,
{
type U = str;
type U = str; //~ overflow evaluating the requirement `for<'b> u32: X<'b>`
}
fn main() {
1u32.f("abc");
//~^ ERROR the method
}

View file

@ -1,13 +1,38 @@
error[E0599]: the method `f` exists for type `u32`, but its trait bounds were not satisfied
--> $DIR/hr-associated-type-bound-2.rs:19:10
error[E0275]: overflow evaluating the requirement `for<'b> u32: X<'b>`
--> $DIR/hr-associated-type-bound-2.rs:11:1
|
LL | 1u32.f("abc");
| ^ method cannot be called on `u32` due to unsatisfied trait bounds
LL | / impl X<'_> for u32
LL | | where
LL | | for<'b> <Self as X<'b>>::U: Clone,
LL | | {
LL | | type U = str;
LL | | }
| |_^
|
= note: the following trait bounds were not satisfied:
`<u32 as X<'b>>::U: Clone`
which is required by `u32: X`
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`hr_associated_type_bound_2`)
note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
--> $DIR/hr-associated-type-bound-2.rs:11:6
|
LL | impl X<'_> for u32
| ^^^^^ ^^^
= note: 128 redundant requirements hidden
= note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
error: aborting due to previous error
error[E0275]: overflow evaluating the requirement `for<'b> u32: X<'b>`
--> $DIR/hr-associated-type-bound-2.rs:15:5
|
LL | type U = str;
| ^^^^^^^^^^^^^
|
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`hr_associated_type_bound_2`)
note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
--> $DIR/hr-associated-type-bound-2.rs:11:6
|
LL | impl X<'_> for u32
| ^^^^^ ^^^
= note: 128 redundant requirements hidden
= note: required because of the requirements on the impl of `for<'b> X<'b>` for `u32`
For more information about this error, try `rustc --explain E0599`.
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0275`.

View file

@ -12,7 +12,7 @@ where
impl<'a> Y<'a, u8> for u8 {
type V = str;
//~^ ERROR the trait bound `for<'b> <u8 as Y<'b, u8>>::V: Clone` is not satisfied
//~^ ERROR the trait bound `str: Clone` is not satisfied
}
fn main() {

View file

@ -1,11 +1,9 @@
error[E0277]: the trait bound `for<'b> <u8 as Y<'b, u8>>::V: Clone` is not satisfied
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-1.rs:14:14
|
LL | type V = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<u8 as Y<'b, u8>>::V`
| ^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `Y`
--> $DIR/hr-associated-type-bound-param-1.rs:4:36
|

View file

@ -2,8 +2,8 @@
trait Z<'a, T: ?Sized>
where
T: Z<'a, u16>,
//~^ the trait bound `for<'b> <u16 as Z<'b, u16>>::W: Clone` is not satisfied
//~| the trait bound `for<'b> <u16 as Z<'b, u16>>::W: Clone` is not satisfied
//~^ the trait bound `str: Clone` is not satisfied
//~| the trait bound `str: Clone` is not satisfied
for<'b> <T as Z<'b, u16>>::W: Clone,
{
type W: ?Sized;
@ -14,7 +14,7 @@ where
impl<'a> Z<'a, u16> for u16 {
type W = str;
//~^ ERROR the trait bound `for<'b> <u16 as Z<'b, u16>>::W: Clone
//~^ ERROR the trait bound `str: Clone
}
fn main() {

View file

@ -1,11 +1,9 @@
error[E0277]: the trait bound `for<'b> <u16 as Z<'b, u16>>::W: Clone` is not satisfied
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-2.rs:4:8
|
LL | T: Z<'a, u16>,
| ^^^^^^^^^^ the trait `for<'b> Clone` is not implemented for `<u16 as Z<'b, u16>>::W`
| ^^^^^^^^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `Z`
--> $DIR/hr-associated-type-bound-param-2.rs:7:35
|
@ -15,14 +13,12 @@ LL | trait Z<'a, T: ?Sized>
LL | for<'b> <T as Z<'b, u16>>::W: Clone,
| ^^^^^ required by this bound in `Z`
error[E0277]: the trait bound `for<'b> <u16 as Z<'b, u16>>::W: Clone` is not satisfied
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-2.rs:4:8
|
LL | T: Z<'a, u16>,
| ^^^^^^^^^^ the trait `for<'b> Clone` is not implemented for `<u16 as Z<'b, u16>>::W`
| ^^^^^^^^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `Z`
--> $DIR/hr-associated-type-bound-param-2.rs:7:35
|
@ -32,14 +28,12 @@ LL | trait Z<'a, T: ?Sized>
LL | for<'b> <T as Z<'b, u16>>::W: Clone,
| ^^^^^ required by this bound in `Z`
error[E0277]: the trait bound `for<'b> <u16 as Z<'b, u16>>::W: Clone` is not satisfied
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-2.rs:16:14
|
LL | type W = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<u16 as Z<'b, u16>>::W`
| ^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `Z`
--> $DIR/hr-associated-type-bound-param-2.rs:7:35
|

View file

@ -11,7 +11,7 @@ where
impl<S, T> X<'_, (T,)> for (S,) {
type U = str;
//~^ ERROR the trait bound `for<'b> <(T,) as X<'b, (T,)>>::U: Clone` is not satisfied
//~^ ERROR the trait bound `str: Clone` is not satisfied
}
pub fn main() {

View file

@ -1,11 +1,9 @@
error[E0277]: the trait bound `for<'b> <(T,) as X<'b, (T,)>>::U: Clone` is not satisfied
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-3.rs:13:14
|
LL | type U = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<(T,) as X<'b, (T,)>>::U`
| ^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-param-3.rs:4:33
|

View file

@ -11,7 +11,7 @@ where
impl<S, T> X<'_, T> for (S,) {
type U = str;
//~^ ERROR the trait bound `for<'b> <(T,) as X<'b, T>>::U: Clone` is not satisfied
//~^ ERROR the trait bound `str: Clone` is not satisfied
}
pub fn main() {

View file

@ -1,11 +1,9 @@
error[E0277]: the trait bound `for<'b> <(T,) as X<'b, T>>::U: Clone` is not satisfied
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-4.rs:13:14
|
LL | type U = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<(T,) as X<'b, T>>::U`
| ^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-param-4.rs:4:36
|

View file

@ -25,14 +25,12 @@ where
impl<S, T> X<'_, Vec<T>> for S {
type U = str;
//~^ ERROR the trait bound `for<'b> <Box<T> as X<'b, Box<T>>>::U: Clone` is not satisfied
//~| ERROR the trait bound `for<'b> <Vec<T> as X<'b, Vec<T>>>::U: Clone` is not satisfied
//~^ ERROR the trait bound `str: Clone` is not satisfied
}
impl<S, T> X<'_, Box<T>> for S {
type U = str;
//~^ ERROR the trait bound `for<'b> <Box<T> as X<'b, Box<T>>>::U: Clone` is not satisfied
//~| ERROR the trait bound `for<'b> <Vec<T> as X<'b, Vec<T>>>::U: Clone` is not satisfied
//~^ ERROR the trait bound `str: Clone` is not satisfied
}
pub fn main() {

View file

@ -1,11 +1,9 @@
error[E0277]: the trait bound `for<'b> <Box<T> as X<'b, Box<T>>>::U: Clone` is not satisfied
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:27:14
|
LL | type U = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<Box<T> as X<'b, Box<T>>>::U`
| ^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-param-5.rs:18:45
|
@ -15,31 +13,12 @@ LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
| ^^^^^ required by this bound in `X`
error[E0277]: the trait bound `for<'b> <Vec<T> as X<'b, Vec<T>>>::U: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:27:14
error[E0277]: the trait bound `str: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:32:14
|
LL | type U = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<Vec<T> as X<'b, Vec<T>>>::U`
| ^^^ the trait `Clone` is not implemented for `str`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-param-5.rs:16:33
|
LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
| - required by a bound in this
LL | where
LL | for<'b> <T as X<'b, T>>::U: Clone,
| ^^^^^ required by this bound in `X`
error[E0277]: the trait bound `for<'b> <Vec<T> as X<'b, Vec<T>>>::U: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:33:14
|
LL | type U = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<Vec<T> as X<'b, Vec<T>>>::U`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-param-5.rs:18:45
|
@ -49,23 +28,6 @@ LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone,
| ^^^^^ required by this bound in `X`
error[E0277]: the trait bound `for<'b> <Box<T> as X<'b, Box<T>>>::U: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:33:14
|
LL | type U = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<Box<T> as X<'b, Box<T>>>::U`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-param-5.rs:16:33
|
LL | trait X<'a, T: Cycle + for<'b> X<'b, T>>
| - required by a bound in this
LL | where
LL | for<'b> <T as X<'b, T>>::U: Clone,
| ^^^^^ required by this bound in `X`
error: aborting due to 4 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -12,7 +12,6 @@ where
impl<S, T> X<'_, T> for (S,) {
//~^ ERROR the trait bound `for<'b> T: X<'b, T>` is not satisfied
type U = str;
//~^ ERROR the trait bound `for<'b> <T as X<'b, T>>::U: Clone` is not satisfied
}
pub fn main() {

View file

@ -1,39 +1,14 @@
error[E0277]: the trait bound `for<'b> <T as X<'b, T>>::U: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-6.rs:14:14
|
LL | type U = str;
| ^^^ the trait `for<'b> Clone` is not implemented for `<T as X<'b, T>>::U`
|
= help: the following implementations were found:
<&T as Clone>
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-param-6.rs:4:33
|
LL | trait X<'a, T>
| - required by a bound in this
...
LL | for<'b> <T as X<'b, T>>::U: Clone,
| ^^^^^ required by this bound in `X`
error[E0277]: the trait bound `for<'b> T: X<'b, T>` is not satisfied
--> $DIR/hr-associated-type-bound-param-6.rs:12:12
|
LL | impl<S, T> X<'_, T> for (S,) {
| ^^^^^^^^ the trait `for<'b> X<'b, T>` is not implemented for `T`
|
note: required by a bound in `X`
--> $DIR/hr-associated-type-bound-param-6.rs:3:16
|
LL | trait X<'a, T>
| - required by a bound in this
LL | where
LL | for<'b> T: X<'b, T>,
| ^^^^^^^^ required by this bound in `X`
help: consider restricting type parameter `T`
|
LL | impl<S, T: for<'b> X<'b, T>> X<'_, T> for (S,) {
| ++++++++++++++++++
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -11,9 +11,8 @@ where
}
impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
//~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
//~^ type mismatch resolving `<T as Deref>::Target == T`
type Item = T;
//~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref
}
pub fn main() {

View file

@ -1,32 +1,16 @@
error[E0277]: the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
--> $DIR/hr-associated-type-projection-1.rs:15:17
|
LL | type Item = T;
| ^ the trait `for<'b> Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
|
= help: the following implementations were found:
<&T as Deref>
<&mut T as Deref>
note: required by a bound in `UnsafeCopy`
--> $DIR/hr-associated-type-projection-1.rs:3:48
|
LL | trait UnsafeCopy<'a, T: Copy>
| ---------- required by a bound in this
LL | where
LL | for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `UnsafeCopy`
error[E0277]: the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
error[E0271]: type mismatch resolving `<T as Deref>::Target == T`
--> $DIR/hr-associated-type-projection-1.rs:13:33
|
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
| ^^^^^^^^^^^^^^^^^ the trait `for<'b> Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
| - this type parameter ^^^^^^^^^^^^^^^^^ expected associated type, found type parameter `T`
|
help: consider further restricting the associated type
= note: expected associated type `<T as Deref>::Target`
found type parameter `T`
help: consider further restricting this bound
|
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref {
| +++++++++++++++++++++++++++++++++++++++++++++++++++
LL | impl<T: Copy + std::ops::Deref + Deref<Target = T>> UnsafeCopy<'_, T> for T {
| +++++++++++++++++++
error: aborting due to 2 previous errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0271`.

View file

@ -0,0 +1,30 @@
// build-pass
// Ensures that we don't regress on "implementation is not general enough" when
// normalizating under binders. Unlike `normalization-generality.rs`, this also produces
// type outlives predicates that we must ignore.
pub unsafe trait Yokeable<'a> {
type Output: 'a;
}
pub struct Yoke<Y: for<'a> Yokeable<'a>> {
_marker: std::marker::PhantomData<Y>,
}
impl<Y: for<'a> Yokeable<'a>> Yoke<Y> {
pub fn project<P>(
&self,
_f: for<'a> fn(&<Y as Yokeable<'a>>::Output, &'a ()) -> <P as Yokeable<'a>>::Output,
) -> Yoke<P>
where
P: for<'a> Yokeable<'a>,
{
unimplemented!()
}
}
pub fn slice(y: Yoke<&'static str>) -> Yoke<&'static [u8]> {
y.project(move |yk, _| yk.as_bytes())
}
unsafe impl<'a, T: 'static + ?Sized> Yokeable<'a> for &'static T {
type Output = &'a T;
}
fn main() {}

View file

@ -1,3 +1,5 @@
// check-pass
trait T<'x> {
type V;
}
@ -8,6 +10,4 @@ impl<'g> T<'g> for u32 {
fn main() {
(&|_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
//~^ ERROR: type mismatch in closure arguments
//~| ERROR: size for values of type `<u32 as T<'_>>::V` cannot be known at compilation time
}

View file

@ -1,32 +0,0 @@
error[E0631]: type mismatch in closure arguments
--> $DIR/issue-41366.rs:10:5
|
LL | (&|_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
| ^^------^
| | |
| | found signature of `fn(u16) -> _`
| expected signature of `for<'x> fn(<u32 as T<'x>>::V) -> _`
|
= note: required for the cast to the object type `dyn for<'x> Fn(<u32 as T<'x>>::V)`
error[E0277]: the size for values of type `<u32 as T<'_>>::V` cannot be known at compilation time
--> $DIR/issue-41366.rs:10:8
|
LL | (&|_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
| ^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `<u32 as T<'_>>::V`
= help: unsized fn params are gated as an unstable feature
help: consider further restricting the associated type
|
LL | fn main() where <u32 as T<'_>>::V: Sized {
| ++++++++++++++++++++++++++++++
help: function arguments must have a statically known size, borrowed types always have a known size
|
LL | (&|&_| ()) as &dyn for<'x> Fn(<u32 as T<'x>>::V);
| +
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0277, E0631.
For more information about an error, try `rustc --explain E0277`.

View file

@ -0,0 +1,88 @@
// FamilyType (GAT workaround)
pub trait FamilyLt<'a> {
type Out;
}
struct RefMutFamily<T>(std::marker::PhantomData<T>, ());
impl<'a, T: 'a> FamilyLt<'a> for RefMutFamily<T> {
type Out = &'a mut T;
}
pub trait Execute {
type E: Inject;
fn execute(self, value: <<Self::E as Inject>::I as FamilyLt>::Out);
}
pub trait Inject
where
Self: Sized,
{
type I: for<'a> FamilyLt<'a>;
fn inject(_: &()) -> <Self::I as FamilyLt>::Out;
}
impl<T: 'static> Inject for RefMutFamily<T> {
type I = Self;
fn inject(_: &()) -> <Self::I as FamilyLt>::Out {
unimplemented!()
}
}
// This struct is only used to give a hint to the compiler about the type `Q`
struct Annotate<Q>(std::marker::PhantomData<Q>);
impl<Q> Annotate<Q> {
fn new() -> Self {
Self(std::marker::PhantomData)
}
}
// This function annotate a closure so it can have Higher-Rank Lifetime Bounds
//
// See 'annotate' workaround: https://github.com/rust-lang/rust/issues/58052
fn annotate<F, Q>(_q: Annotate<Q>, func: F) -> impl Execute + 'static
where
F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out) + 'static,
Q: Inject + 'static,
{
let wrapper: Wrapper<Q, F> = Wrapper(std::marker::PhantomData, func);
wrapper
}
struct Wrapper<Q, F>(std::marker::PhantomData<Q>, F);
impl<Q, F> Execute for Wrapper<Q, F>
where
Q: Inject,
F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out),
{
type E = Q;
fn execute(self, value: <<Self::E as Inject>::I as FamilyLt>::Out) {
(self.1)(value)
}
}
struct Task {
_processor: Box<dyn FnOnce()>,
}
// This function consume the closure
fn task<P>(processor: P) -> Task
where P: Execute + 'static {
Task {
_processor: Box::new(move || {
let q = P::E::inject(&());
processor.execute(q);
})
}
}
fn main() {
task(annotate( //~ type mismatch
//~^ the size
//~^^ the trait bound
Annotate::<RefMutFamily<usize>>::new(),
|value: &mut usize| {
*value = 2;
}
));
}

View file

@ -0,0 +1,67 @@
error[E0631]: type mismatch in closure arguments
--> $DIR/issue-62529-1.rs:80:10
|
LL | task(annotate(
| ^^^^^^^^ expected signature of `for<'r> fn(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
...
LL | |value: &mut usize| {
| ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
|
note: required by a bound in `annotate`
--> $DIR/issue-62529-1.rs:44:8
|
LL | fn annotate<F, Q>(_q: Annotate<Q>, func: F) -> impl Execute + 'static
| -------- required by a bound in this
LL | where
LL | F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out) + 'static,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `annotate`
error[E0277]: the size for values of type `impl Execute` cannot be known at compilation time
--> $DIR/issue-62529-1.rs:80:10
|
LL | task(annotate(
| __________^
LL | |
LL | |
LL | | Annotate::<RefMutFamily<usize>>::new(),
... |
LL | | }
LL | | ));
| |_____^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `impl Execute`
note: required by a bound in `task`
--> $DIR/issue-62529-1.rs:69:9
|
LL | fn task<P>(processor: P) -> Task
| ^ required by this bound in `task`
help: consider relaxing the implicit `Sized` restriction
|
LL | fn task<P: ?Sized>(processor: P) -> Task
| ++++++++
error[E0277]: the trait bound `impl Execute: Execute` is not satisfied
--> $DIR/issue-62529-1.rs:80:10
|
LL | task(annotate(
| __________^
LL | |
LL | |
LL | | Annotate::<RefMutFamily<usize>>::new(),
... |
LL | | }
LL | | ));
| |_____^ the trait `Execute` is not implemented for `impl Execute`
|
note: required by a bound in `task`
--> $DIR/issue-62529-1.rs:70:10
|
LL | fn task<P>(processor: P) -> Task
| ---- required by a bound in this
LL | where P: Execute + 'static {
| ^^^^^^^ required by this bound in `task`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0631.
For more information about an error, try `rustc --explain E0277`.

View file

@ -0,0 +1,33 @@
// check-pass
use std::marker::PhantomData;
trait Lt<'a> {
type T;
}
struct Id<T>(PhantomData<T>);
impl<'a,T> Lt<'a> for Id<T> {
type T = T;
}
struct Ref<T>(PhantomData<T>) where T: ?Sized;
impl<'a,T> Lt<'a> for Ref<T>
where T: 'a + Lt<'a> + ?Sized
{
type T = &'a T;
}
struct Mut<T>(PhantomData<T>) where T: ?Sized;
impl<'a,T> Lt<'a> for Mut<T>
where T: 'a + Lt<'a> + ?Sized
{
type T = &'a mut T;
}
struct C<I,O>(for<'a> fn(<I as Lt<'a>>::T) -> O) where I: for<'a> Lt<'a>;
fn main() {
let c = C::<Id<_>,_>(|()| 3);
c.0(());
}

View file

@ -0,0 +1,32 @@
trait ATC<'a> {
type Type: Sized;
}
trait WithDefault: for<'a> ATC<'a> {
fn with_default<F: for<'a> Fn(<Self as ATC<'a>>::Type)>(f: F);
}
fn call<'b, T: for<'a> ATC<'a>, F: for<'a> Fn(<T as ATC<'a>>::Type)>(
f: F,
x: <T as ATC<'b>>::Type,
) {
f(x);
}
impl<'a> ATC<'a> for () {
type Type = Self;
}
impl WithDefault for () {
fn with_default<F: for<'a> Fn(<Self as ATC<'a>>::Type)>(f: F) {
// Errors with a bogus type mismatch.
//f(());
// Going through another generic function works fine.
call(f, ());
//~^ expected a
}
}
fn main() {
// <()>::with_default(|_| {});
}

View file

@ -0,0 +1,15 @@
error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
--> $DIR/issue-62529-3.rs:25:9
|
LL | call(f, ());
| ^^^^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
|
note: required by a bound in `call`
--> $DIR/issue-62529-3.rs:9:36
|
LL | fn call<'b, T: for<'a> ATC<'a>, F: for<'a> Fn(<T as ATC<'a>>::Type)>(
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `call`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,39 @@
// check-pass
use std::marker::PhantomData;
use std::mem;
trait Container<'a> {
type Root: 'a;
}
type RootOf<'a, T> = <T as Container<'a>>::Root;
struct Test<'a, T> where T: Container<'a> {
pub root: T::Root,
marker: PhantomData<&'a mut &'a mut ()>,
}
impl<'a, 'b> Container<'b> for &'a str {
type Root = &'b str;
}
impl<'a, T> Test<'a, T> where T: for<'b> Container<'b> {
fn new(root: RootOf<'a, T>) -> Test<'a, T> {
Test {
root: root,
marker: PhantomData
}
}
fn with_mut<F, R>(&mut self, f: F) -> R where
F: for<'b> FnOnce(&'b mut RootOf<'b, T>) -> R {
f(unsafe { mem::transmute(&mut self.root) })
}
}
fn main() {
let val = "root";
let mut test: Test<&str> = Test::new(val);
test.with_mut(|_| { });
}

View file

@ -0,0 +1,27 @@
// check-pass
pub struct Struct {}
pub trait Trait<'a> {
type Assoc;
fn method() -> Self::Assoc;
}
impl<'a> Trait<'a> for Struct {
type Assoc = ();
fn method() -> Self::Assoc {}
}
pub fn function<F, T>(f: F)
where
F: for<'a> FnOnce(<T as Trait<'a>>::Assoc),
T: for<'b> Trait<'b>,
{
f(T::method());
}
fn main() {
function::<_, Struct>(|_| {});
}

View file

@ -0,0 +1,77 @@
// check-pass
use std::cell::RefMut;
fn main() {
StateMachine2::Init.resume();
}
enum StateMachine2<'a> {
Init,
#[allow(dead_code)] // match required for ICE
AfterTwoYields {
p: Backed<'a, *mut String>,
},
}
impl<'a> StateMachine2<'a> {
fn take(&self) -> Self {
StateMachine2::Init
}
}
impl<'a> StateMachine2<'a> {
fn resume(&mut self) -> () {
use StateMachine2::*;
match self.take() {
AfterTwoYields { p } => {
p.with(|_| {});
}
_ => panic!("Resume after completed."),
}
}
}
unsafe trait Unpack<'a> {
type Unpacked: 'a;
fn unpack(&self) -> Self::Unpacked {
unsafe { std::mem::transmute_copy(&self) }
}
}
unsafe trait Pack {
type Packed;
fn pack(&self) -> Self::Packed {
unsafe { std::mem::transmute_copy(&self) }
}
}
unsafe impl<'a> Unpack<'a> for String {
type Unpacked = String;
}
unsafe impl Pack for String {
type Packed = String;
}
unsafe impl<'a> Unpack<'a> for *mut String {
type Unpacked = &'a mut String;
}
unsafe impl<'a> Pack for &'a mut String {
type Packed = *mut String;
}
struct Backed<'a, U>(RefMut<'a, Option<String>>, U);
impl<'a, 'b, U: Unpack<'b>> Backed<'a, U> {
fn with<F>(self, f: F) -> Backed<'a, ()>
where
F: for<'f> FnOnce(<U as Unpack<'f>>::Unpacked) -> (),
{
let result = f(self.1.unpack());
Backed(self.0, result)
}
}

View file

@ -0,0 +1,29 @@
pub trait MyTrait<'a> {
type Output: 'a;
fn gimme_value(&self) -> Self::Output;
}
pub struct MyStruct;
impl<'a> MyTrait<'a> for MyStruct {
type Output = &'a usize;
fn gimme_value(&self) -> Self::Output {
unimplemented!()
}
}
fn meow<T, F>(t: T, f: F)
where
T: for<'any> MyTrait<'any>,
F: for<'any2> Fn(<T as MyTrait<'any2>>::Output),
{
let v = t.gimme_value();
f(v);
}
fn main() {
let struc = MyStruct;
meow(struc, |foo| { //~ type mismatch
println!("{:?}", foo);
})
}

View file

@ -0,0 +1,20 @@
error[E0631]: type mismatch in closure arguments
--> $DIR/issue-70120.rs:26:5
|
LL | meow(struc, |foo| {
| ^^^^ ----- found signature of `for<'r> fn(&'r usize) -> _`
| |
| expected signature of `for<'any2> fn(<MyStruct as MyTrait<'any2>>::Output) -> _`
|
note: required by a bound in `meow`
--> $DIR/issue-70120.rs:18:8
|
LL | fn meow<T, F>(t: T, f: F)
| ---- required by a bound in this
...
LL | F: for<'any2> Fn(<T as MyTrait<'any2>>::Output),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `meow`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0631`.

View file

@ -1,4 +1,4 @@
error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39]> as T0<'r, (<Unit2 as Ty<'r>>::V,)>>::O == <_ as Ty<'r>>::V`
error[E0271]: type mismatch resolving `for<'r> <L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39]> as T0<'r, (&'r u8,)>>::O == <_ as Ty<'r>>::V`
--> $DIR/issue-62203-hrtb-ice.rs:38:19
|
LL | let v = Unit2.m(
@ -9,13 +9,13 @@ LL | let v = Unit2.m(
= help: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
error[E0271]: type mismatch resolving `<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as FnOnce<((&u8,),)>>::Output == Unit3`
error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as FnOnce<((&'r u8,),)>>::Output == Unit3`
--> $DIR/issue-62203-hrtb-ice.rs:38:19
|
LL | let v = Unit2.m(
| ^ expected struct `Unit4`, found struct `Unit3`
|
note: required because of the requirements on the impl of `for<'r> T0<'r, (<Unit2 as Ty<'r>>::V,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39]>`
note: required because of the requirements on the impl of `for<'r> T0<'r, (&'r u8,)>` for `L<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39]>`
--> $DIR/issue-62203-hrtb-ice.rs:17:16
|
LL | impl<'a, A, T> T0<'a, A> for L<T>

View file

@ -5,7 +5,7 @@ LL | fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
|
= note: expected associated type `<T as impl_trait::Trait>::Assoc`
found type `()`
found unit 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> {
@ -24,7 +24,7 @@ LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
|
= note: expected associated type `<T as lifetimes::Trait<'static>>::Assoc`
found type `()`
found unit 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> {

View file

@ -1,5 +1,3 @@
// check-pass
use std::mem;
trait Trait1<T> {}
@ -8,6 +6,7 @@ trait Trait2<'a> {
}
fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
//~^ the trait bound `for<'a> (): Trait2<'a>` is not satisfied
let _e: (usize, usize) = unsafe{mem::transmute(param)};
}

View file

@ -0,0 +1,9 @@
error[E0277]: the trait bound `for<'a> (): Trait2<'a>` is not satisfied
--> $DIR/issue-35570.rs:8:4
|
LL | fn _ice(param: Box<dyn for <'a> Trait1<<() as Trait2<'a>>::Ty>>) {
| ^^^^ the trait `for<'a> Trait2<'a>` is not implemented for `()`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,3 +1,5 @@
// check-pass
pub trait Trait<'a> {
type Assoc;
}
@ -14,7 +16,6 @@ where
F: for<'b> FnMut(<T as Trait<'b>>::Assoc),
{
break_me::<Type, fn(_)>;
//~^ ERROR: type mismatch in function arguments
}
fn main() {}

View file

@ -1,21 +0,0 @@
error[E0631]: type mismatch in function arguments
--> $DIR/issue-43623.rs:16:5
|
LL | break_me::<Type, fn(_)>;
| ^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
| found signature of `fn(()) -> _`
|
note: required by a bound in `break_me`
--> $DIR/issue-43623.rs:14:16
|
LL | pub fn break_me<T, F>(f: F)
| -------- required by a bound in this
...
LL | F: for<'b> FnMut(<T as Trait<'b>>::Assoc),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `break_me`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0631`.

View file

@ -1,4 +1,3 @@
// build-pass
pub trait Foo<'a> {
type Bar;
fn foo(&'a self) -> Self::Bar;
@ -12,8 +11,9 @@ impl<'a, 'b, T: 'a> Foo<'a> for &'b T {
}
pub fn uncallable<T, F>(x: T, f: F)
where T: for<'a> Foo<'a>,
F: for<'a> Fn(<T as Foo<'a>>::Bar)
where
T: for<'a> Foo<'a>,
F: for<'a> Fn(<T as Foo<'a>>::Bar),
{
f(x.foo());
}
@ -24,6 +24,7 @@ pub fn catalyst(x: &i32) {
pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
uncallable(x, |y| f(y));
//~^ type mismatch
}
fn main() { }
fn main() {}

View file

@ -0,0 +1,20 @@
error[E0631]: type mismatch in closure arguments
--> $DIR/issue-44005.rs:26:5
|
LL | uncallable(x, |y| f(y));
| ^^^^^^^^^^ -------- found signature of `for<'r> fn(&'r i32) -> _`
| |
| expected signature of `for<'a> fn(<&i32 as Foo<'a>>::Bar) -> _`
|
note: required by a bound in `uncallable`
--> $DIR/issue-44005.rs:16:8
|
LL | pub fn uncallable<T, F>(x: T, f: F)
| ---------- required by a bound in this
...
LL | F: for<'a> Fn(<T as Foo<'a>>::Bar),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `uncallable`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0631`.

View file

@ -1,11 +0,0 @@
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-57843.rs:25:9
|
LL | Foo(Box::new(|_| ()));
| ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 bool)` must implement `FnOnce<(&'1 bool,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 bool,)>`, for some specific lifetime `'2`
error: aborting due to previous error

View file

@ -1,8 +1,8 @@
error[E0277]: the trait bound `for<'t> <Map<<&'t _ as IntoIterator>::IntoIter, _> as Iterator>::Item: Foo` is not satisfied
error[E0277]: the trait bound `&u32: Foo` is not satisfied
--> $DIR/issue-60218.rs:18:5
|
LL | trigger_error(vec![], |x: &u32| x)
| ^^^^^^^^^^^^^ the trait `for<'t> Foo` is not implemented for `<Map<<&'t _ as IntoIterator>::IntoIter, _> as Iterator>::Item`
| ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `&u32`
|
note: required by a bound in `trigger_error`
--> $DIR/issue-60218.rs:13:72

View file

@ -4,8 +4,8 @@ error[E0271]: type mismatch resolving `<Rc<Apple> as Deref>::Target == Rc<Apple>
LL | let _ = Pin::new(Apple) == Rc::pin(Apple);
| ^^ expected struct `Apple`, found struct `Rc`
|
= note: expected type `Apple`
found struct `Rc<Apple>`
= note: expected struct `Apple`
found struct `Rc<Apple>`
= note: required because of the requirements on the impl of `PartialEq<Pin<Rc<Apple>>>` for `Pin<Apple>`
error: aborting due to previous error

View file

@ -2,10 +2,10 @@ error: `impl` item signature doesn't match `trait` item signature
--> $DIR/issue-75361-mismatched-impl.rs:18:3
|
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType>>;
| --------------------------------------------------------------------- expected `fn(&T) -> Box<(dyn MyTrait<Item = &_> + 'static)>`
| --------------------------------------------------------------------- expected `fn(&T) -> Box<(dyn MyTrait<Item = &T> + 'static)>`
...
LL | fn adjacent_edges(&self) -> Box<dyn MyTrait<Item = &Self::EdgeType> + '_> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&T) -> Box<dyn MyTrait<Item = &_>>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&T) -> Box<dyn MyTrait<Item = &T>>`
|
= note: expected `fn(&T) -> Box<(dyn MyTrait<Item = &T> + 'static)>`
found `fn(&T) -> Box<dyn MyTrait<Item = &T>>`

View file

@ -19,7 +19,7 @@ trait Trait2<'a, 'b> {
// since for it to be WF, we would need to know that `'y: 'x`, but we
// do not infer that.
fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
//~^ ERROR reference has a longer lifetime than the data it references
//~^ the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
{
}

View file

@ -1,20 +1,14 @@
error[E0491]: in type `&'x (dyn for<'z> Trait1<<T as Trait2<'y, 'z>>::Foo> + 'x)`, reference has a longer lifetime than the data it references
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:25
error[E0277]: the trait bound `for<'z> T: Trait2<'y, 'z>` is not satisfied
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:4
|
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^ the trait `for<'z> Trait2<'y, 'z>` is not implemented for `T`
|
note: the pointer is valid for the lifetime `'x` as defined on the function body at 21:11
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:11
help: consider restricting type parameter `T`
|
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ^^
note: but the referenced data is only valid for the lifetime `'y` as defined on the function body at 21:15
--> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:15
|
LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ^^
LL | fn callee<'x, 'y, T: for<'z> Trait2<'y, 'z>>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >)
| ++++++++++++++++++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0491`.
For more information about this error, try `rustc --explain E0277`.