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.rs615
1 files changed, 275 insertions, 340 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 50d248674..e77f24e4e 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -25,32 +25,31 @@ 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, AssocContainerId, DefWithBodyId,
31 expr::ExprId, 31 FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId,
32 type_ref::{Mutability, Rawness}, 32 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::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind};
51
52pub(crate) use crate::traits::chalk::Interner;
54 53
55#[derive(Clone, PartialEq, Eq, Debug, Hash)] 54#[derive(Clone, PartialEq, Eq, Debug, Hash)]
56pub enum Lifetime { 55pub enum Lifetime {
@@ -58,211 +57,6 @@ pub enum Lifetime {
58 Static, 57 Static,
59} 58}
60 59
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)] 60#[derive(Clone, PartialEq, Eq, Debug, Hash)]
267pub struct OpaqueTy { 61pub struct OpaqueTy {
268 pub opaque_ty_id: OpaqueTyId, 62 pub opaque_ty_id: OpaqueTyId,
@@ -305,29 +99,118 @@ impl TypeWalk for ProjectionTy {
305 } 99 }
306} 100}
307 101
308/// A type. 102#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
309/// 103pub struct FnSig {
310/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 104 pub variadic: bool,
311/// the same thing (but in a different way). 105}
312/// 106
313/// This should be cheap to clone.
314#[derive(Clone, PartialEq, Eq, Debug, Hash)] 107#[derive(Clone, PartialEq, Eq, Debug, Hash)]
315pub enum Ty { 108pub struct FnPointer {
316 /// A nominal type with (maybe 0) type parameters. This might be a primitive 109 pub num_args: usize,
317 /// type like `bool`, a struct, tuple, function pointer, reference or 110 pub sig: FnSig,
318 /// several other things. 111 pub substs: Substs,
319 Apply(ApplicationTy), 112}
320 113
114#[derive(Clone, PartialEq, Eq, Debug, Hash)]
115pub enum AliasTy {
321 /// A "projection" type corresponds to an (unnormalized) 116 /// A "projection" type corresponds to an (unnormalized)
322 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 117 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
323 /// trait and all its parameters are fully known. 118 /// trait and all its parameters are fully known.
324 Projection(ProjectionTy), 119 Projection(ProjectionTy),
325
326 /// An opaque type (`impl Trait`). 120 /// An opaque type (`impl Trait`).
327 /// 121 ///
328 /// This is currently only used for return type impl trait; each instance of 122 /// This is currently only used for return type impl trait; each instance of
329 /// `impl Trait` in a return type gets its own ID. 123 /// `impl Trait` in a return type gets its own ID.
330 Opaque(OpaqueTy), 124 Opaque(OpaqueTy),
125}
126
127/// A type.
128///
129/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
130/// the same thing (but in a different way).
131///
132/// This should be cheap to clone.
133#[derive(Clone, PartialEq, Eq, Debug, Hash)]
134pub enum Ty {
135 /// Structures, enumerations and unions.
136 Adt(AdtId<Interner>, Substs),
137
138 /// Represents an associated item like `Iterator::Item`. This is used
139 /// when we have tried to normalize a projection like `T::Item` but
140 /// couldn't find a better representation. In that case, we generate
141 /// an **application type** like `(Iterator::Item)<T>`.
142 AssociatedType(TypeAliasId, Substs),
143
144 /// a scalar type like `bool` or `u32`
145 Scalar(Scalar),
146
147 /// A tuple type. For example, `(i32, bool)`.
148 Tuple(usize, Substs),
149
150 /// An array with the given length. Written as `[T; n]`.
151 Array(Substs),
152
153 /// The pointee of an array slice. Written as `[T]`.
154 Slice(Substs),
155
156 /// A raw pointer. Written as `*mut T` or `*const T`
157 Raw(Mutability, Substs),
158
159 /// A reference; a pointer with an associated lifetime. Written as
160 /// `&'a mut T` or `&'a T`.
161 Ref(Mutability, Substs),
162
163 /// This represents a placeholder for an opaque type in situations where we
164 /// don't know the hidden type (i.e. currently almost always). This is
165 /// analogous to the `AssociatedType` type constructor.
166 /// It is also used as the type of async block, with one type parameter
167 /// representing the Future::Output type.
168 OpaqueType(OpaqueTyId, Substs),
169
170 /// The anonymous type of a function declaration/definition. Each
171 /// function has a unique type, which is output (for a function
172 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
173 ///
174 /// This includes tuple struct / enum variant constructors as well.
175 ///
176 /// For example the type of `bar` here:
177 ///
178 /// ```
179 /// fn foo() -> i32 { 1 }
180 /// let bar = foo; // bar: fn() -> i32 {foo}
181 /// ```
182 FnDef(CallableDefId, Substs),
183
184 /// The pointee of a string slice. Written as `str`.
185 Str,
186
187 /// The never type `!`.
188 Never,
189
190 /// The type of a specific closure.
191 ///
192 /// The closure signature is stored in a `FnPtr` type in the first type
193 /// parameter.
194 Closure(DefWithBodyId, ExprId, Substs),
195
196 /// Represents a foreign type declared in external blocks.
197 ForeignType(TypeAliasId),
198
199 /// A pointer to a function. Written as `fn() -> i32`.
200 ///
201 /// For example the type of `bar` here:
202 ///
203 /// ```
204 /// fn foo() -> i32 { 1 }
205 /// let bar: fn() -> i32 = foo;
206 /// ```
207 Function(FnPointer),
208
209 /// An "alias" type represents some form of type alias, such as:
210 /// - An associated type projection like `<T as Iterator>::Item`
211 /// - `impl Trait` types
212 /// - Named type aliases like `type Foo<X> = Vec<X>`
213 Alias(AliasTy),
331 214
332 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) 215 /// 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 216 /// {}` when we're type-checking the body of that function. In this
@@ -340,10 +223,10 @@ pub enum Ty {
340 /// parameters get turned into variables; during trait resolution, inference 223 /// parameters get turned into variables; during trait resolution, inference
341 /// variables get turned into bound variables and back; and in `Dyn` the 224 /// variables get turned into bound variables and back; and in `Dyn` the
342 /// `Self` type is represented with a bound variable as well. 225 /// `Self` type is represented with a bound variable as well.
343 Bound(BoundVar), 226 BoundVar(BoundVar),
344 227
345 /// A type variable used during type checking. 228 /// A type variable used during type checking.
346 Infer(InferTy), 229 InferenceVar(InferenceVar, TyVariableKind),
347 230
348 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). 231 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
349 /// 232 ///
@@ -424,7 +307,7 @@ impl Substs {
424 generic_params 307 generic_params
425 .iter() 308 .iter()
426 .enumerate() 309 .enumerate()
427 .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) 310 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx)))
428 .collect(), 311 .collect(),
429 ) 312 )
430 } 313 }
@@ -440,10 +323,6 @@ impl Substs {
440 Substs::builder(generic_params.len()) 323 Substs::builder(generic_params.len())
441 } 324 }
442 325
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 { 326 fn builder(param_count: usize) -> SubstsBuilder {
448 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } 327 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
449 } 328 }
@@ -476,7 +355,7 @@ impl SubstsBuilder {
476 } 355 }
477 356
478 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 357 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)))) 358 self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx))))
480 } 359 }
481 360
482 pub fn fill_with_unknown(self) -> Self { 361 pub fn fill_with_unknown(self) -> Self {
@@ -656,41 +535,41 @@ impl TypeWalk for GenericPredicate {
656#[derive(Debug, Clone, PartialEq, Eq, Hash)] 535#[derive(Debug, Clone, PartialEq, Eq, Hash)]
657pub struct Canonical<T> { 536pub struct Canonical<T> {
658 pub value: T, 537 pub value: T,
659 pub kinds: Arc<[TyKind]>, 538 pub kinds: Arc<[TyVariableKind]>,
660} 539}
661 540
662impl<T> Canonical<T> { 541impl<T> Canonical<T> {
663 pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { 542 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
664 Self { value, kinds: kinds.into_iter().collect() } 543 Self { value, kinds: kinds.into_iter().collect() }
665 } 544 }
666} 545}
667 546
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 547/// A function signature as seen by type inference: Several parameter types and
676/// one return type. 548/// one return type.
677#[derive(Clone, PartialEq, Eq, Debug)] 549#[derive(Clone, PartialEq, Eq, Debug)]
678pub struct FnSig { 550pub struct CallableSig {
679 params_and_return: Arc<[Ty]>, 551 params_and_return: Arc<[Ty]>,
680 is_varargs: bool, 552 is_varargs: bool,
681} 553}
682 554
683/// A polymorphic function signature. 555/// A polymorphic function signature.
684pub type PolyFnSig = Binders<FnSig>; 556pub type PolyFnSig = Binders<CallableSig>;
685 557
686impl FnSig { 558impl CallableSig {
687 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { 559 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig {
688 params.push(ret); 560 params.push(ret);
689 FnSig { params_and_return: params.into(), is_varargs } 561 CallableSig { params_and_return: params.into(), is_varargs }
562 }
563
564 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
565 CallableSig {
566 params_and_return: Arc::clone(&fn_ptr.substs.0),
567 is_varargs: fn_ptr.sig.variadic,
568 }
690 } 569 }
691 570
692 pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { 571 pub fn from_substs(substs: &Substs) -> CallableSig {
693 FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } 572 CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false }
694 } 573 }
695 574
696 pub fn params(&self) -> &[Ty] { 575 pub fn params(&self) -> &[Ty] {
@@ -702,7 +581,7 @@ impl FnSig {
702 } 581 }
703} 582}
704 583
705impl TypeWalk for FnSig { 584impl TypeWalk for CallableSig {
706 fn walk(&self, f: &mut impl FnMut(&Ty)) { 585 fn walk(&self, f: &mut impl FnMut(&Ty)) {
707 for t in self.params_and_return.iter() { 586 for t in self.params_and_return.iter() {
708 t.walk(f); 587 t.walk(f);
@@ -721,49 +600,46 @@ impl TypeWalk for FnSig {
721} 600}
722 601
723impl Ty { 602impl 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 { 603 pub fn unit() -> Self {
734 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) 604 Ty::Tuple(0, Substs::empty())
735 } 605 }
736 pub fn fn_ptr(sig: FnSig) -> Self { 606
737 Ty::apply( 607 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty {
738 TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, 608 Ty::Adt(AdtId(adt), substs)
739 Substs(sig.params_and_return),
740 )
741 } 609 }
742 pub fn builtin(builtin: BuiltinType) -> Self { 610
743 Ty::simple(match builtin { 611 pub fn fn_ptr(sig: CallableSig) -> Self {
744 BuiltinType::Char => TypeCtor::Char, 612 Ty::Function(FnPointer {
745 BuiltinType::Bool => TypeCtor::Bool, 613 num_args: sig.params().len(),
746 BuiltinType::Str => TypeCtor::Str, 614 sig: FnSig { variadic: sig.is_varargs },
747 BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), 615 substs: Substs(sig.params_and_return),
748 BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()),
749 }) 616 })
750 } 617 }
751 618
619 pub fn builtin(builtin: BuiltinType) -> Self {
620 match builtin {
621 BuiltinType::Char => Ty::Scalar(Scalar::Char),
622 BuiltinType::Bool => Ty::Scalar(Scalar::Bool),
623 BuiltinType::Str => Ty::Str,
624 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
625 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))),
626 BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))),
627 }
628 }
629
752 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 630 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
753 match self { 631 match self {
754 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 632 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
755 Some((parameters.as_single(), *mutability))
756 }
757 _ => None, 633 _ => None,
758 } 634 }
759 } 635 }
760 636
761 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 637 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
762 match self { 638 match self {
763 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 639 Ty::Ref(mutability, parameters) => {
764 Some((parameters.as_single(), Rawness::Ref, *mutability)) 640 Some((parameters.as_single(), Rawness::Ref, *mutability))
765 } 641 }
766 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { 642 Ty::Raw(mutability, parameters) => {
767 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 643 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
768 } 644 }
769 _ => None, 645 _ => None,
@@ -773,39 +649,69 @@ impl Ty {
773 pub fn strip_references(&self) -> &Ty { 649 pub fn strip_references(&self) -> &Ty {
774 let mut t: &Ty = self; 650 let mut t: &Ty = self;
775 651
776 while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { 652 while let Ty::Ref(_mutability, parameters) = t {
777 t = parameters.as_single(); 653 t = parameters.as_single();
778 } 654 }
779 655
780 t 656 t
781 } 657 }
782 658
783 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { 659 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> {
784 match self { 660 match self {
785 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 661 Ty::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
786 Some((*adt_def, parameters))
787 }
788 _ => None, 662 _ => None,
789 } 663 }
790 } 664 }
791 665
792 pub fn as_tuple(&self) -> Option<&Substs> { 666 pub fn as_tuple(&self) -> Option<&Substs> {
793 match self { 667 match self {
794 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { 668 Ty::Tuple(_, substs) => Some(substs),
795 Some(parameters) 669 _ => None,
796 } 670 }
671 }
672
673 pub fn as_generic_def(&self) -> Option<GenericDefId> {
674 match *self {
675 Ty::Adt(AdtId(adt), ..) => Some(adt.into()),
676 Ty::FnDef(callable, ..) => Some(callable.into()),
677 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()),
678 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()),
797 _ => None, 679 _ => None,
798 } 680 }
799 } 681 }
800 682
801 pub fn is_never(&self) -> bool { 683 pub fn is_never(&self) -> bool {
802 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) 684 matches!(self, Ty::Never)
803 } 685 }
804 686
805 pub fn is_unknown(&self) -> bool { 687 pub fn is_unknown(&self) -> bool {
806 matches!(self, Ty::Unknown) 688 matches!(self, Ty::Unknown)
807 } 689 }
808 690
691 pub fn equals_ctor(&self, other: &Ty) -> bool {
692 match (self, other) {
693 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2,
694 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true,
695 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2,
696 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
697 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..))
698 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
699 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => {
700 expr == expr2 && def == def2
701 }
702 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
703 | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2,
704 (
705 Ty::Function(FnPointer { num_args, sig, .. }),
706 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
707 ) => num_args == num_args2 && sig == sig2,
708 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2,
709 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true,
710 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2,
711 _ => false,
712 }
713 }
714
809 /// If this is a `dyn Trait` type, this returns the `Trait` part. 715 /// If this is a `dyn Trait` type, this returns the `Trait` part.
810 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 716 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
811 match self { 717 match self {
@@ -824,41 +730,30 @@ impl Ty {
824 730
825 fn builtin_deref(&self) -> Option<Ty> { 731 fn builtin_deref(&self) -> Option<Ty> {
826 match self { 732 match self {
827 Ty::Apply(a_ty) => match a_ty.ctor { 733 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
828 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), 734 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, 735 _ => None,
833 } 736 }
834 } 737 }
835 738
836 pub fn as_fn_def(&self) -> Option<FunctionId> { 739 pub fn as_fn_def(&self) -> Option<FunctionId> {
837 match self { 740 match self {
838 &Ty::Apply(ApplicationTy { 741 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func),
839 ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)),
840 ..
841 }) => Some(func),
842 _ => None, 742 _ => None,
843 } 743 }
844 } 744 }
845 745
846 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 746 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
847 match self { 747 match self {
848 Ty::Apply(a_ty) => match a_ty.ctor { 748 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
849 TypeCtor::FnPtr { is_varargs, .. } => { 749 Ty::FnDef(def, parameters) => {
850 Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) 750 let sig = db.callable_item_signature(*def);
851 } 751 Some(sig.subst(&parameters))
852 TypeCtor::FnDef(def) => { 752 }
853 let sig = db.callable_item_signature(def); 753 Ty::Closure(.., substs) => {
854 Some(sig.subst(&a_ty.parameters)) 754 let sig_param = &substs[0];
855 } 755 sig_param.callable_sig(db)
856 TypeCtor::Closure { .. } => { 756 }
857 let sig_param = &a_ty.parameters[0];
858 sig_param.callable_sig(db)
859 }
860 _ => None,
861 },
862 _ => None, 757 _ => None,
863 } 758 }
864 } 759 }
@@ -867,28 +762,66 @@ impl Ty {
867 /// the `Substs` for these type parameters with the given ones. (So e.g. if 762 /// 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 763 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
869 /// `Option<u32>` afterwards.) 764 /// `Option<u32>` afterwards.)
870 pub fn apply_substs(self, substs: Substs) -> Ty { 765 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
871 match self { 766 match &mut self {
872 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { 767 Ty::Adt(_, substs)
873 assert_eq!(previous_substs.len(), substs.len()); 768 | Ty::Slice(substs)
874 Ty::Apply(ApplicationTy { ctor, parameters: substs }) 769 | Ty::Array(substs)
770 | Ty::Raw(_, substs)
771 | Ty::Ref(_, substs)
772 | Ty::FnDef(_, substs)
773 | Ty::Function(FnPointer { substs, .. })
774 | Ty::Tuple(_, substs)
775 | Ty::OpaqueType(_, substs)
776 | Ty::AssociatedType(_, substs)
777 | Ty::Closure(.., substs) => {
778 assert_eq!(substs.len(), new_substs.len());
779 *substs = new_substs;
875 } 780 }
876 _ => self, 781 _ => (),
877 } 782 }
783 self
878 } 784 }
879 785
880 /// Returns the type parameters of this type if it has some (i.e. is an ADT 786 /// 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`. 787 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
882 pub fn substs(&self) -> Option<Substs> { 788 pub fn substs(&self) -> Option<&Substs> {
883 match self { 789 match self {
884 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), 790 Ty::Adt(_, substs)
791 | Ty::Slice(substs)
792 | Ty::Array(substs)
793 | Ty::Raw(_, substs)
794 | Ty::Ref(_, substs)
795 | Ty::FnDef(_, substs)
796 | Ty::Function(FnPointer { substs, .. })
797 | Ty::Tuple(_, substs)
798 | Ty::OpaqueType(_, substs)
799 | Ty::AssociatedType(_, substs)
800 | Ty::Closure(.., substs) => Some(substs),
801 _ => None,
802 }
803 }
804
805 pub fn substs_mut(&mut self) -> Option<&mut Substs> {
806 match self {
807 Ty::Adt(_, substs)
808 | Ty::Slice(substs)
809 | Ty::Array(substs)
810 | Ty::Raw(_, substs)
811 | Ty::Ref(_, substs)
812 | Ty::FnDef(_, substs)
813 | Ty::Function(FnPointer { substs, .. })
814 | Ty::Tuple(_, substs)
815 | Ty::OpaqueType(_, substs)
816 | Ty::AssociatedType(_, substs)
817 | Ty::Closure(.., substs) => Some(substs),
885 _ => None, 818 _ => None,
886 } 819 }
887 } 820 }
888 821
889 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 822 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
890 match self { 823 match self {
891 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { 824 Ty::OpaqueType(opaque_ty_id, ..) => {
892 match opaque_ty_id { 825 match opaque_ty_id {
893 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 826 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
894 let krate = def.module(db.upcast()).krate(); 827 let krate = def.module(db.upcast()).krate();
@@ -911,7 +844,7 @@ impl Ty {
911 OpaqueTyId::ReturnTypeImplTrait(..) => None, 844 OpaqueTyId::ReturnTypeImplTrait(..) => None,
912 } 845 }
913 } 846 }
914 Ty::Opaque(opaque_ty) => { 847 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
915 let predicates = match opaque_ty.opaque_ty_id { 848 let predicates = match opaque_ty.opaque_ty_id {
916 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 849 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
917 db.return_type_impl_traits(func).map(|it| { 850 db.return_type_impl_traits(func).map(|it| {
@@ -949,13 +882,13 @@ impl Ty {
949 882
950 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 883 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
951 match self { 884 match self {
952 Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { 885 Ty::AssociatedType(type_alias_id, ..) => {
953 match type_alias_id.lookup(db.upcast()).container { 886 match type_alias_id.lookup(db.upcast()).container {
954 AssocContainerId::TraitId(trait_id) => Some(trait_id), 887 AssocContainerId::TraitId(trait_id) => Some(trait_id),
955 _ => None, 888 _ => None,
956 } 889 }
957 } 890 }
958 Ty::Projection(projection_ty) => { 891 Ty::Alias(AliasTy::Projection(projection_ty)) => {
959 match projection_ty.associated_ty.lookup(db.upcast()).container { 892 match projection_ty.associated_ty.lookup(db.upcast()).container {
960 AssocContainerId::TraitId(trait_id) => Some(trait_id), 893 AssocContainerId::TraitId(trait_id) => Some(trait_id),
961 _ => None, 894 _ => None,
@@ -1033,7 +966,7 @@ pub trait TypeWalk {
1033 { 966 {
1034 self.walk_mut_binders( 967 self.walk_mut_binders(
1035 &mut |ty, binders| { 968 &mut |ty, binders| {
1036 if let &mut Ty::Bound(bound) = ty { 969 if let &mut Ty::BoundVar(bound) = ty {
1037 if bound.debruijn >= binders { 970 if bound.debruijn >= binders {
1038 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 971 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
1039 } 972 }
@@ -1051,8 +984,8 @@ pub trait TypeWalk {
1051 { 984 {
1052 self.fold_binders( 985 self.fold_binders(
1053 &mut |ty, binders| match ty { 986 &mut |ty, binders| match ty {
1054 Ty::Bound(bound) if bound.debruijn >= binders => { 987 Ty::BoundVar(bound) if bound.debruijn >= binders => {
1055 Ty::Bound(bound.shifted_in_from(n)) 988 Ty::BoundVar(bound.shifted_in_from(n))
1056 } 989 }
1057 ty => ty, 990 ty => ty,
1058 }, 991 },
@@ -1064,13 +997,13 @@ pub trait TypeWalk {
1064impl TypeWalk for Ty { 997impl TypeWalk for Ty {
1065 fn walk(&self, f: &mut impl FnMut(&Ty)) { 998 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1066 match self { 999 match self {
1067 Ty::Apply(a_ty) => { 1000 Ty::Alias(AliasTy::Projection(p_ty)) => {
1068 for t in a_ty.parameters.iter() { 1001 for t in p_ty.parameters.iter() {
1069 t.walk(f); 1002 t.walk(f);
1070 } 1003 }
1071 } 1004 }
1072 Ty::Projection(p_ty) => { 1005 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1073 for t in p_ty.parameters.iter() { 1006 for t in o_ty.parameters.iter() {
1074 t.walk(f); 1007 t.walk(f);
1075 } 1008 }
1076 } 1009 }
@@ -1079,12 +1012,13 @@ impl TypeWalk for Ty {
1079 p.walk(f); 1012 p.walk(f);
1080 } 1013 }
1081 } 1014 }
1082 Ty::Opaque(o_ty) => { 1015 _ => {
1083 for t in o_ty.parameters.iter() { 1016 if let Some(substs) = self.substs() {
1084 t.walk(f); 1017 for t in substs.iter() {
1018 t.walk(f);
1019 }
1085 } 1020 }
1086 } 1021 }
1087 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
1088 } 1022 }
1089 f(self); 1023 f(self);
1090 } 1024 }
@@ -1095,10 +1029,7 @@ impl TypeWalk for Ty {
1095 binders: DebruijnIndex, 1029 binders: DebruijnIndex,
1096 ) { 1030 ) {
1097 match self { 1031 match self {
1098 Ty::Apply(a_ty) => { 1032 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); 1033 p_ty.parameters.walk_mut_binders(f, binders);
1103 } 1034 }
1104 Ty::Dyn(predicates) => { 1035 Ty::Dyn(predicates) => {
@@ -1106,10 +1037,14 @@ impl TypeWalk for Ty {
1106 p.walk_mut_binders(f, binders.shifted_in()); 1037 p.walk_mut_binders(f, binders.shifted_in());
1107 } 1038 }
1108 } 1039 }
1109 Ty::Opaque(o_ty) => { 1040 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1110 o_ty.parameters.walk_mut_binders(f, binders); 1041 o_ty.parameters.walk_mut_binders(f, binders);
1111 } 1042 }
1112 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1043 _ => {
1044 if let Some(substs) = self.substs_mut() {
1045 substs.walk_mut_binders(f, binders);
1046 }
1047 }
1113 } 1048 }
1114 f(self, binders); 1049 f(self, binders);
1115 } 1050 }