From cf94bdc0742c13e2a0cac864c478b8626b266e1b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_trait_selection/src/traits/mod.rs | 175 +++++++++++------------ 1 file changed, 82 insertions(+), 93 deletions(-) (limited to 'compiler/rustc_trait_selection/src/traits/mod.rs') diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 40596078f..0bf54c096 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -26,7 +26,7 @@ pub mod wf; use crate::errors::DumpVTableEntries; use crate::infer::outlives::env::OutlivesEnvironment; use crate::infer::{InferCtxt, TyCtxtInferExt}; -use crate::traits::error_reporting::InferCtxtExt as _; +use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -34,12 +34,11 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::TraitEngineExt as _; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ - self, DefIdTree, GenericParamDefKind, Subst, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, - VtblEntry, + self, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, VtblEntry, }; +use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_span::{sym, Span}; use smallvec::SmallVec; @@ -130,7 +129,7 @@ pub fn predicates_for_generics<'tcx>( move |(idx, (predicate, span))| Obligation { cause: cause(idx, span), recursion_depth: 0, - param_env: param_env, + param_env, predicate, }, ) @@ -141,8 +140,8 @@ pub fn predicates_for_generics<'tcx>( /// `bound` or is not known to meet bound (note that this is /// conservative towards *no impl*, which is the opposite of the /// `evaluate` methods). -pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( - infcx: &InferCtxt<'a, 'tcx>, +pub fn type_known_to_meet_bound_modulo_regions<'tcx>( + infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, def_id: DefId, @@ -171,7 +170,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( result ); - if result && ty.has_infer_types_or_consts() { + if result && ty.has_non_region_infer() { // Because of inference "guessing", selection can sometimes claim // to succeed while the success requires a guess. To ensure // this function's result remains infallible, we must confirm @@ -235,54 +234,51 @@ fn do_normalize_predicates<'tcx>( // by wfcheck anyway, so I'm not sure we have to check // them here too, and we will remove this function when // we move over to lazy normalization *anyway*. - tcx.infer_ctxt().ignoring_regions().enter(|infcx| { - let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) { - Ok(predicates) => predicates, - Err(errors) => { - let reported = infcx.report_fulfillment_errors(&errors, None, false); - return Err(reported); - } - }; + let infcx = tcx.infer_ctxt().ignoring_regions().build(); + let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) { + Ok(predicates) => predicates, + Err(errors) => { + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); + return Err(reported); + } + }; - debug!("do_normalize_predictes: normalized predicates = {:?}", predicates); + debug!("do_normalize_predictes: normalized predicates = {:?}", predicates); - // We can use the `elaborated_env` here; the region code only - // cares about declarations like `'a: 'b`. - let outlives_env = OutlivesEnvironment::new(elaborated_env); + // We can use the `elaborated_env` here; the region code only + // cares about declarations like `'a: 'b`. + let outlives_env = OutlivesEnvironment::new(elaborated_env); + + // FIXME: It's very weird that we ignore region obligations but apparently + // still need to use `resolve_regions` as we need the resolved regions in + // the normalized predicates. + let errors = infcx.resolve_regions(&outlives_env); + if !errors.is_empty() { + tcx.sess.delay_span_bug( + span, + format!("failed region resolution while normalizing {elaborated_env:?}: {errors:?}"), + ); + } - // FIXME: It's very weird that we ignore region obligations but apparently - // still need to use `resolve_regions` as we need the resolved regions in - // the normalized predicates. - let errors = infcx.resolve_regions(&outlives_env); - if !errors.is_empty() { - tcx.sess.delay_span_bug( + match infcx.fully_resolve(predicates) { + Ok(predicates) => Ok(predicates), + Err(fixup_err) => { + // If we encounter a fixup error, it means that some type + // variable wound up unconstrained. I actually don't know + // if this can happen, and I certainly don't expect it to + // happen often, but if it did happen it probably + // represents a legitimate failure due to some kind of + // unconstrained variable. + // + // @lcnr: Let's still ICE here for now. I want a test case + // for that. + span_bug!( span, - format!( - "failed region resolution while normalizing {elaborated_env:?}: {errors:?}" - ), + "inference variables in normalized parameter environment: {}", + fixup_err ); } - - match infcx.fully_resolve(predicates) { - Ok(predicates) => Ok(predicates), - Err(fixup_err) => { - // If we encounter a fixup error, it means that some type - // variable wound up unconstrained. I actually don't know - // if this can happen, and I certainly don't expect it to - // happen often, but if it did happen it probably - // represents a legitimate failure due to some kind of - // unconstrained variable. - // - // @lcnr: Let's still ICE here for now. I want a test case - // for that. - span_bug!( - span, - "inference variables in normalized parameter environment: {}", - fixup_err - ); - } - } - }) + } } // FIXME: this is gonna need to be removed ... @@ -394,8 +390,8 @@ pub fn normalize_param_env_or_error<'tcx>( } /// Normalize a type and process all resulting obligations, returning any errors -pub fn fully_normalize<'a, 'tcx, T>( - infcx: &InferCtxt<'a, 'tcx>, +pub fn fully_normalize<'tcx, T>( + infcx: &InferCtxt<'tcx>, cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, value: T, @@ -430,8 +426,8 @@ where /// Process an obligation (and any nested obligations that come from it) to /// completion, returning any errors -pub fn fully_solve_obligation<'a, 'tcx>( - infcx: &InferCtxt<'a, 'tcx>, +pub fn fully_solve_obligation<'tcx>( + infcx: &InferCtxt<'tcx>, obligation: PredicateObligation<'tcx>, ) -> Vec> { let mut engine = >::new(infcx.tcx); @@ -441,8 +437,8 @@ pub fn fully_solve_obligation<'a, 'tcx>( /// Process a set of obligations (and any nested obligations that come from them) /// to completion -pub fn fully_solve_obligations<'a, 'tcx>( - infcx: &InferCtxt<'a, 'tcx>, +pub fn fully_solve_obligations<'tcx>( + infcx: &InferCtxt<'tcx>, obligations: impl IntoIterator>, ) -> Vec> { let mut engine = >::new(infcx.tcx); @@ -453,8 +449,8 @@ pub fn fully_solve_obligations<'a, 'tcx>( /// Process a bound (and any nested obligations that come from it) to completion. /// This is a convenience function for traits that have no generic arguments, such /// as auto traits, and builtin traits like Copy or Sized. -pub fn fully_solve_bound<'a, 'tcx>( - infcx: &InferCtxt<'a, 'tcx>, +pub fn fully_solve_bound<'tcx>( + infcx: &InferCtxt<'tcx>, cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, @@ -474,21 +470,20 @@ pub fn impossible_predicates<'tcx>( ) -> bool { debug!("impossible_predicates(predicates={:?})", predicates); - let result = tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::reveal_all(); - let ocx = ObligationCtxt::new(&infcx); - let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates); - for predicate in predicates { - let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate); - ocx.register_obligation(obligation); - } - let errors = ocx.select_all_or_error(); + let infcx = tcx.infer_ctxt().build(); + let param_env = ty::ParamEnv::reveal_all(); + let ocx = ObligationCtxt::new(&infcx); + let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates); + for predicate in predicates { + let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate); + ocx.register_obligation(obligation); + } + let errors = ocx.select_all_or_error(); - // Clean up after ourselves - let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + // Clean up after ourselves + let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); - !errors.is_empty() - }); + let result = !errors.is_empty(); debug!("impossible_predicates = {:?}", result); result } @@ -579,18 +574,16 @@ fn is_impossible_method<'tcx>( } }); - tcx.infer_ctxt().ignoring_regions().enter(|ref infcx| { - for obligation in predicates_for_trait { - // Ignore overflow error, to be conservative. - if let Ok(result) = infcx.evaluate_obligation(&obligation) - && !result.may_apply() - { - return true; - } + let infcx = tcx.infer_ctxt().ignoring_regions().build(); + for obligation in predicates_for_trait { + // Ignore overflow error, to be conservative. + if let Ok(result) = infcx.evaluate_obligation(&obligation) + && !result.may_apply() + { + return true; } - - false - }) + } + false } #[derive(Clone, Debug)] @@ -771,12 +764,9 @@ fn dump_vtable_entries<'tcx>( }); } -fn own_existential_vtable_entries<'tcx>( - tcx: TyCtxt<'tcx>, - trait_ref: ty::PolyExistentialTraitRef<'tcx>, -) -> &'tcx [DefId] { +fn own_existential_vtable_entries<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> &'tcx [DefId] { let trait_methods = tcx - .associated_items(trait_ref.def_id()) + .associated_items(trait_def_id) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Fn); // Now list each method's DefId (for within its trait). @@ -785,7 +775,7 @@ fn own_existential_vtable_entries<'tcx>( let def_id = trait_method.def_id; // Some methods cannot be called on an object; skip those. - if !is_vtable_safe_method(tcx, trait_ref.def_id(), &trait_method) { + if !is_vtable_safe_method(tcx, trait_def_id, &trait_method) { debug!("own_existential_vtable_entry: not vtable safe"); return None; } @@ -817,7 +807,7 @@ fn vtable_entries<'tcx>( // Lookup the shape of vtable for the trait. let own_existential_entries = - tcx.own_existential_vtable_entries(existential_trait_ref); + tcx.own_existential_vtable_entries(existential_trait_ref.def_id()); let own_entries = own_existential_entries.iter().copied().map(|def_id| { debug!("vtable_entries: trait_method={:?}", def_id); @@ -953,10 +943,9 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( }), ); - let implsrc = tcx.infer_ctxt().enter(|infcx| { - let mut selcx = SelectionContext::new(&infcx); - selcx.select(&obligation).unwrap() - }); + let infcx = tcx.infer_ctxt().build(); + let mut selcx = SelectionContext::new(&infcx); + let implsrc = selcx.select(&obligation).unwrap(); let Some(ImplSource::TraitUpcasting(implsrc_traitcasting)) = implsrc else { bug!(); -- cgit v1.2.3