inline CanonicalTyVarKind

This commit is contained in:
lcnr 2025-04-28 17:21:36 +00:00
parent 67965f817d
commit 2cb04b960f
6 changed files with 58 additions and 83 deletions

View file

@ -17,7 +17,7 @@ use tracing::debug;
use crate::infer::InferCtxt;
use crate::infer::canonical::{
Canonical, CanonicalQueryInput, CanonicalTyVarKind, CanonicalVarKind, OriginalQueryValues,
Canonical, CanonicalQueryInput, CanonicalVarKind, OriginalQueryValues,
};
impl<'tcx> InferCtxt<'tcx> {
@ -361,10 +361,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
// FIXME: perf problem described in #55921.
ui = ty::UniverseIndex::ROOT;
}
self.canonicalize_ty_var(
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
t,
)
self.canonicalize_ty_var(CanonicalVarKind::Ty(ui), t)
}
}
}
@ -374,7 +371,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
if nt != t {
return self.fold_ty(nt);
} else {
self.canonicalize_ty_var(CanonicalVarKind::Ty(CanonicalTyVarKind::Int), t)
self.canonicalize_ty_var(CanonicalVarKind::Int, t)
}
}
ty::Infer(ty::FloatVar(vid)) => {
@ -382,7 +379,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
if nt != t {
return self.fold_ty(nt);
} else {
self.canonicalize_ty_var(CanonicalVarKind::Ty(CanonicalTyVarKind::Float), t)
self.canonicalize_ty_var(CanonicalVarKind::Float, t)
}
}
@ -679,12 +676,10 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
self.variables
.iter()
.map(|&kind| match kind {
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
CanonicalVarKind::Int | CanonicalVarKind::Float => {
return kind;
}
CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
CanonicalVarKind::Ty(CanonicalTyVarKind::General(reverse_universe_map[&u]))
}
CanonicalVarKind::Ty(u) => CanonicalVarKind::Ty(reverse_universe_map[&u]),
CanonicalVarKind::Region(u) => CanonicalVarKind::Region(reverse_universe_map[&u]),
CanonicalVarKind::Const(u) => CanonicalVarKind::Const(reverse_universe_map[&u]),
CanonicalVarKind::PlaceholderTy(placeholder) => {

View file

@ -108,18 +108,11 @@ impl<'tcx> InferCtxt<'tcx> {
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
) -> GenericArg<'tcx> {
match kind {
CanonicalVarKind::Ty(ty_kind) => {
let ty = match ty_kind {
CanonicalTyVarKind::General(ui) => {
self.next_ty_var_in_universe(span, universe_map(ui))
}
CanonicalVarKind::Ty(ui) => self.next_ty_var_in_universe(span, universe_map(ui)).into(),
CanonicalTyVarKind::Int => self.next_int_var(),
CanonicalVarKind::Int => self.next_int_var().into(),
CanonicalTyVarKind::Float => self.next_float_var(),
};
ty.into()
}
CanonicalVarKind::Float => self.next_float_var().into(),
CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, bound }) => {
let universe_mapped = universe_map(universe);

View file

@ -27,7 +27,6 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lock;
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
pub use rustc_type_ir as ir;
pub use rustc_type_ir::CanonicalTyVarKind;
use smallvec::SmallVec;
use crate::mir::ConstraintCategory;

View file

@ -2,9 +2,8 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
use rustc_type_ir::inherent::*;
use rustc_type_ir::solve::{Goal, QueryInput};
use rustc_type_ir::{
self as ty, Canonical, CanonicalParamEnvCacheEntry, CanonicalTyVarKind, CanonicalVarKind,
Flags, InferCtxtLike, Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt,
self as ty, Canonical, CanonicalParamEnvCacheEntry, CanonicalVarKind, Flags, InferCtxtLike,
Interner, TypeFlags, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
};
use crate::delegate::SolverDelegate;
@ -314,14 +313,12 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
);
match self.canonicalize_mode {
CanonicalizeMode::Input { .. } => CanonicalVarKind::Ty(
CanonicalTyVarKind::General(ty::UniverseIndex::ROOT),
),
CanonicalizeMode::Input { .. } => {
CanonicalVarKind::Ty(ty::UniverseIndex::ROOT)
}
CanonicalizeMode::Response { .. } => {
CanonicalVarKind::Ty(CanonicalTyVarKind::General(
self.delegate.universe_of_ty(vid).unwrap_or_else(|| {
panic!("ty var should have been resolved: {t:?}")
}),
CanonicalVarKind::Ty(self.delegate.universe_of_ty(vid).unwrap_or_else(
|| panic!("ty var should have been resolved: {t:?}"),
))
}
}
@ -332,7 +329,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
t,
"ty vid should have been resolved fully before canonicalization"
);
CanonicalVarKind::Ty(CanonicalTyVarKind::Int)
CanonicalVarKind::Int
}
ty::FloatVar(vid) => {
debug_assert_eq!(
@ -340,7 +337,7 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
t,
"ty vid should have been resolved fully before canonicalization"
);
CanonicalVarKind::Ty(CanonicalTyVarKind::Float)
CanonicalVarKind::Float
}
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
panic!("fresh vars not expected in canonicalization")

View file

@ -1,5 +1,4 @@
use std::fmt;
use std::hash::Hash;
use std::ops::Index;
use derive_where::derive_where;
@ -91,8 +90,14 @@ impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
)]
pub enum CanonicalVarKind<I: Interner> {
/// Some kind of type inference variable.
Ty(CanonicalTyVarKind),
/// General type variable `?T` that can be unified with arbitrary types.
Ty(UniverseIndex),
/// Integral type variable `?I` (that can only be unified with integral types).
Int,
/// Floating-point type variable `?F` (that can only be unified with float types).
Float,
/// A "placeholder" that represents "any type".
PlaceholderTy(I::PlaceholderTy),
@ -117,15 +122,13 @@ impl<I: Interner> Eq for CanonicalVarKind<I> {}
impl<I: Interner> CanonicalVarKind<I> {
pub fn universe(self) -> UniverseIndex {
match self {
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui,
CanonicalVarKind::Ty(ui) => ui,
CanonicalVarKind::Region(ui) => ui,
CanonicalVarKind::Const(ui) => ui,
CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(),
CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(),
CanonicalVarKind::PlaceholderConst(placeholder) => placeholder.universe(),
CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => {
UniverseIndex::ROOT
}
CanonicalVarKind::Float | CanonicalVarKind::Int => UniverseIndex::ROOT,
}
}
@ -135,9 +138,7 @@ impl<I: Interner> CanonicalVarKind<I> {
/// the updated universe is not the root.
pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind<I> {
match self {
CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => {
CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui))
}
CanonicalVarKind::Ty(_) => CanonicalVarKind::Ty(ui),
CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui),
CanonicalVarKind::Const(_) => CanonicalVarKind::Const(ui),
@ -150,7 +151,7 @@ impl<I: Interner> CanonicalVarKind<I> {
CanonicalVarKind::PlaceholderConst(placeholder) => {
CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui))
}
CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
CanonicalVarKind::Int | CanonicalVarKind::Float => {
assert_eq!(ui, UniverseIndex::ROOT);
self
}
@ -159,12 +160,14 @@ impl<I: Interner> CanonicalVarKind<I> {
pub fn is_existential(self) -> bool {
match self {
CanonicalVarKind::Ty(_) => true,
CanonicalVarKind::PlaceholderTy(_) => false,
CanonicalVarKind::Region(_) => true,
CanonicalVarKind::PlaceholderRegion(..) => false,
CanonicalVarKind::Const(_) => true,
CanonicalVarKind::PlaceholderConst(_) => false,
CanonicalVarKind::Ty(_)
| CanonicalVarKind::Int
| CanonicalVarKind::Float
| CanonicalVarKind::Region(_)
| CanonicalVarKind::Const(_) => true,
CanonicalVarKind::PlaceholderTy(_)
| CanonicalVarKind::PlaceholderRegion(..)
| CanonicalVarKind::PlaceholderConst(_) => false,
}
}
@ -172,6 +175,8 @@ impl<I: Interner> CanonicalVarKind<I> {
match self {
CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true,
CanonicalVarKind::Ty(_)
| CanonicalVarKind::Int
| CanonicalVarKind::Float
| CanonicalVarKind::PlaceholderTy(_)
| CanonicalVarKind::Const(_)
| CanonicalVarKind::PlaceholderConst(_) => false,
@ -180,7 +185,11 @@ impl<I: Interner> CanonicalVarKind<I> {
pub fn expect_placeholder_index(self) -> usize {
match self {
CanonicalVarKind::Ty(_) | CanonicalVarKind::Region(_) | CanonicalVarKind::Const(_) => {
CanonicalVarKind::Ty(_)
| CanonicalVarKind::Int
| CanonicalVarKind::Float
| CanonicalVarKind::Region(_)
| CanonicalVarKind::Const(_) => {
panic!("expected placeholder: {self:?}")
}
@ -191,27 +200,6 @@ impl<I: Interner> CanonicalVarKind<I> {
}
}
/// Rust actually has more than one category of type variables;
/// notably, the type variables we create for literals (e.g., 22 or
/// 22.) can only be instantiated with integral/float types (e.g.,
/// usize or f32). In order to faithfully reproduce a type, we need to
/// know what set of types a given type variable can be unified with.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "nightly",
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
)]
pub enum CanonicalTyVarKind {
/// General type variable `?T` that can be unified with arbitrary types.
General(UniverseIndex),
/// Integral type variable `?I` (that can only be unified with integral types).
Int,
/// Floating-point type variable `?F` (that can only be unified with float types).
Float,
}
/// A set of values corresponding to the canonical variables from some
/// `Canonical`. You can give these values to
/// `canonical_value.instantiate` to instantiate them into the canonical
@ -287,7 +275,10 @@ impl<I: Interner> CanonicalVarValues<I> {
var_values: cx.mk_args_from_iter(infos.iter().enumerate().map(
|(i, kind)| -> I::GenericArg {
match kind {
CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
CanonicalVarKind::Ty(_)
| CanonicalVarKind::Int
| CanonicalVarKind::Float
| CanonicalVarKind::PlaceholderTy(_) => {
Ty::new_anon_bound(cx, ty::INNERMOST, ty::BoundVar::from_usize(i))
.into()
}

View file

@ -1,30 +1,30 @@
// MIR for `address_of_reborrow` after SimplifyCfg-initial
| User Type Annotations
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10]
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:8:10: 8:18, inferred_ty: *const [i32; 10]
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:10:10: 10:25, inferred_ty: *const dyn std::marker::Send
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10]
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:19:10: 19:18, inferred_ty: *const [i32; 10]
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:21:10: 21:25, inferred_ty: *const dyn std::marker::Send
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10]
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:29:10: 29:16, inferred_ty: *mut [i32; 10]
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:31:10: 31:23, inferred_ty: *mut dyn std::marker::Send
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(General(U0))] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [Ty(U0)] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [Region(U0)] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send