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.rs608
1 files changed, 279 insertions, 329 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index e00c7e176..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 expr::ExprId, 30 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AdtId, AssocContainerId,
31 type_ref::{Mutability, Rawness}, 31 DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId,
32 AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, LifetimeParamId, Lookup, 32 TypeAliasId, TypeParamId,
33 TraitId, TypeAliasId, TypeParamId,
34}; 33};
35use itertools::Itertools; 34use itertools::Itertools;
36 35
37use crate::{ 36use crate::{
38 db::HirDatabase, 37 db::HirDatabase,
39 display::HirDisplay, 38 display::HirDisplay,
40 primitive::{FloatTy, IntTy},
41 utils::{generics, make_mut_slice, Generics}, 39 utils::{generics, make_mut_slice, Generics},
42}; 40};
43 41
44pub use autoderef::autoderef; 42pub use autoderef::autoderef;
45pub use infer::{InferTy, InferenceResult}; 43pub use infer::{InferenceResult, InferenceVar};
46pub use lower::CallableDefId;
47pub use lower::{ 44pub use lower::{
48 associated_type_shorthand_candidates, callable_item_sig, ImplTraitLoweringMode, TyDefId, 45 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
49 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,209 +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, _) => Some(def.module(db.upcast()).krate),
227 },
228 }
229 }
230
231 pub fn as_generic_def(self) -> Option<GenericDefId> {
232 match self {
233 TypeCtor::Bool
234 | TypeCtor::Char
235 | TypeCtor::Int(_)
236 | TypeCtor::Float(_)
237 | TypeCtor::Str
238 | TypeCtor::Never
239 | TypeCtor::Slice
240 | TypeCtor::Array
241 | TypeCtor::RawPtr(_)
242 | TypeCtor::Ref(_)
243 | TypeCtor::FnPtr { .. }
244 | TypeCtor::Tuple { .. }
245 | TypeCtor::Closure { .. } => None,
246 TypeCtor::Adt(adt) => Some(adt.into()),
247 TypeCtor::FnDef(callable) => Some(callable.into()),
248 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
249 TypeCtor::ForeignType(type_alias) => Some(type_alias.into()),
250 TypeCtor::OpaqueType(_impl_trait_id) => None,
251 }
252 }
253}
254
255/// A nominal type with (maybe 0) type parameters. This might be a primitive
256/// type like `bool`, a struct, tuple, function pointer, reference or
257/// several other things.
258#[derive(Clone, PartialEq, Eq, Debug, Hash)]
259pub struct ApplicationTy {
260 pub ctor: TypeCtor,
261 pub parameters: Substs,
262}
263
264#[derive(Clone, PartialEq, Eq, Debug, Hash)] 58#[derive(Clone, PartialEq, Eq, Debug, Hash)]
265pub struct OpaqueTy { 59pub struct OpaqueTy {
266 pub opaque_ty_id: OpaqueTyId, 60 pub opaque_ty_id: OpaqueTyId,
@@ -303,29 +97,118 @@ impl TypeWalk for ProjectionTy {
303 } 97 }
304} 98}
305 99
306/// A type. 100#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
307/// 101pub struct FnSig {
308/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 102 pub variadic: bool,
309/// the same thing (but in a different way). 103}
310/// 104
311/// This should be cheap to clone.
312#[derive(Clone, PartialEq, Eq, Debug, Hash)] 105#[derive(Clone, PartialEq, Eq, Debug, Hash)]
313pub enum Ty { 106pub struct FnPointer {
314 /// A nominal type with (maybe 0) type parameters. This might be a primitive 107 pub num_args: usize,
315 /// type like `bool`, a struct, tuple, function pointer, reference or 108 pub sig: FnSig,
316 /// several other things. 109 pub substs: Substs,
317 Apply(ApplicationTy), 110}
318 111
112#[derive(Clone, PartialEq, Eq, Debug, Hash)]
113pub enum AliasTy {
319 /// A "projection" type corresponds to an (unnormalized) 114 /// A "projection" type corresponds to an (unnormalized)
320 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 115 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
321 /// trait and all its parameters are fully known. 116 /// trait and all its parameters are fully known.
322 Projection(ProjectionTy), 117 Projection(ProjectionTy),
323
324 /// An opaque type (`impl Trait`). 118 /// An opaque type (`impl Trait`).
325 /// 119 ///
326 /// 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
327 /// `impl Trait` in a return type gets its own ID. 121 /// `impl Trait` in a return type gets its own ID.
328 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),
329 212
330 /// 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)
331 /// {}` 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
@@ -338,10 +221,10 @@ pub enum Ty {
338 /// parameters get turned into variables; during trait resolution, inference 221 /// parameters get turned into variables; during trait resolution, inference
339 /// 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
340 /// `Self` type is represented with a bound variable as well. 223 /// `Self` type is represented with a bound variable as well.
341 Bound(BoundVar), 224 BoundVar(BoundVar),
342 225
343 /// A type variable used during type checking. 226 /// A type variable used during type checking.
344 Infer(InferTy), 227 InferenceVar(InferenceVar, TyVariableKind),
345 228
346 /// 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).
347 /// 230 ///
@@ -422,7 +305,7 @@ impl Substs {
422 generic_params 305 generic_params
423 .iter() 306 .iter()
424 .enumerate() 307 .enumerate()
425 .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) 308 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx)))
426 .collect(), 309 .collect(),
427 ) 310 )
428 } 311 }
@@ -438,10 +321,6 @@ impl Substs {
438 Substs::builder(generic_params.len()) 321 Substs::builder(generic_params.len())
439 } 322 }
440 323
441 pub fn build_for_type_ctor(db: &dyn HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder {
442 Substs::builder(type_ctor.num_ty_params(db))
443 }
444
445 fn builder(param_count: usize) -> SubstsBuilder { 324 fn builder(param_count: usize) -> SubstsBuilder {
446 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } 325 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
447 } 326 }
@@ -474,7 +353,7 @@ impl SubstsBuilder {
474 } 353 }
475 354
476 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 {
477 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))))
478 } 357 }
479 358
480 pub fn fill_with_unknown(self) -> Self { 359 pub fn fill_with_unknown(self) -> Self {
@@ -654,41 +533,41 @@ impl TypeWalk for GenericPredicate {
654#[derive(Debug, Clone, PartialEq, Eq, Hash)] 533#[derive(Debug, Clone, PartialEq, Eq, Hash)]
655pub struct Canonical<T> { 534pub struct Canonical<T> {
656 pub value: T, 535 pub value: T,
657 pub kinds: Arc<[TyKind]>, 536 pub kinds: Arc<[TyVariableKind]>,
658} 537}
659 538
660impl<T> Canonical<T> { 539impl<T> Canonical<T> {
661 pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { 540 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
662 Self { value, kinds: kinds.into_iter().collect() } 541 Self { value, kinds: kinds.into_iter().collect() }
663 } 542 }
664} 543}
665 544
666#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
667pub enum TyKind {
668 General,
669 Integer,
670 Float,
671}
672
673/// 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
674/// one return type. 546/// one return type.
675#[derive(Clone, PartialEq, Eq, Debug)] 547#[derive(Clone, PartialEq, Eq, Debug)]
676pub struct FnSig { 548pub struct CallableSig {
677 params_and_return: Arc<[Ty]>, 549 params_and_return: Arc<[Ty]>,
678 is_varargs: bool, 550 is_varargs: bool,
679} 551}
680 552
681/// A polymorphic function signature. 553/// A polymorphic function signature.
682pub type PolyFnSig = Binders<FnSig>; 554pub type PolyFnSig = Binders<CallableSig>;
683 555
684impl FnSig { 556impl CallableSig {
685 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 {
686 params.push(ret); 558 params.push(ret);
687 FnSig { params_and_return: params.into(), is_varargs } 559 CallableSig { params_and_return: params.into(), is_varargs }
688 } 560 }
689 561
690 pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { 562 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
691 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 }
692 } 571 }
693 572
694 pub fn params(&self) -> &[Ty] { 573 pub fn params(&self) -> &[Ty] {
@@ -700,7 +579,7 @@ impl FnSig {
700 } 579 }
701} 580}
702 581
703impl TypeWalk for FnSig { 582impl TypeWalk for CallableSig {
704 fn walk(&self, f: &mut impl FnMut(&Ty)) { 583 fn walk(&self, f: &mut impl FnMut(&Ty)) {
705 for t in self.params_and_return.iter() { 584 for t in self.params_and_return.iter() {
706 t.walk(f); 585 t.walk(f);
@@ -719,40 +598,42 @@ impl TypeWalk for FnSig {
719} 598}
720 599
721impl Ty { 600impl Ty {
722 pub fn simple(ctor: TypeCtor) -> Ty {
723 Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() })
724 }
725 pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty {
726 Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) })
727 }
728 pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty {
729 Ty::Apply(ApplicationTy { ctor, parameters })
730 }
731 pub fn unit() -> Self { 601 pub fn unit() -> Self {
732 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) 602 Ty::Tuple(0, Substs::empty())
733 } 603 }
734 pub fn fn_ptr(sig: FnSig) -> Self { 604
735 Ty::apply( 605 pub fn fn_ptr(sig: CallableSig) -> Self {
736 TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, 606 Ty::Function(FnPointer {
737 Substs(sig.params_and_return), 607 num_args: sig.params().len(),
738 ) 608 sig: FnSig { variadic: sig.is_varargs },
609 substs: Substs(sig.params_and_return),
610 })
611 }
612
613 pub fn builtin(builtin: BuiltinType) -> Self {
614 match builtin {
615 BuiltinType::Char => Ty::Scalar(Scalar::Char),
616 BuiltinType::Bool => Ty::Scalar(Scalar::Bool),
617 BuiltinType::Str => Ty::Str,
618 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
619 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))),
620 BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))),
621 }
739 } 622 }
740 623
741 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 624 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
742 match self { 625 match self {
743 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 626 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
744 Some((parameters.as_single(), *mutability))
745 }
746 _ => None, 627 _ => None,
747 } 628 }
748 } 629 }
749 630
750 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 631 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
751 match self { 632 match self {
752 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 633 Ty::Ref(mutability, parameters) => {
753 Some((parameters.as_single(), Rawness::Ref, *mutability)) 634 Some((parameters.as_single(), Rawness::Ref, *mutability))
754 } 635 }
755 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { 636 Ty::Raw(mutability, parameters) => {
756 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 637 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
757 } 638 }
758 _ => None, 639 _ => None,
@@ -762,7 +643,7 @@ impl Ty {
762 pub fn strip_references(&self) -> &Ty { 643 pub fn strip_references(&self) -> &Ty {
763 let mut t: &Ty = self; 644 let mut t: &Ty = self;
764 645
765 while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { 646 while let Ty::Ref(_mutability, parameters) = t {
766 t = parameters.as_single(); 647 t = parameters.as_single();
767 } 648 }
768 649
@@ -771,30 +652,60 @@ impl Ty {
771 652
772 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { 653 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
773 match self { 654 match self {
774 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 655 Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)),
775 Some((*adt_def, parameters))
776 }
777 _ => None, 656 _ => None,
778 } 657 }
779 } 658 }
780 659
781 pub fn as_tuple(&self) -> Option<&Substs> { 660 pub fn as_tuple(&self) -> Option<&Substs> {
782 match self { 661 match self {
783 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { 662 Ty::Tuple(_, substs) => Some(substs),
784 Some(parameters) 663 _ => None,
785 } 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()),
786 _ => None, 673 _ => None,
787 } 674 }
788 } 675 }
789 676
790 pub fn is_never(&self) -> bool { 677 pub fn is_never(&self) -> bool {
791 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) 678 matches!(self, Ty::Never)
792 } 679 }
793 680
794 pub fn is_unknown(&self) -> bool { 681 pub fn is_unknown(&self) -> bool {
795 matches!(self, Ty::Unknown) 682 matches!(self, Ty::Unknown)
796 } 683 }
797 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
798 /// 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.
799 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 710 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
800 match self { 711 match self {
@@ -813,31 +724,30 @@ impl Ty {
813 724
814 fn builtin_deref(&self) -> Option<Ty> { 725 fn builtin_deref(&self) -> Option<Ty> {
815 match self { 726 match self {
816 Ty::Apply(a_ty) => match a_ty.ctor { 727 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
817 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), 728 Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())),
818 TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
819 _ => None,
820 },
821 _ => None, 729 _ => None,
822 } 730 }
823 } 731 }
824 732
825 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 733 pub fn as_fn_def(&self) -> Option<FunctionId> {
826 match self { 734 match self {
827 Ty::Apply(a_ty) => match a_ty.ctor { 735 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func),
828 TypeCtor::FnPtr { is_varargs, .. } => { 736 _ => None,
829 Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) 737 }
830 } 738 }
831 TypeCtor::FnDef(def) => { 739
832 let sig = db.callable_item_signature(def); 740 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
833 Some(sig.subst(&a_ty.parameters)) 741 match self {
834 } 742 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
835 TypeCtor::Closure { .. } => { 743 Ty::FnDef(def, parameters) => {
836 let sig_param = &a_ty.parameters[0]; 744 let sig = db.callable_item_signature(*def);
837 sig_param.callable_sig(db) 745 Some(sig.subst(&parameters))
838 } 746 }
839 _ => None, 747 Ty::Closure(.., substs) => {
840 }, 748 let sig_param = &substs[0];
749 sig_param.callable_sig(db)
750 }
841 _ => None, 751 _ => None,
842 } 752 }
843 } 753 }
@@ -846,31 +756,69 @@ impl Ty {
846 /// 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
847 /// `self` is `Option<_>` and the substs contain `u32`, we'll have 757 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
848 /// `Option<u32>` afterwards.) 758 /// `Option<u32>` afterwards.)
849 pub fn apply_substs(self, substs: Substs) -> Ty { 759 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
850 match self { 760 match &mut self {
851 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { 761 Ty::Adt(_, substs)
852 assert_eq!(previous_substs.len(), substs.len()); 762 | Ty::Slice(substs)
853 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;
854 } 774 }
855 _ => self, 775 _ => (),
856 } 776 }
777 self
857 } 778 }
858 779
859 /// 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
860 /// 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`.
861 pub fn substs(&self) -> Option<Substs> { 782 pub fn substs(&self) -> Option<&Substs> {
862 match self { 783 match self {
863 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),
864 _ => None, 812 _ => None,
865 } 813 }
866 } 814 }
867 815
868 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>> {
869 match self { 817 match self {
870 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { 818 Ty::OpaqueType(opaque_ty_id, ..) => {
871 match opaque_ty_id { 819 match opaque_ty_id {
872 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 820 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
873 let krate = def.module(db.upcast()).krate; 821 let krate = def.module(db.upcast()).krate();
874 if let Some(future_trait) = db 822 if let Some(future_trait) = db
875 .lang_item(krate, "future_trait".into()) 823 .lang_item(krate, "future_trait".into())
876 .and_then(|item| item.as_trait()) 824 .and_then(|item| item.as_trait())
@@ -890,7 +838,7 @@ impl Ty {
890 OpaqueTyId::ReturnTypeImplTrait(..) => None, 838 OpaqueTyId::ReturnTypeImplTrait(..) => None,
891 } 839 }
892 } 840 }
893 Ty::Opaque(opaque_ty) => { 841 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
894 let predicates = match opaque_ty.opaque_ty_id { 842 let predicates = match opaque_ty.opaque_ty_id {
895 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 843 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
896 db.return_type_impl_traits(func).map(|it| { 844 db.return_type_impl_traits(func).map(|it| {
@@ -928,13 +876,13 @@ impl Ty {
928 876
929 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> {
930 match self { 878 match self {
931 Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { 879 Ty::AssociatedType(type_alias_id, ..) => {
932 match type_alias_id.lookup(db.upcast()).container { 880 match type_alias_id.lookup(db.upcast()).container {
933 AssocContainerId::TraitId(trait_id) => Some(trait_id), 881 AssocContainerId::TraitId(trait_id) => Some(trait_id),
934 _ => None, 882 _ => None,
935 } 883 }
936 } 884 }
937 Ty::Projection(projection_ty) => { 885 Ty::Alias(AliasTy::Projection(projection_ty)) => {
938 match projection_ty.associated_ty.lookup(db.upcast()).container { 886 match projection_ty.associated_ty.lookup(db.upcast()).container {
939 AssocContainerId::TraitId(trait_id) => Some(trait_id), 887 AssocContainerId::TraitId(trait_id) => Some(trait_id),
940 _ => None, 888 _ => None,
@@ -1012,7 +960,7 @@ pub trait TypeWalk {
1012 { 960 {
1013 self.walk_mut_binders( 961 self.walk_mut_binders(
1014 &mut |ty, binders| { 962 &mut |ty, binders| {
1015 if let &mut Ty::Bound(bound) = ty { 963 if let &mut Ty::BoundVar(bound) = ty {
1016 if bound.debruijn >= binders { 964 if bound.debruijn >= binders {
1017 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 965 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
1018 } 966 }
@@ -1030,8 +978,8 @@ pub trait TypeWalk {
1030 { 978 {
1031 self.fold_binders( 979 self.fold_binders(
1032 &mut |ty, binders| match ty { 980 &mut |ty, binders| match ty {
1033 Ty::Bound(bound) if bound.debruijn >= binders => { 981 Ty::BoundVar(bound) if bound.debruijn >= binders => {
1034 Ty::Bound(bound.shifted_in_from(n)) 982 Ty::BoundVar(bound.shifted_in_from(n))
1035 } 983 }
1036 ty => ty, 984 ty => ty,
1037 }, 985 },
@@ -1043,13 +991,13 @@ pub trait TypeWalk {
1043impl TypeWalk for Ty { 991impl TypeWalk for Ty {
1044 fn walk(&self, f: &mut impl FnMut(&Ty)) { 992 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1045 match self { 993 match self {
1046 Ty::Apply(a_ty) => { 994 Ty::Alias(AliasTy::Projection(p_ty)) => {
1047 for t in a_ty.parameters.iter() { 995 for t in p_ty.parameters.iter() {
1048 t.walk(f); 996 t.walk(f);
1049 } 997 }
1050 } 998 }
1051 Ty::Projection(p_ty) => { 999 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1052 for t in p_ty.parameters.iter() { 1000 for t in o_ty.parameters.iter() {
1053 t.walk(f); 1001 t.walk(f);
1054 } 1002 }
1055 } 1003 }
@@ -1058,12 +1006,13 @@ impl TypeWalk for Ty {
1058 p.walk(f); 1006 p.walk(f);
1059 } 1007 }
1060 } 1008 }
1061 Ty::Opaque(o_ty) => { 1009 _ => {
1062 for t in o_ty.parameters.iter() { 1010 if let Some(substs) = self.substs() {
1063 t.walk(f); 1011 for t in substs.iter() {
1012 t.walk(f);
1013 }
1064 } 1014 }
1065 } 1015 }
1066 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
1067 } 1016 }
1068 f(self); 1017 f(self);
1069 } 1018 }
@@ -1074,10 +1023,7 @@ impl TypeWalk for Ty {
1074 binders: DebruijnIndex, 1023 binders: DebruijnIndex,
1075 ) { 1024 ) {
1076 match self { 1025 match self {
1077 Ty::Apply(a_ty) => { 1026 Ty::Alias(AliasTy::Projection(p_ty)) => {
1078 a_ty.parameters.walk_mut_binders(f, binders);
1079 }
1080 Ty::Projection(p_ty) => {
1081 p_ty.parameters.walk_mut_binders(f, binders); 1027 p_ty.parameters.walk_mut_binders(f, binders);
1082 } 1028 }
1083 Ty::Dyn(predicates) => { 1029 Ty::Dyn(predicates) => {
@@ -1085,10 +1031,14 @@ impl TypeWalk for Ty {
1085 p.walk_mut_binders(f, binders.shifted_in()); 1031 p.walk_mut_binders(f, binders.shifted_in());
1086 } 1032 }
1087 } 1033 }
1088 Ty::Opaque(o_ty) => { 1034 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1089 o_ty.parameters.walk_mut_binders(f, binders); 1035 o_ty.parameters.walk_mut_binders(f, binders);
1090 } 1036 }
1091 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 }
1092 } 1042 }
1093 f(self, binders); 1043 f(self, binders);
1094 } 1044 }