diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_trait_selection/src/traits/mod.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/mod.rs')
-rw-r--r-- | compiler/rustc_trait_selection/src/traits/mod.rs | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 8a203dec8..f265230ff 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -17,6 +17,7 @@ pub mod query; mod select; mod specialize; mod structural_match; +mod structural_normalize; mod util; mod vtable; pub mod wf; @@ -26,6 +27,7 @@ use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; +use rustc_middle::query::Providers; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeSuperVisitable}; @@ -49,20 +51,24 @@ pub use self::object_safety::astconv_object_safety_violations; pub use self::object_safety::is_vtable_safe_method; pub use self::object_safety::MethodViolationCode; pub use self::object_safety::ObjectSafetyViolation; -pub use self::project::{normalize_projection_type, NormalizeExt}; +pub use self::project::NormalizeExt; +pub use self::project::{normalize_inherent_projection, normalize_projection_type}; pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; pub use self::specialize::specialization_graph::FutureCompatOverlapError; pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind; -pub use self::specialize::{specialization_graph, translate_substs, OverlapError}; +pub use self::specialize::{ + specialization_graph, translate_substs, translate_substs_with_cause, OverlapError, +}; pub use self::structural_match::{ search_for_adt_const_param_violation, search_for_structural_match_violation, }; +pub use self::structural_normalize::StructurallyNormalizeExt; pub use self::util::elaborate; pub use self::util::{expand_trait_aliases, TraitAliasExpander}; pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices}; pub use self::util::{ - supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_type, + supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_item, SupertraitDefIds, }; @@ -127,7 +133,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( ty: Ty<'tcx>, def_id: DefId, ) -> bool { - let trait_ref = ty::Binder::dummy(infcx.tcx.mk_trait_ref(def_id, [ty])); + let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]); pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const()) } @@ -139,35 +145,36 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( fn pred_known_to_hold_modulo_regions<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - pred: impl ToPredicate<'tcx> + TypeVisitable<TyCtxt<'tcx>>, + pred: impl ToPredicate<'tcx>, ) -> bool { - let has_non_region_infer = pred.has_non_region_infer(); let obligation = Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, pred); let result = infcx.evaluate_obligation_no_overflow(&obligation); debug!(?result); - if result.must_apply_modulo_regions() && !has_non_region_infer { + if result.must_apply_modulo_regions() { true } else if result.may_apply() { - // 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 - // that guess. While imperfect, I believe this is sound. - - // The handling of regions in this area of the code is terrible, - // see issue #29149. We should be able to improve on this with - // NLL. - let ocx = ObligationCtxt::new(infcx); - ocx.register_obligation(obligation); - let errors = ocx.select_all_or_error(); - match errors.as_slice() { - [] => true, - errors => { - debug!(?errors); - false + // Sometimes obligations are ambiguous because the recursive evaluator + // is not smart enough, so we fall back to fulfillment when we're not certain + // that an obligation holds or not. Even still, we must make sure that + // the we do no inference in the process of checking this obligation. + let goal = infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env)); + infcx.probe(|_| { + let ocx = ObligationCtxt::new_in_snapshot(infcx); + ocx.register_obligation(obligation); + + let errors = ocx.select_all_or_error(); + match errors.as_slice() { + // Only known to hold if we did no inference. + [] => infcx.shallow_resolve(goal) == goal, + + errors => { + debug!(?errors); + false + } } - } + }) } else { false } @@ -203,7 +210,7 @@ fn do_normalize_predicates<'tcx>( } }; - debug!("do_normalize_predictes: normalized predicates = {:?}", predicates); + debug!("do_normalize_predicates: normalized predicates = {:?}", predicates); // We can use the `elaborated_env` here; the region code only // cares about declarations like `'a: 'b`. @@ -414,7 +421,7 @@ fn subst_and_check_impossible_predicates<'tcx>( predicates.push(ty::Binder::dummy(trait_ref).to_predicate(tcx)); } - predicates.retain(|predicate| !predicate.needs_subst()); + predicates.retain(|predicate| !predicate.has_param()); let result = impossible_predicates(tcx, predicates); debug!("subst_and_check_impossible_predicates(key={:?}) = {:?}", key, result); @@ -450,7 +457,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI { return ControlFlow::Break(()); } - r.super_visit_with(self) + ControlFlow::Continue(()) } fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { if let ty::ConstKind::Param(param) = ct.kind() @@ -495,10 +502,10 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI false } -pub fn provide(providers: &mut ty::query::Providers) { +pub fn provide(providers: &mut Providers) { object_safety::provide(providers); vtable::provide(providers); - *providers = ty::query::Providers { + *providers = Providers { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, subst_and_check_impossible_predicates, |