always emit AliasRelate goals when relating aliases

Add `StructurallyRelateAliases` to allow instantiating infer vars with rigid aliases.
Change `instantiate_query_response` to be infallible in the new solver. This requires canonicalization to not hide any information used by the query, so weaken
universe compression. It also modifies `term_is_fully_unconstrained` to allow
region inference variables in a higher universe.
This commit is contained in:
lcnr
2024-02-26 10:17:43 +01:00
parent eeeb9b4d31
commit 1b3164f5c9
21 changed files with 417 additions and 272 deletions

View File

@@ -58,44 +58,26 @@ impl<'tcx> InferCtxt<'tcx> {
}
let candidate = candidates.pop().unwrap();
let (certainty, nested_goals) = ecx
.instantiate_and_apply_query_response(
trait_goal.param_env,
orig_values,
candidate.result,
)
.map_err(|_| SelectionError::Unimplemented)?;
let certainty = ecx.instantiate_and_apply_query_response(
trait_goal.param_env,
orig_values,
candidate.result,
);
Ok(Some((candidate, certainty, nested_goals)))
Ok(Some((candidate, certainty)))
});
let (candidate, certainty, nested_goals) = match result {
Ok(Some((candidate, certainty, nested_goals))) => {
(candidate, certainty, nested_goals)
}
let (candidate, certainty) = match result {
Ok(Some(result)) => result,
Ok(None) => return Ok(None),
Err(e) => return Err(e),
};
let nested_obligations: Vec<_> = nested_goals
.into_iter()
.map(|goal| {
Obligation::new(
self.tcx,
ObligationCause::dummy(),
goal.param_env,
goal.predicate,
)
})
.collect();
let goal = self.resolve_vars_if_possible(trait_goal);
match (certainty, candidate.source) {
// Rematching the implementation will instantiate the same nested goals that
// would have caused the ambiguity, so we can still make progress here regardless.
(_, CandidateSource::Impl(def_id)) => {
rematch_impl(self, goal, def_id, nested_obligations)
}
(_, CandidateSource::Impl(def_id)) => rematch_impl(self, goal, def_id),
// If an unsize goal is ambiguous, then we can manually rematch it to make
// selection progress for coercion during HIR typeck. If it is *not* ambiguous,
@@ -108,20 +90,20 @@ impl<'tcx> InferCtxt<'tcx> {
| (Certainty::Yes, CandidateSource::BuiltinImpl(src @ BuiltinImplSource::Misc))
if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) =>
{
rematch_unsize(self, goal, nested_obligations, src, certainty)
rematch_unsize(self, goal, src, certainty)
}
// Technically some builtin impls have nested obligations, but if
// `Certainty::Yes`, then they should've all been verified and don't
// need re-checking.
(Certainty::Yes, CandidateSource::BuiltinImpl(src)) => {
Ok(Some(ImplSource::Builtin(src, nested_obligations)))
Ok(Some(ImplSource::Builtin(src, vec![])))
}
// It's fine not to do anything to rematch these, since there are no
// nested obligations.
(Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => {
Ok(Some(ImplSource::Param(nested_obligations)))
Ok(Some(ImplSource::Param(vec![])))
}
(Certainty::Maybe(_), _) => Ok(None),
@@ -192,19 +174,16 @@ fn rematch_impl<'tcx>(
infcx: &InferCtxt<'tcx>,
goal: Goal<'tcx, ty::TraitPredicate<'tcx>>,
impl_def_id: DefId,
mut nested: Vec<PredicateObligation<'tcx>>,
) -> SelectionResult<'tcx, Selection<'tcx>> {
let args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
let impl_trait_ref =
infcx.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(infcx.tcx, args);
nested.extend(
infcx
.at(&ObligationCause::dummy(), goal.param_env)
.eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref)
.map_err(|_| SelectionError::Unimplemented)?
.into_obligations(),
);
let mut nested = infcx
.at(&ObligationCause::dummy(), goal.param_env)
.eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref)
.map_err(|_| SelectionError::Unimplemented)?
.into_obligations();
nested.extend(
infcx.tcx.predicates_of(impl_def_id).instantiate(infcx.tcx, args).into_iter().map(
@@ -221,11 +200,11 @@ fn rematch_impl<'tcx>(
fn rematch_unsize<'tcx>(
infcx: &InferCtxt<'tcx>,
goal: Goal<'tcx, ty::TraitPredicate<'tcx>>,
mut nested: Vec<PredicateObligation<'tcx>>,
source: BuiltinImplSource,
certainty: Certainty,
) -> SelectionResult<'tcx, Selection<'tcx>> {
let tcx = infcx.tcx;
let mut nested = vec![];
let a_ty = structurally_normalize(goal.predicate.self_ty(), infcx, goal.param_env, &mut nested);
let b_ty = structurally_normalize(
goal.predicate.trait_ref.args.type_at(1),