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:
commit
0afc20860e
55 changed files with 813 additions and 393 deletions
|
@ -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!(),
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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`.
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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`.
|
||||
|
|
30
src/test/ui/associated-types/normalization-generality-2.rs
Normal file
30
src/test/ui/associated-types/normalization-generality-2.rs
Normal 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() {}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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`.
|
|
@ -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;
|
||||
}
|
||||
));
|
||||
}
|
|
@ -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`.
|
|
@ -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(());
|
||||
|
||||
}
|
|
@ -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(|_| {});
|
||||
}
|
|
@ -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`.
|
|
@ -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(|_| { });
|
||||
}
|
|
@ -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>(|_| {});
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
})
|
||||
}
|
|
@ -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`.
|
|
@ -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>
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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)};
|
||||
}
|
||||
|
||||
|
|
9
src/test/ui/issues/issue-35570.stderr
Normal file
9
src/test/ui/issues/issue-35570.stderr
Normal 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`.
|
|
@ -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() {}
|
||||
|
|
|
@ -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`.
|
|
@ -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() {}
|
||||
|
|
20
src/test/ui/issues/issue-44005.stderr
Normal file
20
src/test/ui/issues/issue-44005.stderr
Normal 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`.
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>>`
|
||||
|
|
|
@ -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
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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`.
|
||||
|
|
Loading…
Add table
Reference in a new issue