@@ -218,6 +218,27 @@ impl std::fmt::Display for UnaryFixity {
218218 }
219219}
220220
221+ struct MultiSugg {
222+ msg : String ,
223+ patches : Vec < ( Span , String ) > ,
224+ applicability : Applicability ,
225+ }
226+
227+ impl MultiSugg {
228+ fn emit ( self , err : & mut DiagnosticBuilder < ' _ > ) {
229+ err. multipart_suggestion ( & self . msg , self . patches , self . applicability ) ;
230+ }
231+
232+ /// Overrides individual messages and applicabilities.
233+ fn emit_many (
234+ err : & mut DiagnosticBuilder < ' _ > ,
235+ msg : & str ,
236+ applicability : Applicability ,
237+ suggestions : impl Iterator < Item = Self > ,
238+ ) {
239+ err. multipart_suggestions ( msg, suggestions. map ( |s| s. patches ) , applicability) ;
240+ }
241+ }
221242// SnapshotParser is used to create a snapshot of the parser
222243// without causing duplicate errors being emitted when the `Parser`
223244// is dropped.
@@ -1281,33 +1302,33 @@ impl<'a> Parser<'a> {
12811302 } ;
12821303
12831304 match kind. standalone {
1284- IsStandalone :: Standalone => {
1285- self . inc_dec_standalone_recovery ( & mut err, kind, spans, false )
1286- }
1305+ IsStandalone :: Standalone => self . inc_dec_standalone_suggest ( kind, spans) . emit ( & mut err) ,
12871306 IsStandalone :: Subexpr => {
12881307 let Ok ( base_src) = self . span_to_snippet ( base. span )
12891308 else { return help_base_case ( err, base) } ;
12901309 match kind. fixity {
12911310 UnaryFixity :: Pre => {
1292- self . prefix_inc_dec_suggest ( base_src, & mut err , kind, spans)
1311+ self . prefix_inc_dec_suggest ( base_src, kind, spans) . emit ( & mut err )
12931312 }
12941313 UnaryFixity :: Post => {
1295- self . postfix_inc_dec_suggest ( base_src, & mut err , kind, spans)
1314+ self . postfix_inc_dec_suggest ( base_src, kind, spans) . emit ( & mut err )
12961315 }
12971316 }
12981317 }
12991318 IsStandalone :: Maybe => {
13001319 let Ok ( base_src) = self . span_to_snippet ( base. span )
13011320 else { return help_base_case ( err, base) } ;
1302- match kind. fixity {
1303- UnaryFixity :: Pre => {
1304- self . prefix_inc_dec_suggest ( base_src, & mut err, kind, spans)
1305- }
1306- UnaryFixity :: Post => {
1307- self . postfix_inc_dec_suggest ( base_src, & mut err, kind, spans)
1308- }
1309- }
1310- self . inc_dec_standalone_recovery ( & mut err, kind, spans, true )
1321+ let sugg1 = match kind. fixity {
1322+ UnaryFixity :: Pre => self . prefix_inc_dec_suggest ( base_src, kind, spans) ,
1323+ UnaryFixity :: Post => self . postfix_inc_dec_suggest ( base_src, kind, spans) ,
1324+ } ;
1325+ let sugg2 = self . inc_dec_standalone_suggest ( kind, spans) ;
1326+ MultiSugg :: emit_many (
1327+ & mut err,
1328+ "use `+= 1` instead" ,
1329+ Applicability :: MaybeIncorrect ,
1330+ [ sugg1, sugg2] . into_iter ( ) ,
1331+ )
13111332 }
13121333 }
13131334 Err ( err)
@@ -1316,61 +1337,46 @@ impl<'a> Parser<'a> {
13161337 fn prefix_inc_dec_suggest (
13171338 & mut self ,
13181339 base_src : String ,
1319- err : & mut DiagnosticBuilder < ' a > ,
13201340 kind : IncDecRecovery ,
13211341 ( pre_span, post_span) : ( Span , Span ) ,
1322- ) {
1323- err . multipart_suggestion (
1324- & format ! ( "use `{}= 1` instead" , kind. op. chr( ) ) ,
1325- vec ! [
1342+ ) -> MultiSugg {
1343+ MultiSugg {
1344+ msg : format ! ( "use `{}= 1` instead" , kind. op. chr( ) ) ,
1345+ patches : vec ! [
13261346 ( pre_span, "{ " . to_string( ) ) ,
13271347 ( post_span, format!( " {}= 1; {} }}" , kind. op. chr( ) , base_src) ) ,
13281348 ] ,
1329- Applicability :: MachineApplicable ,
1330- ) ;
1349+ applicability : Applicability :: MachineApplicable ,
1350+ }
13311351 }
13321352
13331353 fn postfix_inc_dec_suggest (
13341354 & mut self ,
13351355 base_src : String ,
1336- err : & mut DiagnosticBuilder < ' a > ,
13371356 kind : IncDecRecovery ,
13381357 ( pre_span, post_span) : ( Span , Span ) ,
1339- ) {
1358+ ) -> MultiSugg {
13401359 let tmp_var = if base_src. trim ( ) == "tmp" { "tmp_" } else { "tmp" } ;
1341- err . multipart_suggestion (
1342- & format ! ( "use `{}= 1` instead" , kind. op. chr( ) ) ,
1343- vec ! [
1360+ MultiSugg {
1361+ msg : format ! ( "use `{}= 1` instead" , kind. op. chr( ) ) ,
1362+ patches : vec ! [
13441363 ( pre_span, format!( "{{ let {} = " , tmp_var) ) ,
13451364 ( post_span, format!( "; {} {}= 1; {} }}" , base_src, kind. op. chr( ) , tmp_var) ) ,
13461365 ] ,
1347- Applicability :: HasPlaceholders ,
1348- ) ;
1366+ applicability : Applicability :: HasPlaceholders ,
1367+ }
13491368 }
13501369
1351- fn inc_dec_standalone_recovery (
1370+ fn inc_dec_standalone_suggest (
13521371 & mut self ,
1353- err : & mut DiagnosticBuilder < ' a > ,
13541372 kind : IncDecRecovery ,
13551373 ( pre_span, post_span) : ( Span , Span ) ,
1356- maybe_not_standalone : bool ,
1357- ) {
1358- let msg = if maybe_not_standalone {
1359- "or, if you don't need to use it as an expression, change it to this" . to_owned ( )
1360- } else {
1361- format ! ( "use `{}= 1` instead" , kind. op. chr( ) )
1362- } ;
1363- let applicability = if maybe_not_standalone {
1364- // FIXME: Unspecified isn't right, but it's the least wrong option
1365- Applicability :: Unspecified
1366- } else {
1367- Applicability :: MachineApplicable
1368- } ;
1369- err. multipart_suggestion (
1370- & msg,
1371- vec ! [ ( pre_span, String :: new( ) ) , ( post_span, format!( " {}= 1" , kind. op. chr( ) ) ) ] ,
1372- applicability,
1373- ) ;
1374+ ) -> MultiSugg {
1375+ MultiSugg {
1376+ msg : format ! ( "use `{}= 1` instead" , kind. op. chr( ) ) ,
1377+ patches : vec ! [ ( pre_span, String :: new( ) ) , ( post_span, format!( " {}= 1" , kind. op. chr( ) ) ) ] ,
1378+ applicability : Applicability :: MachineApplicable ,
1379+ }
13741380 }
13751381
13761382 /// Tries to recover from associated item paths like `[T]::AssocItem` / `(T, U)::AssocItem`.
0 commit comments