@@ -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,10 @@ pub struct TypesSourceMap {
187219}
188220
189221impl 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+
190226 pub ( crate ) fn shrink_to_fit ( & mut self ) {
191227 let TypesSourceMap { types_map_back } = self ;
192228 types_map_back. shrink_to_fit ( ) ;
@@ -214,15 +250,15 @@ impl LifetimeRef {
214250
215251#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
216252pub enum TypeBound {
217- Path ( Path , TraitBoundModifier ) ,
218- ForLifetime ( Box < [ Name ] > , Path ) ,
253+ Path ( PathId , TraitBoundModifier ) ,
254+ ForLifetime ( Box < [ Name ] > , PathId ) ,
219255 Lifetime ( LifetimeRef ) ,
220256 Use ( Box < [ UseArgRef ] > ) ,
221257 Error ,
222258}
223259
224260#[ cfg( target_pointer_width = "64" ) ]
225- const _: [ ( ) ; 32 ] = [ ( ) ; :: std:: mem:: size_of :: < TypeBound > ( ) ] ;
261+ const _: [ ( ) ; 24 ] = [ ( ) ; :: std:: mem:: size_of :: < TypeBound > ( ) ] ;
226262
227263#[ derive( Clone , PartialEq , Eq , Hash , Debug ) ]
228264pub enum UseArgRef {
@@ -365,8 +401,8 @@ impl TypeRef {
365401 TypeRef :: ImplTrait ( bounds) | TypeRef :: DynTrait ( bounds) => {
366402 for bound in bounds {
367403 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)
370406 }
371407 TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => ( ) ,
372408 }
@@ -397,8 +433,8 @@ impl TypeRef {
397433 }
398434 for bound in binding. bounds . iter ( ) {
399435 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)
402438 }
403439 TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => ( ) ,
404440 }
@@ -425,16 +461,18 @@ pub(crate) fn type_bounds_from_ast(
425461
426462impl TypeBound {
427463 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 ( ) ?) ;
429465
430466 match node. kind ( ) {
431467 ast:: TypeBoundKind :: PathType ( path_type) => {
432468 let m = match node. question_mark_token ( ) {
433469 Some ( _) => TraitBoundModifier :: Maybe ,
434470 None => TraitBoundModifier :: None ,
435471 } ;
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+ } )
438476 . unwrap_or ( TypeBound :: Error )
439477 }
440478 ast:: TypeBoundKind :: ForType ( for_type) => {
@@ -445,12 +483,14 @@ impl TypeBound {
445483 . collect ( ) ,
446484 None => Box :: default ( ) ,
447485 } ;
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 ) ) ,
450488 _ => None ,
451489 } ) ;
452490 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+ }
454494 None => TypeBound :: Error ,
455495 }
456496 }
@@ -470,10 +510,10 @@ impl TypeBound {
470510 }
471511 }
472512
473- pub fn as_path ( & self ) -> Option < ( & Path , & TraitBoundModifier ) > {
513+ pub fn as_path < ' a > ( & self , map : & ' a TypesMap ) -> Option < ( & ' a Path , TraitBoundModifier ) > {
474514 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 ) ) ,
477517 TypeBound :: Lifetime ( _) | TypeBound :: Error | TypeBound :: Use ( _) => None ,
478518 }
479519 }
0 commit comments