diff options
| author | lcnr <rust@lcnr.de> | 2024-02-26 10:19:03 +0100 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2024-02-26 10:57:38 +0100 |
| commit | a788be0aae7558b41beb344c090470da4a60f277 (patch) | |
| tree | 6fcdb58797cfbbef936e85524269184623cca5b7 | |
| parent | 1b3164f5c9098c239bc23b3bfea657cc27ff80c7 (diff) | |
| download | rust-a788be0aae7558b41beb344c090470da4a60f277.tar.gz rust-a788be0aae7558b41beb344c090470da4a60f277.zip | |
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`.
| -rw-r--r-- | compiler/rustc_hir_typeck/src/coercion.rs | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 9f6175eac13..ba3000d8037 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -44,6 +44,8 @@ use rustc_hir::Expr; 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_target::spec::abi::Abi; 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 @@ impl<'f, 'tcx> Coerce<'f, '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 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { 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) => { |
