@@ -38,11 +38,11 @@ impl Display for ImportAlias {
38
38
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
39
39
pub struct Path {
40
40
/// 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`.
42
42
type_anchor : Option < Interned < TypeRef > > ,
43
43
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 > > ] > > ,
46
46
}
47
47
48
48
/// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This
@@ -102,7 +102,7 @@ impl Path {
102
102
) -> Path {
103
103
let generic_args = generic_args. into ( ) ;
104
104
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 ) }
106
106
}
107
107
108
108
pub fn kind ( & self ) -> & PathKind {
@@ -114,7 +114,14 @@ impl Path {
114
114
}
115
115
116
116
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
118
125
}
119
126
120
127
pub fn mod_path ( & self ) -> & ModPath {
@@ -131,13 +138,15 @@ impl Path {
131
138
self . mod_path . kind ,
132
139
self . mod_path . segments ( ) [ ..self . mod_path . segments ( ) . len ( ) - 1 ] . iter ( ) . cloned ( ) ,
133
140
) ) ,
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 ( ) ) ,
135
142
} ;
136
143
Some ( res)
137
144
}
138
145
139
146
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 ( )
141
150
}
142
151
}
143
152
@@ -149,11 +158,11 @@ pub struct PathSegment<'a> {
149
158
150
159
pub struct PathSegments < ' a > {
151
160
segments : & ' a [ Name ] ,
152
- generic_args : & ' a [ Option < Interned < GenericArgs > > ] ,
161
+ generic_args : Option < & ' a [ Option < Interned < GenericArgs > > ] > ,
153
162
}
154
163
155
164
impl < ' a > PathSegments < ' a > {
156
- pub const EMPTY : PathSegments < ' static > = PathSegments { segments : & [ ] , generic_args : & [ ] } ;
165
+ pub const EMPTY : PathSegments < ' static > = PathSegments { segments : & [ ] , generic_args : None } ;
157
166
pub fn is_empty ( & self ) -> bool {
158
167
self . len ( ) == 0
159
168
}
@@ -167,26 +176,29 @@ impl<'a> PathSegments<'a> {
167
176
self . get ( self . len ( ) . checked_sub ( 1 ) ?)
168
177
}
169
178
pub fn get ( & self , idx : usize ) -> Option < PathSegment < ' a > > {
170
- assert_eq ! ( self . segments. len( ) , self . generic_args. len( ) ) ;
171
179
let res = PathSegment {
172
180
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 ( ) ) ,
174
182
} ;
175
183
Some ( res)
176
184
}
177
185
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
+ }
180
190
}
181
191
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
+ }
184
196
}
185
197
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 ( ) } )
190
202
}
191
203
}
192
204
@@ -213,7 +225,7 @@ impl From<Name> for Path {
213
225
Path {
214
226
type_anchor : None ,
215
227
mod_path : Interned :: new ( ModPath :: from_segments ( PathKind :: Plain , iter:: once ( name) ) ) ,
216
- generic_args : Box :: new ( [ None ] ) ,
228
+ generic_args : None ,
217
229
}
218
230
}
219
231
}
0 commit comments