@@ -38,11 +38,11 @@ impl Display for ImportAlias {
3838#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
3939pub struct Path {
4040 /// Type based path like `<T>::foo`.
41- /// Note that paths like `<Type as Trait>::foo` are desugard to `Trait::<Self=Type>::foo`.
41+ /// Note that paths like `<Type as Trait>::foo` are desugared to `Trait::<Self=Type>::foo`.
4242 type_anchor : Option < Interned < TypeRef > > ,
4343 mod_path : Interned < ModPath > ,
44- /// Invariant: the same len as `self.mod_path.segments`
45- generic_args : Box < [ Option < Interned < GenericArgs > > ] > ,
44+ /// Invariant: the same len as `self.mod_path.segments` or `None` if all segments are `None`.
45+ generic_args : Option < Box < [ Option < Interned < GenericArgs > > ] > > ,
4646}
4747
4848/// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This
@@ -102,7 +102,7 @@ impl Path {
102102 ) -> Path {
103103 let generic_args = generic_args. into ( ) ;
104104 assert_eq ! ( path. len( ) , generic_args. len( ) ) ;
105- Path { type_anchor : None , mod_path : Interned :: new ( path) , generic_args }
105+ Path { type_anchor : None , mod_path : Interned :: new ( path) , generic_args : Some ( generic_args ) }
106106 }
107107
108108 pub fn kind ( & self ) -> & PathKind {
@@ -114,7 +114,14 @@ impl Path {
114114 }
115115
116116 pub fn segments ( & self ) -> PathSegments < ' _ > {
117- PathSegments { segments : self . mod_path . segments ( ) , generic_args : & self . generic_args }
117+ let s = PathSegments {
118+ segments : self . mod_path . segments ( ) ,
119+ generic_args : self . generic_args . as_deref ( ) ,
120+ } ;
121+ if let Some ( generic_args) = s. generic_args {
122+ assert_eq ! ( s. segments. len( ) , generic_args. len( ) ) ;
123+ }
124+ s
118125 }
119126
120127 pub fn mod_path ( & self ) -> & ModPath {
@@ -131,13 +138,15 @@ impl Path {
131138 self . mod_path . kind ,
132139 self . mod_path . segments ( ) [ ..self . mod_path . segments ( ) . len ( ) - 1 ] . iter ( ) . cloned ( ) ,
133140 ) ) ,
134- generic_args : self . generic_args [ .. self . generic_args . len ( ) - 1 ] . to_vec ( ) . into ( ) ,
141+ generic_args : self . generic_args . as_ref ( ) . map ( |it| it [ ..it . len ( ) - 1 ] . to_vec ( ) . into ( ) ) ,
135142 } ;
136143 Some ( res)
137144 }
138145
139146 pub fn is_self_type ( & self ) -> bool {
140- self . type_anchor . is_none ( ) && * self . generic_args == [ None ] && self . mod_path . is_Self ( )
147+ self . type_anchor . is_none ( )
148+ && self . generic_args . as_deref ( ) . is_none ( )
149+ && self . mod_path . is_Self ( )
141150 }
142151}
143152
@@ -149,11 +158,11 @@ pub struct PathSegment<'a> {
149158
150159pub struct PathSegments < ' a > {
151160 segments : & ' a [ Name ] ,
152- generic_args : & ' a [ Option < Interned < GenericArgs > > ] ,
161+ generic_args : Option < & ' a [ Option < Interned < GenericArgs > > ] > ,
153162}
154163
155164impl < ' a > PathSegments < ' a > {
156- pub const EMPTY : PathSegments < ' static > = PathSegments { segments : & [ ] , generic_args : & [ ] } ;
165+ pub const EMPTY : PathSegments < ' static > = PathSegments { segments : & [ ] , generic_args : None } ;
157166 pub fn is_empty ( & self ) -> bool {
158167 self . len ( ) == 0
159168 }
@@ -167,26 +176,29 @@ impl<'a> PathSegments<'a> {
167176 self . get ( self . len ( ) . checked_sub ( 1 ) ?)
168177 }
169178 pub fn get ( & self , idx : usize ) -> Option < PathSegment < ' a > > {
170- assert_eq ! ( self . segments. len( ) , self . generic_args. len( ) ) ;
171179 let res = PathSegment {
172180 name : self . segments . get ( idx) ?,
173- args_and_bindings : self . generic_args . get ( idx) . unwrap ( ) . as_ref ( ) . map ( |it| & * * it ) ,
181+ args_and_bindings : self . generic_args . and_then ( |it| it . get ( idx) ? . as_deref ( ) ) ,
174182 } ;
175183 Some ( res)
176184 }
177185 pub fn skip ( & self , len : usize ) -> PathSegments < ' a > {
178- assert_eq ! ( self . segments. len( ) , self . generic_args. len( ) ) ;
179- PathSegments { segments : & self . segments [ len..] , generic_args : & self . generic_args [ len..] }
186+ PathSegments {
187+ segments : & self . segments . get ( len..) . unwrap_or ( & [ ] ) ,
188+ generic_args : self . generic_args . and_then ( |it| it. get ( len..) ) ,
189+ }
180190 }
181191 pub fn take ( & self , len : usize ) -> PathSegments < ' a > {
182- assert_eq ! ( self . segments. len( ) , self . generic_args. len( ) ) ;
183- PathSegments { segments : & self . segments [ ..len] , generic_args : & self . generic_args [ ..len] }
192+ PathSegments {
193+ segments : & self . segments . get ( ..len) . unwrap_or ( & self . segments ) ,
194+ generic_args : self . generic_args . map ( |it| it. get ( ..len) . unwrap_or ( it) ) ,
195+ }
184196 }
185197 pub fn iter ( & self ) -> impl Iterator < Item = PathSegment < ' a > > {
186- self . segments . iter ( ) . zip ( self . generic_args . iter ( ) ) . map ( | ( name , args ) | PathSegment {
187- name ,
188- args_and_bindings : args . as_ref ( ) . map ( |it| & * * it ) ,
189- } )
198+ self . segments
199+ . iter ( )
200+ . zip ( self . generic_args . into_iter ( ) . flatten ( ) . chain ( iter :: repeat ( & None ) ) )
201+ . map ( | ( name , args ) | PathSegment { name , args_and_bindings : args . as_deref ( ) } )
190202 }
191203}
192204
@@ -213,7 +225,7 @@ impl From<Name> for Path {
213225 Path {
214226 type_anchor : None ,
215227 mod_path : Interned :: new ( ModPath :: from_segments ( PathKind :: Plain , iter:: once ( name) ) ) ,
216- generic_args : Box :: new ( [ None ] ) ,
228+ generic_args : None ,
217229 }
218230 }
219231}
0 commit comments