@@ -1012,7 +1012,10 @@ impl<'a> Parser<'a> {
1012
1012
if text. is_empty ( ) {
1013
1013
self . span_bug ( sp, "found empty literal suffix in Some" )
1014
1014
}
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 ( ) ;
1016
1019
}
1017
1020
}
1018
1021
}
@@ -1768,9 +1771,11 @@ impl<'a> Parser<'a> {
1768
1771
Mutability :: Immutable
1769
1772
} else {
1770
1773
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 ( ) ;
1774
1779
Mutability :: Immutable
1775
1780
} ;
1776
1781
let t = self . parse_ty_no_plus ( ) ?;
@@ -3815,8 +3820,12 @@ impl<'a> Parser<'a> {
3815
3820
ddpos = Some ( fields. len ( ) ) ;
3816
3821
} else {
3817
3822
// 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 ( ) ;
3820
3829
}
3821
3830
} else if !self . check ( & token:: CloseDelim ( token:: Paren ) ) {
3822
3831
fields. push ( self . parse_pat ( None ) ?) ;
@@ -3832,7 +3841,10 @@ impl<'a> Parser<'a> {
3832
3841
3833
3842
if ddpos == Some ( fields. len ( ) ) && trailing_comma {
3834
3843
// `..` 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 ( ) ;
3836
3848
}
3837
3849
3838
3850
Ok ( ( fields, ddpos, trailing_comma) )
@@ -5256,8 +5268,12 @@ impl<'a> Parser<'a> {
5256
5268
// Check for trailing attributes and stop parsing.
5257
5269
if !attrs. is_empty ( ) {
5258
5270
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 ( ) ;
5261
5277
}
5262
5278
break
5263
5279
}
@@ -5315,39 +5331,62 @@ impl<'a> Parser<'a> {
5315
5331
5316
5332
/// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
5317
5333
/// 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 > ) > {
5320
5335
let mut args = Vec :: new ( ) ;
5321
5336
let mut bindings = Vec :: new ( ) ;
5322
5337
let mut seen_type = false ;
5323
5338
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 ! [ ] ;
5324
5343
loop {
5325
5344
if self . check_lifetime ( ) && self . look_ahead ( 1 , |t| !t. is_like_plus ( ) ) {
5326
5345
// Parse lifetime argument.
5327
5346
args. push ( GenericArg :: Lifetime ( self . expect_lifetime ( ) ) ) ;
5328
5347
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
+ }
5331
5356
}
5332
5357
} else if self . check_ident ( ) && self . look_ahead ( 1 , |t| t == & token:: Eq ) {
5333
5358
// Parse associated type binding.
5334
5359
let lo = self . span ;
5335
5360
let ident = self . parse_ident ( ) ?;
5336
5361
self . bump ( ) ;
5337
5362
let ty = self . parse_ty ( ) ?;
5363
+ let span = lo. to ( self . prev_span ) ;
5338
5364
bindings. push ( TypeBinding {
5339
5365
id : ast:: DUMMY_NODE_ID ,
5340
5366
ident,
5341
5367
ty,
5342
- span : lo . to ( self . prev_span ) ,
5368
+ span,
5343
5369
} ) ;
5344
5370
seen_binding = true ;
5371
+ if first_type_or_binding_span. is_none ( ) {
5372
+ first_type_or_binding_span = Some ( span) ;
5373
+ }
5345
5374
} else if self . check_type ( ) {
5346
5375
// Parse type argument.
5347
5376
let ty_param = self . parse_ty ( ) ?;
5348
5377
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 ) ;
5351
5390
}
5352
5391
args. push ( GenericArg :: Type ( ty_param) ) ;
5353
5392
seen_type = true ;
@@ -5357,7 +5396,29 @@ impl<'a> Parser<'a> {
5357
5396
5358
5397
if !self . eat ( & token:: Comma ) {
5359
5398
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
+ ) ;
5360
5420
}
5421
+ err. emit ( ) ;
5361
5422
}
5362
5423
Ok ( ( args, bindings) )
5363
5424
}
@@ -5386,8 +5447,12 @@ impl<'a> Parser<'a> {
5386
5447
// change we parse those generics now, but report an error.
5387
5448
if self . choose_generics_over_qpath ( ) {
5388
5449
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 ( ) ;
5391
5456
}
5392
5457
5393
5458
loop {
@@ -5587,15 +5652,20 @@ impl<'a> Parser<'a> {
5587
5652
// *mut self
5588
5653
// *not_self
5589
5654
// Emit special error for `self` cases.
5655
+ let msg = "cannot pass `self` by raw pointer" ;
5590
5656
( if isolated_self ( self , 1 ) {
5591
5657
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 ( ) ;
5593
5661
SelfKind :: Value ( Mutability :: Immutable )
5594
5662
} else if self . look_ahead ( 1 , |t| t. is_mutability ( ) ) &&
5595
5663
isolated_self ( self , 2 ) {
5596
5664
self . bump ( ) ;
5597
5665
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 ( ) ;
5599
5669
SelfKind :: Value ( Mutability :: Immutable )
5600
5670
} else {
5601
5671
return Ok ( None ) ;
@@ -5932,7 +6002,10 @@ impl<'a> Parser<'a> {
5932
6002
tps. where_clause = self . parse_where_clause ( ) ?;
5933
6003
self . expect ( & token:: Semi ) ?;
5934
6004
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 ( ) ;
5936
6009
}
5937
6010
Ok ( ( ident, ItemKind :: TraitAlias ( tps, bounds) , None ) )
5938
6011
} else {
@@ -6048,7 +6121,13 @@ impl<'a> Parser<'a> {
6048
6121
Some ( ty_second) => {
6049
6122
// impl Trait for Type
6050
6123
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 ( ) ;
6052
6131
}
6053
6132
6054
6133
let ty_first = ty_first. into_inner ( ) ;
@@ -6939,7 +7018,7 @@ impl<'a> Parser<'a> {
6939
7018
fn parse_enum_def ( & mut self , _generics : & ast:: Generics ) -> PResult < ' a , EnumDef > {
6940
7019
let mut variants = Vec :: new ( ) ;
6941
7020
let mut all_nullary = true ;
6942
- let mut any_disr = None ;
7021
+ let mut any_disr = vec ! [ ] ;
6943
7022
while self . token != token:: CloseDelim ( token:: Brace ) {
6944
7023
let variant_attrs = self . parse_outer_attributes ( ) ?;
6945
7024
let vlo = self . span ;
@@ -6961,7 +7040,9 @@ impl<'a> Parser<'a> {
6961
7040
id : ast:: DUMMY_NODE_ID ,
6962
7041
value : self . parse_expr ( ) ?,
6963
7042
} ) ;
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
+ }
6965
7046
struct_def = VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ;
6966
7047
} else {
6967
7048
struct_def = VariantData :: Unit ( ast:: DUMMY_NODE_ID ) ;
@@ -6978,11 +7059,15 @@ impl<'a> Parser<'a> {
6978
7059
if !self . eat ( & token:: Comma ) { break ; }
6979
7060
}
6980
7061
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 ( ) ;
6986
7071
}
6987
7072
6988
7073
Ok ( ast:: EnumDef { variants } )
0 commit comments