1
Fork 0

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:
lcnr 2024-02-26 10:19:03 +01:00
parent 1b3164f5c9
commit a788be0aae

View file

@ -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) => {