diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:25 +0000 |
commit | 5363f350887b1e5b5dd21a86f88c8af9d7fea6da (patch) | |
tree | 35ca005eb6e0e9a1ba3bb5dbc033209ad445dc17 /compiler/rustc_borrowck/src/region_infer | |
parent | Adding debian version 1.66.0+dfsg1-1. (diff) | |
download | rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.tar.xz rustc-5363f350887b1e5b5dd21a86f88c8af9d7fea6da.zip |
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_borrowck/src/region_infer')
6 files changed, 103 insertions, 202 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs index fe5193102..6524b594e 100644 --- a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs +++ b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! As part of generating the regions, if you enable `-Zdump-mir=nll`, //! we will generate an annotated copy of the MIR that includes the //! state of region inference. This code handles emitting the region @@ -74,8 +76,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut constraints: Vec<_> = self.constraints.outlives().iter().collect(); constraints.sort_by_key(|c| (c.sup, c.sub)); for constraint in &constraints { - let OutlivesConstraint { sup, sub, locations, category, span, variance_info: _ } = - constraint; + let OutlivesConstraint { sup, sub, locations, category, span, .. } = constraint; let (name, arg) = match locations { Locations::All(span) => { ("All", tcx.sess.source_map().span_to_embeddable_string(*span)) diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs index f31ccd74c..2e15586e0 100644 --- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs +++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] //! This module provides linkage between RegionInferenceContext and //! `rustc_graphviz` traits, specialized to attaching borrowck analysis //! data to rendered labels. diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 8b63294fb..90e2b6b69 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -6,10 +6,9 @@ use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::scc::Sccs; use rustc_errors::Diagnostic; -use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; +use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::CRATE_HIR_ID; use rustc_index::vec::IndexVec; -use rustc_infer::infer::canonical::QueryOutlivesConstraint; use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; @@ -19,9 +18,7 @@ use rustc_middle::mir::{ }; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCauseCode; -use rustc_middle::ty::{ - self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable, -}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_span::Span; use crate::{ @@ -89,10 +86,6 @@ pub struct RegionInferenceContext<'tcx> { /// `member_region_scc`. member_constraints_applied: Vec<AppliedMemberConstraint>, - /// Map closure bounds to a `Span` that should be used for error reporting. - closure_bounds_mapping: - FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>>, - /// Map universe indexes to information on why we created it. universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>, @@ -135,6 +128,7 @@ pub struct RegionInferenceContext<'tcx> { /// adds a new lower bound to the SCC it is analyzing: so you wind up /// with `'R: 'O` where `'R` is the pick-region and `'O` is the /// minimal viable option. +#[derive(Debug)] pub(crate) struct AppliedMemberConstraint { /// The SCC that was affected. (The "member region".) /// @@ -221,8 +215,8 @@ pub struct TypeTest<'tcx> { /// The region `'x` that the type must outlive. pub lower_bound: RegionVid, - /// Where did this constraint arise and why? - pub locations: Locations, + /// The span to blame. + pub span: Span, /// A test which, if met by the region `'x`, proves that this type /// constraint is satisfied. @@ -265,10 +259,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, outlives_constraints: OutlivesConstraintSet<'tcx>, member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, - closure_bounds_mapping: FxHashMap< - Location, - FxHashMap<(RegionVid, RegionVid), (ConstraintCategory<'tcx>, Span)>, - >, universe_causes: FxHashMap<ty::UniverseIndex, UniverseInfo<'tcx>>, type_tests: Vec<TypeTest<'tcx>>, liveness_constraints: LivenessValues<RegionVid>, @@ -310,7 +300,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { rev_scc_graph: None, member_constraints, member_constraints_applied: Vec::new(), - closure_bounds_mapping, universe_causes, scc_universes, scc_representatives, @@ -882,13 +871,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { if deduplicate_errors.insert(( erased_generic_kind, type_test.lower_bound, - type_test.locations, + type_test.span, )) { debug!( "check_type_test: reporting error for erased_generic_kind={:?}, \ lower_bound_region={:?}, \ - type_test.locations={:?}", - erased_generic_kind, type_test.lower_bound, type_test.locations, + type_test.span={:?}", + erased_generic_kind, type_test.lower_bound, type_test.span, ); errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() }); @@ -931,7 +920,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) -> bool { let tcx = infcx.tcx; - let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test; + let TypeTest { generic_kind, lower_bound, span: _, verify_bound: _ } = type_test; let generic_ty = generic_kind.to_ty(tcx); let Some(subject) = self.try_promote_type_test_subject(infcx, generic_ty) else { @@ -959,7 +948,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { propagated_outlives_requirements.push(ClosureOutlivesRequirement { subject, outlived_free_region: static_r, - blame_span: locations.span(body), + blame_span: type_test.span, category: ConstraintCategory::Boring, }); @@ -1011,7 +1000,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let requirement = ClosureOutlivesRequirement { subject, outlived_free_region: upper_bound, - blame_span: locations.span(body), + blame_span: type_test.span, category: ConstraintCategory::Boring, }; debug!("try_promote_type_test: pushing {:#?}", requirement); @@ -1716,6 +1705,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); } + #[instrument(level = "debug", skip(self, infcx, errors_buffer))] fn check_member_constraints( &self, infcx: &InferCtxt<'tcx>, @@ -1723,22 +1713,21 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) { let member_constraints = self.member_constraints.clone(); for m_c_i in member_constraints.all_indices() { - debug!("check_member_constraint(m_c_i={:?})", m_c_i); + debug!(?m_c_i); let m_c = &member_constraints[m_c_i]; let member_region_vid = m_c.member_region_vid; debug!( - "check_member_constraint: member_region_vid={:?} with value {}", - member_region_vid, - self.region_value_str(member_region_vid), + ?member_region_vid, + value = ?self.region_value_str(member_region_vid), ); let choice_regions = member_constraints.choice_regions(m_c_i); - debug!("check_member_constraint: choice_regions={:?}", choice_regions); + debug!(?choice_regions); // Did the member region wind up equal to any of the option regions? if let Some(o) = choice_regions.iter().find(|&&o_r| self.eval_equal(o_r, m_c.member_region_vid)) { - debug!("check_member_constraint: evaluated as equal to {:?}", o); + debug!("evaluated as equal to {:?}", o); continue; } @@ -1804,18 +1793,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - pub(crate) fn retrieve_closure_constraint_info( - &self, - constraint: OutlivesConstraint<'tcx>, - ) -> Option<(ConstraintCategory<'tcx>, Span)> { - match constraint.locations { - Locations::All(_) => None, - Locations::Single(loc) => { - self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)).copied() - } - } - } - /// Finds a good `ObligationCause` to blame for the fact that `fr1` outlives `fr2`. pub(crate) fn find_outlives_blame_span( &self, @@ -1921,6 +1898,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { span: p_c.definition_span, category: ConstraintCategory::OpaqueType, variance_info: ty::VarianceDiagInfo::default(), + from_closure: false, }; handle_constraint(constraint); } @@ -2066,31 +2044,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Classify each of the constraints along the path. let mut categorized_path: Vec<BlameConstraint<'tcx>> = path .iter() - .map(|constraint| { - let (category, span, from_closure, cause_code) = - if constraint.category == ConstraintCategory::ClosureBounds { - if let Some((category, span)) = - self.retrieve_closure_constraint_info(*constraint) - { - (category, span, true, ObligationCauseCode::MiscObligation) - } else { - ( - constraint.category, - constraint.span, - false, - ObligationCauseCode::MiscObligation, - ) - } - } else { - (constraint.category, constraint.span, false, cause_code.clone()) - }; - BlameConstraint { - category, - from_closure, - cause: ObligationCause::new(span, CRATE_HIR_ID, cause_code), - variance_info: constraint.variance_info, - outlives_constraint: *constraint, - } + .map(|constraint| BlameConstraint { + category: constraint.category, + from_closure: constraint.from_closure, + cause: ObligationCause::new(constraint.span, CRATE_HIR_ID, cause_code.clone()), + variance_info: constraint.variance_info, + outlives_constraint: *constraint, }) .collect(); debug!("categorized_path={:#?}", categorized_path); @@ -2274,92 +2233,6 @@ impl<'tcx> RegionDefinition<'tcx> { } } -pub trait ClosureRegionRequirementsExt<'tcx> { - fn apply_requirements( - &self, - tcx: TyCtxt<'tcx>, - closure_def_id: DefId, - closure_substs: SubstsRef<'tcx>, - ) -> Vec<QueryOutlivesConstraint<'tcx>>; -} - -impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx> { - /// Given an instance T of the closure type, this method - /// instantiates the "extra" requirements that we computed for the - /// closure into the inference context. This has the effect of - /// adding new outlives obligations to existing variables. - /// - /// As described on `ClosureRegionRequirements`, the extra - /// requirements are expressed in terms of regionvids that index - /// into the free regions that appear on the closure type. So, to - /// do this, we first copy those regions out from the type T into - /// a vector. Then we can just index into that vector to extract - /// out the corresponding region from T and apply the - /// requirements. - fn apply_requirements( - &self, - tcx: TyCtxt<'tcx>, - closure_def_id: DefId, - closure_substs: SubstsRef<'tcx>, - ) -> Vec<QueryOutlivesConstraint<'tcx>> { - debug!( - "apply_requirements(closure_def_id={:?}, closure_substs={:?})", - closure_def_id, closure_substs - ); - - // Extract the values of the free regions in `closure_substs` - // into a vector. These are the regions that we will be - // relating to one another. - let closure_mapping = &UniversalRegions::closure_mapping( - tcx, - closure_substs, - self.num_external_vids, - tcx.typeck_root_def_id(closure_def_id), - ); - debug!("apply_requirements: closure_mapping={:?}", closure_mapping); - - // Create the predicates. - self.outlives_requirements - .iter() - .map(|outlives_requirement| { - let outlived_region = closure_mapping[outlives_requirement.outlived_free_region]; - - match outlives_requirement.subject { - ClosureOutlivesSubject::Region(region) => { - let region = closure_mapping[region]; - debug!( - "apply_requirements: region={:?} \ - outlived_region={:?} \ - outlives_requirement={:?}", - region, outlived_region, outlives_requirement, - ); - ( - ty::Binder::dummy(ty::OutlivesPredicate( - region.into(), - outlived_region, - )), - ConstraintCategory::BoringNoLocation, - ) - } - - ClosureOutlivesSubject::Ty(ty) => { - debug!( - "apply_requirements: ty={:?} \ - outlived_region={:?} \ - outlives_requirement={:?}", - ty, outlived_region, outlives_requirement, - ); - ( - ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region)), - ConstraintCategory::BoringNoLocation, - ) - } - } - }) - .collect() - } -} - #[derive(Clone, Debug)] pub struct BlameConstraint<'tcx> { pub category: ConstraintCategory<'tcx>, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 465f353aa..516a08077 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,18 +1,16 @@ -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::vec_map::VecMap; use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; use rustc_infer::infer::TyCtxtInferExt as _; use rustc_infer::infer::{DefiningAnchor, InferCtxt}; -use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine}; +use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{ - self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt, TypeFoldable, -}; +use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::TraitEngineExt as _; +use rustc_trait_selection::traits::ObligationCtxt; use super::RegionInferenceContext; @@ -63,17 +61,21 @@ impl<'tcx> RegionInferenceContext<'tcx> { opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, ) -> VecMap<LocalDefId, OpaqueHiddenType<'tcx>> { let mut result: VecMap<LocalDefId, OpaqueHiddenType<'tcx>> = VecMap::new(); + + let member_constraints: FxHashMap<_, _> = self + .member_constraints + .all_indices() + .map(|ci| (self.member_constraints[ci].key, ci)) + .collect(); + debug!(?member_constraints); + for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls { let substs = opaque_type_key.substs; debug!(?concrete_type, ?substs); let mut subst_regions = vec![self.universal_regions.fr_static]; - let universal_substs = infcx.tcx.fold_regions(substs, |region, _| { - if let ty::RePlaceholder(..) = region.kind() { - // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs. - return region; - } - let vid = self.to_region_vid(region); + + let to_universal_region = |vid, subst_regions: &mut Vec<_>| { trace!(?vid); let scc = self.constraint_sccs.scc(vid); trace!(?scc); @@ -94,10 +96,33 @@ impl<'tcx> RegionInferenceContext<'tcx> { infcx.tcx.lifetimes.re_static } } + }; + + // Start by inserting universal regions from the member_constraint choice regions. + // This will ensure they get precedence when folding the regions in the concrete type. + if let Some(&ci) = member_constraints.get(&opaque_type_key) { + for &vid in self.member_constraints.choice_regions(ci) { + to_universal_region(vid, &mut subst_regions); + } + } + debug!(?subst_regions); + + // Next, insert universal regions from substs, so we can translate regions that appear + // in them but are not subject to member constraints, for instance closure substs. + let universal_substs = infcx.tcx.fold_regions(substs, |region, _| { + if let ty::RePlaceholder(..) = region.kind() { + // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs. + return region; + } + let vid = self.to_region_vid(region); + to_universal_region(vid, &mut subst_regions) }); + debug!(?universal_substs); + debug!(?subst_regions); - subst_regions.sort(); - subst_regions.dedup(); + // Deduplicate the set of regions while keeping the chosen order. + let subst_regions = subst_regions.into_iter().collect::<FxIndexSet<_>>(); + debug!(?subst_regions); let universal_concrete_type = infcx.tcx.fold_regions(concrete_type, |region, _| match *region { @@ -108,8 +133,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { .unwrap_or(infcx.tcx.lifetimes.re_erased), _ => region, }); - - debug!(?universal_concrete_type, ?universal_substs); + debug!(?universal_concrete_type); let opaque_type_key = OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs }; @@ -221,12 +245,12 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { instantiated_ty: OpaqueHiddenType<'tcx>, origin: OpaqueTyOrigin, ) -> Ty<'tcx> { - if self.is_tainted_by_errors() { - return self.tcx.ty_error(); + if let Some(e) = self.tainted_by_errors() { + return self.tcx.ty_error_with_guaranteed(e); } let definition_ty = instantiated_ty - .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false, origin) + .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) .ty; if !check_opaque_type_parameter_valid( @@ -252,48 +276,45 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // type-alias-impl-trait/issue-67844-nested-opaque.rs let infcx = self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); + let ocx = ObligationCtxt::new(&infcx); // Require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())) - .to_predicate(infcx.tcx); - let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx); + let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())); let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id()); // Require that the hidden type actually fulfills all the bounds of the opaque type, even without // the bounds that the function supplies. let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs); - match infcx - .at(&ObligationCause::misc(instantiated_ty.span, body_id), param_env) - .eq(opaque_ty, definition_ty) - { - Ok(infer_ok) => { - for obligation in infer_ok.obligations { - fulfillment_cx.register_predicate_obligation(&infcx, obligation); - } - } - Err(err) => { - infcx - .err_ctxt() - .report_mismatched_types( - &ObligationCause::misc(instantiated_ty.span, body_id), - opaque_ty, - definition_ty, - err, - ) - .emit(); - } + if let Err(err) = ocx.eq( + &ObligationCause::misc(instantiated_ty.span, body_id), + param_env, + opaque_ty, + definition_ty, + ) { + infcx + .err_ctxt() + .report_mismatched_types( + &ObligationCause::misc(instantiated_ty.span, body_id), + opaque_ty, + definition_ty, + err, + ) + .emit(); } - fulfillment_cx.register_predicate_obligation( - &infcx, - Obligation::misc(instantiated_ty.span, body_id, param_env, predicate), - ); + ocx.register_obligation(Obligation::misc( + infcx.tcx, + instantiated_ty.span, + body_id, + param_env, + predicate, + )); // Check that all obligations are satisfied by the implementation's // version. - let errors = fulfillment_cx.select_all_or_error(&infcx); + let errors = ocx.select_all_or_error(); // This is still required for many(half of the tests in ui/type-alias-impl-trait) // tests to pass @@ -302,8 +323,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { if errors.is_empty() { definition_ty } else { - infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); - self.tcx.ty_error() + let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); + self.tcx.ty_error_with_guaranteed(reported) } } } diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index 1e6798eee..167f66460 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use crate::constraints::ConstraintSccIndex; use crate::RegionInferenceContext; use itertools::Itertools; diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index de20a4bb4..7498ddccf 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -1,3 +1,5 @@ +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::fx::FxIndexSet; use rustc_index::bit_set::SparseBitMatrix; use rustc_index::interval::IntervalSet; |