Skip to content

Commit a788be0

Browse files
committed
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`.
1 parent 1b3164f commit a788be0

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ use rustc_hir::Expr;
4444
use rustc_hir_analysis::astconv::AstConv;
4545
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
4646
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
47+
use rustc_infer::traits::TraitEngine;
48+
use rustc_infer::traits::TraitEngineExt as _;
4749
use rustc_infer::traits::{Obligation, PredicateObligation};
4850
use rustc_middle::lint::in_external_macro;
4951
use rustc_middle::traits::BuiltinImplSource;
@@ -61,6 +63,7 @@ use rustc_target::spec::abi::Abi;
6163
use rustc_trait_selection::infer::InferCtxtExt as _;
6264
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
6365
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
66+
use rustc_trait_selection::traits::TraitEngineExt as _;
6467
use rustc_trait_selection::traits::{
6568
self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
6669
};
@@ -157,17 +160,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
157160
// In the new solver, lazy norm may allow us to shallowly equate
158161
// more types, but we emit possibly impossible-to-satisfy obligations.
159162
// Filter these cases out to make sure our coercion is more accurate.
160-
if self.next_trait_solver() {
161-
if let Ok(res) = &res {
162-
for obligation in &res.obligations {
163-
if !self.predicate_may_hold(obligation) {
164-
return Err(TypeError::Mismatch);
165-
}
163+
match res {
164+
Ok(InferOk { value, obligations }) if self.next_trait_solver() => {
165+
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
166+
fulfill_cx.register_predicate_obligations(self, obligations);
167+
let errs = fulfill_cx.select_where_possible(self);
168+
if errs.is_empty() {
169+
Ok(InferOk { value, obligations: fulfill_cx.pending_obligations() })
170+
} else {
171+
Err(TypeError::Mismatch)
166172
}
167173
}
174+
res => res,
168175
}
169-
170-
res
171176
})
172177
}
173178

@@ -625,19 +630,18 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
625630
let traits = [coerce_unsized_did, unsize_did];
626631
while !queue.is_empty() {
627632
let obligation = queue.remove(0);
628-
debug!("coerce_unsized resolve step: {:?}", obligation);
629633
let trait_pred = match obligation.predicate.kind().no_bound_vars() {
630634
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)))
631635
if traits.contains(&trait_pred.def_id()) =>
632636
{
633-
trait_pred
637+
self.resolve_vars_if_possible(trait_pred)
634638
}
635639
_ => {
636640
coercion.obligations.push(obligation);
637641
continue;
638642
}
639643
};
640-
let trait_pred = self.resolve_vars_if_possible(trait_pred);
644+
debug!("coerce_unsized resolve step: {:?}", trait_pred);
641645
match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
642646
// Uncertain or unimplemented.
643647
Ok(None) => {

0 commit comments

Comments
 (0)