diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
commit | 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch) | |
tree | 3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_infer/src/infer/region_constraints | |
parent | Releasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_infer/src/infer/region_constraints')
-rw-r--r-- | compiler/rustc_infer/src/infer/region_constraints/leak_check.rs | 7 | ||||
-rw-r--r-- | compiler/rustc_infer/src/infer/region_constraints/mod.rs | 89 |
2 files changed, 26 insertions, 70 deletions
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index e413b2bb5..b8ba98fc0 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -290,9 +290,9 @@ impl<'me, 'tcx> LeakCheck<'me, 'tcx> { ) -> TypeError<'tcx> { debug!("error: placeholder={:?}, other_region={:?}", placeholder, other_region); if self.overly_polymorphic { - TypeError::RegionsOverlyPolymorphic(placeholder.name, other_region) + TypeError::RegionsOverlyPolymorphic(placeholder.bound.kind, other_region) } else { - TypeError::RegionsInsufficientlyPolymorphic(placeholder.name, other_region) + TypeError::RegionsInsufficientlyPolymorphic(placeholder.bound.kind, other_region) } } } @@ -424,9 +424,6 @@ impl<'tcx> MiniGraph<'tcx> { &AddConstraint(Constraint::RegSubReg(a, b)) => { each_edge(a, b); } - &AddGiven(a, b) => { - each_edge(a, tcx.mk_re_var(b)); - } &AddVerify(i) => span_bug!( verifys[i].origin.span(), "we never add verifications while doing higher-ranked things", diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 872f61747..7b272dfd2 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -7,7 +7,7 @@ use super::{ InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, Rollback, Snapshot, SubregionOrigin, }; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::UndoLogs; @@ -104,26 +104,6 @@ pub struct RegionConstraintData<'tcx> { /// An example is a `A <= B` where neither `A` nor `B` are /// inference variables. pub verifys: Vec<Verify<'tcx>>, - - /// A "given" is a relationship that is known to hold. In - /// particular, we often know from closure fn signatures that a - /// particular free region must be a subregion of a region - /// variable: - /// - /// foo.iter().filter(<'a> |x: &'a &'b T| ...) - /// - /// In situations like this, `'b` is in fact a region variable - /// introduced by the call to `iter()`, and `'a` is a bound region - /// on the closure (as indicated by the `<'a>` prefix). If we are - /// naive, we wind up inferring that `'b` must be `'static`, - /// because we require that it be greater than `'a` and we do not - /// know what `'a` is precisely. - /// - /// This hashmap is used to avoid that naive scenario. Basically - /// we record the fact that `'a <= 'b` is implied by the fn - /// signature, and then ignore the constraint when solving - /// equations. This is a bit of a hack but seems to work. - pub givens: FxIndexSet<(Region<'tcx>, ty::RegionVid)>, } /// Represents a constraint that influences the inference process. @@ -297,9 +277,6 @@ pub(crate) enum UndoLog<'tcx> { /// We added the given `verify`. AddVerify(usize), - /// We added the given `given`. - AddGiven(Region<'tcx>, ty::RegionVid), - /// We added a GLB/LUB "combination variable". AddCombination(CombineMapType, TwoRegions<'tcx>), } @@ -348,9 +325,6 @@ impl<'tcx> RegionConstraintStorage<'tcx> { self.data.verifys.pop(); assert_eq!(self.data.verifys.len(), index); } - AddGiven(sub, sup) => { - self.data.givens.remove(&(sub, sup)); - } AddCombination(Glb, ref regions) => { self.glbs.remove(regions); } @@ -420,7 +394,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { // `RegionConstraintData` contains the relationship here. if *any_unifications { *any_unifications = false; - self.unification_table().reset_unifications(|_| UnifiedRegion(None)); + self.unification_table_mut().reset_unifications(|_| UnifiedRegion::new(None)); } data @@ -447,7 +421,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { ) -> RegionVid { let vid = self.var_infos.push(RegionVariableInfo { origin, universe }); - let u_vid = self.unification_table().new_key(UnifiedRegion(None)); + let u_vid = self.unification_table_mut().new_key(UnifiedRegion::new(None)); assert_eq!(vid, u_vid.vid); self.undo_log.push(AddVar(vid)); debug!("created new region variable {:?} in {:?} with origin {:?}", vid, universe, origin); @@ -492,15 +466,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.undo_log.push(AddVerify(index)); } - pub(super) fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) { - // cannot add givens once regions are resolved - if self.data.givens.insert((sub, sup)) { - debug!("add_given({:?} <= {:?})", sub, sup); - - self.undo_log.push(AddGiven(sub, sup)); - } - } - pub(super) fn make_eqregion( &mut self, origin: SubregionOrigin<'tcx>, @@ -516,13 +481,13 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { match (sub, sup) { (Region(Interned(ReVar(sub), _)), Region(Interned(ReVar(sup), _))) => { debug!("make_eqregion: unifying {:?} with {:?}", sub, sup); - self.unification_table().union(*sub, *sup); + self.unification_table_mut().union(*sub, *sup); self.any_unifications = true; } (Region(Interned(ReVar(vid), _)), value) | (value, Region(Interned(ReVar(vid), _))) => { debug!("make_eqregion: unifying {:?} with {:?}", vid, value); - self.unification_table().union_value(*vid, UnifiedRegion(Some(value))); + self.unification_table_mut().union_value(*vid, UnifiedRegion::new(Some(value))); self.any_unifications = true; } (_, _) => {} @@ -633,28 +598,25 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } } - /// Resolves the passed RegionVid to the root RegionVid in the unification table - pub(super) fn opportunistic_resolve_var(&mut self, rid: ty::RegionVid) -> ty::RegionVid { - self.unification_table().find(rid).vid - } - - /// If the Region is a `ReVar`, then resolves it either to the root value in - /// the unification table, if it exists, or to the root `ReVar` in the table. - /// If the Region is not a `ReVar`, just returns the Region itself. - pub fn opportunistic_resolve_region( + /// Resolves a region var to its value in the unification table, if it exists. + /// Otherwise, it is resolved to the root `ReVar` in the table. + pub fn opportunistic_resolve_var( &mut self, tcx: TyCtxt<'tcx>, - region: ty::Region<'tcx>, + vid: ty::RegionVid, ) -> ty::Region<'tcx> { - match *region { - ty::ReVar(rid) => { - let unified_region = self.unification_table().probe_value(rid); - unified_region.0.unwrap_or_else(|| { - let root = self.unification_table().find(rid).vid; - tcx.mk_re_var(root) - }) - } - _ => region, + let mut ut = self.unification_table_mut(); // FIXME(rust-lang/ena#42): unnecessary mut + let root_vid = ut.find(vid).vid; + let resolved = ut + .probe_value(root_vid) + .get_value_ignoring_universes() + .unwrap_or_else(|| tcx.mk_re_var(root_vid)); + + // Don't resolve a variable to a region that it cannot name. + if self.var_universe(vid).can_name(self.universe(resolved)) { + resolved + } else { + tcx.mk_re_var(vid) } } @@ -733,7 +695,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } #[inline] - fn unification_table(&mut self) -> super::UnificationTable<'_, 'tcx, RegionVidKey<'tcx>> { + fn unification_table_mut(&mut self) -> super::UnificationTable<'_, 'tcx, RegionVidKey<'tcx>> { ut::UnificationTable::with_log(&mut self.storage.unification_table, self.undo_log) } } @@ -807,11 +769,8 @@ impl<'tcx> RegionConstraintData<'tcx> { /// Returns `true` if this region constraint data contains no constraints, and `false` /// otherwise. pub fn is_empty(&self) -> bool { - let RegionConstraintData { constraints, member_constraints, verifys, givens } = self; - constraints.is_empty() - && member_constraints.is_empty() - && verifys.is_empty() - && givens.is_empty() + let RegionConstraintData { constraints, member_constraints, verifys } = self; + constraints.is_empty() && member_constraints.is_empty() && verifys.is_empty() } } |