@@ -23,6 +23,7 @@ use crate::{
23
23
hir:: Literal ,
24
24
lower:: LowerCtx ,
25
25
path:: { GenericArg , Path } ,
26
+ SyntheticSyntax ,
26
27
} ;
27
28
28
29
#[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
@@ -91,19 +92,37 @@ impl Rawness {
91
92
}
92
93
}
93
94
94
- #[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
95
+ #[ derive( Clone , Copy , PartialEq , Eq , Hash , Debug ) ]
96
+ /// A `TypeRefId` that is guaranteed to always be `TypeRef::Path`. We use this for things like
97
+ /// impl's trait, that are always paths but need to be traced back to source code.
98
+ pub struct PathId ( TypeRefId ) ;
99
+
100
+ impl PathId {
101
+ #[ inline]
102
+ pub fn from_type_ref_unchecked ( type_ref : TypeRefId ) -> Self {
103
+ Self ( type_ref)
104
+ }
105
+
106
+ #[ inline]
107
+ pub fn type_ref ( self ) -> TypeRefId {
108
+ self . 0
109
+ }
110
+ }
111
+
112
+ #[ derive( Clone , Copy , PartialEq , Eq , Hash , Debug ) ]
95
113
pub struct TraitRef {
96
- pub path : Path ,
114
+ pub path : PathId ,
97
115
}
98
116
99
117
impl TraitRef {
100
118
/// Converts an `ast::PathType` to a `hir::TraitRef`.
101
119
pub ( crate ) fn from_ast ( ctx : & mut LowerCtx < ' _ > , node : ast:: Type ) -> Option < Self > {
102
120
// FIXME: Use `Path::from_src`
103
- match node {
104
- ast:: Type :: PathType ( path) => {
105
- path. path ( ) . and_then ( |it| ctx. lower_path ( it) ) . map ( |path| TraitRef { path } )
106
- }
121
+ match & node {
122
+ ast:: Type :: PathType ( path) => path
123
+ . path ( )
124
+ . and_then ( |it| ctx. lower_path ( it) )
125
+ . map ( |path| TraitRef { path : ctx. alloc_path ( path, AstPtr :: new ( & node) ) } ) ,
107
126
_ => None ,
108
127
}
109
128
}
@@ -173,11 +192,24 @@ impl TypesMap {
173
192
impl Index < TypeRefId > for TypesMap {
174
193
type Output = TypeRef ;
175
194
195
+ #[ inline]
176
196
fn index ( & self , index : TypeRefId ) -> & Self :: Output {
177
197
& self . types [ index]
178
198
}
179
199
}
180
200
201
+ impl Index < PathId > for TypesMap {
202
+ type Output = Path ;
203
+
204
+ #[ inline]
205
+ fn index ( & self , index : PathId ) -> & Self :: Output {
206
+ let TypeRef :: Path ( path) = & self [ index. type_ref ( ) ] else {
207
+ unreachable ! ( "`PathId` always points to `TypeRef::Path`" ) ;
208
+ } ;
209
+ path
210
+ }
211
+ }
212
+
181
213
pub type TypePtr = AstPtr < ast:: Type > ;
182
214
pub type TypeSource = InFile < TypePtr > ;
183
215
@@ -187,6 +219,12 @@ pub struct TypesSourceMap {
187
219
}
188
220
189
221
impl TypesSourceMap {
222
+ pub const EMPTY : Self = Self { types_map_back : ArenaMap :: new ( ) } ;
223
+
224
+ pub fn type_syntax ( & self , id : TypeRefId ) -> Result < TypeSource , SyntheticSyntax > {
225
+ self . types_map_back . get ( id) . cloned ( ) . ok_or ( SyntheticSyntax )
226
+ }
227
+
190
228
pub ( crate ) fn shrink_to_fit ( & mut self ) {
191
229
let TypesSourceMap { types_map_back } = self ;
192
230
types_map_back. shrink_to_fit ( ) ;
@@ -214,15 +252,15 @@ impl LifetimeRef {
214
252
215
253
#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
216
254
pub enum TypeBound {
217
- Path ( Path , TraitBoundModifier ) ,
218
- ForLifetime ( Box < [ Name ] > , Path ) ,
255
+ Path ( PathId , TraitBoundModifier ) ,
256
+ ForLifetime ( Box < [ Name ] > , PathId ) ,
219
257
Lifetime ( LifetimeRef ) ,
220
258
Use ( Box < [ UseArgRef ] > ) ,
221
259
Error ,
222
260
}
223
261
224
262
#[ cfg( target_pointer_width = "64" ) ]
225
- const _: [ ( ) ; 32 ] = [ ( ) ; :: std:: mem:: size_of :: < TypeBound > ( ) ] ;
263
+ const _: [ ( ) ; 24 ] = [ ( ) ; :: std:: mem:: size_of :: < TypeBound > ( ) ] ;
226
264
227
265
#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
228
266
pub enum UseArgRef {
@@ -365,8 +403,8 @@ impl TypeRef {
365
403
TypeRef :: ImplTrait ( bounds) | TypeRef :: DynTrait ( bounds) => {
366
404
for bound in bounds {
367
405
match bound {
368
- TypeBound :: Path ( path, _) | TypeBound :: ForLifetime ( _, path) => {
369
- go_path ( path, f, map)
406
+ & TypeBound :: Path ( path, _) | & TypeBound :: ForLifetime ( _, path) => {
407
+ go_path ( & map [ path] , f, map)
370
408
}
371
409
TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => ( ) ,
372
410
}
@@ -397,8 +435,8 @@ impl TypeRef {
397
435
}
398
436
for bound in binding. bounds . iter ( ) {
399
437
match bound {
400
- TypeBound :: Path ( path, _) | TypeBound :: ForLifetime ( _, path) => {
401
- go_path ( path, f, map)
438
+ & TypeBound :: Path ( path, _) | & TypeBound :: ForLifetime ( _, path) => {
439
+ go_path ( & map [ path] , f, map)
402
440
}
403
441
TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => ( ) ,
404
442
}
@@ -425,16 +463,18 @@ pub(crate) fn type_bounds_from_ast(
425
463
426
464
impl TypeBound {
427
465
pub ( crate ) fn from_ast ( ctx : & mut LowerCtx < ' _ > , node : ast:: TypeBound ) -> Self {
428
- let mut lower_path_type = |path_type : ast:: PathType | ctx. lower_path ( path_type. path ( ) ?) ;
466
+ let mut lower_path_type = |path_type : & ast:: PathType | ctx. lower_path ( path_type. path ( ) ?) ;
429
467
430
468
match node. kind ( ) {
431
469
ast:: TypeBoundKind :: PathType ( path_type) => {
432
470
let m = match node. question_mark_token ( ) {
433
471
Some ( _) => TraitBoundModifier :: Maybe ,
434
472
None => TraitBoundModifier :: None ,
435
473
} ;
436
- lower_path_type ( path_type)
437
- . map ( |p| TypeBound :: Path ( p, m) )
474
+ lower_path_type ( & path_type)
475
+ . map ( |p| {
476
+ TypeBound :: Path ( ctx. alloc_path ( p, AstPtr :: new ( & path_type) . upcast ( ) ) , m)
477
+ } )
438
478
. unwrap_or ( TypeBound :: Error )
439
479
}
440
480
ast:: TypeBoundKind :: ForType ( for_type) => {
@@ -445,12 +485,14 @@ impl TypeBound {
445
485
. collect ( ) ,
446
486
None => Box :: default ( ) ,
447
487
} ;
448
- let path = for_type. ty ( ) . and_then ( |ty| match ty {
449
- ast:: Type :: PathType ( path_type) => lower_path_type ( path_type) ,
488
+ let path = for_type. ty ( ) . and_then ( |ty| match & ty {
489
+ ast:: Type :: PathType ( path_type) => lower_path_type ( path_type) . map ( |p| ( p , ty ) ) ,
450
490
_ => None ,
451
491
} ) ;
452
492
match path {
453
- Some ( p) => TypeBound :: ForLifetime ( lt_refs, p) ,
493
+ Some ( ( p, ty) ) => {
494
+ TypeBound :: ForLifetime ( lt_refs, ctx. alloc_path ( p, AstPtr :: new ( & ty) ) )
495
+ }
454
496
None => TypeBound :: Error ,
455
497
}
456
498
}
@@ -470,10 +512,10 @@ impl TypeBound {
470
512
}
471
513
}
472
514
473
- pub fn as_path ( & self ) -> Option < ( & Path , & TraitBoundModifier ) > {
515
+ pub fn as_path < ' a > ( & self , map : & ' a TypesMap ) -> Option < ( & ' a Path , TraitBoundModifier ) > {
474
516
match self {
475
- TypeBound :: Path ( p, m) => Some ( ( p , m) ) ,
476
- TypeBound :: ForLifetime ( _, p) => Some ( ( p , & TraitBoundModifier :: None ) ) ,
517
+ & TypeBound :: Path ( p, m) => Some ( ( & map [ p ] , m) ) ,
518
+ & TypeBound :: ForLifetime ( _, p) => Some ( ( & map [ p ] , TraitBoundModifier :: None ) ) ,
477
519
TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => None ,
478
520
}
479
521
}
0 commit comments