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:
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user