aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lib.rs
diff options
context:
space:
mode:
authorSeivan Heidari <[email protected]>2019-11-28 07:19:14 +0000
committerSeivan Heidari <[email protected]>2019-11-28 07:19:14 +0000
commit18a0937585b836ec5ed054b9ae48e0156ab6d9ef (patch)
tree9de2c0267ddcc00df717f90034d0843d751a851b /crates/ra_hir_ty/src/lib.rs
parenta7394b44c870f585eacfeb3036a33471aff49ff8 (diff)
parent484acc8a61d599662ed63a4cbda091d38a982551 (diff)
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
Diffstat (limited to 'crates/ra_hir_ty/src/lib.rs')
-rw-r--r--crates/ra_hir_ty/src/lib.rs1138
1 files changed, 1138 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
new file mode 100644
index 000000000..b45c8f82f
--- /dev/null
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -0,0 +1,1138 @@
1//! The type system. We currently use this to infer types for completion, hover
2//! information and various assists.
3
4macro_rules! impl_froms {
5 ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
6 $(
7 impl From<$v> for $e {
8 fn from(it: $v) -> $e {
9 $e::$v(it)
10 }
11 }
12 $($(
13 impl From<$sv> for $e {
14 fn from(it: $sv) -> $e {
15 $e::$v($v::$sv(it))
16 }
17 }
18 )*)?
19 )*
20 }
21}
22
23mod autoderef;
24pub mod primitive;
25pub mod traits;
26pub mod method_resolution;
27mod op;
28mod lower;
29mod infer;
30pub mod display;
31pub(crate) mod utils;
32pub mod db;
33pub mod diagnostics;
34pub mod expr;
35
36#[cfg(test)]
37mod tests;
38#[cfg(test)]
39mod test_db;
40mod marks;
41
42use std::ops::Deref;
43use std::sync::Arc;
44use std::{fmt, iter, mem};
45
46use hir_def::{
47 expr::ExprId, generics::GenericParams, type_ref::Mutability, AdtId, ContainerId, DefWithBodyId,
48 GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
49};
50use hir_expand::name::Name;
51use ra_db::{impl_intern_key, salsa, CrateId};
52
53use crate::{
54 db::HirDatabase,
55 primitive::{FloatTy, IntTy, Uncertain},
56 utils::make_mut_slice,
57};
58use display::{HirDisplay, HirFormatter};
59
60pub use autoderef::autoderef;
61pub use infer::{infer_query, InferTy, InferenceResult};
62pub use lower::CallableDef;
63pub use lower::{callable_item_sig, TyDefId, ValueTyDefId};
64pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
65
66/// A type constructor or type name: this might be something like the primitive
67/// type `bool`, a struct like `Vec`, or things like function pointers or
68/// tuples.
69#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
70pub enum TypeCtor {
71 /// The primitive boolean type. Written as `bool`.
72 Bool,
73
74 /// The primitive character type; holds a Unicode scalar value
75 /// (a non-surrogate code point). Written as `char`.
76 Char,
77
78 /// A primitive integer type. For example, `i32`.
79 Int(Uncertain<IntTy>),
80
81 /// A primitive floating-point type. For example, `f64`.
82 Float(Uncertain<FloatTy>),
83
84 /// Structures, enumerations and unions.
85 Adt(AdtId),
86
87 /// The pointee of a string slice. Written as `str`.
88 Str,
89
90 /// The pointee of an array slice. Written as `[T]`.
91 Slice,
92
93 /// An array with the given length. Written as `[T; n]`.
94 Array,
95
96 /// A raw pointer. Written as `*mut T` or `*const T`
97 RawPtr(Mutability),
98
99 /// A reference; a pointer with an associated lifetime. Written as
100 /// `&'a mut T` or `&'a T`.
101 Ref(Mutability),
102
103 /// The anonymous type of a function declaration/definition. Each
104 /// function has a unique type, which is output (for a function
105 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
106 ///
107 /// This includes tuple struct / enum variant constructors as well.
108 ///
109 /// For example the type of `bar` here:
110 ///
111 /// ```
112 /// fn foo() -> i32 { 1 }
113 /// let bar = foo; // bar: fn() -> i32 {foo}
114 /// ```
115 FnDef(CallableDef),
116
117 /// A pointer to a function. Written as `fn() -> i32`.
118 ///
119 /// For example the type of `bar` here:
120 ///
121 /// ```
122 /// fn foo() -> i32 { 1 }
123 /// let bar: fn() -> i32 = foo;
124 /// ```
125 FnPtr { num_args: u16 },
126
127 /// The never type `!`.
128 Never,
129
130 /// A tuple type. For example, `(i32, bool)`.
131 Tuple { cardinality: u16 },
132
133 /// Represents an associated item like `Iterator::Item`. This is used
134 /// when we have tried to normalize a projection like `T::Item` but
135 /// couldn't find a better representation. In that case, we generate
136 /// an **application type** like `(Iterator::Item)<T>`.
137 AssociatedType(TypeAliasId),
138
139 /// The type of a specific closure.
140 ///
141 /// The closure signature is stored in a `FnPtr` type in the first type
142 /// parameter.
143 Closure { def: DefWithBodyId, expr: ExprId },
144}
145
146/// This exists just for Chalk, because Chalk just has a single `StructId` where
147/// we have different kinds of ADTs, primitive types and special type
148/// constructors like tuples and function pointers.
149#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
150pub struct TypeCtorId(salsa::InternId);
151impl_intern_key!(TypeCtorId);
152
153impl TypeCtor {
154 pub fn num_ty_params(self, db: &impl HirDatabase) -> usize {
155 match self {
156 TypeCtor::Bool
157 | TypeCtor::Char
158 | TypeCtor::Int(_)
159 | TypeCtor::Float(_)
160 | TypeCtor::Str
161 | TypeCtor::Never => 0,
162 TypeCtor::Slice
163 | TypeCtor::Array
164 | TypeCtor::RawPtr(_)
165 | TypeCtor::Ref(_)
166 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure
167 => 1,
168 TypeCtor::Adt(adt) => {
169 let generic_params = db.generic_params(AdtId::from(adt).into());
170 generic_params.count_params_including_parent()
171 }
172 TypeCtor::FnDef(callable) => {
173 let generic_params = db.generic_params(callable.into());
174 generic_params.count_params_including_parent()
175 }
176 TypeCtor::AssociatedType(type_alias) => {
177 let generic_params = db.generic_params(type_alias.into());
178 generic_params.count_params_including_parent()
179 }
180 TypeCtor::FnPtr { num_args } => num_args as usize + 1,
181 TypeCtor::Tuple { cardinality } => cardinality as usize,
182 }
183 }
184
185 pub fn krate(self, db: &impl HirDatabase) -> Option<CrateId> {
186 match self {
187 TypeCtor::Bool
188 | TypeCtor::Char
189 | TypeCtor::Int(_)
190 | TypeCtor::Float(_)
191 | TypeCtor::Str
192 | TypeCtor::Never
193 | TypeCtor::Slice
194 | TypeCtor::Array
195 | TypeCtor::RawPtr(_)
196 | TypeCtor::Ref(_)
197 | TypeCtor::FnPtr { .. }
198 | TypeCtor::Tuple { .. } => None,
199 // Closure's krate is irrelevant for coherence I would think?
200 TypeCtor::Closure { .. } => None,
201 TypeCtor::Adt(adt) => Some(adt.module(db).krate),
202 TypeCtor::FnDef(callable) => Some(callable.krate(db)),
203 TypeCtor::AssociatedType(type_alias) => Some(type_alias.lookup(db).module(db).krate),
204 }
205 }
206
207 pub fn as_generic_def(self) -> Option<GenericDefId> {
208 match self {
209 TypeCtor::Bool
210 | TypeCtor::Char
211 | TypeCtor::Int(_)
212 | TypeCtor::Float(_)
213 | TypeCtor::Str
214 | TypeCtor::Never
215 | TypeCtor::Slice
216 | TypeCtor::Array
217 | TypeCtor::RawPtr(_)
218 | TypeCtor::Ref(_)
219 | TypeCtor::FnPtr { .. }
220 | TypeCtor::Tuple { .. }
221 | TypeCtor::Closure { .. } => None,
222 TypeCtor::Adt(adt) => Some(adt.into()),
223 TypeCtor::FnDef(callable) => Some(callable.into()),
224 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
225 }
226 }
227}
228
229/// A nominal type with (maybe 0) type parameters. This might be a primitive
230/// type like `bool`, a struct, tuple, function pointer, reference or
231/// several other things.
232#[derive(Clone, PartialEq, Eq, Debug, Hash)]
233pub struct ApplicationTy {
234 pub ctor: TypeCtor,
235 pub parameters: Substs,
236}
237
238/// A "projection" type corresponds to an (unnormalized)
239/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
240/// trait and all its parameters are fully known.
241#[derive(Clone, PartialEq, Eq, Debug, Hash)]
242pub struct ProjectionTy {
243 pub associated_ty: TypeAliasId,
244 pub parameters: Substs,
245}
246
247impl ProjectionTy {
248 pub fn trait_ref(&self, db: &impl HirDatabase) -> TraitRef {
249 TraitRef { trait_: self.trait_(db).into(), substs: self.parameters.clone() }
250 }
251
252 fn trait_(&self, db: &impl HirDatabase) -> TraitId {
253 match self.associated_ty.lookup(db).container {
254 ContainerId::TraitId(it) => it,
255 _ => panic!("projection ty without parent trait"),
256 }
257 }
258}
259
260impl TypeWalk for ProjectionTy {
261 fn walk(&self, f: &mut impl FnMut(&Ty)) {
262 self.parameters.walk(f);
263 }
264
265 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
266 self.parameters.walk_mut_binders(f, binders);
267 }
268}
269
270/// A type.
271///
272/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
273/// the same thing (but in a different way).
274///
275/// This should be cheap to clone.
276#[derive(Clone, PartialEq, Eq, Debug, Hash)]
277pub enum Ty {
278 /// A nominal type with (maybe 0) type parameters. This might be a primitive
279 /// type like `bool`, a struct, tuple, function pointer, reference or
280 /// several other things.
281 Apply(ApplicationTy),
282
283 /// A "projection" type corresponds to an (unnormalized)
284 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
285 /// trait and all its parameters are fully known.
286 Projection(ProjectionTy),
287
288 /// A type parameter; for example, `T` in `fn f<T>(x: T) {}
289 Param {
290 /// The index of the parameter (starting with parameters from the
291 /// surrounding impl, then the current function).
292 idx: u32,
293 /// The name of the parameter, for displaying.
294 // FIXME get rid of this
295 name: Name,
296 },
297
298 /// A bound type variable. Used during trait resolution to represent Chalk
299 /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type.
300 Bound(u32),
301
302 /// A type variable used during type checking. Not to be confused with a
303 /// type parameter.
304 Infer(InferTy),
305
306 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
307 ///
308 /// The predicates are quantified over the `Self` type, i.e. `Ty::Bound(0)`
309 /// represents the `Self` type inside the bounds. This is currently
310 /// implicit; Chalk has the `Binders` struct to make it explicit, but it
311 /// didn't seem worth the overhead yet.
312 Dyn(Arc<[GenericPredicate]>),
313
314 /// An opaque type (`impl Trait`).
315 ///
316 /// The predicates are quantified over the `Self` type; see `Ty::Dyn` for
317 /// more.
318 Opaque(Arc<[GenericPredicate]>),
319
320 /// A placeholder for a type which could not be computed; this is propagated
321 /// to avoid useless error messages. Doubles as a placeholder where type
322 /// variables are inserted before type checking, since we want to try to
323 /// infer a better type here anyway -- for the IDE use case, we want to try
324 /// to infer as much as possible even in the presence of type errors.
325 Unknown,
326}
327
328/// A list of substitutions for generic parameters.
329#[derive(Clone, PartialEq, Eq, Debug, Hash)]
330pub struct Substs(Arc<[Ty]>);
331
332impl TypeWalk for Substs {
333 fn walk(&self, f: &mut impl FnMut(&Ty)) {
334 for t in self.0.iter() {
335 t.walk(f);
336 }
337 }
338
339 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
340 for t in make_mut_slice(&mut self.0) {
341 t.walk_mut_binders(f, binders);
342 }
343 }
344}
345
346impl Substs {
347 pub fn empty() -> Substs {
348 Substs(Arc::new([]))
349 }
350
351 pub fn single(ty: Ty) -> Substs {
352 Substs(Arc::new([ty]))
353 }
354
355 pub fn prefix(&self, n: usize) -> Substs {
356 Substs(self.0[..std::cmp::min(self.0.len(), n)].into())
357 }
358
359 pub fn as_single(&self) -> &Ty {
360 if self.0.len() != 1 {
361 panic!("expected substs of len 1, got {:?}", self);
362 }
363 &self.0[0]
364 }
365
366 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
367 pub fn identity(generic_params: &GenericParams) -> Substs {
368 Substs(
369 generic_params
370 .params_including_parent()
371 .into_iter()
372 .map(|p| Ty::Param { idx: p.idx, name: p.name.clone() })
373 .collect(),
374 )
375 }
376
377 /// Return Substs that replace each parameter by a bound variable.
378 pub fn bound_vars(generic_params: &GenericParams) -> Substs {
379 Substs(
380 generic_params
381 .params_including_parent()
382 .into_iter()
383 .map(|p| Ty::Bound(p.idx))
384 .collect(),
385 )
386 }
387
388 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
389 let def = def.into();
390 let params = db.generic_params(def);
391 let param_count = params.count_params_including_parent();
392 Substs::builder(param_count)
393 }
394
395 pub fn build_for_generics(generic_params: &GenericParams) -> SubstsBuilder {
396 Substs::builder(generic_params.count_params_including_parent())
397 }
398
399 pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder {
400 Substs::builder(type_ctor.num_ty_params(db))
401 }
402
403 fn builder(param_count: usize) -> SubstsBuilder {
404 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
405 }
406}
407
408#[derive(Debug, Clone)]
409pub struct SubstsBuilder {
410 vec: Vec<Ty>,
411 param_count: usize,
412}
413
414impl SubstsBuilder {
415 pub fn build(self) -> Substs {
416 assert_eq!(self.vec.len(), self.param_count);
417 Substs(self.vec.into())
418 }
419
420 pub fn push(mut self, ty: Ty) -> Self {
421 self.vec.push(ty);
422 self
423 }
424
425 fn remaining(&self) -> usize {
426 self.param_count - self.vec.len()
427 }
428
429 pub fn fill_with_bound_vars(self, starting_from: u32) -> Self {
430 self.fill((starting_from..).map(Ty::Bound))
431 }
432
433 pub fn fill_with_params(self) -> Self {
434 let start = self.vec.len() as u32;
435 self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() }))
436 }
437
438 pub fn fill_with_unknown(self) -> Self {
439 self.fill(iter::repeat(Ty::Unknown))
440 }
441
442 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self {
443 self.vec.extend(filler.take(self.remaining()));
444 assert_eq!(self.remaining(), 0);
445 self
446 }
447
448 pub fn use_parent_substs(mut self, parent_substs: &Substs) -> Self {
449 assert!(self.vec.is_empty());
450 assert!(parent_substs.len() <= self.param_count);
451 self.vec.extend(parent_substs.iter().cloned());
452 self
453 }
454}
455
456impl Deref for Substs {
457 type Target = [Ty];
458
459 fn deref(&self) -> &[Ty] {
460 &self.0
461 }
462}
463
464/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
465/// Name to be bikeshedded: TraitBound? TraitImplements?
466#[derive(Clone, PartialEq, Eq, Debug, Hash)]
467pub struct TraitRef {
468 /// FIXME name?
469 pub trait_: TraitId,
470 pub substs: Substs,
471}
472
473impl TraitRef {
474 pub fn self_ty(&self) -> &Ty {
475 &self.substs[0]
476 }
477}
478
479impl TypeWalk for TraitRef {
480 fn walk(&self, f: &mut impl FnMut(&Ty)) {
481 self.substs.walk(f);
482 }
483
484 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
485 self.substs.walk_mut_binders(f, binders);
486 }
487}
488
489#[derive(Clone, PartialEq, Eq, Debug)]
490pub enum ImplTy {
491 Inherent(Ty),
492 TraitRef(TraitRef),
493}
494
495impl ImplTy {
496 pub(crate) fn self_type(&self) -> &Ty {
497 match self {
498 ImplTy::Inherent(it) => it,
499 ImplTy::TraitRef(tr) => &tr.substs[0],
500 }
501 }
502}
503
504/// Like `generics::WherePredicate`, but with resolved types: A condition on the
505/// parameters of a generic item.
506#[derive(Debug, Clone, PartialEq, Eq, Hash)]
507pub enum GenericPredicate {
508 /// The given trait needs to be implemented for its type parameters.
509 Implemented(TraitRef),
510 /// An associated type bindings like in `Iterator<Item = T>`.
511 Projection(ProjectionPredicate),
512 /// We couldn't resolve the trait reference. (If some type parameters can't
513 /// be resolved, they will just be Unknown).
514 Error,
515}
516
517impl GenericPredicate {
518 pub fn is_error(&self) -> bool {
519 match self {
520 GenericPredicate::Error => true,
521 _ => false,
522 }
523 }
524
525 pub fn is_implemented(&self) -> bool {
526 match self {
527 GenericPredicate::Implemented(_) => true,
528 _ => false,
529 }
530 }
531
532 pub fn trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
533 match self {
534 GenericPredicate::Implemented(tr) => Some(tr.clone()),
535 GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)),
536 GenericPredicate::Error => None,
537 }
538 }
539}
540
541impl TypeWalk for GenericPredicate {
542 fn walk(&self, f: &mut impl FnMut(&Ty)) {
543 match self {
544 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
545 GenericPredicate::Projection(projection_pred) => projection_pred.walk(f),
546 GenericPredicate::Error => {}
547 }
548 }
549
550 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
551 match self {
552 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
553 GenericPredicate::Projection(projection_pred) => {
554 projection_pred.walk_mut_binders(f, binders)
555 }
556 GenericPredicate::Error => {}
557 }
558 }
559}
560
561/// Basically a claim (currently not validated / checked) that the contained
562/// type / trait ref contains no inference variables; any inference variables it
563/// contained have been replaced by bound variables, and `num_vars` tells us how
564/// many there are. This is used to erase irrelevant differences between types
565/// before using them in queries.
566#[derive(Debug, Clone, PartialEq, Eq, Hash)]
567pub struct Canonical<T> {
568 pub value: T,
569 pub num_vars: usize,
570}
571
572/// A function signature as seen by type inference: Several parameter types and
573/// one return type.
574#[derive(Clone, PartialEq, Eq, Debug)]
575pub struct FnSig {
576 params_and_return: Arc<[Ty]>,
577}
578
579impl FnSig {
580 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
581 params.push(ret);
582 FnSig { params_and_return: params.into() }
583 }
584
585 pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig {
586 FnSig { params_and_return: Arc::clone(&substs.0) }
587 }
588
589 pub fn params(&self) -> &[Ty] {
590 &self.params_and_return[0..self.params_and_return.len() - 1]
591 }
592
593 pub fn ret(&self) -> &Ty {
594 &self.params_and_return[self.params_and_return.len() - 1]
595 }
596}
597
598impl TypeWalk for FnSig {
599 fn walk(&self, f: &mut impl FnMut(&Ty)) {
600 for t in self.params_and_return.iter() {
601 t.walk(f);
602 }
603 }
604
605 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
606 for t in make_mut_slice(&mut self.params_and_return) {
607 t.walk_mut_binders(f, binders);
608 }
609 }
610}
611
612impl Ty {
613 pub fn simple(ctor: TypeCtor) -> Ty {
614 Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() })
615 }
616 pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty {
617 Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) })
618 }
619 pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty {
620 Ty::Apply(ApplicationTy { ctor, parameters })
621 }
622 pub fn unit() -> Self {
623 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty())
624 }
625
626 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
627 match self {
628 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => {
629 Some((parameters.as_single(), *mutability))
630 }
631 _ => None,
632 }
633 }
634
635 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
636 match self {
637 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => {
638 Some((*adt_def, parameters))
639 }
640 _ => None,
641 }
642 }
643
644 pub fn as_tuple(&self) -> Option<&Substs> {
645 match self {
646 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => {
647 Some(parameters)
648 }
649 _ => None,
650 }
651 }
652
653 pub fn as_callable(&self) -> Option<(CallableDef, &Substs)> {
654 match self {
655 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => {
656 Some((*callable_def, parameters))
657 }
658 _ => None,
659 }
660 }
661
662 fn builtin_deref(&self) -> Option<Ty> {
663 match self {
664 Ty::Apply(a_ty) => match a_ty.ctor {
665 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())),
666 TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
667 _ => None,
668 },
669 _ => None,
670 }
671 }
672
673 fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
674 match self {
675 Ty::Apply(a_ty) => match a_ty.ctor {
676 TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)),
677 TypeCtor::FnDef(def) => {
678 let sig = db.callable_item_signature(def);
679 Some(sig.subst(&a_ty.parameters))
680 }
681 TypeCtor::Closure { .. } => {
682 let sig_param = &a_ty.parameters[0];
683 sig_param.callable_sig(db)
684 }
685 _ => None,
686 },
687 _ => None,
688 }
689 }
690
691 /// If this is a type with type parameters (an ADT or function), replaces
692 /// the `Substs` for these type parameters with the given ones. (So e.g. if
693 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
694 /// `Option<u32>` afterwards.)
695 pub fn apply_substs(self, substs: Substs) -> Ty {
696 match self {
697 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => {
698 assert_eq!(previous_substs.len(), substs.len());
699 Ty::Apply(ApplicationTy { ctor, parameters: substs })
700 }
701 _ => self,
702 }
703 }
704
705 /// Returns the type parameters of this type if it has some (i.e. is an ADT
706 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
707 pub fn substs(&self) -> Option<Substs> {
708 match self {
709 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()),
710 _ => None,
711 }
712 }
713
714 /// If this is an `impl Trait` or `dyn Trait`, returns that trait.
715 pub fn inherent_trait(&self) -> Option<TraitId> {
716 match self {
717 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
718 predicates.iter().find_map(|pred| match pred {
719 GenericPredicate::Implemented(tr) => Some(tr.trait_),
720 _ => None,
721 })
722 }
723 _ => None,
724 }
725 }
726}
727
728/// This allows walking structures that contain types to do something with those
729/// types, similar to Chalk's `Fold` trait.
730pub trait TypeWalk {
731 fn walk(&self, f: &mut impl FnMut(&Ty));
732 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
733 self.walk_mut_binders(&mut |ty, _binders| f(ty), 0);
734 }
735 /// Walk the type, counting entered binders.
736 ///
737 /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers
738 /// to the innermost binder, 1 to the next, etc.. So when we want to
739 /// substitute a certain bound variable, we can't just walk the whole type
740 /// and blindly replace each instance of a certain index; when we 'enter'
741 /// things that introduce new bound variables, we have to keep track of
742 /// that. Currently, the only thing that introduces bound variables on our
743 /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound
744 /// variable for the self type.
745 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize);
746
747 fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self
748 where
749 Self: Sized,
750 {
751 self.walk_mut(&mut |ty_mut| {
752 let ty = mem::replace(ty_mut, Ty::Unknown);
753 *ty_mut = f(ty);
754 });
755 self
756 }
757
758 /// Replaces type parameters in this type using the given `Substs`. (So e.g.
759 /// if `self` is `&[T]`, where type parameter T has index 0, and the
760 /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
761 fn subst(self, substs: &Substs) -> Self
762 where
763 Self: Sized,
764 {
765 self.fold(&mut |ty| match ty {
766 Ty::Param { idx, name } => {
767 substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name })
768 }
769 ty => ty,
770 })
771 }
772
773 /// Substitutes `Ty::Bound` vars (as opposed to type parameters).
774 fn subst_bound_vars(mut self, substs: &Substs) -> Self
775 where
776 Self: Sized,
777 {
778 self.walk_mut_binders(
779 &mut |ty, binders| match ty {
780 &mut Ty::Bound(idx) => {
781 if idx as usize >= binders && (idx as usize - binders) < substs.len() {
782 *ty = substs.0[idx as usize - binders].clone();
783 }
784 }
785 _ => {}
786 },
787 0,
788 );
789 self
790 }
791
792 /// Shifts up `Ty::Bound` vars by `n`.
793 fn shift_bound_vars(self, n: i32) -> Self
794 where
795 Self: Sized,
796 {
797 self.fold(&mut |ty| match ty {
798 Ty::Bound(idx) => {
799 assert!(idx as i32 >= -n);
800 Ty::Bound((idx as i32 + n) as u32)
801 }
802 ty => ty,
803 })
804 }
805}
806
807impl TypeWalk for Ty {
808 fn walk(&self, f: &mut impl FnMut(&Ty)) {
809 match self {
810 Ty::Apply(a_ty) => {
811 for t in a_ty.parameters.iter() {
812 t.walk(f);
813 }
814 }
815 Ty::Projection(p_ty) => {
816 for t in p_ty.parameters.iter() {
817 t.walk(f);
818 }
819 }
820 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
821 for p in predicates.iter() {
822 p.walk(f);
823 }
824 }
825 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
826 }
827 f(self);
828 }
829
830 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
831 match self {
832 Ty::Apply(a_ty) => {
833 a_ty.parameters.walk_mut_binders(f, binders);
834 }
835 Ty::Projection(p_ty) => {
836 p_ty.parameters.walk_mut_binders(f, binders);
837 }
838 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
839 for p in make_mut_slice(predicates) {
840 p.walk_mut_binders(f, binders + 1);
841 }
842 }
843 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
844 }
845 f(self, binders);
846 }
847}
848
849impl HirDisplay for &Ty {
850 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
851 HirDisplay::hir_fmt(*self, f)
852 }
853}
854
855impl HirDisplay for ApplicationTy {
856 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
857 if f.should_truncate() {
858 return write!(f, "…");
859 }
860
861 match self.ctor {
862 TypeCtor::Bool => write!(f, "bool")?,
863 TypeCtor::Char => write!(f, "char")?,
864 TypeCtor::Int(t) => write!(f, "{}", t)?,
865 TypeCtor::Float(t) => write!(f, "{}", t)?,
866 TypeCtor::Str => write!(f, "str")?,
867 TypeCtor::Slice => {
868 let t = self.parameters.as_single();
869 write!(f, "[{}]", t.display(f.db))?;
870 }
871 TypeCtor::Array => {
872 let t = self.parameters.as_single();
873 write!(f, "[{};_]", t.display(f.db))?;
874 }
875 TypeCtor::RawPtr(m) => {
876 let t = self.parameters.as_single();
877 write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;
878 }
879 TypeCtor::Ref(m) => {
880 let t = self.parameters.as_single();
881 write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
882 }
883 TypeCtor::Never => write!(f, "!")?,
884 TypeCtor::Tuple { .. } => {
885 let ts = &self.parameters;
886 if ts.len() == 1 {
887 write!(f, "({},)", ts[0].display(f.db))?;
888 } else {
889 write!(f, "(")?;
890 f.write_joined(&*ts.0, ", ")?;
891 write!(f, ")")?;
892 }
893 }
894 TypeCtor::FnPtr { .. } => {
895 let sig = FnSig::from_fn_ptr_substs(&self.parameters);
896 write!(f, "fn(")?;
897 f.write_joined(sig.params(), ", ")?;
898 write!(f, ") -> {}", sig.ret().display(f.db))?;
899 }
900 TypeCtor::FnDef(def) => {
901 let sig = f.db.callable_item_signature(def);
902 let name = match def {
903 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
904 CallableDef::StructId(s) => f.db.struct_data(s).name.clone(),
905 CallableDef::EnumVariantId(e) => {
906 let enum_data = f.db.enum_data(e.parent);
907 enum_data.variants[e.local_id].name.clone()
908 }
909 };
910 match def {
911 CallableDef::FunctionId(_) => write!(f, "fn {}", name)?,
912 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {
913 write!(f, "{}", name)?
914 }
915 }
916 if self.parameters.len() > 0 {
917 write!(f, "<")?;
918 f.write_joined(&*self.parameters.0, ", ")?;
919 write!(f, ">")?;
920 }
921 write!(f, "(")?;
922 f.write_joined(sig.params(), ", ")?;
923 write!(f, ") -> {}", sig.ret().display(f.db))?;
924 }
925 TypeCtor::Adt(def_id) => {
926 let name = match def_id {
927 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
928 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
929 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
930 };
931 write!(f, "{}", name)?;
932 if self.parameters.len() > 0 {
933 write!(f, "<")?;
934 f.write_joined(&*self.parameters.0, ", ")?;
935 write!(f, ">")?;
936 }
937 }
938 TypeCtor::AssociatedType(type_alias) => {
939 let trait_ = match type_alias.lookup(f.db).container {
940 ContainerId::TraitId(it) => it,
941 _ => panic!("not an associated type"),
942 };
943 let trait_name = f.db.trait_data(trait_).name.clone();
944 let name = f.db.type_alias_data(type_alias).name.clone();
945 write!(f, "{}::{}", trait_name, name)?;
946 if self.parameters.len() > 0 {
947 write!(f, "<")?;
948 f.write_joined(&*self.parameters.0, ", ")?;
949 write!(f, ">")?;
950 }
951 }
952 TypeCtor::Closure { .. } => {
953 let sig = self.parameters[0]
954 .callable_sig(f.db)
955 .expect("first closure parameter should contain signature");
956 write!(f, "|")?;
957 f.write_joined(sig.params(), ", ")?;
958 write!(f, "| -> {}", sig.ret().display(f.db))?;
959 }
960 }
961 Ok(())
962 }
963}
964
965impl HirDisplay for ProjectionTy {
966 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
967 if f.should_truncate() {
968 return write!(f, "…");
969 }
970
971 let trait_name = f.db.trait_data(self.trait_(f.db)).name.clone();
972 write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?;
973 if self.parameters.len() > 1 {
974 write!(f, "<")?;
975 f.write_joined(&self.parameters[1..], ", ")?;
976 write!(f, ">")?;
977 }
978 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
979 Ok(())
980 }
981}
982
983impl HirDisplay for Ty {
984 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
985 if f.should_truncate() {
986 return write!(f, "…");
987 }
988
989 match self {
990 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
991 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
992 Ty::Param { name, .. } => write!(f, "{}", name)?,
993 Ty::Bound(idx) => write!(f, "?{}", idx)?,
994 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
995 match self {
996 Ty::Dyn(_) => write!(f, "dyn ")?,
997 Ty::Opaque(_) => write!(f, "impl ")?,
998 _ => unreachable!(),
999 };
1000 // Note: This code is written to produce nice results (i.e.
1001 // corresponding to surface Rust) for types that can occur in
1002 // actual Rust. It will have weird results if the predicates
1003 // aren't as expected (i.e. self types = $0, projection
1004 // predicates for a certain trait come after the Implemented
1005 // predicate for that trait).
1006 let mut first = true;
1007 let mut angle_open = false;
1008 for p in predicates.iter() {
1009 match p {
1010 GenericPredicate::Implemented(trait_ref) => {
1011 if angle_open {
1012 write!(f, ">")?;
1013 }
1014 if !first {
1015 write!(f, " + ")?;
1016 }
1017 // We assume that the self type is $0 (i.e. the
1018 // existential) here, which is the only thing that's
1019 // possible in actual Rust, and hence don't print it
1020 write!(f, "{}", f.db.trait_data(trait_ref.trait_).name.clone())?;
1021 if trait_ref.substs.len() > 1 {
1022 write!(f, "<")?;
1023 f.write_joined(&trait_ref.substs[1..], ", ")?;
1024 // there might be assoc type bindings, so we leave the angle brackets open
1025 angle_open = true;
1026 }
1027 }
1028 GenericPredicate::Projection(projection_pred) => {
1029 // in types in actual Rust, these will always come
1030 // after the corresponding Implemented predicate
1031 if angle_open {
1032 write!(f, ", ")?;
1033 } else {
1034 write!(f, "<")?;
1035 angle_open = true;
1036 }
1037 let name =
1038 f.db.type_alias_data(projection_pred.projection_ty.associated_ty)
1039 .name
1040 .clone();
1041 write!(f, "{} = ", name)?;
1042 projection_pred.ty.hir_fmt(f)?;
1043 }
1044 GenericPredicate::Error => {
1045 if angle_open {
1046 // impl Trait<X, {error}>
1047 write!(f, ", ")?;
1048 } else if !first {
1049 // impl Trait + {error}
1050 write!(f, " + ")?;
1051 }
1052 p.hir_fmt(f)?;
1053 }
1054 }
1055 first = false;
1056 }
1057 if angle_open {
1058 write!(f, ">")?;
1059 }
1060 }
1061 Ty::Unknown => write!(f, "{{unknown}}")?,
1062 Ty::Infer(..) => write!(f, "_")?,
1063 }
1064 Ok(())
1065 }
1066}
1067
1068impl TraitRef {
1069 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result {
1070 if f.should_truncate() {
1071 return write!(f, "…");
1072 }
1073
1074 self.substs[0].hir_fmt(f)?;
1075 if use_as {
1076 write!(f, " as ")?;
1077 } else {
1078 write!(f, ": ")?;
1079 }
1080 write!(f, "{}", f.db.trait_data(self.trait_).name.clone())?;
1081 if self.substs.len() > 1 {
1082 write!(f, "<")?;
1083 f.write_joined(&self.substs[1..], ", ")?;
1084 write!(f, ">")?;
1085 }
1086 Ok(())
1087 }
1088}
1089
1090impl HirDisplay for TraitRef {
1091 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1092 self.hir_fmt_ext(f, false)
1093 }
1094}
1095
1096impl HirDisplay for &GenericPredicate {
1097 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1098 HirDisplay::hir_fmt(*self, f)
1099 }
1100}
1101
1102impl HirDisplay for GenericPredicate {
1103 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1104 if f.should_truncate() {
1105 return write!(f, "…");
1106 }
1107
1108 match self {
1109 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
1110 GenericPredicate::Projection(projection_pred) => {
1111 write!(f, "<")?;
1112 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
1113 write!(
1114 f,
1115 ">::{} = {}",
1116 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name,
1117 projection_pred.ty.display(f.db)
1118 )?;
1119 }
1120 GenericPredicate::Error => write!(f, "{{error}}")?,
1121 }
1122 Ok(())
1123 }
1124}
1125
1126impl HirDisplay for Obligation {
1127 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1128 match self {
1129 Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)),
1130 Obligation::Projection(proj) => write!(
1131 f,
1132 "Normalize({} => {})",
1133 proj.projection_ty.display(f.db),
1134 proj.ty.display(f.db)
1135 ),
1136 }
1137 }
1138}