aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs607
1 files changed, 268 insertions, 339 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 50d248674..c2a20c480 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -25,32 +25,29 @@ mod test_db;
25 25
26use std::{iter, mem, ops::Deref, sync::Arc}; 26use std::{iter, mem, ops::Deref, sync::Arc};
27 27
28use base_db::{salsa, CrateId}; 28use base_db::salsa;
29use hir_def::{ 29use hir_def::{
30 builtin_type::BuiltinType, 30 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AdtId, AssocContainerId,
31 expr::ExprId, 31 DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId,
32 type_ref::{Mutability, Rawness}, 32 TypeAliasId, TypeParamId,
33 AdtId, AssocContainerId, DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId,
34 Lookup, TraitId, TypeAliasId, TypeParamId,
35}; 33};
36use itertools::Itertools; 34use itertools::Itertools;
37 35
38use crate::{ 36use crate::{
39 db::HirDatabase, 37 db::HirDatabase,
40 display::HirDisplay, 38 display::HirDisplay,
41 primitive::{FloatTy, IntTy},
42 utils::{generics, make_mut_slice, Generics}, 39 utils::{generics, make_mut_slice, Generics},
43}; 40};
44 41
45pub use autoderef::autoderef; 42pub use autoderef::autoderef;
46pub use infer::{InferTy, InferenceResult}; 43pub use infer::{InferenceResult, InferenceVar};
47pub use lower::{ 44pub use lower::{
48 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, 45 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
49 TyDefId, TyLoweringContext, ValueTyDefId, 46 TyDefId, TyLoweringContext, ValueTyDefId,
50}; 47};
51pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 48pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
52 49
53pub use chalk_ir::{BoundVar, DebruijnIndex}; 50pub use chalk_ir::{BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind};
54 51
55#[derive(Clone, PartialEq, Eq, Debug, Hash)] 52#[derive(Clone, PartialEq, Eq, Debug, Hash)]
56pub enum Lifetime { 53pub enum Lifetime {
@@ -58,211 +55,6 @@ pub enum Lifetime {
58 Static, 55 Static,
59} 56}
60 57
61/// A type constructor or type name: this might be something like the primitive
62/// type `bool`, a struct like `Vec`, or things like function pointers or
63/// tuples.
64#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
65pub enum TypeCtor {
66 /// The primitive boolean type. Written as `bool`.
67 Bool,
68
69 /// The primitive character type; holds a Unicode scalar value
70 /// (a non-surrogate code point). Written as `char`.
71 Char,
72
73 /// A primitive integer type. For example, `i32`.
74 Int(IntTy),
75
76 /// A primitive floating-point type. For example, `f64`.
77 Float(FloatTy),
78
79 /// Structures, enumerations and unions.
80 Adt(AdtId),
81
82 /// The pointee of a string slice. Written as `str`.
83 Str,
84
85 /// The pointee of an array slice. Written as `[T]`.
86 Slice,
87
88 /// An array with the given length. Written as `[T; n]`.
89 Array,
90
91 /// A raw pointer. Written as `*mut T` or `*const T`
92 RawPtr(Mutability),
93
94 /// A reference; a pointer with an associated lifetime. Written as
95 /// `&'a mut T` or `&'a T`.
96 Ref(Mutability),
97
98 /// The anonymous type of a function declaration/definition. Each
99 /// function has a unique type, which is output (for a function
100 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
101 ///
102 /// This includes tuple struct / enum variant constructors as well.
103 ///
104 /// For example the type of `bar` here:
105 ///
106 /// ```
107 /// fn foo() -> i32 { 1 }
108 /// let bar = foo; // bar: fn() -> i32 {foo}
109 /// ```
110 FnDef(CallableDefId),
111
112 /// A pointer to a function. Written as `fn() -> i32`.
113 ///
114 /// For example the type of `bar` here:
115 ///
116 /// ```
117 /// fn foo() -> i32 { 1 }
118 /// let bar: fn() -> i32 = foo;
119 /// ```
120 // FIXME make this a Ty variant like in Chalk
121 FnPtr { num_args: u16, is_varargs: bool },
122
123 /// The never type `!`.
124 Never,
125
126 /// A tuple type. For example, `(i32, bool)`.
127 Tuple { cardinality: u16 },
128
129 /// Represents an associated item like `Iterator::Item`. This is used
130 /// when we have tried to normalize a projection like `T::Item` but
131 /// couldn't find a better representation. In that case, we generate
132 /// an **application type** like `(Iterator::Item)<T>`.
133 AssociatedType(TypeAliasId),
134
135 /// This represents a placeholder for an opaque type in situations where we
136 /// don't know the hidden type (i.e. currently almost always). This is
137 /// analogous to the `AssociatedType` type constructor.
138 /// It is also used as the type of async block, with one type parameter
139 /// representing the Future::Output type.
140 OpaqueType(OpaqueTyId),
141
142 /// Represents a foreign type declared in external blocks.
143 ForeignType(TypeAliasId),
144
145 /// The type of a specific closure.
146 ///
147 /// The closure signature is stored in a `FnPtr` type in the first type
148 /// parameter.
149 Closure { def: DefWithBodyId, expr: ExprId },
150}
151
152impl TypeCtor {
153 pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize {
154 match self {
155 TypeCtor::Bool
156 | TypeCtor::Char
157 | TypeCtor::Int(_)
158 | TypeCtor::Float(_)
159 | TypeCtor::Str
160 | TypeCtor::Never => 0,
161 TypeCtor::Slice
162 | TypeCtor::Array
163 | TypeCtor::RawPtr(_)
164 | TypeCtor::Ref(_)
165 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure
166 => 1,
167 TypeCtor::Adt(adt) => {
168 let generic_params = generics(db.upcast(), adt.into());
169 generic_params.len()
170 }
171 TypeCtor::FnDef(callable) => {
172 let generic_params = generics(db.upcast(), callable.into());
173 generic_params.len()
174 }
175 TypeCtor::AssociatedType(type_alias) => {
176 let generic_params = generics(db.upcast(), type_alias.into());
177 generic_params.len()
178 }
179 TypeCtor::ForeignType(type_alias) => {
180 let generic_params = generics(db.upcast(), type_alias.into());
181 generic_params.len()
182 }
183 TypeCtor::OpaqueType(opaque_ty_id) => {
184 match opaque_ty_id {
185 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
186 let generic_params = generics(db.upcast(), func.into());
187 generic_params.len()
188 }
189 // 1 param representing Future::Output type.
190 OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1,
191 }
192 }
193 TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1,
194 TypeCtor::Tuple { cardinality } => cardinality as usize,
195 }
196 }
197
198 pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> {
199 match self {
200 TypeCtor::Bool
201 | TypeCtor::Char
202 | TypeCtor::Int(_)
203 | TypeCtor::Float(_)
204 | TypeCtor::Str
205 | TypeCtor::Never
206 | TypeCtor::Slice
207 | TypeCtor::Array
208 | TypeCtor::RawPtr(_)
209 | TypeCtor::Ref(_)
210 | TypeCtor::FnPtr { .. }
211 | TypeCtor::Tuple { .. } => None,
212 // Closure's krate is irrelevant for coherence I would think?
213 TypeCtor::Closure { .. } => None,
214 TypeCtor::Adt(adt) => Some(adt.module(db.upcast()).krate()),
215 TypeCtor::FnDef(callable) => Some(callable.krate(db)),
216 TypeCtor::AssociatedType(type_alias) => {
217 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate())
218 }
219 TypeCtor::ForeignType(type_alias) => {
220 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate())
221 }
222 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
223 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
224 Some(func.lookup(db.upcast()).module(db.upcast()).krate())
225 }
226 OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => {
227 Some(def.module(db.upcast()).krate())
228 }
229 },
230 }
231 }
232
233 pub fn as_generic_def(self) -> Option<GenericDefId> {
234 match self {
235 TypeCtor::Bool
236 | TypeCtor::Char
237 | TypeCtor::Int(_)
238 | TypeCtor::Float(_)
239 | TypeCtor::Str
240 | TypeCtor::Never
241 | TypeCtor::Slice
242 | TypeCtor::Array
243 | TypeCtor::RawPtr(_)
244 | TypeCtor::Ref(_)
245 | TypeCtor::FnPtr { .. }
246 | TypeCtor::Tuple { .. }
247 | TypeCtor::Closure { .. } => None,
248 TypeCtor::Adt(adt) => Some(adt.into()),
249 TypeCtor::FnDef(callable) => Some(callable.into()),
250 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
251 TypeCtor::ForeignType(type_alias) => Some(type_alias.into()),
252 TypeCtor::OpaqueType(_impl_trait_id) => None,
253 }
254 }
255}
256
257/// A nominal type with (maybe 0) type parameters. This might be a primitive
258/// type like `bool`, a struct, tuple, function pointer, reference or
259/// several other things.
260#[derive(Clone, PartialEq, Eq, Debug, Hash)]
261pub struct ApplicationTy {
262 pub ctor: TypeCtor,
263 pub parameters: Substs,
264}
265
266#[derive(Clone, PartialEq, Eq, Debug, Hash)] 58#[derive(Clone, PartialEq, Eq, Debug, Hash)]
267pub struct OpaqueTy { 59pub struct OpaqueTy {
268 pub opaque_ty_id: OpaqueTyId, 60 pub opaque_ty_id: OpaqueTyId,
@@ -305,29 +97,118 @@ impl TypeWalk for ProjectionTy {
305 } 97 }
306} 98}
307 99
308/// A type. 100#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
309/// 101pub struct FnSig {
310/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 102 pub variadic: bool,
311/// the same thing (but in a different way). 103}
312/// 104
313/// This should be cheap to clone.
314#[derive(Clone, PartialEq, Eq, Debug, Hash)] 105#[derive(Clone, PartialEq, Eq, Debug, Hash)]
315pub enum Ty { 106pub struct FnPointer {
316 /// A nominal type with (maybe 0) type parameters. This might be a primitive 107 pub num_args: usize,
317 /// type like `bool`, a struct, tuple, function pointer, reference or 108 pub sig: FnSig,
318 /// several other things. 109 pub substs: Substs,
319 Apply(ApplicationTy), 110}
320 111
112#[derive(Clone, PartialEq, Eq, Debug, Hash)]
113pub enum AliasTy {
321 /// A "projection" type corresponds to an (unnormalized) 114 /// A "projection" type corresponds to an (unnormalized)
322 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 115 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
323 /// trait and all its parameters are fully known. 116 /// trait and all its parameters are fully known.
324 Projection(ProjectionTy), 117 Projection(ProjectionTy),
325
326 /// An opaque type (`impl Trait`). 118 /// An opaque type (`impl Trait`).
327 /// 119 ///
328 /// This is currently only used for return type impl trait; each instance of 120 /// This is currently only used for return type impl trait; each instance of
329 /// `impl Trait` in a return type gets its own ID. 121 /// `impl Trait` in a return type gets its own ID.
330 Opaque(OpaqueTy), 122 Opaque(OpaqueTy),
123}
124
125/// A type.
126///
127/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
128/// the same thing (but in a different way).
129///
130/// This should be cheap to clone.
131#[derive(Clone, PartialEq, Eq, Debug, Hash)]
132pub enum Ty {
133 /// Structures, enumerations and unions.
134 Adt(AdtId, Substs),
135
136 /// Represents an associated item like `Iterator::Item`. This is used
137 /// when we have tried to normalize a projection like `T::Item` but
138 /// couldn't find a better representation. In that case, we generate
139 /// an **application type** like `(Iterator::Item)<T>`.
140 AssociatedType(TypeAliasId, Substs),
141
142 /// a scalar type like `bool` or `u32`
143 Scalar(Scalar),
144
145 /// A tuple type. For example, `(i32, bool)`.
146 Tuple(usize, Substs),
147
148 /// An array with the given length. Written as `[T; n]`.
149 Array(Substs),
150
151 /// The pointee of an array slice. Written as `[T]`.
152 Slice(Substs),
153
154 /// A raw pointer. Written as `*mut T` or `*const T`
155 Raw(Mutability, Substs),
156
157 /// A reference; a pointer with an associated lifetime. Written as
158 /// `&'a mut T` or `&'a T`.
159 Ref(Mutability, Substs),
160
161 /// This represents a placeholder for an opaque type in situations where we
162 /// don't know the hidden type (i.e. currently almost always). This is
163 /// analogous to the `AssociatedType` type constructor.
164 /// It is also used as the type of async block, with one type parameter
165 /// representing the Future::Output type.
166 OpaqueType(OpaqueTyId, Substs),
167
168 /// The anonymous type of a function declaration/definition. Each
169 /// function has a unique type, which is output (for a function
170 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
171 ///
172 /// This includes tuple struct / enum variant constructors as well.
173 ///
174 /// For example the type of `bar` here:
175 ///
176 /// ```
177 /// fn foo() -> i32 { 1 }
178 /// let bar = foo; // bar: fn() -> i32 {foo}
179 /// ```
180 FnDef(CallableDefId, Substs),
181
182 /// The pointee of a string slice. Written as `str`.
183 Str,
184
185 /// The never type `!`.
186 Never,
187
188 /// The type of a specific closure.
189 ///
190 /// The closure signature is stored in a `FnPtr` type in the first type
191 /// parameter.
192 Closure(DefWithBodyId, ExprId, Substs),
193
194 /// Represents a foreign type declared in external blocks.
195 ForeignType(TypeAliasId),
196
197 /// A pointer to a function. Written as `fn() -> i32`.
198 ///
199 /// For example the type of `bar` here:
200 ///
201 /// ```
202 /// fn foo() -> i32 { 1 }
203 /// let bar: fn() -> i32 = foo;
204 /// ```
205 Function(FnPointer),
206
207 /// An "alias" type represents some form of type alias, such as:
208 /// - An associated type projection like `<T as Iterator>::Item`
209 /// - `impl Trait` types
210 /// - Named type aliases like `type Foo<X> = Vec<X>`
211 Alias(AliasTy),
331 212
332 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) 213 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T)
333 /// {}` when we're type-checking the body of that function. In this 214 /// {}` when we're type-checking the body of that function. In this
@@ -340,10 +221,10 @@ pub enum Ty {
340 /// parameters get turned into variables; during trait resolution, inference 221 /// parameters get turned into variables; during trait resolution, inference
341 /// variables get turned into bound variables and back; and in `Dyn` the 222 /// variables get turned into bound variables and back; and in `Dyn` the
342 /// `Self` type is represented with a bound variable as well. 223 /// `Self` type is represented with a bound variable as well.
343 Bound(BoundVar), 224 BoundVar(BoundVar),
344 225
345 /// A type variable used during type checking. 226 /// A type variable used during type checking.
346 Infer(InferTy), 227 InferenceVar(InferenceVar, TyVariableKind),
347 228
348 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). 229 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
349 /// 230 ///
@@ -424,7 +305,7 @@ impl Substs {
424 generic_params 305 generic_params
425 .iter() 306 .iter()
426 .enumerate() 307 .enumerate()
427 .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) 308 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx)))
428 .collect(), 309 .collect(),
429 ) 310 )
430 } 311 }
@@ -440,10 +321,6 @@ impl Substs {
440 Substs::builder(generic_params.len()) 321 Substs::builder(generic_params.len())
441 } 322 }
442 323
443 pub fn build_for_type_ctor(db: &dyn HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder {
444 Substs::builder(type_ctor.num_ty_params(db))
445 }
446
447 fn builder(param_count: usize) -> SubstsBuilder { 324 fn builder(param_count: usize) -> SubstsBuilder {
448 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } 325 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
449 } 326 }
@@ -476,7 +353,7 @@ impl SubstsBuilder {
476 } 353 }
477 354
478 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 355 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
479 self.fill((starting_from..).map(|idx| Ty::Bound(BoundVar::new(debruijn, idx)))) 356 self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx))))
480 } 357 }
481 358
482 pub fn fill_with_unknown(self) -> Self { 359 pub fn fill_with_unknown(self) -> Self {
@@ -656,41 +533,41 @@ impl TypeWalk for GenericPredicate {
656#[derive(Debug, Clone, PartialEq, Eq, Hash)] 533#[derive(Debug, Clone, PartialEq, Eq, Hash)]
657pub struct Canonical<T> { 534pub struct Canonical<T> {
658 pub value: T, 535 pub value: T,
659 pub kinds: Arc<[TyKind]>, 536 pub kinds: Arc<[TyVariableKind]>,
660} 537}
661 538
662impl<T> Canonical<T> { 539impl<T> Canonical<T> {
663 pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { 540 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
664 Self { value, kinds: kinds.into_iter().collect() } 541 Self { value, kinds: kinds.into_iter().collect() }
665 } 542 }
666} 543}
667 544
668#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
669pub enum TyKind {
670 General,
671 Integer,
672 Float,
673}
674
675/// A function signature as seen by type inference: Several parameter types and 545/// A function signature as seen by type inference: Several parameter types and
676/// one return type. 546/// one return type.
677#[derive(Clone, PartialEq, Eq, Debug)] 547#[derive(Clone, PartialEq, Eq, Debug)]
678pub struct FnSig { 548pub struct CallableSig {
679 params_and_return: Arc<[Ty]>, 549 params_and_return: Arc<[Ty]>,
680 is_varargs: bool, 550 is_varargs: bool,
681} 551}
682 552
683/// A polymorphic function signature. 553/// A polymorphic function signature.
684pub type PolyFnSig = Binders<FnSig>; 554pub type PolyFnSig = Binders<CallableSig>;
685 555
686impl FnSig { 556impl CallableSig {
687 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { 557 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig {
688 params.push(ret); 558 params.push(ret);
689 FnSig { params_and_return: params.into(), is_varargs } 559 CallableSig { params_and_return: params.into(), is_varargs }
690 } 560 }
691 561
692 pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { 562 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
693 FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } 563 CallableSig {
564 params_and_return: Arc::clone(&fn_ptr.substs.0),
565 is_varargs: fn_ptr.sig.variadic,
566 }
567 }
568
569 pub fn from_substs(substs: &Substs) -> CallableSig {
570 CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false }
694 } 571 }
695 572
696 pub fn params(&self) -> &[Ty] { 573 pub fn params(&self) -> &[Ty] {
@@ -702,7 +579,7 @@ impl FnSig {
702 } 579 }
703} 580}
704 581
705impl TypeWalk for FnSig { 582impl TypeWalk for CallableSig {
706 fn walk(&self, f: &mut impl FnMut(&Ty)) { 583 fn walk(&self, f: &mut impl FnMut(&Ty)) {
707 for t in self.params_and_return.iter() { 584 for t in self.params_and_return.iter() {
708 t.walk(f); 585 t.walk(f);
@@ -721,49 +598,42 @@ impl TypeWalk for FnSig {
721} 598}
722 599
723impl Ty { 600impl Ty {
724 pub fn simple(ctor: TypeCtor) -> Ty {
725 Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() })
726 }
727 pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty {
728 Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) })
729 }
730 pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty {
731 Ty::Apply(ApplicationTy { ctor, parameters })
732 }
733 pub fn unit() -> Self { 601 pub fn unit() -> Self {
734 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) 602 Ty::Tuple(0, Substs::empty())
735 } 603 }
736 pub fn fn_ptr(sig: FnSig) -> Self { 604
737 Ty::apply( 605 pub fn fn_ptr(sig: CallableSig) -> Self {
738 TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, 606 Ty::Function(FnPointer {
739 Substs(sig.params_and_return), 607 num_args: sig.params().len(),
740 ) 608 sig: FnSig { variadic: sig.is_varargs },
609 substs: Substs(sig.params_and_return),
610 })
741 } 611 }
612
742 pub fn builtin(builtin: BuiltinType) -> Self { 613 pub fn builtin(builtin: BuiltinType) -> Self {
743 Ty::simple(match builtin { 614 match builtin {
744 BuiltinType::Char => TypeCtor::Char, 615 BuiltinType::Char => Ty::Scalar(Scalar::Char),
745 BuiltinType::Bool => TypeCtor::Bool, 616 BuiltinType::Bool => Ty::Scalar(Scalar::Bool),
746 BuiltinType::Str => TypeCtor::Str, 617 BuiltinType::Str => Ty::Str,
747 BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), 618 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
748 BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), 619 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))),
749 }) 620 BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))),
621 }
750 } 622 }
751 623
752 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 624 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
753 match self { 625 match self {
754 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 626 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
755 Some((parameters.as_single(), *mutability))
756 }
757 _ => None, 627 _ => None,
758 } 628 }
759 } 629 }
760 630
761 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 631 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
762 match self { 632 match self {
763 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 633 Ty::Ref(mutability, parameters) => {
764 Some((parameters.as_single(), Rawness::Ref, *mutability)) 634 Some((parameters.as_single(), Rawness::Ref, *mutability))
765 } 635 }
766 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { 636 Ty::Raw(mutability, parameters) => {
767 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 637 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
768 } 638 }
769 _ => None, 639 _ => None,
@@ -773,7 +643,7 @@ impl Ty {
773 pub fn strip_references(&self) -> &Ty { 643 pub fn strip_references(&self) -> &Ty {
774 let mut t: &Ty = self; 644 let mut t: &Ty = self;
775 645
776 while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { 646 while let Ty::Ref(_mutability, parameters) = t {
777 t = parameters.as_single(); 647 t = parameters.as_single();
778 } 648 }
779 649
@@ -782,30 +652,60 @@ impl Ty {
782 652
783 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { 653 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
784 match self { 654 match self {
785 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 655 Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)),
786 Some((*adt_def, parameters))
787 }
788 _ => None, 656 _ => None,
789 } 657 }
790 } 658 }
791 659
792 pub fn as_tuple(&self) -> Option<&Substs> { 660 pub fn as_tuple(&self) -> Option<&Substs> {
793 match self { 661 match self {
794 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { 662 Ty::Tuple(_, substs) => Some(substs),
795 Some(parameters) 663 _ => None,
796 } 664 }
665 }
666
667 pub fn as_generic_def(&self) -> Option<GenericDefId> {
668 match *self {
669 Ty::Adt(adt, ..) => Some(adt.into()),
670 Ty::FnDef(callable, ..) => Some(callable.into()),
671 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()),
672 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()),
797 _ => None, 673 _ => None,
798 } 674 }
799 } 675 }
800 676
801 pub fn is_never(&self) -> bool { 677 pub fn is_never(&self) -> bool {
802 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) 678 matches!(self, Ty::Never)
803 } 679 }
804 680
805 pub fn is_unknown(&self) -> bool { 681 pub fn is_unknown(&self) -> bool {
806 matches!(self, Ty::Unknown) 682 matches!(self, Ty::Unknown)
807 } 683 }
808 684
685 pub fn equals_ctor(&self, other: &Ty) -> bool {
686 match (self, other) {
687 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2,
688 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true,
689 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2,
690 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
691 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..))
692 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
693 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => {
694 expr == expr2 && def == def2
695 }
696 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
697 | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2,
698 (
699 Ty::Function(FnPointer { num_args, sig, .. }),
700 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
701 ) => num_args == num_args2 && sig == sig2,
702 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2,
703 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true,
704 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2,
705 _ => false,
706 }
707 }
708
809 /// If this is a `dyn Trait` type, this returns the `Trait` part. 709 /// If this is a `dyn Trait` type, this returns the `Trait` part.
810 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 710 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
811 match self { 711 match self {
@@ -824,41 +724,30 @@ impl Ty {
824 724
825 fn builtin_deref(&self) -> Option<Ty> { 725 fn builtin_deref(&self) -> Option<Ty> {
826 match self { 726 match self {
827 Ty::Apply(a_ty) => match a_ty.ctor { 727 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
828 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), 728 Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())),
829 TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
830 _ => None,
831 },
832 _ => None, 729 _ => None,
833 } 730 }
834 } 731 }
835 732
836 pub fn as_fn_def(&self) -> Option<FunctionId> { 733 pub fn as_fn_def(&self) -> Option<FunctionId> {
837 match self { 734 match self {
838 &Ty::Apply(ApplicationTy { 735 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func),
839 ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)),
840 ..
841 }) => Some(func),
842 _ => None, 736 _ => None,
843 } 737 }
844 } 738 }
845 739
846 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 740 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
847 match self { 741 match self {
848 Ty::Apply(a_ty) => match a_ty.ctor { 742 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
849 TypeCtor::FnPtr { is_varargs, .. } => { 743 Ty::FnDef(def, parameters) => {
850 Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) 744 let sig = db.callable_item_signature(*def);
851 } 745 Some(sig.subst(&parameters))
852 TypeCtor::FnDef(def) => { 746 }
853 let sig = db.callable_item_signature(def); 747 Ty::Closure(.., substs) => {
854 Some(sig.subst(&a_ty.parameters)) 748 let sig_param = &substs[0];
855 } 749 sig_param.callable_sig(db)
856 TypeCtor::Closure { .. } => { 750 }
857 let sig_param = &a_ty.parameters[0];
858 sig_param.callable_sig(db)
859 }
860 _ => None,
861 },
862 _ => None, 751 _ => None,
863 } 752 }
864 } 753 }
@@ -867,28 +756,66 @@ impl Ty {
867 /// the `Substs` for these type parameters with the given ones. (So e.g. if 756 /// the `Substs` for these type parameters with the given ones. (So e.g. if
868 /// `self` is `Option<_>` and the substs contain `u32`, we'll have 757 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
869 /// `Option<u32>` afterwards.) 758 /// `Option<u32>` afterwards.)
870 pub fn apply_substs(self, substs: Substs) -> Ty { 759 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
871 match self { 760 match &mut self {
872 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { 761 Ty::Adt(_, substs)
873 assert_eq!(previous_substs.len(), substs.len()); 762 | Ty::Slice(substs)
874 Ty::Apply(ApplicationTy { ctor, parameters: substs }) 763 | Ty::Array(substs)
764 | Ty::Raw(_, substs)
765 | Ty::Ref(_, substs)
766 | Ty::FnDef(_, substs)
767 | Ty::Function(FnPointer { substs, .. })
768 | Ty::Tuple(_, substs)
769 | Ty::OpaqueType(_, substs)
770 | Ty::AssociatedType(_, substs)
771 | Ty::Closure(.., substs) => {
772 assert_eq!(substs.len(), new_substs.len());
773 *substs = new_substs;
875 } 774 }
876 _ => self, 775 _ => (),
877 } 776 }
777 self
878 } 778 }
879 779
880 /// Returns the type parameters of this type if it has some (i.e. is an ADT 780 /// Returns the type parameters of this type if it has some (i.e. is an ADT
881 /// or function); so if `self` is `Option<u32>`, this returns the `u32`. 781 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
882 pub fn substs(&self) -> Option<Substs> { 782 pub fn substs(&self) -> Option<&Substs> {
883 match self { 783 match self {
884 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), 784 Ty::Adt(_, substs)
785 | Ty::Slice(substs)
786 | Ty::Array(substs)
787 | Ty::Raw(_, substs)
788 | Ty::Ref(_, substs)
789 | Ty::FnDef(_, substs)
790 | Ty::Function(FnPointer { substs, .. })
791 | Ty::Tuple(_, substs)
792 | Ty::OpaqueType(_, substs)
793 | Ty::AssociatedType(_, substs)
794 | Ty::Closure(.., substs) => Some(substs),
795 _ => None,
796 }
797 }
798
799 pub fn substs_mut(&mut self) -> Option<&mut Substs> {
800 match self {
801 Ty::Adt(_, substs)
802 | Ty::Slice(substs)
803 | Ty::Array(substs)
804 | Ty::Raw(_, substs)
805 | Ty::Ref(_, substs)
806 | Ty::FnDef(_, substs)
807 | Ty::Function(FnPointer { substs, .. })
808 | Ty::Tuple(_, substs)
809 | Ty::OpaqueType(_, substs)
810 | Ty::AssociatedType(_, substs)
811 | Ty::Closure(.., substs) => Some(substs),
885 _ => None, 812 _ => None,
886 } 813 }
887 } 814 }
888 815
889 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 816 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
890 match self { 817 match self {
891 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { 818 Ty::OpaqueType(opaque_ty_id, ..) => {
892 match opaque_ty_id { 819 match opaque_ty_id {
893 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 820 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
894 let krate = def.module(db.upcast()).krate(); 821 let krate = def.module(db.upcast()).krate();
@@ -911,7 +838,7 @@ impl Ty {
911 OpaqueTyId::ReturnTypeImplTrait(..) => None, 838 OpaqueTyId::ReturnTypeImplTrait(..) => None,
912 } 839 }
913 } 840 }
914 Ty::Opaque(opaque_ty) => { 841 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
915 let predicates = match opaque_ty.opaque_ty_id { 842 let predicates = match opaque_ty.opaque_ty_id {
916 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 843 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
917 db.return_type_impl_traits(func).map(|it| { 844 db.return_type_impl_traits(func).map(|it| {
@@ -949,13 +876,13 @@ impl Ty {
949 876
950 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 877 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
951 match self { 878 match self {
952 Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { 879 Ty::AssociatedType(type_alias_id, ..) => {
953 match type_alias_id.lookup(db.upcast()).container { 880 match type_alias_id.lookup(db.upcast()).container {
954 AssocContainerId::TraitId(trait_id) => Some(trait_id), 881 AssocContainerId::TraitId(trait_id) => Some(trait_id),
955 _ => None, 882 _ => None,
956 } 883 }
957 } 884 }
958 Ty::Projection(projection_ty) => { 885 Ty::Alias(AliasTy::Projection(projection_ty)) => {
959 match projection_ty.associated_ty.lookup(db.upcast()).container { 886 match projection_ty.associated_ty.lookup(db.upcast()).container {
960 AssocContainerId::TraitId(trait_id) => Some(trait_id), 887 AssocContainerId::TraitId(trait_id) => Some(trait_id),
961 _ => None, 888 _ => None,
@@ -1033,7 +960,7 @@ pub trait TypeWalk {
1033 { 960 {
1034 self.walk_mut_binders( 961 self.walk_mut_binders(
1035 &mut |ty, binders| { 962 &mut |ty, binders| {
1036 if let &mut Ty::Bound(bound) = ty { 963 if let &mut Ty::BoundVar(bound) = ty {
1037 if bound.debruijn >= binders { 964 if bound.debruijn >= binders {
1038 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 965 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
1039 } 966 }
@@ -1051,8 +978,8 @@ pub trait TypeWalk {
1051 { 978 {
1052 self.fold_binders( 979 self.fold_binders(
1053 &mut |ty, binders| match ty { 980 &mut |ty, binders| match ty {
1054 Ty::Bound(bound) if bound.debruijn >= binders => { 981 Ty::BoundVar(bound) if bound.debruijn >= binders => {
1055 Ty::Bound(bound.shifted_in_from(n)) 982 Ty::BoundVar(bound.shifted_in_from(n))
1056 } 983 }
1057 ty => ty, 984 ty => ty,
1058 }, 985 },
@@ -1064,13 +991,13 @@ pub trait TypeWalk {
1064impl TypeWalk for Ty { 991impl TypeWalk for Ty {
1065 fn walk(&self, f: &mut impl FnMut(&Ty)) { 992 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1066 match self { 993 match self {
1067 Ty::Apply(a_ty) => { 994 Ty::Alias(AliasTy::Projection(p_ty)) => {
1068 for t in a_ty.parameters.iter() { 995 for t in p_ty.parameters.iter() {
1069 t.walk(f); 996 t.walk(f);
1070 } 997 }
1071 } 998 }
1072 Ty::Projection(p_ty) => { 999 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1073 for t in p_ty.parameters.iter() { 1000 for t in o_ty.parameters.iter() {
1074 t.walk(f); 1001 t.walk(f);
1075 } 1002 }
1076 } 1003 }
@@ -1079,12 +1006,13 @@ impl TypeWalk for Ty {
1079 p.walk(f); 1006 p.walk(f);
1080 } 1007 }
1081 } 1008 }
1082 Ty::Opaque(o_ty) => { 1009 _ => {
1083 for t in o_ty.parameters.iter() { 1010 if let Some(substs) = self.substs() {
1084 t.walk(f); 1011 for t in substs.iter() {
1012 t.walk(f);
1013 }
1085 } 1014 }
1086 } 1015 }
1087 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
1088 } 1016 }
1089 f(self); 1017 f(self);
1090 } 1018 }
@@ -1095,10 +1023,7 @@ impl TypeWalk for Ty {
1095 binders: DebruijnIndex, 1023 binders: DebruijnIndex,
1096 ) { 1024 ) {
1097 match self { 1025 match self {
1098 Ty::Apply(a_ty) => { 1026 Ty::Alias(AliasTy::Projection(p_ty)) => {
1099 a_ty.parameters.walk_mut_binders(f, binders);
1100 }
1101 Ty::Projection(p_ty) => {
1102 p_ty.parameters.walk_mut_binders(f, binders); 1027 p_ty.parameters.walk_mut_binders(f, binders);
1103 } 1028 }
1104 Ty::Dyn(predicates) => { 1029 Ty::Dyn(predicates) => {
@@ -1106,10 +1031,14 @@ impl TypeWalk for Ty {
1106 p.walk_mut_binders(f, binders.shifted_in()); 1031 p.walk_mut_binders(f, binders.shifted_in());
1107 } 1032 }
1108 } 1033 }
1109 Ty::Opaque(o_ty) => { 1034 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1110 o_ty.parameters.walk_mut_binders(f, binders); 1035 o_ty.parameters.walk_mut_binders(f, binders);
1111 } 1036 }
1112 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1037 _ => {
1038 if let Some(substs) = self.substs_mut() {
1039 substs.walk_mut_binders(f, binders);
1040 }
1041 }
1113 } 1042 }
1114 f(self, binders); 1043 f(self, binders);
1115 } 1044 }