From af466f8542173002361eb134e66102908c7cd024 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 14 Mar 2021 17:25:29 +0100 Subject: Make Ty wrap TyKind in an Arc ... like it will be in Chalk. We still keep `interned_mut` and `into_inner` methods that will probably not exist with Chalk. This worsens performance slightly (5ginstr inference on RA), but doesn't include other simplifications we can do yet. --- crates/hir_ty/src/infer.rs | 30 ++++++++++++++++++++++++------ crates/hir_ty/src/infer/coerce.rs | 2 +- crates/hir_ty/src/infer/expr.rs | 2 +- crates/hir_ty/src/infer/pat.rs | 12 ++++++------ crates/hir_ty/src/infer/unify.rs | 4 ++-- crates/hir_ty/src/lib.rs | 26 +++++++++++++++++--------- crates/hir_ty/src/lower.rs | 2 +- crates/hir_ty/src/traits/chalk/mapping.rs | 2 +- 8 files changed, 53 insertions(+), 27 deletions(-) (limited to 'crates') diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index fbfedb4e6..6dfe53902 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -108,6 +108,17 @@ pub struct TypeMismatch { pub actual: Ty, } +#[derive(Clone, PartialEq, Eq, Debug)] +struct InternedStandardTypes { + unknown: Ty, +} + +impl Default for InternedStandardTypes { + fn default() -> Self { + InternedStandardTypes { unknown: TyKind::Unknown.intern(&Interner) } + } +} + /// The result of type inference: A mapping from expressions and patterns to types. #[derive(Clone, PartialEq, Eq, Debug, Default)] pub struct InferenceResult { @@ -126,6 +137,8 @@ pub struct InferenceResult { pub type_of_expr: ArenaMap, pub type_of_pat: ArenaMap, pub(super) type_mismatches: ArenaMap, + /// Interned Unknown to return references to. + standard_types: InternedStandardTypes, } impl InferenceResult { @@ -170,7 +183,7 @@ impl Index for InferenceResult { type Output = Ty; fn index(&self, expr: ExprId) -> &Ty { - self.type_of_expr.get(expr).unwrap_or(&Ty(TyKind::Unknown)) + self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown) } } @@ -178,7 +191,7 @@ impl Index for InferenceResult { type Output = Ty; fn index(&self, pat: PatId) -> &Ty { - self.type_of_pat.get(pat).unwrap_or(&Ty(TyKind::Unknown)) + self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown) } } @@ -723,14 +736,19 @@ impl Expectation { /// This expresses no expectation on the type. fn none() -> Self { - Expectation { ty: TyKind::Unknown.intern(&Interner), rvalue_hint: false } + Expectation { + // FIXME + ty: TyKind::Unknown.intern(&Interner), + rvalue_hint: false, + } } - fn coercion_target(&self) -> &Ty { + fn coercion_target(&self) -> Ty { if self.rvalue_hint { - &Ty(TyKind::Unknown) + // FIXME + TyKind::Unknown.intern(&Interner) } else { - &self.ty + self.ty.clone() } } } diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 36670043a..435f7d0db 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs @@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> { } // Pointer weakening and function to pointer - match (&mut from_ty.0, to_ty.interned(&Interner)) { + match (from_ty.interned_mut(), to_ty.interned(&Interner)) { // `*mut T` -> `*const T` // `&mut T` -> `&T` (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..)) diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 55163c963..e9ca2b86f 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -800,7 +800,7 @@ impl<'a> InferenceContext<'a> { // we don't even make an attempt at coercion self.table.new_maybe_never_var() } else { - self.coerce(&Ty::unit(), expected.coercion_target()); + self.coerce(&Ty::unit(), &expected.coercion_target()); Ty::unit() } }; diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index a16755cda..2e812ab94 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs @@ -158,11 +158,11 @@ impl<'a> InferenceContext<'a> { if mutability != exp_mut { // FIXME: emit type error? } - inner_ty + inner_ty.clone() } - _ => &Ty(TyKind::Unknown), + _ => self.result.standard_types.unknown.clone(), }; - let subty = self.infer_pat(*pat, expectation, default_bm); + let subty = self.infer_pat(*pat, &expectation, default_bm); TyKind::Ref(mutability, Substs::single(subty)).intern(&Interner) } Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( @@ -232,11 +232,11 @@ impl<'a> InferenceContext<'a> { Pat::Box { inner } => match self.resolve_boxed_box() { Some(box_adt) => { let inner_expected = match expected.as_adt() { - Some((adt, substs)) if adt == box_adt => substs.as_single(), - _ => &Ty(TyKind::Unknown), + Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), + _ => self.result.standard_types.unknown.clone(), }; - let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); + let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); Ty::adt_ty(box_adt, Substs::single(inner_ty)) } None => self.err_ty(), diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index ebc612ca9..2501a4e0a 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -108,7 +108,7 @@ impl Canonicalized { pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { ty.walk_mut_binders( &mut |ty, binders| { - if let &mut TyKind::BoundVar(bound) = &mut ty.0 { + if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { if bound.debruijn >= binders { let (v, k) = self.free_vars[bound.index]; *ty = TyKind::InferenceVar(v, k).intern(&Interner); @@ -404,7 +404,7 @@ impl InferenceTable { if i > 0 { cov_mark::hit!(type_var_resolves_to_int_var); } - match &ty.0 { + match ty.interned(&Interner) { TyKind::InferenceVar(tv, _) => { let inner = tv.to_inner(); match self.var_unification_table.inlined_probe_value(inner).known() { diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 484652073..0b2da8971 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -248,11 +248,11 @@ pub enum TyKind { } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct Ty(TyKind); +pub struct Ty(Arc); impl TyKind { pub fn intern(self, _interner: &Interner) -> Ty { - Ty(self) + Ty(Arc::new(self)) } } @@ -260,6 +260,14 @@ impl Ty { pub fn interned(&self, _interner: &Interner) -> &TyKind { &self.0 } + + pub fn interned_mut(&mut self) -> &mut TyKind { + Arc::make_mut(&mut self.0) + } + + pub fn into_inner(self) -> TyKind { + Arc::try_unwrap(self.0).unwrap_or_else(|a| (*a).clone()) + } } /// A list of substitutions for generic parameters. @@ -814,7 +822,7 @@ impl Ty { /// `self` is `Option<_>` and the substs contain `u32`, we'll have /// `Option` afterwards.) pub fn apply_substs(mut self, new_substs: Substs) -> Ty { - match &mut self.0 { + match self.interned_mut() { TyKind::Adt(_, substs) | TyKind::Slice(substs) | TyKind::Array(substs) @@ -854,7 +862,7 @@ impl Ty { } pub fn substs_mut(&mut self) -> Option<&mut Substs> { - match &mut self.0 { + match self.interned_mut() { TyKind::Adt(_, substs) | TyKind::Slice(substs) | TyKind::Array(substs) @@ -988,7 +996,7 @@ pub trait TypeWalk { { self.walk_mut_binders( &mut |ty_mut, binders| { - let ty = mem::replace(ty_mut, Ty(TyKind::Unknown)); + let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); *ty_mut = f(ty, binders); }, binders, @@ -1001,7 +1009,7 @@ pub trait TypeWalk { Self: Sized, { self.walk_mut(&mut |ty_mut| { - let ty = mem::replace(ty_mut, Ty(TyKind::Unknown)); + let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); *ty_mut = f(ty); }); self @@ -1022,7 +1030,7 @@ pub trait TypeWalk { { self.walk_mut_binders( &mut |ty, binders| { - if let &mut TyKind::BoundVar(bound) = &mut ty.0 { + if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { if bound.debruijn >= binders { *ty = substs.0[bound.index].clone().shift_bound_vars(binders); } @@ -1039,7 +1047,7 @@ pub trait TypeWalk { Self: Sized, { self.fold_binders( - &mut |ty, binders| match &ty.0 { + &mut |ty, binders| match ty.interned(&Interner) { TyKind::BoundVar(bound) if bound.debruijn >= binders => { TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner) } @@ -1084,7 +1092,7 @@ impl TypeWalk for Ty { f: &mut impl FnMut(&mut Ty, DebruijnIndex), binders: DebruijnIndex, ) { - match &mut self.0 { + match self.interned_mut() { TyKind::Alias(AliasTy::Projection(p_ty)) => { p_ty.substitution.walk_mut_binders(f, binders); } diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index d026310f4..2a4ad9172 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -993,7 +993,7 @@ pub(crate) fn generic_defaults_query( // Each default can only refer to previous parameters. ty.walk_mut_binders( - &mut |ty, binders| match &mut ty.0 { + &mut |ty, binders| match ty.interned_mut() { TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { if *index >= idx { // type variable default referring to parameter coming diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 05a4bf0df..2ab976190 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -24,7 +24,7 @@ use super::*; impl ToChalk for Ty { type Chalk = chalk_ir::Ty; fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty { - match self.0 { + match self.into_inner() { TyKind::Ref(m, parameters) => ref_to_chalk(db, m, parameters), TyKind::Array(parameters) => array_to_chalk(db, parameters), TyKind::Function(FnPointer { sig, substs, .. }) => { -- cgit v1.2.3 From 42217738e0b121a8e5d48a9a55cb51ef6c98975f Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 14 Mar 2021 17:40:55 +0100 Subject: Don't use Substs for Ref/Raw/Array/Slice --- crates/hir/src/lib.rs | 34 +++++++++++++--- crates/hir_ty/src/display.rs | 9 ++--- crates/hir_ty/src/infer/coerce.rs | 10 +---- crates/hir_ty/src/infer/expr.rs | 19 ++++----- crates/hir_ty/src/infer/pat.rs | 10 ++--- crates/hir_ty/src/infer/unify.rs | 24 ++++++++--- crates/hir_ty/src/lib.rs | 67 +++++++++---------------------- crates/hir_ty/src/lower.rs | 10 ++--- crates/hir_ty/src/method_resolution.rs | 6 +-- crates/hir_ty/src/traits/chalk/mapping.rs | 30 ++++++-------- 10 files changed, 103 insertions(+), 116 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index eb1cd66fb..c0810c69b 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -1598,7 +1598,7 @@ impl Type { pub fn remove_ref(&self) -> Option { match &self.ty.value.interned(&Interner) { - TyKind::Ref(.., substs) => Some(self.derived(substs[0].clone())), + TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), _ => None, } } @@ -1752,10 +1752,30 @@ impl Type { return go(&self.ty.value); fn go(ty: &Ty) -> bool { - if ty.is_unknown() { - true - } else { - ty.substs().map_or(false, |substs| substs.iter().any(go)) + match ty.interned(&Interner) { + TyKind::Unknown => true, + + TyKind::Adt(_, substs) + | TyKind::AssociatedType(_, substs) + | TyKind::Tuple(_, substs) + | TyKind::OpaqueType(_, substs) + | TyKind::FnDef(_, substs) + | TyKind::Closure(_, substs) => substs.iter().any(go), + + TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { + go(ty) + } + + TyKind::Scalar(_) + | TyKind::Str + | TyKind::Never + | TyKind::Placeholder(_) + | TyKind::BoundVar(_) + | TyKind::InferenceVar(_, _) + | TyKind::Dyn(_) + | TyKind::Function(_) + | TyKind::Alias(_) + | TyKind::ForeignType(_) => false, } } } @@ -1990,6 +2010,10 @@ impl Type { walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); } + TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { + walk_type(db, &type_.derived(ty.clone()), cb); + } + _ => {} } if let Some(substs) = ty.substs() { diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 378c951c5..c1062387e 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -276,20 +276,17 @@ impl HirDisplay for Ty { &TyKind::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, &TyKind::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, &TyKind::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, - TyKind::Slice(parameters) => { - let t = parameters.as_single(); + TyKind::Slice(t) => { write!(f, "[")?; t.hir_fmt(f)?; write!(f, "]")?; } - TyKind::Array(parameters) => { - let t = parameters.as_single(); + TyKind::Array(t) => { write!(f, "[")?; t.hir_fmt(f)?; write!(f, "; _]")?; } - TyKind::Raw(m, parameters) | TyKind::Ref(m, parameters) => { - let t = parameters.as_single(); + TyKind::Raw(m, t) | TyKind::Ref(m, t) => { let ty_display = t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 435f7d0db..137419264 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs @@ -111,9 +111,7 @@ impl<'a> InferenceContext<'a> { // Auto Deref if cannot coerce match (from_ty.interned(&Interner), to_ty.interned(&Interner)) { // FIXME: DerefMut - (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => { - self.unify_autoderef_behind_ref(&st1[0], &st2[0]) - } + (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => self.unify_autoderef_behind_ref(st1, st2), // Otherwise, normal unify _ => self.unify(&from_ty, to_ty), @@ -178,11 +176,7 @@ impl<'a> InferenceContext<'a> { // Stop when constructor matches. if from_ty.equals_ctor(&to_ty) { // It will not recurse to `coerce`. - return match (from_ty.substs(), to_ty.substs()) { - (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0), - (None, None) => true, - _ => false, - }; + return self.table.unify(&from_ty, &to_ty); } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { return true; } diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index e9ca2b86f..8c58a1b6c 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -504,8 +504,8 @@ impl<'a> InferenceContext<'a> { }; let inner_ty = self.infer_expr_inner(*expr, &expectation); match rawness { - Rawness::RawPtr => TyKind::Raw(mutability, Substs::single(inner_ty)), - Rawness::Ref => TyKind::Ref(mutability, Substs::single(inner_ty)), + Rawness::RawPtr => TyKind::Raw(mutability, inner_ty), + Rawness::Ref => TyKind::Ref(mutability, inner_ty), } .intern(&Interner) } @@ -686,7 +686,7 @@ impl<'a> InferenceContext<'a> { } Expr::Array(array) => { let elem_ty = match expected.ty.interned(&Interner) { - TyKind::Array(st) | TyKind::Slice(st) => st.as_single().clone(), + TyKind::Array(st) | TyKind::Slice(st) => st.clone(), _ => self.table.new_type_var(), }; @@ -710,18 +710,17 @@ impl<'a> InferenceContext<'a> { } } - TyKind::Array(Substs::single(elem_ty)).intern(&Interner) + TyKind::Array(elem_ty).intern(&Interner) } Expr::Literal(lit) => match lit { Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner), Literal::String(..) => { - TyKind::Ref(Mutability::Not, Substs::single(TyKind::Str.intern(&Interner))) - .intern(&Interner) + TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner) } Literal::ByteString(..) => { let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner); - let array_type = TyKind::Array(Substs::single(byte_type)).intern(&Interner); - TyKind::Ref(Mutability::Not, Substs::single(array_type)).intern(&Interner) + let array_type = TyKind::Array(byte_type).intern(&Interner); + TyKind::Ref(Mutability::Not, array_type).intern(&Interner) } Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner), Literal::Int(_v, ty) => match ty { @@ -855,9 +854,7 @@ impl<'a> InferenceContext<'a> { // Apply autoref so the below unification works correctly // FIXME: return correct autorefs from lookup_method let actual_receiver_ty = match expected_receiver_ty.as_reference() { - Some((_, mutability)) => { - TyKind::Ref(mutability, Substs::single(derefed_receiver_ty)).intern(&Interner) - } + Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner), _ => derefed_receiver_ty, }; self.unify(&expected_receiver_ty, &actual_receiver_ty); diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index 2e812ab94..9e8ca18ef 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs @@ -163,7 +163,7 @@ impl<'a> InferenceContext<'a> { _ => self.result.standard_types.unknown.clone(), }; let subty = self.infer_pat(*pat, &expectation, default_bm); - TyKind::Ref(mutability, Substs::single(subty)).intern(&Interner) + TyKind::Ref(mutability, subty).intern(&Interner) } Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( p.as_ref(), @@ -196,7 +196,7 @@ impl<'a> InferenceContext<'a> { let bound_ty = match mode { BindingMode::Ref(mutability) => { - TyKind::Ref(mutability, Substs::single(inner_ty.clone())).intern(&Interner) + TyKind::Ref(mutability, inner_ty.clone()).intern(&Interner) } BindingMode::Move => inner_ty.clone(), }; @@ -206,8 +206,8 @@ impl<'a> InferenceContext<'a> { } Pat::Slice { prefix, slice, suffix } => { let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) { - TyKind::Array(st) => (TyKind::Array, st.as_single().clone()), - TyKind::Slice(st) => (TyKind::Slice, st.as_single().clone()), + TyKind::Array(st) => (TyKind::Array, st.clone()), + TyKind::Slice(st) => (TyKind::Slice, st.clone()), _ => (TyKind::Slice, self.err_ty()), }; @@ -215,7 +215,7 @@ impl<'a> InferenceContext<'a> { self.infer_pat(*pat_id, &elem_ty, default_bm); } - let pat_ty = container_ty(Substs::single(elem_ty)).intern(&Interner); + let pat_ty = container_ty(elem_ty).intern(&Interner); if let Some(slice_pat_id) = slice { self.infer_pat(*slice_pat_id, &pat_ty, default_bm); } diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 2501a4e0a..66f8fe8a3 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; use super::{InferenceContext, Obligation}; use crate::{ - BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Interner, - Scalar, Substs, Ty, TyKind, TypeWalk, + BoundVar, Canonical, DebruijnIndex, FnPointer, GenericPredicate, InEnvironment, InferenceVar, + Interner, Scalar, Substs, Ty, TyKind, TypeWalk, }; impl<'a> InferenceContext<'a> { @@ -283,9 +283,23 @@ impl InferenceTable { let ty1 = self.resolve_ty_shallow(ty1); let ty2 = self.resolve_ty_shallow(ty2); if ty1.equals_ctor(&ty2) { - match (ty1.substs(), ty2.substs()) { - (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1), - (None, None) => true, + match (ty1.interned(&Interner), ty2.interned(&Interner)) { + (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2)) + | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2)) + | ( + TyKind::Function(FnPointer { substs: substs1, .. }), + TyKind::Function(FnPointer { substs: substs2, .. }), + ) + | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2)) + | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2)) + | (TyKind::AssociatedType(_, substs1), TyKind::AssociatedType(_, substs2)) + | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => { + self.unify_substs(substs1, substs2, depth + 1) + } + (TyKind::Ref(_, ty1), TyKind::Ref(_, ty2)) + | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2)) + | (TyKind::Array(ty1), TyKind::Array(ty2)) + | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1), _ => false, } } else { diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 0b2da8971..503910dde 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -151,17 +151,17 @@ pub enum TyKind { Tuple(usize, Substs), /// An array with the given length. Written as `[T; n]`. - Array(Substs), + Array(Ty), /// The pointee of an array slice. Written as `[T]`. - Slice(Substs), + Slice(Ty), /// A raw pointer. Written as `*mut T` or `*const T` - Raw(Mutability, Substs), + Raw(Mutability, Ty), /// A reference; a pointer with an associated lifetime. Written as /// `&'a mut T` or `&'a T`. - Ref(Mutability, Substs), + Ref(Mutability, Ty), /// This represents a placeholder for an opaque type in situations where we /// don't know the hidden type (i.e. currently almost always). This is @@ -673,19 +673,15 @@ impl Ty { pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { match self.interned(&Interner) { - TyKind::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), + TyKind::Ref(mutability, ty) => Some((ty, *mutability)), _ => None, } } pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { match self.interned(&Interner) { - TyKind::Ref(mutability, parameters) => { - Some((parameters.as_single(), Rawness::Ref, *mutability)) - } - TyKind::Raw(mutability, parameters) => { - Some((parameters.as_single(), Rawness::RawPtr, *mutability)) - } + TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)), + TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)), _ => None, } } @@ -693,8 +689,8 @@ impl Ty { pub fn strip_references(&self) -> &Ty { let mut t: &Ty = self; - while let TyKind::Ref(_mutability, parameters) = t.interned(&Interner) { - t = parameters.as_single(); + while let TyKind::Ref(_mutability, ty) = t.interned(&Interner) { + t = ty; } t @@ -780,8 +776,8 @@ impl Ty { fn builtin_deref(&self) -> Option { match self.interned(&Interner) { - TyKind::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), - TyKind::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), + TyKind::Ref(.., ty) => Some(ty.clone()), + TyKind::Raw(.., ty) => Some(ty.clone()), _ => None, } } @@ -817,40 +813,11 @@ impl Ty { } } - /// If this is a type with type parameters (an ADT or function), replaces - /// the `Substs` for these type parameters with the given ones. (So e.g. if - /// `self` is `Option<_>` and the substs contain `u32`, we'll have - /// `Option` afterwards.) - pub fn apply_substs(mut self, new_substs: Substs) -> Ty { - match self.interned_mut() { - TyKind::Adt(_, substs) - | TyKind::Slice(substs) - | TyKind::Array(substs) - | TyKind::Raw(_, substs) - | TyKind::Ref(_, substs) - | TyKind::FnDef(_, substs) - | TyKind::Function(FnPointer { substs, .. }) - | TyKind::Tuple(_, substs) - | TyKind::OpaqueType(_, substs) - | TyKind::AssociatedType(_, substs) - | TyKind::Closure(.., substs) => { - assert_eq!(substs.len(), new_substs.len()); - *substs = new_substs; - } - _ => (), - } - self - } - /// Returns the type parameters of this type if it has some (i.e. is an ADT /// or function); so if `self` is `Option`, this returns the `u32`. pub fn substs(&self) -> Option<&Substs> { match self.interned(&Interner) { TyKind::Adt(_, substs) - | TyKind::Slice(substs) - | TyKind::Array(substs) - | TyKind::Raw(_, substs) - | TyKind::Ref(_, substs) | TyKind::FnDef(_, substs) | TyKind::Function(FnPointer { substs, .. }) | TyKind::Tuple(_, substs) @@ -861,13 +828,9 @@ impl Ty { } } - pub fn substs_mut(&mut self) -> Option<&mut Substs> { + fn substs_mut(&mut self) -> Option<&mut Substs> { match self.interned_mut() { TyKind::Adt(_, substs) - | TyKind::Slice(substs) - | TyKind::Array(substs) - | TyKind::Raw(_, substs) - | TyKind::Ref(_, substs) | TyKind::FnDef(_, substs) | TyKind::Function(FnPointer { substs, .. }) | TyKind::Tuple(_, substs) @@ -1076,6 +1039,9 @@ impl TypeWalk for Ty { p.walk(f); } } + TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { + ty.walk(f); + } _ => { if let Some(substs) = self.substs() { for t in substs.iter() { @@ -1104,6 +1070,9 @@ impl TypeWalk for Ty { TyKind::Alias(AliasTy::Opaque(o_ty)) => { o_ty.substitution.walk_mut_binders(f, binders); } + TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { + ty.walk_mut_binders(f, binders); + } _ => { if let Some(substs) = self.substs_mut() { substs.walk_mut_binders(f, binders); diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 2a4ad9172..b4c650fa1 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -160,21 +160,19 @@ impl<'a> TyLoweringContext<'a> { } TypeRef::RawPtr(inner, mutability) => { let inner_ty = self.lower_ty(inner); - TyKind::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) - .intern(&Interner) + TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner) } TypeRef::Array(inner) => { let inner_ty = self.lower_ty(inner); - TyKind::Array(Substs::single(inner_ty)).intern(&Interner) + TyKind::Array(inner_ty).intern(&Interner) } TypeRef::Slice(inner) => { let inner_ty = self.lower_ty(inner); - TyKind::Slice(Substs::single(inner_ty)).intern(&Interner) + TyKind::Slice(inner_ty).intern(&Interner) } TypeRef::Reference(inner, _, mutability) => { let inner_ty = self.lower_ty(inner); - TyKind::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) - .intern(&Interner) + TyKind::Ref(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner) } TypeRef::Placeholder => TyKind::Unknown.intern(&Interner), TypeRef::Fn(params, is_varargs) => { diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index c7055bee5..741440006 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -435,8 +435,7 @@ fn iterate_method_candidates_with_autoref( } let refed = Canonical { kinds: deref_chain[0].kinds.clone(), - value: TyKind::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())) - .intern(&Interner), + value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner), }; if iterate_method_candidates_by_receiver( &refed, @@ -452,8 +451,7 @@ fn iterate_method_candidates_with_autoref( } let ref_muted = Canonical { kinds: deref_chain[0].kinds.clone(), - value: TyKind::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())) - .intern(&Interner), + value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner), }; if iterate_method_candidates_by_receiver( &ref_muted, diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 2ab976190..6a8b6752e 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -25,8 +25,8 @@ impl ToChalk for Ty { type Chalk = chalk_ir::Ty; fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty { match self.into_inner() { - TyKind::Ref(m, parameters) => ref_to_chalk(db, m, parameters), - TyKind::Array(parameters) => array_to_chalk(db, parameters), + TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty), + TyKind::Array(ty) => array_to_chalk(db, ty), TyKind::Function(FnPointer { sig, substs, .. }) => { let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); chalk_ir::TyKind::Function(chalk_ir::FnPointer { @@ -54,13 +54,11 @@ impl ToChalk for Ty { let substitution = substs.to_chalk(db); chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) } - TyKind::Raw(mutability, substs) => { - let ty = substs[0].clone().to_chalk(db); + TyKind::Raw(mutability, ty) => { + let ty = ty.to_chalk(db); chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner) } - TyKind::Slice(substs) => { - chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner) - } + TyKind::Slice(ty) => chalk_ir::TyKind::Slice(ty.to_chalk(db)).intern(&Interner), TyKind::Str => chalk_ir::TyKind::Str.intern(&Interner), TyKind::FnDef(id, substs) => { let substitution = substs.to_chalk(db); @@ -114,7 +112,7 @@ impl ToChalk for Ty { fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty) -> Self { match chalk.data(&Interner).kind.clone() { chalk_ir::TyKind::Error => TyKind::Unknown, - chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(Substs::single(from_chalk(db, ty))), + chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(from_chalk(db, ty)), chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx), chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => { let associated_ty = proj.associated_ty_id; @@ -168,12 +166,10 @@ impl ToChalk for Ty { chalk_ir::TyKind::Tuple(cardinality, subst) => { TyKind::Tuple(cardinality, from_chalk(db, subst)) } - chalk_ir::TyKind::Raw(mutability, ty) => { - TyKind::Raw(mutability, Substs::single(from_chalk(db, ty))) - } - chalk_ir::TyKind::Slice(ty) => TyKind::Slice(Substs::single(from_chalk(db, ty))), + chalk_ir::TyKind::Raw(mutability, ty) => TyKind::Raw(mutability, from_chalk(db, ty)), + chalk_ir::TyKind::Slice(ty) => TyKind::Slice(from_chalk(db, ty)), chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { - TyKind::Ref(mutability, Substs::single(from_chalk(db, ty))) + TyKind::Ref(mutability, from_chalk(db, ty)) } chalk_ir::TyKind::Str => TyKind::Str, chalk_ir::TyKind::Never => TyKind::Never, @@ -197,17 +193,17 @@ impl ToChalk for Ty { fn ref_to_chalk( db: &dyn HirDatabase, mutability: chalk_ir::Mutability, - subst: Substs, + ty: Ty, ) -> chalk_ir::Ty { - let arg = subst[0].clone().to_chalk(db); + let arg = ty.to_chalk(db); let lifetime = LifetimeData::Static.intern(&Interner); chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner) } /// We currently don't model constants, but Chalk does. So, we have to insert a /// fake constant here, because Chalks built-in logic may expect it to be there. -fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty { - let arg = subst[0].clone().to_chalk(db); +fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty { + let arg = ty.to_chalk(db); let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); let const_ = chalk_ir::ConstData { ty: usize_ty, -- cgit v1.2.3