aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/lib.rs')
-rw-r--r--crates/ra_hir_ty/src/lib.rs1134
1 files changed, 1132 insertions, 2 deletions
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 28859ba63..f25846326 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -1,4 +1,1134 @@
1//! Work in Progress: everything related to types, type inference and trait 1//! The type system. We currently use this to infer types for completion, hover
2//! solving. 2//! information and various assists.
3 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;
4pub mod primitive; 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/// Like `generics::WherePredicate`, but with resolved types: A condition on the
490/// parameters of a generic item.
491#[derive(Debug, Clone, PartialEq, Eq, Hash)]
492pub enum GenericPredicate {
493 /// The given trait needs to be implemented for its type parameters.
494 Implemented(TraitRef),
495 /// An associated type bindings like in `Iterator<Item = T>`.
496 Projection(ProjectionPredicate),
497 /// We couldn't resolve the trait reference. (If some type parameters can't
498 /// be resolved, they will just be Unknown).
499 Error,
500}
501
502impl GenericPredicate {
503 pub fn is_error(&self) -> bool {
504 match self {
505 GenericPredicate::Error => true,
506 _ => false,
507 }
508 }
509
510 pub fn is_implemented(&self) -> bool {
511 match self {
512 GenericPredicate::Implemented(_) => true,
513 _ => false,
514 }
515 }
516
517 pub fn trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> {
518 match self {
519 GenericPredicate::Implemented(tr) => Some(tr.clone()),
520 GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)),
521 GenericPredicate::Error => None,
522 }
523 }
524}
525
526impl TypeWalk for GenericPredicate {
527 fn walk(&self, f: &mut impl FnMut(&Ty)) {
528 match self {
529 GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f),
530 GenericPredicate::Projection(projection_pred) => projection_pred.walk(f),
531 GenericPredicate::Error => {}
532 }
533 }
534
535 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
536 match self {
537 GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders),
538 GenericPredicate::Projection(projection_pred) => {
539 projection_pred.walk_mut_binders(f, binders)
540 }
541 GenericPredicate::Error => {}
542 }
543 }
544}
545
546/// Basically a claim (currently not validated / checked) that the contained
547/// type / trait ref contains no inference variables; any inference variables it
548/// contained have been replaced by bound variables, and `num_vars` tells us how
549/// many there are. This is used to erase irrelevant differences between types
550/// before using them in queries.
551#[derive(Debug, Clone, PartialEq, Eq, Hash)]
552pub struct Canonical<T> {
553 pub value: T,
554 pub num_vars: usize,
555}
556
557/// A function signature as seen by type inference: Several parameter types and
558/// one return type.
559#[derive(Clone, PartialEq, Eq, Debug)]
560pub struct FnSig {
561 params_and_return: Arc<[Ty]>,
562}
563
564impl FnSig {
565 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty) -> FnSig {
566 params.push(ret);
567 FnSig { params_and_return: params.into() }
568 }
569
570 pub fn from_fn_ptr_substs(substs: &Substs) -> FnSig {
571 FnSig { params_and_return: Arc::clone(&substs.0) }
572 }
573
574 pub fn params(&self) -> &[Ty] {
575 &self.params_and_return[0..self.params_and_return.len() - 1]
576 }
577
578 pub fn ret(&self) -> &Ty {
579 &self.params_and_return[self.params_and_return.len() - 1]
580 }
581}
582
583impl TypeWalk for FnSig {
584 fn walk(&self, f: &mut impl FnMut(&Ty)) {
585 for t in self.params_and_return.iter() {
586 t.walk(f);
587 }
588 }
589
590 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
591 for t in make_mut_slice(&mut self.params_and_return) {
592 t.walk_mut_binders(f, binders);
593 }
594 }
595}
596
597impl Ty {
598 pub fn simple(ctor: TypeCtor) -> Ty {
599 Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() })
600 }
601 pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty {
602 Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) })
603 }
604 pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty {
605 Ty::Apply(ApplicationTy { ctor, parameters })
606 }
607 pub fn unit() -> Self {
608 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty())
609 }
610
611 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
612 match self {
613 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => {
614 Some((parameters.as_single(), *mutability))
615 }
616 _ => None,
617 }
618 }
619
620 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
621 match self {
622 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => {
623 Some((*adt_def, parameters))
624 }
625 _ => None,
626 }
627 }
628
629 pub fn as_tuple(&self) -> Option<&Substs> {
630 match self {
631 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => {
632 Some(parameters)
633 }
634 _ => None,
635 }
636 }
637
638 pub fn as_callable(&self) -> Option<(CallableDef, &Substs)> {
639 match self {
640 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(callable_def), parameters }) => {
641 Some((*callable_def, parameters))
642 }
643 _ => None,
644 }
645 }
646
647 fn builtin_deref(&self) -> Option<Ty> {
648 match self {
649 Ty::Apply(a_ty) => match a_ty.ctor {
650 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())),
651 TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
652 _ => None,
653 },
654 _ => None,
655 }
656 }
657
658 fn callable_sig(&self, db: &impl HirDatabase) -> Option<FnSig> {
659 match self {
660 Ty::Apply(a_ty) => match a_ty.ctor {
661 TypeCtor::FnPtr { .. } => Some(FnSig::from_fn_ptr_substs(&a_ty.parameters)),
662 TypeCtor::FnDef(def) => {
663 let sig = db.callable_item_signature(def);
664 Some(sig.subst(&a_ty.parameters))
665 }
666 TypeCtor::Closure { .. } => {
667 let sig_param = &a_ty.parameters[0];
668 sig_param.callable_sig(db)
669 }
670 _ => None,
671 },
672 _ => None,
673 }
674 }
675
676 /// If this is a type with type parameters (an ADT or function), replaces
677 /// the `Substs` for these type parameters with the given ones. (So e.g. if
678 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
679 /// `Option<u32>` afterwards.)
680 pub fn apply_substs(self, substs: Substs) -> Ty {
681 match self {
682 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => {
683 assert_eq!(previous_substs.len(), substs.len());
684 Ty::Apply(ApplicationTy { ctor, parameters: substs })
685 }
686 _ => self,
687 }
688 }
689
690 /// Returns the type parameters of this type if it has some (i.e. is an ADT
691 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
692 pub fn substs(&self) -> Option<Substs> {
693 match self {
694 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()),
695 _ => None,
696 }
697 }
698
699 /// If this is an `impl Trait` or `dyn Trait`, returns that trait.
700 pub fn inherent_trait(&self) -> Option<TraitId> {
701 match self {
702 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
703 predicates.iter().find_map(|pred| match pred {
704 GenericPredicate::Implemented(tr) => Some(tr.trait_),
705 _ => None,
706 })
707 }
708 _ => None,
709 }
710 }
711}
712
713/// This allows walking structures that contain types to do something with those
714/// types, similar to Chalk's `Fold` trait.
715pub trait TypeWalk {
716 fn walk(&self, f: &mut impl FnMut(&Ty));
717 fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) {
718 self.walk_mut_binders(&mut |ty, _binders| f(ty), 0);
719 }
720 /// Walk the type, counting entered binders.
721 ///
722 /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers
723 /// to the innermost binder, 1 to the next, etc.. So when we want to
724 /// substitute a certain bound variable, we can't just walk the whole type
725 /// and blindly replace each instance of a certain index; when we 'enter'
726 /// things that introduce new bound variables, we have to keep track of
727 /// that. Currently, the only thing that introduces bound variables on our
728 /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound
729 /// variable for the self type.
730 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize);
731
732 fn fold(mut self, f: &mut impl FnMut(Ty) -> Ty) -> Self
733 where
734 Self: Sized,
735 {
736 self.walk_mut(&mut |ty_mut| {
737 let ty = mem::replace(ty_mut, Ty::Unknown);
738 *ty_mut = f(ty);
739 });
740 self
741 }
742
743 /// Replaces type parameters in this type using the given `Substs`. (So e.g.
744 /// if `self` is `&[T]`, where type parameter T has index 0, and the
745 /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
746 fn subst(self, substs: &Substs) -> Self
747 where
748 Self: Sized,
749 {
750 self.fold(&mut |ty| match ty {
751 Ty::Param { idx, name } => {
752 substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name })
753 }
754 ty => ty,
755 })
756 }
757
758 /// Substitutes `Ty::Bound` vars (as opposed to type parameters).
759 fn subst_bound_vars(mut self, substs: &Substs) -> Self
760 where
761 Self: Sized,
762 {
763 self.walk_mut_binders(
764 &mut |ty, binders| match ty {
765 &mut Ty::Bound(idx) => {
766 if idx as usize >= binders && (idx as usize - binders) < substs.len() {
767 *ty = substs.0[idx as usize - binders].clone();
768 }
769 }
770 _ => {}
771 },
772 0,
773 );
774 self
775 }
776
777 /// Shifts up `Ty::Bound` vars by `n`.
778 fn shift_bound_vars(self, n: i32) -> Self
779 where
780 Self: Sized,
781 {
782 self.fold(&mut |ty| match ty {
783 Ty::Bound(idx) => {
784 assert!(idx as i32 >= -n);
785 Ty::Bound((idx as i32 + n) as u32)
786 }
787 ty => ty,
788 })
789 }
790}
791
792impl TypeWalk for Ty {
793 fn walk(&self, f: &mut impl FnMut(&Ty)) {
794 match self {
795 Ty::Apply(a_ty) => {
796 for t in a_ty.parameters.iter() {
797 t.walk(f);
798 }
799 }
800 Ty::Projection(p_ty) => {
801 for t in p_ty.parameters.iter() {
802 t.walk(f);
803 }
804 }
805 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
806 for p in predicates.iter() {
807 p.walk(f);
808 }
809 }
810 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
811 }
812 f(self);
813 }
814
815 fn walk_mut_binders(&mut self, f: &mut impl FnMut(&mut Ty, usize), binders: usize) {
816 match self {
817 Ty::Apply(a_ty) => {
818 a_ty.parameters.walk_mut_binders(f, binders);
819 }
820 Ty::Projection(p_ty) => {
821 p_ty.parameters.walk_mut_binders(f, binders);
822 }
823 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
824 for p in make_mut_slice(predicates) {
825 p.walk_mut_binders(f, binders + 1);
826 }
827 }
828 Ty::Param { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
829 }
830 f(self, binders);
831 }
832}
833
834impl HirDisplay for &Ty {
835 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
836 HirDisplay::hir_fmt(*self, f)
837 }
838}
839
840impl HirDisplay for ApplicationTy {
841 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
842 if f.should_truncate() {
843 return write!(f, "…");
844 }
845
846 match self.ctor {
847 TypeCtor::Bool => write!(f, "bool")?,
848 TypeCtor::Char => write!(f, "char")?,
849 TypeCtor::Int(t) => write!(f, "{}", t)?,
850 TypeCtor::Float(t) => write!(f, "{}", t)?,
851 TypeCtor::Str => write!(f, "str")?,
852 TypeCtor::Slice => {
853 let t = self.parameters.as_single();
854 write!(f, "[{}]", t.display(f.db))?;
855 }
856 TypeCtor::Array => {
857 let t = self.parameters.as_single();
858 write!(f, "[{};_]", t.display(f.db))?;
859 }
860 TypeCtor::RawPtr(m) => {
861 let t = self.parameters.as_single();
862 write!(f, "*{}{}", m.as_keyword_for_ptr(), t.display(f.db))?;
863 }
864 TypeCtor::Ref(m) => {
865 let t = self.parameters.as_single();
866 write!(f, "&{}{}", m.as_keyword_for_ref(), t.display(f.db))?;
867 }
868 TypeCtor::Never => write!(f, "!")?,
869 TypeCtor::Tuple { .. } => {
870 let ts = &self.parameters;
871 if ts.len() == 1 {
872 write!(f, "({},)", ts[0].display(f.db))?;
873 } else {
874 write!(f, "(")?;
875 f.write_joined(&*ts.0, ", ")?;
876 write!(f, ")")?;
877 }
878 }
879 TypeCtor::FnPtr { .. } => {
880 let sig = FnSig::from_fn_ptr_substs(&self.parameters);
881 write!(f, "fn(")?;
882 f.write_joined(sig.params(), ", ")?;
883 write!(f, ") -> {}", sig.ret().display(f.db))?;
884 }
885 TypeCtor::FnDef(def) => {
886 let sig = f.db.callable_item_signature(def);
887 let name = match def {
888 CallableDef::FunctionId(ff) => f.db.function_data(ff).name.clone(),
889 CallableDef::StructId(s) => {
890 f.db.struct_data(s).name.clone().unwrap_or_else(Name::missing)
891 }
892 CallableDef::EnumVariantId(e) => {
893 let enum_data = f.db.enum_data(e.parent);
894 enum_data.variants[e.local_id].name.clone().unwrap_or_else(Name::missing)
895 }
896 };
897 match def {
898 CallableDef::FunctionId(_) => write!(f, "fn {}", name)?,
899 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => {
900 write!(f, "{}", name)?
901 }
902 }
903 if self.parameters.len() > 0 {
904 write!(f, "<")?;
905 f.write_joined(&*self.parameters.0, ", ")?;
906 write!(f, ">")?;
907 }
908 write!(f, "(")?;
909 f.write_joined(sig.params(), ", ")?;
910 write!(f, ") -> {}", sig.ret().display(f.db))?;
911 }
912 TypeCtor::Adt(def_id) => {
913 let name = match def_id {
914 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
915 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
916 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
917 }
918 .unwrap_or_else(Name::missing);
919 write!(f, "{}", name)?;
920 if self.parameters.len() > 0 {
921 write!(f, "<")?;
922 f.write_joined(&*self.parameters.0, ", ")?;
923 write!(f, ">")?;
924 }
925 }
926 TypeCtor::AssociatedType(type_alias) => {
927 let trait_ = match type_alias.lookup(f.db).container {
928 ContainerId::TraitId(it) => it,
929 _ => panic!("not an associated type"),
930 };
931 let trait_name = f.db.trait_data(trait_).name.clone().unwrap_or_else(Name::missing);
932 let name = f.db.type_alias_data(type_alias).name.clone();
933 write!(f, "{}::{}", trait_name, name)?;
934 if self.parameters.len() > 0 {
935 write!(f, "<")?;
936 f.write_joined(&*self.parameters.0, ", ")?;
937 write!(f, ">")?;
938 }
939 }
940 TypeCtor::Closure { .. } => {
941 let sig = self.parameters[0]
942 .callable_sig(f.db)
943 .expect("first closure parameter should contain signature");
944 write!(f, "|")?;
945 f.write_joined(sig.params(), ", ")?;
946 write!(f, "| -> {}", sig.ret().display(f.db))?;
947 }
948 }
949 Ok(())
950 }
951}
952
953impl HirDisplay for ProjectionTy {
954 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
955 if f.should_truncate() {
956 return write!(f, "…");
957 }
958
959 let trait_name =
960 f.db.trait_data(self.trait_(f.db)).name.clone().unwrap_or_else(Name::missing);
961 write!(f, "<{} as {}", self.parameters[0].display(f.db), trait_name,)?;
962 if self.parameters.len() > 1 {
963 write!(f, "<")?;
964 f.write_joined(&self.parameters[1..], ", ")?;
965 write!(f, ">")?;
966 }
967 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
968 Ok(())
969 }
970}
971
972impl HirDisplay for Ty {
973 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
974 if f.should_truncate() {
975 return write!(f, "…");
976 }
977
978 match self {
979 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
980 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
981 Ty::Param { name, .. } => write!(f, "{}", name)?,
982 Ty::Bound(idx) => write!(f, "?{}", idx)?,
983 Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
984 match self {
985 Ty::Dyn(_) => write!(f, "dyn ")?,
986 Ty::Opaque(_) => write!(f, "impl ")?,
987 _ => unreachable!(),
988 };
989 // Note: This code is written to produce nice results (i.e.
990 // corresponding to surface Rust) for types that can occur in
991 // actual Rust. It will have weird results if the predicates
992 // aren't as expected (i.e. self types = $0, projection
993 // predicates for a certain trait come after the Implemented
994 // predicate for that trait).
995 let mut first = true;
996 let mut angle_open = false;
997 for p in predicates.iter() {
998 match p {
999 GenericPredicate::Implemented(trait_ref) => {
1000 if angle_open {
1001 write!(f, ">")?;
1002 }
1003 if !first {
1004 write!(f, " + ")?;
1005 }
1006 // We assume that the self type is $0 (i.e. the
1007 // existential) here, which is the only thing that's
1008 // possible in actual Rust, and hence don't print it
1009 write!(
1010 f,
1011 "{}",
1012 f.db.trait_data(trait_ref.trait_)
1013 .name
1014 .clone()
1015 .unwrap_or_else(Name::missing)
1016 )?;
1017 if trait_ref.substs.len() > 1 {
1018 write!(f, "<")?;
1019 f.write_joined(&trait_ref.substs[1..], ", ")?;
1020 // there might be assoc type bindings, so we leave the angle brackets open
1021 angle_open = true;
1022 }
1023 }
1024 GenericPredicate::Projection(projection_pred) => {
1025 // in types in actual Rust, these will always come
1026 // after the corresponding Implemented predicate
1027 if angle_open {
1028 write!(f, ", ")?;
1029 } else {
1030 write!(f, "<")?;
1031 angle_open = true;
1032 }
1033 let name =
1034 f.db.type_alias_data(projection_pred.projection_ty.associated_ty)
1035 .name
1036 .clone();
1037 write!(f, "{} = ", name)?;
1038 projection_pred.ty.hir_fmt(f)?;
1039 }
1040 GenericPredicate::Error => {
1041 if angle_open {
1042 // impl Trait<X, {error}>
1043 write!(f, ", ")?;
1044 } else if !first {
1045 // impl Trait + {error}
1046 write!(f, " + ")?;
1047 }
1048 p.hir_fmt(f)?;
1049 }
1050 }
1051 first = false;
1052 }
1053 if angle_open {
1054 write!(f, ">")?;
1055 }
1056 }
1057 Ty::Unknown => write!(f, "{{unknown}}")?,
1058 Ty::Infer(..) => write!(f, "_")?,
1059 }
1060 Ok(())
1061 }
1062}
1063
1064impl TraitRef {
1065 fn hir_fmt_ext(&self, f: &mut HirFormatter<impl HirDatabase>, use_as: bool) -> fmt::Result {
1066 if f.should_truncate() {
1067 return write!(f, "…");
1068 }
1069
1070 self.substs[0].hir_fmt(f)?;
1071 if use_as {
1072 write!(f, " as ")?;
1073 } else {
1074 write!(f, ": ")?;
1075 }
1076 write!(f, "{}", f.db.trait_data(self.trait_).name.clone().unwrap_or_else(Name::missing))?;
1077 if self.substs.len() > 1 {
1078 write!(f, "<")?;
1079 f.write_joined(&self.substs[1..], ", ")?;
1080 write!(f, ">")?;
1081 }
1082 Ok(())
1083 }
1084}
1085
1086impl HirDisplay for TraitRef {
1087 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1088 self.hir_fmt_ext(f, false)
1089 }
1090}
1091
1092impl HirDisplay for &GenericPredicate {
1093 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1094 HirDisplay::hir_fmt(*self, f)
1095 }
1096}
1097
1098impl HirDisplay for GenericPredicate {
1099 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1100 if f.should_truncate() {
1101 return write!(f, "…");
1102 }
1103
1104 match self {
1105 GenericPredicate::Implemented(trait_ref) => trait_ref.hir_fmt(f)?,
1106 GenericPredicate::Projection(projection_pred) => {
1107 write!(f, "<")?;
1108 projection_pred.projection_ty.trait_ref(f.db).hir_fmt_ext(f, true)?;
1109 write!(
1110 f,
1111 ">::{} = {}",
1112 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name,
1113 projection_pred.ty.display(f.db)
1114 )?;
1115 }
1116 GenericPredicate::Error => write!(f, "{{error}}")?,
1117 }
1118 Ok(())
1119 }
1120}
1121
1122impl HirDisplay for Obligation {
1123 fn hir_fmt(&self, f: &mut HirFormatter<impl HirDatabase>) -> fmt::Result {
1124 match self {
1125 Obligation::Trait(tr) => write!(f, "Implements({})", tr.display(f.db)),
1126 Obligation::Projection(proj) => write!(
1127 f,
1128 "Normalize({} => {})",
1129 proj.projection_ty.display(f.db),
1130 proj.ty.display(f.db)
1131 ),
1132 }
1133 }
1134}