@@ -23,6 +23,7 @@ use crate::{
2323 hir:: Literal ,
2424 lower:: LowerCtx ,
2525 path:: { GenericArg , Path } ,
26+ SyntheticSyntax ,
2627} ;
2728
2829#[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
@@ -91,19 +92,37 @@ impl Rawness {
9192 }
9293}
9394
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 ) ]
95113pub struct TraitRef {
96- pub path : Path ,
114+ pub path : PathId ,
97115}
98116
99117impl TraitRef {
100118 /// Converts an `ast::PathType` to a `hir::TraitRef`.
101119 pub ( crate ) fn from_ast ( ctx : & mut LowerCtx < ' _ > , node : ast:: Type ) -> Option < Self > {
102120 // 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) ) } ) ,
107126 _ => None ,
108127 }
109128 }
@@ -173,11 +192,24 @@ impl TypesMap {
173192impl Index < TypeRefId > for TypesMap {
174193 type Output = TypeRef ;
175194
195+ #[ inline]
176196 fn index ( & self , index : TypeRefId ) -> & Self :: Output {
177197 & self . types [ index]
178198 }
179199}
180200
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+
181213pub type TypePtr = AstPtr < ast:: Type > ;
182214pub type TypeSource = InFile < TypePtr > ;
183215
@@ -187,6 +219,12 @@ pub struct TypesSourceMap {
187219}
188220
189221impl 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+
190228 pub ( crate ) fn shrink_to_fit ( & mut self ) {
191229 let TypesSourceMap { types_map_back } = self ;
192230 types_map_back. shrink_to_fit ( ) ;
@@ -214,15 +252,15 @@ impl LifetimeRef {
214252
215253#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
216254pub enum TypeBound {
217- Path ( Path , TraitBoundModifier ) ,
218- ForLifetime ( Box < [ Name ] > , Path ) ,
255+ Path ( PathId , TraitBoundModifier ) ,
256+ ForLifetime ( Box < [ Name ] > , PathId ) ,
219257 Lifetime ( LifetimeRef ) ,
220258 Use ( Box < [ UseArgRef ] > ) ,
221259 Error ,
222260}
223261
224262#[ cfg( target_pointer_width = "64" ) ]
225- const _: [ ( ) ; 32 ] = [ ( ) ; :: std:: mem:: size_of :: < TypeBound > ( ) ] ;
263+ const _: [ ( ) ; 24 ] = [ ( ) ; :: std:: mem:: size_of :: < TypeBound > ( ) ] ;
226264
227265#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
228266pub enum UseArgRef {
@@ -365,8 +403,8 @@ impl TypeRef {
365403 TypeRef :: ImplTrait ( bounds) | TypeRef :: DynTrait ( bounds) => {
366404 for bound in bounds {
367405 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)
370408 }
371409 TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => ( ) ,
372410 }
@@ -397,8 +435,8 @@ impl TypeRef {
397435 }
398436 for bound in binding. bounds . iter ( ) {
399437 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)
402440 }
403441 TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => ( ) ,
404442 }
@@ -425,16 +463,18 @@ pub(crate) fn type_bounds_from_ast(
425463
426464impl TypeBound {
427465 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 ( ) ?) ;
429467
430468 match node. kind ( ) {
431469 ast:: TypeBoundKind :: PathType ( path_type) => {
432470 let m = match node. question_mark_token ( ) {
433471 Some ( _) => TraitBoundModifier :: Maybe ,
434472 None => TraitBoundModifier :: None ,
435473 } ;
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+ } )
438478 . unwrap_or ( TypeBound :: Error )
439479 }
440480 ast:: TypeBoundKind :: ForType ( for_type) => {
@@ -445,12 +485,14 @@ impl TypeBound {
445485 . collect ( ) ,
446486 None => Box :: default ( ) ,
447487 } ;
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 ) ) ,
450490 _ => None ,
451491 } ) ;
452492 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+ }
454496 None => TypeBound :: Error ,
455497 }
456498 }
@@ -470,10 +512,10 @@ impl TypeBound {
470512 }
471513 }
472514
473- pub fn as_path ( & self ) -> Option < ( & Path , & TraitBoundModifier ) > {
515+ pub fn as_path < ' a > ( & self , map : & ' a TypesMap ) -> Option < ( & ' a Path , TraitBoundModifier ) > {
474516 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 ) ) ,
477519 TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => None ,
478520 }
479521 }
0 commit comments