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
1 changed files with 15 additions and 11 deletions
|
@ -44,6 +44,8 @@ use rustc_hir::Expr;
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
use rustc_hir_analysis::astconv::AstConv;
|
||||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
|
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_infer::traits::{Obligation, PredicateObligation};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_middle::traits::BuiltinImplSource;
|
use rustc_middle::traits::BuiltinImplSource;
|
||||||
|
@ -61,6 +63,7 @@ use rustc_target::spec::abi::Abi;
|
||||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||||
|
use rustc_trait_selection::traits::TraitEngineExt as _;
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
|
self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
|
||||||
};
|
};
|
||||||
|
@ -157,17 +160,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
// In the new solver, lazy norm may allow us to shallowly equate
|
// In the new solver, lazy norm may allow us to shallowly equate
|
||||||
// more types, but we emit possibly impossible-to-satisfy obligations.
|
// more types, but we emit possibly impossible-to-satisfy obligations.
|
||||||
// Filter these cases out to make sure our coercion is more accurate.
|
// Filter these cases out to make sure our coercion is more accurate.
|
||||||
if self.next_trait_solver() {
|
match res {
|
||||||
if let Ok(res) = &res {
|
Ok(InferOk { value, obligations }) if self.next_trait_solver() => {
|
||||||
for obligation in &res.obligations {
|
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
|
||||||
if !self.predicate_may_hold(obligation) {
|
fulfill_cx.register_predicate_obligations(self, obligations);
|
||||||
return Err(TypeError::Mismatch);
|
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 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
let traits = [coerce_unsized_did, unsize_did];
|
let traits = [coerce_unsized_did, unsize_did];
|
||||||
while !queue.is_empty() {
|
while !queue.is_empty() {
|
||||||
let obligation = queue.remove(0);
|
let obligation = queue.remove(0);
|
||||||
debug!("coerce_unsized resolve step: {:?}", obligation);
|
|
||||||
let trait_pred = match obligation.predicate.kind().no_bound_vars() {
|
let trait_pred = match obligation.predicate.kind().no_bound_vars() {
|
||||||
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)))
|
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)))
|
||||||
if traits.contains(&trait_pred.def_id()) =>
|
if traits.contains(&trait_pred.def_id()) =>
|
||||||
{
|
{
|
||||||
trait_pred
|
self.resolve_vars_if_possible(trait_pred)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
coercion.obligations.push(obligation);
|
coercion.obligations.push(obligation);
|
||||||
continue;
|
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)) {
|
match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
|
||||||
// Uncertain or unimplemented.
|
// Uncertain or unimplemented.
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue