@@ -11,9 +11,9 @@ pub use rustc_ast::{CaptureBy, Movability, Mutability};
1111use rustc_ast:: { InlineAsmOptions , InlineAsmTemplatePiece } ;
1212use rustc_data_structures:: sync:: { par_for_each_in, Send , Sync } ;
1313use rustc_macros:: HashStable_Generic ;
14- use rustc_span:: def_id:: LocalDefId ;
15- use rustc_span:: source_map:: Spanned ;
14+ use rustc_span:: source_map:: { SourceMap , Spanned } ;
1615use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
16+ use rustc_span:: { def_id:: LocalDefId , BytePos } ;
1717use rustc_span:: { MultiSpan , Span , DUMMY_SP } ;
1818use rustc_target:: asm:: InlineAsmRegOrRegClass ;
1919use rustc_target:: spec:: abi:: Abi ;
@@ -231,7 +231,11 @@ impl<'hir> PathSegment<'hir> {
231231 PathSegment { ident, hir_id : None , res : None , infer_args : true , args : None }
232232 }
233233
234- pub fn generic_args ( & self ) -> & GenericArgs < ' hir > {
234+ pub fn invalid ( ) -> Self {
235+ Self :: from_ident ( Ident :: invalid ( ) )
236+ }
237+
238+ pub fn args ( & self ) -> & GenericArgs < ' hir > {
235239 if let Some ( ref args) = self . args {
236240 args
237241 } else {
@@ -275,19 +279,15 @@ impl GenericArg<'_> {
275279 matches ! ( self , GenericArg :: Const ( _) )
276280 }
277281
278- pub fn descr ( & self ) -> & ' static str {
279- match self {
280- GenericArg :: Lifetime ( _) => "lifetime" ,
281- GenericArg :: Type ( _) => "type" ,
282- GenericArg :: Const ( _) => "constant" ,
283- }
282+ pub fn is_synthetic ( & self ) -> bool {
283+ matches ! ( self , GenericArg :: Lifetime ( lifetime) if lifetime. name. ident( ) == Ident :: invalid( ) )
284284 }
285285
286- pub fn short_descr ( & self ) -> & ' static str {
286+ pub fn descr ( & self ) -> & ' static str {
287287 match self {
288288 GenericArg :: Lifetime ( _) => "lifetime" ,
289289 GenericArg :: Type ( _) => "type" ,
290- GenericArg :: Const ( _) => "const " ,
290+ GenericArg :: Const ( _) => "constant " ,
291291 }
292292 }
293293
@@ -352,6 +352,39 @@ impl GenericArgs<'_> {
352352
353353 own_counts
354354 }
355+
356+ pub fn span ( & self ) -> Option < Span > {
357+ self . args
358+ . iter ( )
359+ . filter ( |arg| !arg. is_synthetic ( ) )
360+ . map ( |arg| arg. span ( ) )
361+ . fold_first ( |span1, span2| span1. to ( span2) )
362+ }
363+
364+ /// Returns span encompassing arguments and their surrounding `<>` or `()`
365+ pub fn span_ext ( & self , sm : & SourceMap ) -> Option < Span > {
366+ let mut span = self . span ( ) ?;
367+
368+ let ( o, c) = if self . parenthesized { ( '(' , ')' ) } else { ( '<' , '>' ) } ;
369+
370+ if let Ok ( snippet) = sm. span_to_snippet ( span) {
371+ let snippet = snippet. as_bytes ( ) ;
372+
373+ if snippet[ 0 ] != ( o as u8 ) || snippet[ snippet. len ( ) - 1 ] != ( c as u8 ) {
374+ span = sm. span_extend_to_prev_char ( span, o, true ) ;
375+ span = span. with_lo ( span. lo ( ) - BytePos ( 1 ) ) ;
376+
377+ span = sm. span_extend_to_next_char ( span, c, true ) ;
378+ span = span. with_hi ( span. hi ( ) + BytePos ( 1 ) ) ;
379+ }
380+ }
381+
382+ Some ( span)
383+ }
384+
385+ pub fn is_empty ( & self ) -> bool {
386+ self . args . is_empty ( )
387+ }
355388}
356389
357390/// A modifier on a bound, currently this is only used for `?Sized`, where the
0 commit comments