@@ -1012,7 +1012,10 @@ impl<'a> Parser<'a> {
10121012 if text. is_empty ( ) {
10131013 self . span_bug ( sp, "found empty literal suffix in Some" )
10141014 }
1015- self . span_err ( sp, & format ! ( "{} with a suffix is invalid" , kind) ) ;
1015+ let msg = format ! ( "{} with a suffix is invalid" , kind) ;
1016+ self . struct_span_err ( sp, & msg)
1017+ . span_label ( sp, msg)
1018+ . emit ( ) ;
10161019 }
10171020 }
10181021 }
@@ -1768,9 +1771,11 @@ impl<'a> Parser<'a> {
17681771 Mutability :: Immutable
17691772 } else {
17701773 let span = self . prev_span ;
1771- self . span_err ( span,
1772- "expected mut or const in raw pointer type (use \
1773- `*mut T` or `*const T` as appropriate)") ;
1774+ let msg = "expected mut or const in raw pointer type" ;
1775+ self . struct_span_err ( span, msg)
1776+ . span_label ( span, msg)
1777+ . help ( "use `*mut T` or `*const T` as appropriate" )
1778+ . emit ( ) ;
17741779 Mutability :: Immutable
17751780 } ;
17761781 let t = self . parse_ty_no_plus ( ) ?;
@@ -3815,8 +3820,12 @@ impl<'a> Parser<'a> {
38153820 ddpos = Some ( fields. len ( ) ) ;
38163821 } else {
38173822 // Emit a friendly error, ignore `..` and continue parsing
3818- self . span_err ( self . prev_span ,
3819- "`..` can only be used once per tuple or tuple struct pattern" ) ;
3823+ self . struct_span_err (
3824+ self . prev_span ,
3825+ "`..` can only be used once per tuple or tuple struct pattern" ,
3826+ )
3827+ . span_label ( self . prev_span , "can only be used once per pattern" )
3828+ . emit ( ) ;
38203829 }
38213830 } else if !self . check ( & token:: CloseDelim ( token:: Paren ) ) {
38223831 fields. push ( self . parse_pat ( None ) ?) ;
@@ -3832,7 +3841,10 @@ impl<'a> Parser<'a> {
38323841
38333842 if ddpos == Some ( fields. len ( ) ) && trailing_comma {
38343843 // `..` needs to be followed by `)` or `, pat`, `..,)` is disallowed.
3835- self . span_err ( self . prev_span , "trailing comma is not permitted after `..`" ) ;
3844+ let msg = "trailing comma is not permitted after `..`" ;
3845+ self . struct_span_err ( self . prev_span , msg)
3846+ . span_label ( self . prev_span , msg)
3847+ . emit ( ) ;
38363848 }
38373849
38383850 Ok ( ( fields, ddpos, trailing_comma) )
@@ -5256,8 +5268,12 @@ impl<'a> Parser<'a> {
52565268 // Check for trailing attributes and stop parsing.
52575269 if !attrs. is_empty ( ) {
52585270 let param_kind = if seen_ty_param. is_some ( ) { "type" } else { "lifetime" } ;
5259- self . span_err ( attrs[ 0 ] . span ,
5260- & format ! ( "trailing attribute after {} parameters" , param_kind) ) ;
5271+ self . struct_span_err (
5272+ attrs[ 0 ] . span ,
5273+ & format ! ( "trailing attribute after {} parameters" , param_kind) ,
5274+ )
5275+ . span_label ( attrs[ 0 ] . span , "attributes must go before parameters" )
5276+ . emit ( ) ;
52615277 }
52625278 break
52635279 }
@@ -5315,39 +5331,62 @@ impl<'a> Parser<'a> {
53155331
53165332 /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
53175333 /// possibly including trailing comma.
5318- fn parse_generic_args ( & mut self )
5319- -> PResult < ' a , ( Vec < GenericArg > , Vec < TypeBinding > ) > {
5334+ fn parse_generic_args ( & mut self ) -> PResult < ' a , ( Vec < GenericArg > , Vec < TypeBinding > ) > {
53205335 let mut args = Vec :: new ( ) ;
53215336 let mut bindings = Vec :: new ( ) ;
53225337 let mut seen_type = false ;
53235338 let mut seen_binding = false ;
5339+ let mut first_type_or_binding_span: Option < Span > = None ;
5340+ let mut bad_lifetime_pos = vec ! [ ] ;
5341+ let mut last_comma_span = None ;
5342+ let mut suggestions = vec ! [ ] ;
53245343 loop {
53255344 if self . check_lifetime ( ) && self . look_ahead ( 1 , |t| !t. is_like_plus ( ) ) {
53265345 // Parse lifetime argument.
53275346 args. push ( GenericArg :: Lifetime ( self . expect_lifetime ( ) ) ) ;
53285347 if seen_type || seen_binding {
5329- self . span_err ( self . prev_span ,
5330- "lifetime parameters must be declared prior to type parameters" ) ;
5348+ let remove_sp = last_comma_span. unwrap_or ( self . prev_span ) . to ( self . prev_span ) ;
5349+ bad_lifetime_pos. push ( self . prev_span ) ;
5350+ if let Ok ( snippet) = self . sess . source_map ( ) . span_to_snippet ( self . prev_span ) {
5351+ suggestions. push ( ( remove_sp, String :: new ( ) ) ) ;
5352+ suggestions. push ( (
5353+ first_type_or_binding_span. unwrap ( ) . shrink_to_lo ( ) ,
5354+ format ! ( "{}, " , snippet) ) ) ;
5355+ }
53315356 }
53325357 } else if self . check_ident ( ) && self . look_ahead ( 1 , |t| t == & token:: Eq ) {
53335358 // Parse associated type binding.
53345359 let lo = self . span ;
53355360 let ident = self . parse_ident ( ) ?;
53365361 self . bump ( ) ;
53375362 let ty = self . parse_ty ( ) ?;
5363+ let span = lo. to ( self . prev_span ) ;
53385364 bindings. push ( TypeBinding {
53395365 id : ast:: DUMMY_NODE_ID ,
53405366 ident,
53415367 ty,
5342- span : lo . to ( self . prev_span ) ,
5368+ span,
53435369 } ) ;
53445370 seen_binding = true ;
5371+ if first_type_or_binding_span. is_none ( ) {
5372+ first_type_or_binding_span = Some ( span) ;
5373+ }
53455374 } else if self . check_type ( ) {
53465375 // Parse type argument.
53475376 let ty_param = self . parse_ty ( ) ?;
53485377 if seen_binding {
5349- self . span_err ( ty_param. span ,
5350- "type parameters must be declared prior to associated type bindings" ) ;
5378+ self . struct_span_err (
5379+ ty_param. span ,
5380+ "type parameters must be declared prior to associated type bindings"
5381+ )
5382+ . span_label (
5383+ ty_param. span ,
5384+ "must be declared prior to associated type bindings" ,
5385+ )
5386+ . emit ( ) ;
5387+ }
5388+ if first_type_or_binding_span. is_none ( ) {
5389+ first_type_or_binding_span = Some ( ty_param. span ) ;
53515390 }
53525391 args. push ( GenericArg :: Type ( ty_param) ) ;
53535392 seen_type = true ;
@@ -5357,7 +5396,29 @@ impl<'a> Parser<'a> {
53575396
53585397 if !self . eat ( & token:: Comma ) {
53595398 break
5399+ } else {
5400+ last_comma_span = Some ( self . prev_span ) ;
5401+ }
5402+ }
5403+ if !bad_lifetime_pos. is_empty ( ) {
5404+ let mut err = self . struct_span_err (
5405+ bad_lifetime_pos. clone ( ) ,
5406+ "lifetime parameters must be declared prior to type parameters"
5407+ ) ;
5408+ for sp in & bad_lifetime_pos {
5409+ err. span_label ( * sp, "must be declared prior to type parameters" ) ;
5410+ }
5411+ if !suggestions. is_empty ( ) {
5412+ err. multipart_suggestion_with_applicability (
5413+ & format ! (
5414+ "move the lifetime parameter{} prior to the first type parameter" ,
5415+ if bad_lifetime_pos. len( ) > 1 { "s" } else { "" } ,
5416+ ) ,
5417+ suggestions,
5418+ Applicability :: MachineApplicable ,
5419+ ) ;
53605420 }
5421+ err. emit ( ) ;
53615422 }
53625423 Ok ( ( args, bindings) )
53635424 }
@@ -5386,8 +5447,12 @@ impl<'a> Parser<'a> {
53865447 // change we parse those generics now, but report an error.
53875448 if self . choose_generics_over_qpath ( ) {
53885449 let generics = self . parse_generics ( ) ?;
5389- self . span_err ( generics. span ,
5390- "generic parameters on `where` clauses are reserved for future use" ) ;
5450+ self . struct_span_err (
5451+ generics. span ,
5452+ "generic parameters on `where` clauses are reserved for future use" ,
5453+ )
5454+ . span_label ( generics. span , "currently unsupported" )
5455+ . emit ( ) ;
53915456 }
53925457
53935458 loop {
@@ -5587,15 +5652,20 @@ impl<'a> Parser<'a> {
55875652 // *mut self
55885653 // *not_self
55895654 // Emit special error for `self` cases.
5655+ let msg = "cannot pass `self` by raw pointer" ;
55905656 ( if isolated_self ( self , 1 ) {
55915657 self . bump ( ) ;
5592- self . span_err ( self . span , "cannot pass `self` by raw pointer" ) ;
5658+ self . struct_span_err ( self . span , msg)
5659+ . span_label ( self . span , msg)
5660+ . emit ( ) ;
55935661 SelfKind :: Value ( Mutability :: Immutable )
55945662 } else if self . look_ahead ( 1 , |t| t. is_mutability ( ) ) &&
55955663 isolated_self ( self , 2 ) {
55965664 self . bump ( ) ;
55975665 self . bump ( ) ;
5598- self . span_err ( self . span , "cannot pass `self` by raw pointer" ) ;
5666+ self . struct_span_err ( self . span , msg)
5667+ . span_label ( self . span , msg)
5668+ . emit ( ) ;
55995669 SelfKind :: Value ( Mutability :: Immutable )
56005670 } else {
56015671 return Ok ( None ) ;
@@ -5932,7 +6002,10 @@ impl<'a> Parser<'a> {
59326002 tps. where_clause = self . parse_where_clause ( ) ?;
59336003 self . expect ( & token:: Semi ) ?;
59346004 if unsafety != Unsafety :: Normal {
5935- self . span_err ( self . prev_span , "trait aliases cannot be unsafe" ) ;
6005+ let msg = "trait aliases cannot be unsafe" ;
6006+ self . struct_span_err ( self . prev_span , msg)
6007+ . span_label ( self . prev_span , msg)
6008+ . emit ( ) ;
59366009 }
59376010 Ok ( ( ident, ItemKind :: TraitAlias ( tps, bounds) , None ) )
59386011 } else {
@@ -6048,7 +6121,13 @@ impl<'a> Parser<'a> {
60486121 Some ( ty_second) => {
60496122 // impl Trait for Type
60506123 if !has_for {
6051- self . span_err ( missing_for_span, "missing `for` in a trait impl" ) ;
6124+ self . struct_span_err ( missing_for_span, "missing `for` in a trait impl" )
6125+ . span_suggestion_short_with_applicability (
6126+ missing_for_span,
6127+ "add `for` here" ,
6128+ " for " . to_string ( ) ,
6129+ Applicability :: MachineApplicable ,
6130+ ) . emit ( ) ;
60526131 }
60536132
60546133 let ty_first = ty_first. into_inner ( ) ;
@@ -6939,7 +7018,7 @@ impl<'a> Parser<'a> {
69397018 fn parse_enum_def ( & mut self , _generics : & ast:: Generics ) -> PResult < ' a , EnumDef > {
69407019 let mut variants = Vec :: new ( ) ;
69417020 let mut all_nullary = true ;
6942- let mut any_disr = None ;
7021+ let mut any_disr = vec ! [ ] ;
69437022 while self . token != token:: CloseDelim ( token:: Brace ) {
69447023 let variant_attrs = self . parse_outer_attributes ( ) ?;
69457024 let vlo = self . span ;
@@ -6961,7 +7040,9 @@ impl<'a> Parser<'a> {
69617040 id : ast:: DUMMY_NODE_ID ,
69627041 value : self . parse_expr ( ) ?,
69637042 } ) ;
6964- any_disr = disr_expr. as_ref ( ) . map ( |c| c. value . span ) ;
7043+ if let Some ( sp) = disr_expr. as_ref ( ) . map ( |c| c. value . span ) {
7044+ any_disr. push ( sp) ;
7045+ }
69657046 struct_def = VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ;
69667047 } else {
69677048 struct_def = VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ;
@@ -6978,11 +7059,15 @@ impl<'a> Parser<'a> {
69787059 if !self . eat ( & token:: Comma ) { break ; }
69797060 }
69807061 self . expect ( & token:: CloseDelim ( token:: Brace ) ) ?;
6981- match any_disr {
6982- Some ( disr_span) if !all_nullary =>
6983- self . span_err ( disr_span,
6984- "discriminator values can only be used with a field-less enum" ) ,
6985- _ => ( )
7062+ if !any_disr. is_empty ( ) && !all_nullary {
7063+ let mut err =self . struct_span_err (
7064+ any_disr. clone ( ) ,
7065+ "discriminator values can only be used with a field-less enum" ,
7066+ ) ;
7067+ for sp in any_disr {
7068+ err. span_label ( sp, "only valid in field-less enums" ) ;
7069+ }
7070+ err. emit ( ) ;
69867071 }
69877072
69887073 Ok ( ast:: EnumDef { variants } )
0 commit comments