implement version of normalize_erasing_regions that doesn't assume value is normalizable
This commit is contained in:
parent
2446a21595
commit
ff448cfcee
6 changed files with 203 additions and 3 deletions
|
@ -20,6 +20,14 @@ crate fn provide(p: &mut Providers) {
|
|||
normalize_mir_const_after_erasing_regions: |tcx, goal| {
|
||||
normalize_after_erasing_regions(tcx, goal)
|
||||
},
|
||||
try_normalize_generic_arg_after_erasing_regions: |tcx, goal| {
|
||||
debug!("try_normalize_generic_arg_after_erasing_regions(goal={:#?}", goal);
|
||||
|
||||
try_normalize_after_erasing_regions(tcx, goal)
|
||||
},
|
||||
try_normalize_mir_const_after_erasing_regions: |tcx, goal| {
|
||||
try_normalize_after_erasing_regions(tcx, goal)
|
||||
},
|
||||
..*p
|
||||
};
|
||||
}
|
||||
|
@ -56,6 +64,38 @@ fn normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Cop
|
|||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Copy>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
goal: ParamEnvAnd<'tcx, T>,
|
||||
) -> Result<T, NoSolution> {
|
||||
let ParamEnvAnd { param_env, value } = goal;
|
||||
tcx.infer_ctxt().enter(|infcx| {
|
||||
let cause = ObligationCause::dummy();
|
||||
match infcx.at(&cause, param_env).normalize(value) {
|
||||
Ok(Normalized { value: normalized_value, obligations: normalized_obligations }) => {
|
||||
// We don't care about the `obligations`; they are
|
||||
// always only region relations, and we are about to
|
||||
// erase those anyway:
|
||||
debug_assert_eq!(
|
||||
normalized_obligations.iter().find(|p| not_outlives_predicate(&p.predicate)),
|
||||
None,
|
||||
);
|
||||
|
||||
let resolved_value = infcx.resolve_vars_if_possible(normalized_value);
|
||||
// It's unclear when `resolve_vars` would have an effect in a
|
||||
// fresh `InferCtxt`. If this assert does trigger, it will give
|
||||
// us a test case.
|
||||
debug_assert_eq!(normalized_value, resolved_value);
|
||||
let erased = infcx.tcx.erase_regions(resolved_value);
|
||||
debug_assert!(!erased.needs_infer(), "{:?}", erased);
|
||||
Ok(erased)
|
||||
}
|
||||
Err(NoSolution) => Err(NoSolution),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn not_outlives_predicate(p: &ty::Predicate<'tcx>) -> bool {
|
||||
match p.kind().skip_binder() {
|
||||
ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::TypeOutlives(..) => false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue