diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:31 +0000 |
commit | dc0db358abe19481e475e10c32149b53370f1a1c (patch) | |
tree | ab8ce99c4b255ce46f99ef402c27916055b899ee /compiler/rustc_infer/src/infer/mod.rs | |
parent | Releasing progress-linux version 1.71.1+dfsg1-2~progress7.99u1. (diff) | |
download | rustc-dc0db358abe19481e475e10c32149b53370f1a1c.tar.xz rustc-dc0db358abe19481e475e10c32149b53370f1a1c.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_infer/src/infer/mod.rs')
-rw-r--r-- | compiler/rustc_infer/src/infer/mod.rs | 190 |
1 files changed, 93 insertions, 97 deletions
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index cd99fc312..fca32b73d 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -6,6 +6,7 @@ pub use self::RegionVariableOrigin::*; pub use self::SubregionOrigin::*; pub use self::ValuePairs::*; pub use combine::ObligationEmittingRelation; +use rustc_data_structures::undo_log::UndoLogs; use self::opaque_types::OpaqueTypeStorage; pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog}; @@ -251,14 +252,13 @@ pub struct InferCtxt<'tcx> { /// solving is left to borrowck instead. pub considering_regions: bool, - pub inner: RefCell<InferCtxtInner<'tcx>>, - /// If set, this flag causes us to skip the 'leak check' during /// higher-ranked subtyping operations. This flag is a temporary one used /// to manage the removal of the leak-check: for the time being, we still run the - /// leak-check, but we issue warnings. This flag can only be set to true - /// when entering a snapshot. - skip_leak_check: Cell<bool>, + /// leak-check, but we issue warnings. + skip_leak_check: bool, + + pub inner: RefCell<InferCtxtInner<'tcx>>, /// Once region inference is done, the values for each variable. lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>, @@ -298,9 +298,6 @@ pub struct InferCtxt<'tcx> { // FIXME(matthewjasper) Merge into `tainted_by_errors` err_count_on_creation: usize, - /// This flag is true while there is an active snapshot. - in_snapshot: Cell<bool>, - /// What is the innermost universe we have created? Starts out as /// `UniverseIndex::root()` but grows from there as we enter /// universal quantifiers. @@ -331,6 +328,8 @@ pub struct InferCtxt<'tcx> { /// there is no type that the user could *actually name* that /// would satisfy it. This avoids crippling inference, basically. pub intercrate: bool, + + next_trait_solver: bool, } /// See the `error_reporting` module for more details. @@ -543,8 +542,12 @@ pub struct InferCtxtBuilder<'tcx> { tcx: TyCtxt<'tcx>, defining_use_anchor: DefiningAnchor, considering_regions: bool, + skip_leak_check: bool, /// Whether we are in coherence mode. intercrate: bool, + /// Whether we should use the new trait solver in the local inference context, + /// which affects things like which solver is used in `predicate_may_hold`. + next_trait_solver: bool, } pub trait TyCtxtInferExt<'tcx> { @@ -557,7 +560,9 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> { tcx: self, defining_use_anchor: DefiningAnchor::Error, considering_regions: true, + skip_leak_check: false, intercrate: false, + next_trait_solver: self.next_trait_solver_globally(), } } } @@ -574,6 +579,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> { self } + pub fn with_next_trait_solver(mut self, next_trait_solver: bool) -> Self { + self.next_trait_solver = next_trait_solver; + self + } + pub fn intercrate(mut self, intercrate: bool) -> Self { self.intercrate = intercrate; self @@ -584,6 +594,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> { self } + pub fn skip_leak_check(mut self, skip_leak_check: bool) -> Self { + self.skip_leak_check = skip_leak_check; + self + } + /// Given a canonical value `C` as a starting point, create an /// inference context that contains each of the bound values /// within instantiated as a fresh variable. The `f` closure is @@ -605,11 +620,19 @@ impl<'tcx> InferCtxtBuilder<'tcx> { } pub fn build(&mut self) -> InferCtxt<'tcx> { - let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self; + let InferCtxtBuilder { + tcx, + defining_use_anchor, + considering_regions, + skip_leak_check, + intercrate, + next_trait_solver, + } = *self; InferCtxt { tcx, defining_use_anchor, considering_regions, + skip_leak_check, inner: RefCell::new(InferCtxtInner::new()), lexical_region_resolutions: RefCell::new(None), selection_cache: Default::default(), @@ -618,10 +641,9 @@ impl<'tcx> InferCtxtBuilder<'tcx> { reported_closure_mismatch: Default::default(), tainted_by_errors: Cell::new(None), err_count_on_creation: tcx.sess.err_count(), - in_snapshot: Cell::new(false), - skip_leak_check: Cell::new(false), universe: Cell::new(ty::UniverseIndex::ROOT), intercrate, + next_trait_solver, } } } @@ -654,10 +676,13 @@ pub struct CombinedSnapshot<'tcx> { undo_snapshot: Snapshot<'tcx>, region_constraints_snapshot: RegionSnapshot, universe: ty::UniverseIndex, - was_in_snapshot: bool, } impl<'tcx> InferCtxt<'tcx> { + pub fn next_trait_solver(&self) -> bool { + self.next_trait_solver + } + /// Creates a `TypeErrCtxt` for emitting various inference errors. /// During typeck, use `FnCtxt::err_ctxt` instead. pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> { @@ -673,10 +698,6 @@ impl<'tcx> InferCtxt<'tcx> { } } - pub fn is_in_snapshot(&self) -> bool { - self.in_snapshot.get() - } - pub fn freshen<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T { t.fold_with(&mut self.freshener()) } @@ -704,19 +725,19 @@ impl<'tcx> InferCtxt<'tcx> { .type_variables() .unsolved_variables() .into_iter() - .map(|t| self.tcx.mk_ty_var(t)) + .map(|t| Ty::new_var(self.tcx, t)) .collect(); vars.extend( (0..inner.int_unification_table().len()) .map(|i| ty::IntVid { index: i as u32 }) .filter(|&vid| inner.int_unification_table().probe_value(vid).is_none()) - .map(|v| self.tcx.mk_int_var(v)), + .map(|v| Ty::new_int_var(self.tcx, v)), ); vars.extend( (0..inner.float_unification_table().len()) .map(|i| ty::FloatVid { index: i as u32 }) .filter(|&vid| inner.float_unification_table().probe_value(vid).is_none()) - .map(|v| self.tcx.mk_float_var(v)), + .map(|v| Ty::new_float_var(self.tcx, v)), ); vars } @@ -737,31 +758,30 @@ impl<'tcx> InferCtxt<'tcx> { } } + pub fn in_snapshot(&self) -> bool { + UndoLogs::<UndoLog<'tcx>>::in_snapshot(&self.inner.borrow_mut().undo_log) + } + + pub fn num_open_snapshots(&self) -> usize { + UndoLogs::<UndoLog<'tcx>>::num_open_snapshots(&self.inner.borrow_mut().undo_log) + } + fn start_snapshot(&self) -> CombinedSnapshot<'tcx> { debug!("start_snapshot()"); - let in_snapshot = self.in_snapshot.replace(true); - let mut inner = self.inner.borrow_mut(); CombinedSnapshot { undo_snapshot: inner.undo_log.start_snapshot(), region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(), universe: self.universe(), - was_in_snapshot: in_snapshot, } } #[instrument(skip(self, snapshot), level = "debug")] fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'tcx>) { - let CombinedSnapshot { - undo_snapshot, - region_constraints_snapshot, - universe, - was_in_snapshot, - } = snapshot; - - self.in_snapshot.set(was_in_snapshot); + let CombinedSnapshot { undo_snapshot, region_constraints_snapshot, universe } = snapshot; + self.universe.set(universe); let mut inner = self.inner.borrow_mut(); @@ -771,14 +791,8 @@ impl<'tcx> InferCtxt<'tcx> { #[instrument(skip(self, snapshot), level = "debug")] fn commit_from(&self, snapshot: CombinedSnapshot<'tcx>) { - let CombinedSnapshot { - undo_snapshot, - region_constraints_snapshot: _, - universe: _, - was_in_snapshot, - } = snapshot; - - self.in_snapshot.set(was_in_snapshot); + let CombinedSnapshot { undo_snapshot, region_constraints_snapshot: _, universe: _ } = + snapshot; self.inner.borrow_mut().commit(undo_snapshot); } @@ -815,32 +829,9 @@ impl<'tcx> InferCtxt<'tcx> { r } - /// If `should_skip` is true, then execute `f` then unroll any bindings it creates. - #[instrument(skip(self, f), level = "debug")] - pub fn probe_maybe_skip_leak_check<R, F>(&self, should_skip: bool, f: F) -> R - where - F: FnOnce(&CombinedSnapshot<'tcx>) -> R, - { - let snapshot = self.start_snapshot(); - let was_skip_leak_check = self.skip_leak_check.get(); - if should_skip { - self.skip_leak_check.set(true); - } - let r = f(&snapshot); - self.rollback_to("probe", snapshot); - self.skip_leak_check.set(was_skip_leak_check); - r - } - - /// Scan the constraints produced since `snapshot` began and returns: - /// - /// - `None` -- if none of them involves "region outlives" constraints. - /// - `Some(true)` -- if there are `'a: 'b` constraints where `'a` or `'b` is a placeholder. - /// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders. - pub fn region_constraints_added_in_snapshot( - &self, - snapshot: &CombinedSnapshot<'tcx>, - ) -> Option<bool> { + /// Scan the constraints produced since `snapshot` and check whether + /// we added any region constraints. + pub fn region_constraints_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool { self.inner .borrow_mut() .unwrap_region_constraints() @@ -987,7 +978,7 @@ impl<'tcx> InferCtxt<'tcx> { } pub fn next_ty_var(&self, origin: TypeVariableOrigin) -> Ty<'tcx> { - self.tcx.mk_ty_var(self.next_ty_var_id(origin)) + Ty::new_var(self.tcx, self.next_ty_var_id(origin)) } pub fn next_ty_var_id_in_universe( @@ -1004,11 +995,11 @@ impl<'tcx> InferCtxt<'tcx> { universe: ty::UniverseIndex, ) -> Ty<'tcx> { let vid = self.next_ty_var_id_in_universe(origin, universe); - self.tcx.mk_ty_var(vid) + Ty::new_var(self.tcx, vid) } pub fn next_const_var(&self, ty: Ty<'tcx>, origin: ConstVariableOrigin) -> ty::Const<'tcx> { - self.tcx.mk_const(self.next_const_var_id(origin), ty) + ty::Const::new_var(self.tcx, self.next_const_var_id(origin), ty) } pub fn next_const_var_in_universe( @@ -1022,7 +1013,7 @@ impl<'tcx> InferCtxt<'tcx> { .borrow_mut() .const_unification_table() .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } }); - self.tcx.mk_const(vid, ty) + ty::Const::new_var(self.tcx, vid, ty) } pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid<'tcx> { @@ -1037,7 +1028,7 @@ impl<'tcx> InferCtxt<'tcx> { } pub fn next_int_var(&self) -> Ty<'tcx> { - self.tcx.mk_int_var(self.next_int_var_id()) + Ty::new_int_var(self.tcx, self.next_int_var_id()) } fn next_float_var_id(&self) -> FloatVid { @@ -1045,7 +1036,7 @@ impl<'tcx> InferCtxt<'tcx> { } pub fn next_float_var(&self) -> Ty<'tcx> { - self.tcx.mk_float_var(self.next_float_var_id()) + Ty::new_float_var(self.tcx, self.next_float_var_id()) } /// Creates a fresh region variable with the next available index. @@ -1065,7 +1056,7 @@ impl<'tcx> InferCtxt<'tcx> { ) -> ty::Region<'tcx> { let region_var = self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe, origin); - self.tcx.mk_re_var(region_var) + ty::Region::new_var(self.tcx, region_var) } /// Return the universe that the region `r` was created in. For @@ -1119,13 +1110,13 @@ impl<'tcx> InferCtxt<'tcx> { TypeVariableOrigin { kind: TypeVariableOriginKind::TypeParameterDefinition( param.name, - Some(param.def_id), + param.def_id, ), span, }, ); - self.tcx.mk_ty_var(ty_var_id).into() + Ty::new_var(self.tcx, ty_var_id).into() } GenericParamDefKind::Const { .. } => { let origin = ConstVariableOrigin { @@ -1140,15 +1131,15 @@ impl<'tcx> InferCtxt<'tcx> { origin, val: ConstVariableValue::Unknown { universe: self.universe() }, }); - self.tcx - .mk_const( - const_var_id, - self.tcx - .type_of(param.def_id) - .no_bound_vars() - .expect("const parameter types cannot be generic"), - ) - .into() + ty::Const::new_var( + self.tcx, + const_var_id, + self.tcx + .type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), + ) + .into() } } } @@ -1206,15 +1197,15 @@ impl<'tcx> InferCtxt<'tcx> { .var_origin(vid) } - /// Takes ownership of the list of variable regions. This implies - /// that all the region constraints have already been taken, and - /// hence that `resolve_regions_and_report_errors` can never be - /// called. This is used only during NLL processing to "hand off" ownership - /// of the set of region variables into the NLL region context. + /// Clone the list of variable regions. This is used only during NLL processing + /// to put the set of region variables into the NLL region context. pub fn get_region_var_origins(&self) -> VarInfos { let mut inner = self.inner.borrow_mut(); let (var_infos, data) = inner .region_constraint_storage + // We clone instead of taking because borrowck still wants to use + // the inference context after calling this for diagnostics + // and the new trait solver. .clone() .expect("regions already resolved") .with_log(&mut inner.undo_log) @@ -1274,7 +1265,7 @@ impl<'tcx> InferCtxt<'tcx> { if let Some(value) = inner.int_unification_table().probe_value(vid) { value.to_type(self.tcx) } else { - self.tcx.mk_int_var(inner.int_unification_table().find(vid)) + Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid)) } } @@ -1285,7 +1276,7 @@ impl<'tcx> InferCtxt<'tcx> { if let Some(value) = inner.float_unification_table().probe_value(vid) { value.to_type(self.tcx) } else { - self.tcx.mk_float_var(inner.float_unification_table().find(vid)) + Ty::new_float_var(self.tcx, inner.float_unification_table().find(vid)) } } @@ -1468,6 +1459,7 @@ impl<'tcx> InferCtxt<'tcx> { /// universes. Updates `self.universe` to that new universe. pub fn create_next_universe(&self) -> ty::UniverseIndex { let u = self.universe.get().next_universe(); + debug!("create_next_universe {u:?}"); self.universe.set(u); u } @@ -1480,7 +1472,7 @@ impl<'tcx> InferCtxt<'tcx> { span: Option<Span>, ) -> Result<ty::Const<'tcx>, ErrorHandled> { match self.const_eval_resolve(param_env, unevaluated, span) { - Ok(Some(val)) => Ok(self.tcx.mk_const(val, ty)), + Ok(Some(val)) => Ok(ty::Const::new_value(self.tcx, val, ty)), Ok(None) => { let tcx = self.tcx; let def_id = unevaluated.def; @@ -1953,13 +1945,16 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( self.idx += 1; idx }; - self.tcx.mk_placeholder(ty::PlaceholderType { - universe: ty::UniverseIndex::ROOT, - bound: ty::BoundTy { - var: ty::BoundVar::from_u32(idx), - kind: ty::BoundTyKind::Anon, + Ty::new_placeholder( + self.tcx, + ty::PlaceholderType { + universe: ty::UniverseIndex::ROOT, + bound: ty::BoundTy { + var: ty::BoundVar::from_u32(idx), + kind: ty::BoundTyKind::Anon, + }, }, - }) + ) } else { t.super_fold_with(self) } @@ -1972,7 +1967,8 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( if ty.has_non_region_param() || ty.has_non_region_infer() { bug!("const `{c}`'s type should not reference params or types"); } - self.tcx.mk_const( + ty::Const::new_placeholder( + self.tcx, ty::PlaceholderConst { universe: ty::UniverseIndex::ROOT, bound: ty::BoundVar::from_u32({ |