use fulfillment in `Coerce::unify'
only checking whether nested goals hold means that we don't consider their inference constraints. Given that we now emit `AliasRelate` when relating aliases and infer vars, this previously resulted in an "unconstrained" inference var in `coerce_unsized`.
This commit is contained in:
parent
1b3164f5c9
commit
a788be0aae
@ -44,6 +44,8 @@
|
||||
use rustc_hir_analysis::astconv::AstConv;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
use rustc_infer::traits::TraitEngineExt as _;
|
||||
use rustc_infer::traits::{Obligation, PredicateObligation};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::traits::BuiltinImplSource;
|
||||
@ -61,6 +63,7 @@
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||
use rustc_trait_selection::traits::{
|
||||
self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
|
||||
};
|
||||
@ -157,17 +160,19 @@ fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
|
||||
// In the new solver, lazy norm may allow us to shallowly equate
|
||||
// more types, but we emit possibly impossible-to-satisfy obligations.
|
||||
// Filter these cases out to make sure our coercion is more accurate.
|
||||
if self.next_trait_solver() {
|
||||
if let Ok(res) = &res {
|
||||
for obligation in &res.obligations {
|
||||
if !self.predicate_may_hold(obligation) {
|
||||
return Err(TypeError::Mismatch);
|
||||
}
|
||||
match res {
|
||||
Ok(InferOk { value, obligations }) if self.next_trait_solver() => {
|
||||
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
|
||||
fulfill_cx.register_predicate_obligations(self, obligations);
|
||||
let errs = fulfill_cx.select_where_possible(self);
|
||||
if errs.is_empty() {
|
||||
Ok(InferOk { value, obligations: fulfill_cx.pending_obligations() })
|
||||
} else {
|
||||
Err(TypeError::Mismatch)
|
||||
}
|
||||
}
|
||||
res => res,
|
||||
}
|
||||
|
||||
res
|
||||
})
|
||||
}
|
||||
|
||||
@ -625,19 +630,18 @@ fn coerce_unsized(&self, mut source: Ty<'tcx>, mut target: Ty<'tcx>) -> CoerceRe
|
||||
let traits = [coerce_unsized_did, unsize_did];
|
||||
while !queue.is_empty() {
|
||||
let obligation = queue.remove(0);
|
||||
debug!("coerce_unsized resolve step: {:?}", obligation);
|
||||
let trait_pred = match obligation.predicate.kind().no_bound_vars() {
|
||||
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)))
|
||||
if traits.contains(&trait_pred.def_id()) =>
|
||||
{
|
||||
trait_pred
|
||||
self.resolve_vars_if_possible(trait_pred)
|
||||
}
|
||||
_ => {
|
||||
coercion.obligations.push(obligation);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let trait_pred = self.resolve_vars_if_possible(trait_pred);
|
||||
debug!("coerce_unsized resolve step: {:?}", trait_pred);
|
||||
match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
|
||||
// Uncertain or unimplemented.
|
||||
Ok(None) => {
|
||||
|
Loading…
Reference in New Issue
Block a user