2
2
//! structs, impls, traits, etc. This module provides a common HIR for these
3
3
//! generic parameters. See also the `Generics` type and the `generics_of` query
4
4
//! in rustc.
5
- use std:: sync:: Arc ;
6
5
7
6
use base_db:: FileId ;
8
7
use either:: Either ;
@@ -18,6 +17,7 @@ use crate::{
18
17
child_by_source:: ChildBySource ,
19
18
db:: DefDatabase ,
20
19
dyn_map:: DynMap ,
20
+ intern:: Interned ,
21
21
keys,
22
22
src:: { HasChildSource , HasSource } ,
23
23
type_ref:: { LifetimeRef , TypeBound , TypeRef } ,
@@ -26,35 +26,35 @@ use crate::{
26
26
} ;
27
27
28
28
/// Data about a generic type parameter (to a function, struct, impl, ...).
29
- #[ derive( Clone , PartialEq , Eq , Debug ) ]
29
+ #[ derive( Clone , PartialEq , Eq , Debug , Hash ) ]
30
30
pub struct TypeParamData {
31
31
pub name : Option < Name > ,
32
- pub default : Option < TypeRef > ,
32
+ pub default : Option < Interned < TypeRef > > ,
33
33
pub provenance : TypeParamProvenance ,
34
34
}
35
35
36
36
/// Data about a generic lifetime parameter (to a function, struct, impl, ...).
37
- #[ derive( Clone , PartialEq , Eq , Debug ) ]
37
+ #[ derive( Clone , PartialEq , Eq , Debug , Hash ) ]
38
38
pub struct LifetimeParamData {
39
39
pub name : Name ,
40
40
}
41
41
42
42
/// Data about a generic const parameter (to a function, struct, impl, ...).
43
- #[ derive( Clone , PartialEq , Eq , Debug ) ]
43
+ #[ derive( Clone , PartialEq , Eq , Debug , Hash ) ]
44
44
pub struct ConstParamData {
45
45
pub name : Name ,
46
- pub ty : TypeRef ,
46
+ pub ty : Interned < TypeRef > ,
47
47
}
48
48
49
- #[ derive( Copy , Clone , PartialEq , Eq , Debug ) ]
49
+ #[ derive( Copy , Clone , PartialEq , Eq , Debug , Hash ) ]
50
50
pub enum TypeParamProvenance {
51
51
TypeParamList ,
52
52
TraitSelf ,
53
53
ArgumentImplTrait ,
54
54
}
55
55
56
56
/// Data about the generic parameters of a function, struct, impl, etc.
57
- #[ derive( Clone , PartialEq , Eq , Debug , Default ) ]
57
+ #[ derive( Clone , PartialEq , Eq , Debug , Default , Hash ) ]
58
58
pub struct GenericParams {
59
59
pub types : Arena < TypeParamData > ,
60
60
pub lifetimes : Arena < LifetimeParamData > ,
@@ -66,16 +66,16 @@ pub struct GenericParams {
66
66
/// where clauses like `where T: Foo + Bar` are turned into multiple of these.
67
67
/// It might still result in multiple actual predicates though, because of
68
68
/// associated type bindings like `Iterator<Item = u32>`.
69
- #[ derive( Clone , PartialEq , Eq , Debug ) ]
69
+ #[ derive( Clone , PartialEq , Eq , Debug , Hash ) ]
70
70
pub enum WherePredicate {
71
71
TypeBound { target : WherePredicateTypeTarget , bound : TypeBound } ,
72
72
Lifetime { target : LifetimeRef , bound : LifetimeRef } ,
73
73
ForLifetime { lifetimes : Box < [ Name ] > , target : WherePredicateTypeTarget , bound : TypeBound } ,
74
74
}
75
75
76
- #[ derive( Clone , PartialEq , Eq , Debug ) ]
76
+ #[ derive( Clone , PartialEq , Eq , Debug , Hash ) ]
77
77
pub enum WherePredicateTypeTarget {
78
- TypeRef ( TypeRef ) ,
78
+ TypeRef ( Interned < TypeRef > ) ,
79
79
/// For desugared where predicates that can directly refer to a type param.
80
80
TypeParam ( LocalTypeParamId ) ,
81
81
}
@@ -91,55 +91,57 @@ impl GenericParams {
91
91
pub ( crate ) fn generic_params_query (
92
92
db : & dyn DefDatabase ,
93
93
def : GenericDefId ,
94
- ) -> Arc < GenericParams > {
94
+ ) -> Interned < GenericParams > {
95
95
let _p = profile:: span ( "generic_params_query" ) ;
96
96
97
97
let generics = match def {
98
98
GenericDefId :: FunctionId ( id) => {
99
99
let id = id. lookup ( db) . id ;
100
100
let tree = id. item_tree ( db) ;
101
101
let item = & tree[ id. value ] ;
102
- tree [ item. generic_params ] . clone ( )
102
+ item. generic_params . clone ( )
103
103
}
104
104
GenericDefId :: AdtId ( AdtId :: StructId ( id) ) => {
105
105
let id = id. lookup ( db) . id ;
106
106
let tree = id. item_tree ( db) ;
107
107
let item = & tree[ id. value ] ;
108
- tree [ item. generic_params ] . clone ( )
108
+ item. generic_params . clone ( )
109
109
}
110
110
GenericDefId :: AdtId ( AdtId :: EnumId ( id) ) => {
111
111
let id = id. lookup ( db) . id ;
112
112
let tree = id. item_tree ( db) ;
113
113
let item = & tree[ id. value ] ;
114
- tree [ item. generic_params ] . clone ( )
114
+ item. generic_params . clone ( )
115
115
}
116
116
GenericDefId :: AdtId ( AdtId :: UnionId ( id) ) => {
117
117
let id = id. lookup ( db) . id ;
118
118
let tree = id. item_tree ( db) ;
119
119
let item = & tree[ id. value ] ;
120
- tree [ item. generic_params ] . clone ( )
120
+ item. generic_params . clone ( )
121
121
}
122
122
GenericDefId :: TraitId ( id) => {
123
123
let id = id. lookup ( db) . id ;
124
124
let tree = id. item_tree ( db) ;
125
125
let item = & tree[ id. value ] ;
126
- tree [ item. generic_params ] . clone ( )
126
+ item. generic_params . clone ( )
127
127
}
128
128
GenericDefId :: TypeAliasId ( id) => {
129
129
let id = id. lookup ( db) . id ;
130
130
let tree = id. item_tree ( db) ;
131
131
let item = & tree[ id. value ] ;
132
- tree [ item. generic_params ] . clone ( )
132
+ item. generic_params . clone ( )
133
133
}
134
134
GenericDefId :: ImplId ( id) => {
135
135
let id = id. lookup ( db) . id ;
136
136
let tree = id. item_tree ( db) ;
137
137
let item = & tree[ id. value ] ;
138
- tree[ item. generic_params ] . clone ( )
138
+ item. generic_params . clone ( )
139
+ }
140
+ GenericDefId :: EnumVariantId ( _) | GenericDefId :: ConstId ( _) => {
141
+ Interned :: new ( GenericParams :: default ( ) )
139
142
}
140
- GenericDefId :: EnumVariantId ( _) | GenericDefId :: ConstId ( _) => GenericParams :: default ( ) ,
141
143
} ;
142
- Arc :: new ( generics)
144
+ generics
143
145
}
144
146
145
147
fn new ( db : & dyn DefDatabase , def : GenericDefId ) -> ( GenericParams , InFile < SourceMap > ) {
@@ -217,6 +219,7 @@ impl GenericParams {
217
219
GenericDefId :: EnumVariantId ( _) | GenericDefId :: ConstId ( _) => FileId ( !0 ) . into ( ) ,
218
220
} ;
219
221
222
+ generics. shrink_to_fit ( ) ;
220
223
( generics, InFile :: new ( file_id, sm) )
221
224
}
222
225
@@ -256,7 +259,8 @@ impl GenericParams {
256
259
for type_param in params. type_params ( ) {
257
260
let name = type_param. name ( ) . map_or_else ( Name :: missing, |it| it. as_name ( ) ) ;
258
261
// FIXME: Use `Path::from_src`
259
- let default = type_param. default_type ( ) . map ( |it| TypeRef :: from_ast ( lower_ctx, it) ) ;
262
+ let default =
263
+ type_param. default_type ( ) . map ( |it| Interned :: new ( TypeRef :: from_ast ( lower_ctx, it) ) ) ;
260
264
let param = TypeParamData {
261
265
name : Some ( name. clone ( ) ) ,
262
266
default,
@@ -280,7 +284,7 @@ impl GenericParams {
280
284
for const_param in params. const_params ( ) {
281
285
let name = const_param. name ( ) . map_or_else ( Name :: missing, |it| it. as_name ( ) ) ;
282
286
let ty = const_param. ty ( ) . map_or ( TypeRef :: Error , |it| TypeRef :: from_ast ( lower_ctx, it) ) ;
283
- let param = ConstParamData { name, ty } ;
287
+ let param = ConstParamData { name, ty : Interned :: new ( ty ) } ;
284
288
let param_id = self . consts . alloc ( param) ;
285
289
sm. const_params . insert ( param_id, const_param. clone ( ) ) ;
286
290
}
@@ -334,11 +338,11 @@ impl GenericParams {
334
338
( Either :: Left ( type_ref) , bound) => match hrtb_lifetimes {
335
339
Some ( hrtb_lifetimes) => WherePredicate :: ForLifetime {
336
340
lifetimes : hrtb_lifetimes. clone ( ) ,
337
- target : WherePredicateTypeTarget :: TypeRef ( type_ref) ,
341
+ target : WherePredicateTypeTarget :: TypeRef ( Interned :: new ( type_ref) ) ,
338
342
bound,
339
343
} ,
340
344
None => WherePredicate :: TypeBound {
341
- target : WherePredicateTypeTarget :: TypeRef ( type_ref) ,
345
+ target : WherePredicateTypeTarget :: TypeRef ( Interned :: new ( type_ref) ) ,
342
346
bound,
343
347
} ,
344
348
} ,
@@ -369,6 +373,14 @@ impl GenericParams {
369
373
} ) ;
370
374
}
371
375
376
+ pub ( crate ) fn shrink_to_fit ( & mut self ) {
377
+ let Self { consts, lifetimes, types, where_predicates } = self ;
378
+ consts. shrink_to_fit ( ) ;
379
+ lifetimes. shrink_to_fit ( ) ;
380
+ types. shrink_to_fit ( ) ;
381
+ where_predicates. shrink_to_fit ( ) ;
382
+ }
383
+
372
384
pub fn find_type_by_name ( & self , name : & Name ) -> Option < LocalTypeParamId > {
373
385
self . types
374
386
. iter ( )
0 commit comments