Deeply normalize associated type bounds before proving them
This commit is contained in:
parent
2cdb7fac95
commit
b002b5cc82
10 changed files with 87 additions and 67 deletions
|
@ -2105,18 +2105,21 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
ObligationCause::new(impl_ty_span, impl_ty_def_id, code)
|
||||
};
|
||||
|
||||
let mut obligations: Vec<_> = tcx
|
||||
.explicit_item_bounds(trait_ty.def_id)
|
||||
.iter_instantiated_copied(tcx, rebased_args)
|
||||
.map(|(concrete_ty_bound, span)| {
|
||||
debug!(?concrete_ty_bound);
|
||||
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
|
||||
})
|
||||
.collect();
|
||||
let mut obligations: Vec<_> = util::elaborate(
|
||||
tcx,
|
||||
tcx.explicit_item_bounds(trait_ty.def_id).iter_instantiated_copied(tcx, rebased_args).map(
|
||||
|(concrete_ty_bound, span)| {
|
||||
debug!(?concrete_ty_bound);
|
||||
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
|
||||
},
|
||||
),
|
||||
)
|
||||
.collect();
|
||||
|
||||
// Only in a const implementation do we need to check that the `~const` item bounds hold.
|
||||
if tcx.is_conditionally_const(impl_ty_def_id) {
|
||||
obligations.extend(
|
||||
obligations.extend(util::elaborate(
|
||||
tcx,
|
||||
tcx.explicit_implied_const_bounds(trait_ty.def_id)
|
||||
.iter_instantiated_copied(tcx, rebased_args)
|
||||
.map(|(c, span)| {
|
||||
|
@ -2127,7 +2130,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
c.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
|
||||
)
|
||||
}),
|
||||
);
|
||||
));
|
||||
}
|
||||
debug!(item_bounds=?obligations);
|
||||
|
||||
|
@ -2135,26 +2138,19 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
// to its definition type. This should be the param-env we use to *prove* the
|
||||
// predicate too, but we don't do that because of performance issues.
|
||||
// See <https://github.com/rust-lang/rust/pull/117542#issue-1976337685>.
|
||||
let trait_projection_ty = Ty::new_projection_from_args(tcx, trait_ty.def_id, rebased_args);
|
||||
let impl_identity_ty = tcx.type_of(impl_ty.def_id).instantiate_identity();
|
||||
let normalize_param_env = param_env_with_gat_bounds(tcx, impl_ty, impl_trait_ref);
|
||||
for mut obligation in util::elaborate(tcx, obligations) {
|
||||
let normalized_predicate = if infcx.next_trait_solver() {
|
||||
obligation.predicate.fold_with(&mut ReplaceTy {
|
||||
tcx,
|
||||
from: trait_projection_ty,
|
||||
to: impl_identity_ty,
|
||||
})
|
||||
} else {
|
||||
ocx.normalize(&normalize_cause, normalize_param_env, obligation.predicate)
|
||||
};
|
||||
debug!(?normalized_predicate);
|
||||
obligation.predicate = normalized_predicate;
|
||||
|
||||
ocx.register_obligation(obligation);
|
||||
for obligation in &mut obligations {
|
||||
match ocx.deeply_normalize(&normalize_cause, normalize_param_env, obligation.predicate) {
|
||||
Ok(pred) => obligation.predicate = pred,
|
||||
Err(e) => {
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
ocx.register_obligations(obligations);
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
|
@ -2166,22 +2162,6 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||
ocx.resolve_regions_and_report_errors(impl_ty_def_id, param_env, assumed_wf_types)
|
||||
}
|
||||
|
||||
struct ReplaceTy<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
from: Ty<'tcx>,
|
||||
to: Ty<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceTy<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if self.from == ty { self.to } else { ty.super_fold_with(self) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Install projection predicates that allow GATs to project to their own
|
||||
/// definition types. This is not allowed in general in cases of default
|
||||
/// associated types in trait definitions, or when specialization is involved,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue