@@ -20,11 +20,84 @@ pub(crate) use lower::{TypableDef, CallableDef, type_for_def, type_for_field, ca
20
20
pub ( crate ) use infer:: { infer, InferenceResult , InferTy } ;
21
21
use display:: { HirDisplay , HirFormatter } ;
22
22
23
+ #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
24
+ pub enum TypeName {
25
+ /// The primitive boolean type. Written as `bool`.
26
+ Bool ,
27
+
28
+ /// The primitive character type; holds a Unicode scalar value
29
+ /// (a non-surrogate code point). Written as `char`.
30
+ Char ,
31
+
32
+ /// A primitive integer type. For example, `i32`.
33
+ Int ( primitive:: UncertainIntTy ) ,
34
+
35
+ /// A primitive floating-point type. For example, `f64`.
36
+ Float ( primitive:: UncertainFloatTy ) ,
37
+
38
+ /// Structures, enumerations and unions.
39
+ Adt ( AdtDef ) ,
40
+
41
+ /// The pointee of a string slice. Written as `str`.
42
+ Str ,
43
+
44
+ /// The pointee of an array slice. Written as `[T]`.
45
+ Slice ,
46
+
47
+ /// An array with the given length. Written as `[T; n]`.
48
+ Array ,
49
+
50
+ /// A raw pointer. Written as `*mut T` or `*const T`
51
+ RawPtr ( Mutability ) ,
52
+
53
+ /// A reference; a pointer with an associated lifetime. Written as
54
+ /// `&'a mut T` or `&'a T`.
55
+ Ref ( Mutability ) ,
56
+
57
+ /// The anonymous type of a function declaration/definition. Each
58
+ /// function has a unique type, which is output (for a function
59
+ /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
60
+ ///
61
+ /// This includes tuple struct / enum variant constructors as well.
62
+ ///
63
+ /// For example the type of `bar` here:
64
+ ///
65
+ /// ```rust
66
+ /// fn foo() -> i32 { 1 }
67
+ /// let bar = foo; // bar: fn() -> i32 {foo}
68
+ /// ```
69
+ FnDef ( CallableDef ) ,
70
+
71
+ /// A pointer to a function. Written as `fn() -> i32`.
72
+ ///
73
+ /// For example the type of `bar` here:
74
+ ///
75
+ /// ```rust
76
+ /// fn foo() -> i32 { 1 }
77
+ /// let bar: fn() -> i32 = foo;
78
+ /// ```
79
+ FnPtr ,
80
+
81
+ /// The never type `!`.
82
+ Never ,
83
+
84
+ /// A tuple type. For example, `(i32, bool)`.
85
+ Tuple ,
86
+ }
87
+
88
+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
89
+ pub struct ApplicationTy {
90
+ pub name : TypeName ,
91
+ pub parameters : Substs ,
92
+ }
93
+
23
94
/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs).
24
95
///
25
96
/// This should be cheap to clone.
26
97
#[ derive( Clone , PartialEq , Eq , Debug ) ]
27
98
pub enum Ty {
99
+ Apply ( ApplicationTy ) ,
100
+
28
101
/// The primitive boolean type. Written as `bool`.
29
102
Bool ,
30
103
@@ -139,6 +212,13 @@ impl Substs {
139
212
}
140
213
self . 0 = v. into ( ) ;
141
214
}
215
+
216
+ pub fn as_single ( & self ) -> & Ty {
217
+ if self . 0 . len ( ) != 1 {
218
+ panic ! ( "expected substs of len 1, got {:?}" , self ) ;
219
+ }
220
+ & self . 0 [ 0 ]
221
+ }
142
222
}
143
223
144
224
/// A function signature.
@@ -176,12 +256,20 @@ impl FnSig {
176
256
}
177
257
178
258
impl Ty {
259
+ pub fn apply ( name : TypeName , parameters : Substs ) -> Ty {
260
+ Ty :: Apply ( ApplicationTy { name, parameters } )
261
+ }
179
262
pub fn unit ( ) -> Self {
180
- Ty :: Tuple ( Substs :: empty ( ) )
263
+ Ty :: apply ( TypeName :: Tuple , Substs :: empty ( ) )
181
264
}
182
265
183
266
pub fn walk ( & self , f : & mut impl FnMut ( & Ty ) ) {
184
267
match self {
268
+ Ty :: Apply ( a_ty) => {
269
+ for t in a_ty. parameters . iter ( ) {
270
+ t. walk ( f) ;
271
+ }
272
+ }
185
273
Ty :: Slice ( t) | Ty :: Array ( t) => t. walk ( f) ,
186
274
Ty :: RawPtr ( t, _) => t. walk ( f) ,
187
275
Ty :: Ref ( t, _) => t. walk ( f) ,
@@ -220,6 +308,9 @@ impl Ty {
220
308
221
309
fn walk_mut ( & mut self , f : & mut impl FnMut ( & mut Ty ) ) {
222
310
match self {
311
+ Ty :: Apply ( a_ty) => {
312
+ a_ty. parameters . walk_mut ( f) ;
313
+ }
223
314
Ty :: Slice ( t) | Ty :: Array ( t) => Arc :: make_mut ( t) . walk_mut ( f) ,
224
315
Ty :: RawPtr ( t, _) => Arc :: make_mut ( t) . walk_mut ( f) ,
225
316
Ty :: Ref ( t, _) => Arc :: make_mut ( t) . walk_mut ( f) ,
@@ -258,6 +349,11 @@ impl Ty {
258
349
259
350
fn builtin_deref ( & self ) -> Option < Ty > {
260
351
match self {
352
+ Ty :: Apply ( a_ty) => match a_ty. name {
353
+ TypeName :: Ref ( ..) => Some ( Ty :: clone ( a_ty. parameters . as_single ( ) ) ) ,
354
+ TypeName :: RawPtr ( ..) => Some ( Ty :: clone ( a_ty. parameters . as_single ( ) ) ) ,
355
+ _ => None ,
356
+ } ,
261
357
Ty :: Ref ( t, _) => Some ( Ty :: clone ( t) ) ,
262
358
Ty :: RawPtr ( t, _) => Some ( Ty :: clone ( t) ) ,
263
359
_ => None ,
@@ -270,6 +366,9 @@ impl Ty {
270
366
/// `Option<u32>` afterwards.)
271
367
pub fn apply_substs ( self , substs : Substs ) -> Ty {
272
368
match self {
369
+ Ty :: Apply ( ApplicationTy { name, .. } ) => {
370
+ Ty :: Apply ( ApplicationTy { name, parameters : substs } )
371
+ }
273
372
Ty :: Adt { def_id, .. } => Ty :: Adt { def_id, substs } ,
274
373
Ty :: FnDef { def, .. } => Ty :: FnDef { def, substs } ,
275
374
_ => self ,
@@ -296,6 +395,7 @@ impl Ty {
296
395
/// or function); so if `self` is `Option<u32>`, this returns the `u32`.
297
396
fn substs ( & self ) -> Option < Substs > {
298
397
match self {
398
+ Ty :: Apply ( ApplicationTy { parameters, .. } ) => Some ( parameters. clone ( ) ) ,
299
399
Ty :: Adt { substs, .. } | Ty :: FnDef { substs, .. } => Some ( substs. clone ( ) ) ,
300
400
_ => None ,
301
401
}
@@ -308,9 +408,85 @@ impl HirDisplay for &Ty {
308
408
}
309
409
}
310
410
411
+ impl HirDisplay for ApplicationTy {
412
+ fn hir_fmt ( & self , f : & mut HirFormatter < impl HirDatabase > ) -> fmt:: Result {
413
+ match self . name {
414
+ TypeName :: Bool => write ! ( f, "bool" ) ?,
415
+ TypeName :: Char => write ! ( f, "char" ) ?,
416
+ TypeName :: Int ( t) => write ! ( f, "{}" , t) ?,
417
+ TypeName :: Float ( t) => write ! ( f, "{}" , t) ?,
418
+ TypeName :: Str => write ! ( f, "str" ) ?,
419
+ TypeName :: Slice | TypeName :: Array => {
420
+ let t = self . parameters . as_single ( ) ;
421
+ write ! ( f, "[{}]" , t. display( f. db) ) ?;
422
+ }
423
+ TypeName :: RawPtr ( m) => {
424
+ let t = self . parameters . as_single ( ) ;
425
+ write ! ( f, "*{}{}" , m. as_keyword_for_ptr( ) , t. display( f. db) ) ?;
426
+ }
427
+ TypeName :: Ref ( m) => {
428
+ let t = self . parameters . as_single ( ) ;
429
+ write ! ( f, "&{}{}" , m. as_keyword_for_ref( ) , t. display( f. db) ) ?;
430
+ }
431
+ TypeName :: Never => write ! ( f, "!" ) ?,
432
+ TypeName :: Tuple => {
433
+ let ts = & self . parameters ;
434
+ if ts. 0 . len ( ) == 1 {
435
+ write ! ( f, "({},)" , ts. 0 [ 0 ] . display( f. db) ) ?;
436
+ } else {
437
+ write ! ( f, "(" ) ?;
438
+ f. write_joined ( & * ts. 0 , ", " ) ?;
439
+ write ! ( f, ")" ) ?;
440
+ }
441
+ }
442
+ TypeName :: FnPtr => {
443
+ let sig = FnSig :: from_fn_ptr_substs ( & self . parameters ) ;
444
+ write ! ( f, "fn(" ) ?;
445
+ f. write_joined ( sig. params ( ) , ", " ) ?;
446
+ write ! ( f, ") -> {}" , sig. ret( ) . display( f. db) ) ?;
447
+ }
448
+ TypeName :: FnDef ( def) => {
449
+ let sig = f. db . callable_item_signature ( def) ;
450
+ let name = match def {
451
+ CallableDef :: Function ( ff) => ff. name ( f. db ) ,
452
+ CallableDef :: Struct ( s) => s. name ( f. db ) . unwrap_or_else ( Name :: missing) ,
453
+ CallableDef :: EnumVariant ( e) => e. name ( f. db ) . unwrap_or_else ( Name :: missing) ,
454
+ } ;
455
+ match def {
456
+ CallableDef :: Function ( _) => write ! ( f, "fn {}" , name) ?,
457
+ CallableDef :: Struct ( _) | CallableDef :: EnumVariant ( _) => write ! ( f, "{}" , name) ?,
458
+ }
459
+ if self . parameters . 0 . len ( ) > 0 {
460
+ write ! ( f, "<" ) ?;
461
+ f. write_joined ( & * self . parameters . 0 , ", " ) ?;
462
+ write ! ( f, ">" ) ?;
463
+ }
464
+ write ! ( f, "(" ) ?;
465
+ f. write_joined ( sig. params ( ) , ", " ) ?;
466
+ write ! ( f, ") -> {}" , sig. ret( ) . display( f. db) ) ?;
467
+ }
468
+ TypeName :: Adt ( def_id) => {
469
+ let name = match def_id {
470
+ AdtDef :: Struct ( s) => s. name ( f. db ) ,
471
+ AdtDef :: Enum ( e) => e. name ( f. db ) ,
472
+ }
473
+ . unwrap_or_else ( Name :: missing) ;
474
+ write ! ( f, "{}" , name) ?;
475
+ if self . parameters . 0 . len ( ) > 0 {
476
+ write ! ( f, "<" ) ?;
477
+ f. write_joined ( & * self . parameters . 0 , ", " ) ?;
478
+ write ! ( f, ">" ) ?;
479
+ }
480
+ }
481
+ }
482
+ Ok ( ( ) )
483
+ }
484
+ }
485
+
311
486
impl HirDisplay for Ty {
312
487
fn hir_fmt ( & self , f : & mut HirFormatter < impl HirDatabase > ) -> fmt:: Result {
313
488
match self {
489
+ Ty :: Apply ( a_ty) => a_ty. hir_fmt ( f) ?,
314
490
Ty :: Bool => write ! ( f, "bool" ) ?,
315
491
Ty :: Char => write ! ( f, "char" ) ?,
316
492
Ty :: Int ( t) => write ! ( f, "{}" , t) ?,
0 commit comments