@@ -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,10 @@ pub struct TypesSourceMap {
187
219
}
188
220
189
221
impl TypesSourceMap {
222
+ pub fn type_syntax ( & self , id : TypeRefId ) -> Result < TypeSource , SyntheticSyntax > {
223
+ self . types_map_back . get ( id) . cloned ( ) . ok_or ( SyntheticSyntax )
224
+ }
225
+
190
226
pub ( crate ) fn shrink_to_fit ( & mut self ) {
191
227
let TypesSourceMap { types_map_back } = self ;
192
228
types_map_back. shrink_to_fit ( ) ;
@@ -214,15 +250,15 @@ impl LifetimeRef {
214
250
215
251
#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
216
252
pub enum TypeBound {
217
- Path ( Path , TraitBoundModifier ) ,
218
- ForLifetime ( Box < [ Name ] > , Path ) ,
253
+ Path ( PathId , TraitBoundModifier ) ,
254
+ ForLifetime ( Box < [ Name ] > , PathId ) ,
219
255
Lifetime ( LifetimeRef ) ,
220
256
Use ( Box < [ UseArgRef ] > ) ,
221
257
Error ,
222
258
}
223
259
224
260
#[ cfg( target_pointer_width = "64" ) ]
225
- const _: [ ( ) ; 32 ] = [ ( ) ; :: std:: mem:: size_of :: < TypeBound > ( ) ] ;
261
+ const _: [ ( ) ; 24 ] = [ ( ) ; :: std:: mem:: size_of :: < TypeBound > ( ) ] ;
226
262
227
263
#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
228
264
pub enum UseArgRef {
@@ -365,8 +401,8 @@ impl TypeRef {
365
401
TypeRef :: ImplTrait ( bounds) | TypeRef :: DynTrait ( bounds) => {
366
402
for bound in bounds {
367
403
match bound {
368
- TypeBound :: Path ( path, _) | TypeBound :: ForLifetime ( _, path) => {
369
- go_path ( path, f, map)
404
+ & TypeBound :: Path ( path, _) | & TypeBound :: ForLifetime ( _, path) => {
405
+ go_path ( & map [ path] , f, map)
370
406
}
371
407
TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => ( ) ,
372
408
}
@@ -397,8 +433,8 @@ impl TypeRef {
397
433
}
398
434
for bound in binding. bounds . iter ( ) {
399
435
match bound {
400
- TypeBound :: Path ( path, _) | TypeBound :: ForLifetime ( _, path) => {
401
- go_path ( path, f, map)
436
+ & TypeBound :: Path ( path, _) | & TypeBound :: ForLifetime ( _, path) => {
437
+ go_path ( & map [ path] , f, map)
402
438
}
403
439
TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => ( ) ,
404
440
}
@@ -425,16 +461,18 @@ pub(crate) fn type_bounds_from_ast(
425
461
426
462
impl TypeBound {
427
463
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 ( ) ?) ;
464
+ let mut lower_path_type = |path_type : & ast:: PathType | ctx. lower_path ( path_type. path ( ) ?) ;
429
465
430
466
match node. kind ( ) {
431
467
ast:: TypeBoundKind :: PathType ( path_type) => {
432
468
let m = match node. question_mark_token ( ) {
433
469
Some ( _) => TraitBoundModifier :: Maybe ,
434
470
None => TraitBoundModifier :: None ,
435
471
} ;
436
- lower_path_type ( path_type)
437
- . map ( |p| TypeBound :: Path ( p, m) )
472
+ lower_path_type ( & path_type)
473
+ . map ( |p| {
474
+ TypeBound :: Path ( ctx. alloc_path ( p, AstPtr :: new ( & path_type) . upcast ( ) ) , m)
475
+ } )
438
476
. unwrap_or ( TypeBound :: Error )
439
477
}
440
478
ast:: TypeBoundKind :: ForType ( for_type) => {
@@ -445,12 +483,14 @@ impl TypeBound {
445
483
. collect ( ) ,
446
484
None => Box :: default ( ) ,
447
485
} ;
448
- let path = for_type. ty ( ) . and_then ( |ty| match ty {
449
- ast:: Type :: PathType ( path_type) => lower_path_type ( path_type) ,
486
+ let path = for_type. ty ( ) . and_then ( |ty| match & ty {
487
+ ast:: Type :: PathType ( path_type) => lower_path_type ( path_type) . map ( |p| ( p , ty ) ) ,
450
488
_ => None ,
451
489
} ) ;
452
490
match path {
453
- Some ( p) => TypeBound :: ForLifetime ( lt_refs, p) ,
491
+ Some ( ( p, ty) ) => {
492
+ TypeBound :: ForLifetime ( lt_refs, ctx. alloc_path ( p, AstPtr :: new ( & ty) ) )
493
+ }
454
494
None => TypeBound :: Error ,
455
495
}
456
496
}
@@ -470,10 +510,10 @@ impl TypeBound {
470
510
}
471
511
}
472
512
473
- pub fn as_path ( & self ) -> Option < ( & Path , & TraitBoundModifier ) > {
513
+ pub fn as_path < ' a > ( & self , map : & ' a TypesMap ) -> Option < ( & ' a Path , TraitBoundModifier ) > {
474
514
match self {
475
- TypeBound :: Path ( p, m) => Some ( ( p , m) ) ,
476
- TypeBound :: ForLifetime ( _, p) => Some ( ( p , & TraitBoundModifier :: None ) ) ,
515
+ & TypeBound :: Path ( p, m) => Some ( ( & map [ p ] , m) ) ,
516
+ & TypeBound :: ForLifetime ( _, p) => Some ( ( & map [ p ] , TraitBoundModifier :: None ) ) ,
477
517
TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => None ,
478
518
}
479
519
}
0 commit comments