From 290651be72ef3c33c47ac73093b26f752e213f6d Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 16 Jan 2024 11:06:42 +0100 Subject: [PATCH] don't store const var origins for known vars --- .../infer/error_reporting/need_type_info.rs | 33 ++++--- compiler/rustc_infer/src/infer/freshen.rs | 10 +-- compiler/rustc_infer/src/infer/fudge.rs | 11 ++- compiler/rustc_infer/src/infer/mod.rs | 21 ++--- .../rustc_infer/src/infer/relate/combine.rs | 26 +++--- .../src/infer/relate/generalize.rs | 15 ++-- compiler/rustc_infer/src/infer/resolve.rs | 90 +------------------ compiler/rustc_middle/src/infer/unify_key.rs | 29 +++--- 8 files changed, 70 insertions(+), 165 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 4aefadf590dd4..6e1889d3538da 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -13,7 +13,9 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource}; use rustc_middle::hir::nested_filter; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::{ + ConstVariableOrigin, ConstVariableOriginKind, ConstVariableValue, +}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::{self, InferConst}; @@ -178,17 +180,23 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte } }; printer.ty_infer_name_resolver = Some(Box::new(ty_getter)); - let const_getter = move |ct_vid| { - if infcx.probe_const_var(ct_vid).is_ok() { + let const_getter = move |ct_vid| match infcx + .inner + .borrow_mut() + .const_unification_table() + .probe_value(ct_vid) + { + ConstVariableValue::Known { value: _ } => { warn!("resolved const var in error message"); - } - if let ConstVariableOriginKind::ConstParameterDefinition(name, _) = - infcx.inner.borrow_mut().const_unification_table().probe_value(ct_vid).origin.kind - { - return Some(name); - } else { None } + ConstVariableValue::Unknown { origin, universe: _ } => { + if let ConstVariableOriginKind::ConstParameterDefinition(name, _) = origin.kind { + return Some(name); + } else { + None + } + } }; printer.const_infer_name_resolver = Some(Box::new(const_getter)); printer @@ -303,7 +311,12 @@ impl<'tcx> InferCtxt<'tcx> { GenericArgKind::Const(ct) => { if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() { let origin = - self.inner.borrow_mut().const_unification_table().probe_value(vid).origin; + match self.inner.borrow_mut().const_unification_table().probe_value(vid) { + ConstVariableValue::Known { value } => { + bug!("resolved infer var: {vid:?} {value}") + } + ConstVariableValue::Unknown { origin, universe: _ } => origin, + }; if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) = origin.kind { diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index c7cab048db1ba..d256994d8d1fd 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -146,14 +146,8 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { match ct.kind() { ty::ConstKind::Infer(ty::InferConst::Var(v)) => { - let opt_ct = self - .infcx - .inner - .borrow_mut() - .const_unification_table() - .probe_value(v) - .val - .known(); + let opt_ct = + self.infcx.inner.borrow_mut().const_unification_table().probe_value(v).known(); self.freshen_const(opt_ct, ty::InferConst::Var(v), ty::InferConst::Fresh, ct.ty()) } ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => { diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index 8ca97ae1b8e5d..99033922bdf76 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -1,4 +1,4 @@ -use rustc_middle::infer::unify_key::ConstVidKey; +use rustc_middle::infer::unify_key::{ConstVariableOriginKind, ConstVariableValue, ConstVidKey}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; @@ -28,10 +28,17 @@ fn const_vars_since_snapshot<'tcx>( snapshot_var_len: usize, ) -> (Range, Vec) { let range = vars_since_snapshot(table, snapshot_var_len); + ( range.start.vid..range.end.vid, (range.start.index()..range.end.index()) - .map(|index| table.probe_value(ConstVid::from_u32(index)).origin) + .map(|index| match table.probe_value(ConstVid::from_u32(index)) { + ConstVariableValue::Known { value: _ } => ConstVariableOrigin { + kind: ConstVariableOriginKind::MiscVariable, + span: rustc_span::DUMMY_SP, + }, + ConstVariableValue::Unknown { origin, universe: _ } => origin, + }) .collect(), ) } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index e164041c5991e..002aad19c4981 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -23,8 +23,8 @@ use rustc_data_structures::unify as ut; use rustc_errors::{DiagCtxt, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; -use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; +use rustc_middle::infer::unify_key::{ConstVariableValue, EffectVarValue}; use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::{select, DefiningAnchor}; @@ -1086,7 +1086,7 @@ impl<'tcx> InferCtxt<'tcx> { .inner .borrow_mut() .const_unification_table() - .new_key(ConstVarValue { origin, val: ConstVariableValue::Unknown { universe } }) + .new_key(ConstVariableValue::Unknown { origin, universe }) .vid; ty::Const::new_var(self.tcx, vid, ty) } @@ -1095,10 +1095,7 @@ impl<'tcx> InferCtxt<'tcx> { self.inner .borrow_mut() .const_unification_table() - .new_key(ConstVarValue { - origin, - val: ConstVariableValue::Unknown { universe: self.universe() }, - }) + .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() }) .vid } @@ -1217,10 +1214,7 @@ impl<'tcx> InferCtxt<'tcx> { .inner .borrow_mut() .const_unification_table() - .new_key(ConstVarValue { - origin, - val: ConstVariableValue::Unknown { universe: self.universe() }, - }) + .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() }) .vid; ty::Const::new_var( self.tcx, @@ -1410,9 +1404,9 @@ impl<'tcx> InferCtxt<'tcx> { } pub fn probe_const_var(&self, vid: ty::ConstVid) -> Result, ty::UniverseIndex> { - match self.inner.borrow_mut().const_unification_table().probe_value(vid).val { + match self.inner.borrow_mut().const_unification_table().probe_value(vid) { ConstVariableValue::Known { value } => Ok(value), - ConstVariableValue::Unknown { universe } => Err(universe), + ConstVariableValue::Unknown { origin: _, universe } => Err(universe), } } @@ -1709,7 +1703,7 @@ impl<'tcx> InferCtxt<'tcx> { // `ty::ConstKind::Infer(ty::InferConst::Var(v))`. // // Not `inlined_probe_value(v)` because this call site is colder. - match self.inner.borrow_mut().const_unification_table().probe_value(v).val { + match self.inner.borrow_mut().const_unification_table().probe_value(v) { ConstVariableValue::Unknown { .. } => false, ConstVariableValue::Known { .. } => true, } @@ -1876,7 +1870,6 @@ impl<'a, 'tcx> TypeFolder> for ShallowResolver<'a, 'tcx> { .borrow_mut() .const_unification_table() .probe_value(vid) - .val .known() .unwrap_or(ct), ty::ConstKind::Infer(InferConst::EffectVar(vid)) => self diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 4b254fc7df518..9e1dab12b4d43 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -30,14 +30,12 @@ use super::sub::Sub; use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace}; use crate::traits::{Obligation, PredicateObligations}; use rustc_middle::infer::canonical::OriginalQueryValues; -use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue}; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::{ConstVariableValue, EffectVarValue}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{RelateResult, TypeRelation}; use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{AliasRelationDirection, TyVar}; use rustc_middle::ty::{IntType, UintType}; -use rustc_span::DUMMY_SP; #[derive(Clone)] pub struct CombineFields<'infcx, 'tcx> { @@ -328,8 +326,12 @@ impl<'tcx> InferCtxt<'tcx> { ct: ty::Const<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { - let span = - self.inner.borrow_mut().const_unification_table().probe_value(target_vid).origin.span; + let span = match self.inner.borrow_mut().const_unification_table().probe_value(target_vid) { + ConstVariableValue::Known { value } => { + bug!("instantiating a known const var: {target_vid:?} {value} {ct}") + } + ConstVariableValue::Unknown { origin, universe: _ } => origin.span, + }; // FIXME(generic_const_exprs): Occurs check failures for unevaluated // constants and generic expressions are not yet handled correctly. let Generalization { value_may_be_infer: value, needs_wf: _ } = generalize::generalize( @@ -340,16 +342,10 @@ impl<'tcx> InferCtxt<'tcx> { ty::Variance::Invariant, )?; - self.inner.borrow_mut().const_unification_table().union_value( - target_vid, - ConstVarValue { - origin: ConstVariableOrigin { - kind: ConstVariableOriginKind::ConstInference, - span: DUMMY_SP, - }, - val: ConstVariableValue::Known { value }, - }, - ); + self.inner + .borrow_mut() + .const_unification_table() + .union_value(target_vid, ConstVariableValue::Known { value }); Ok(value) } diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 27d37fd93697e..417c8695e248b 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -3,7 +3,7 @@ use std::mem; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; -use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue}; +use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::visit::MaxUniverse; @@ -431,22 +431,19 @@ where let mut inner = self.infcx.inner.borrow_mut(); let variable_table = &mut inner.const_unification_table(); - let var_value = variable_table.probe_value(vid); - match var_value.val { + match variable_table.probe_value(vid) { ConstVariableValue::Known { value: u } => { drop(inner); self.relate(u, u) } - ConstVariableValue::Unknown { universe } => { + ConstVariableValue::Unknown { origin, universe } => { if self.for_universe.can_name(universe) { Ok(c) } else { let new_var_id = variable_table - .new_key(ConstVarValue { - origin: var_value.origin, - val: ConstVariableValue::Unknown { - universe: self.for_universe, - }, + .new_key(ConstVariableValue::Unknown { + origin, + universe: self.for_universe, }) .vid; Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty())) diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index f317ccee6918a..959b09031277c 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,12 +1,8 @@ -use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use super::{FixupError, FixupResult, InferCtxt, Span}; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use super::{FixupError, FixupResult, InferCtxt}; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitableExt, TypeVisitor}; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; -use std::ops::ControlFlow; - /////////////////////////////////////////////////////////////////////////// // OPPORTUNISTIC VAR RESOLVER @@ -104,88 +100,6 @@ impl<'a, 'tcx> TypeFolder> for OpportunisticRegionResolver<'a, 'tcx } } -/////////////////////////////////////////////////////////////////////////// -// UNRESOLVED TYPE FINDER - -/// The unresolved type **finder** walks a type searching for -/// type variables that don't yet have a value. The first unresolved type is stored. -/// It does not construct the fully resolved type (which might -/// involve some hashing and so forth). -pub struct UnresolvedTypeOrConstFinder<'a, 'tcx> { - infcx: &'a InferCtxt<'tcx>, -} - -impl<'a, 'tcx> UnresolvedTypeOrConstFinder<'a, 'tcx> { - pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { - UnresolvedTypeOrConstFinder { infcx } - } -} - -impl<'a, 'tcx> TypeVisitor> for UnresolvedTypeOrConstFinder<'a, 'tcx> { - type BreakTy = (ty::Term<'tcx>, Option); - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - let t = self.infcx.shallow_resolve(t); - if let ty::Infer(infer_ty) = *t.kind() { - // Since we called `shallow_resolve` above, this must - // be an (as yet...) unresolved inference variable. - let ty_var_span = if let ty::TyVar(ty_vid) = infer_ty { - let mut inner = self.infcx.inner.borrow_mut(); - let ty_vars = &inner.type_variables(); - if let TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeParameterDefinition(_, _), - span, - } = ty_vars.var_origin(ty_vid) - { - Some(span) - } else { - None - } - } else { - None - }; - ControlFlow::Break((t.into(), ty_var_span)) - } else if !t.has_non_region_infer() { - // All const/type variables in inference types must already be resolved, - // no need to visit the contents. - ControlFlow::Continue(()) - } else { - // Otherwise, keep visiting. - t.super_visit_with(self) - } - } - - fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow { - let ct = self.infcx.shallow_resolve(ct); - if let ty::ConstKind::Infer(i) = ct.kind() { - // Since we called `shallow_resolve` above, this must - // be an (as yet...) unresolved inference variable. - let ct_var_span = if let ty::InferConst::Var(vid) = i { - let mut inner = self.infcx.inner.borrow_mut(); - let ct_vars = &mut inner.const_unification_table(); - if let ConstVariableOrigin { - span, - kind: ConstVariableOriginKind::ConstParameterDefinition(_, _), - } = ct_vars.probe_value(vid).origin - { - Some(span) - } else { - None - } - } else { - None - }; - ControlFlow::Break((ct.into(), ct_var_span)) - } else if !ct.has_non_region_infer() { - // All const/type variables in inference types must already be resolved, - // no need to visit the contents. - ControlFlow::Continue(()) - } else { - // Otherwise, keep visiting. - ct.super_visit_with(self) - } - } -} - /////////////////////////////////////////////////////////////////////////// // FULL TYPE RESOLUTION diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 6e50e89404648..c35799ef47f2b 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -120,7 +120,7 @@ pub enum ConstVariableOriginKind { #[derive(Copy, Clone, Debug)] pub enum ConstVariableValue<'tcx> { Known { value: ty::Const<'tcx> }, - Unknown { universe: ty::UniverseIndex }, + Unknown { origin: ConstVariableOrigin, universe: ty::UniverseIndex }, } impl<'tcx> ConstVariableValue<'tcx> { @@ -134,12 +134,6 @@ impl<'tcx> ConstVariableValue<'tcx> { } } -#[derive(Copy, Clone, Debug)] -pub struct ConstVarValue<'tcx> { - pub origin: ConstVariableOrigin, - pub val: ConstVariableValue<'tcx>, -} - #[derive(PartialEq, Copy, Clone, Debug)] pub struct ConstVidKey<'tcx> { pub vid: ty::ConstVid, @@ -153,7 +147,7 @@ impl<'tcx> From for ConstVidKey<'tcx> { } impl<'tcx> UnifyKey for ConstVidKey<'tcx> { - type Value = ConstVarValue<'tcx>; + type Value = ConstVariableValue<'tcx>; #[inline] fn index(&self) -> u32 { self.vid.as_u32() @@ -167,23 +161,23 @@ impl<'tcx> UnifyKey for ConstVidKey<'tcx> { } } -impl<'tcx> UnifyValue for ConstVarValue<'tcx> { +impl<'tcx> UnifyValue for ConstVariableValue<'tcx> { type Error = NoError; fn unify_values(&value1: &Self, &value2: &Self) -> Result { - Ok(match (value1.val, value2.val) { + match (value1, value2) { (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => { bug!("equating two const variables, both of which have known values") } // If one side is known, prefer that one. - (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => value1, - (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => value2, + (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => Ok(value1), + (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => Ok(value2), // If both sides are *unknown*, it hardly matters, does it? ( - ConstVariableValue::Unknown { universe: universe1 }, - ConstVariableValue::Unknown { universe: universe2 }, + ConstVariableValue::Unknown { origin, universe: universe1 }, + ConstVariableValue::Unknown { origin: _, universe: universe2 }, ) => { // If we unify two unbound variables, ?T and ?U, then whatever // value they wind up taking (which must be the same value) must @@ -191,12 +185,9 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> { // universe is the minimum of the two universes, because that is // the one which contains the fewest names in scope. let universe = cmp::min(universe1, universe2); - ConstVarValue { - val: ConstVariableValue::Unknown { universe }, - origin: value1.origin, - } + Ok(ConstVariableValue::Unknown { origin, universe }) } - }) + } } }