diff options
| author | Noah Lev <camelidcamel@gmail.com> | 2022-02-21 18:52:47 -0800 |
|---|---|---|
| committer | Noah Lev <camelidcamel@gmail.com> | 2022-03-23 22:31:57 -0700 |
| commit | 725cde42d5673d1957ad58c6b2fada28a6a4edbd (patch) | |
| tree | 52ae46999082cf7e0682b2849bee18c72146334c /compiler/rustc_parse | |
| parent | ef74796178edd2cf28f17109083cbd235808f88d (diff) | |
| download | rust-725cde42d5673d1957ad58c6b2fada28a6a4edbd.tar.gz rust-725cde42d5673d1957ad58c6b2fada28a6a4edbd.zip | |
Use `multipart_suggestions`
This records that the suggestions are mutually-exclusive (i.e., only one should be applied).
Diffstat (limited to 'compiler/rustc_parse')
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 102 |
1 files changed, 54 insertions, 48 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 9590f26a76f..0e0954d6ee2 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -218,6 +218,27 @@ impl std::fmt::Display for UnaryFixity { } } +struct MultiSugg { + msg: String, + patches: Vec<(Span, String)>, + applicability: Applicability, +} + +impl MultiSugg { + fn emit(self, err: &mut DiagnosticBuilder<'_>) { + err.multipart_suggestion(&self.msg, self.patches, self.applicability); + } + + /// Overrides individual messages and applicabilities. + fn emit_many( + err: &mut DiagnosticBuilder<'_>, + msg: &str, + applicability: Applicability, + suggestions: impl Iterator<Item = Self>, + ) { + err.multipart_suggestions(msg, suggestions.map(|s| s.patches), applicability); + } +} // SnapshotParser is used to create a snapshot of the parser // without causing duplicate errors being emitted when the `Parser` // is dropped. @@ -1281,33 +1302,33 @@ impl<'a> Parser<'a> { }; match kind.standalone { - IsStandalone::Standalone => { - self.inc_dec_standalone_recovery(&mut err, kind, spans, false) - } + IsStandalone::Standalone => self.inc_dec_standalone_suggest(kind, spans).emit(&mut err), IsStandalone::Subexpr => { let Ok(base_src) = self.span_to_snippet(base.span) else { return help_base_case(err, base) }; match kind.fixity { UnaryFixity::Pre => { - self.prefix_inc_dec_suggest(base_src, &mut err, kind, spans) + self.prefix_inc_dec_suggest(base_src, kind, spans).emit(&mut err) } UnaryFixity::Post => { - self.postfix_inc_dec_suggest(base_src, &mut err, kind, spans) + self.postfix_inc_dec_suggest(base_src, kind, spans).emit(&mut err) } } } IsStandalone::Maybe => { let Ok(base_src) = self.span_to_snippet(base.span) else { return help_base_case(err, base) }; - match kind.fixity { - UnaryFixity::Pre => { - self.prefix_inc_dec_suggest(base_src, &mut err, kind, spans) - } - UnaryFixity::Post => { - self.postfix_inc_dec_suggest(base_src, &mut err, kind, spans) - } - } - self.inc_dec_standalone_recovery(&mut err, kind, spans, true) + let sugg1 = match kind.fixity { + UnaryFixity::Pre => self.prefix_inc_dec_suggest(base_src, kind, spans), + UnaryFixity::Post => self.postfix_inc_dec_suggest(base_src, kind, spans), + }; + let sugg2 = self.inc_dec_standalone_suggest(kind, spans); + MultiSugg::emit_many( + &mut err, + "use `+= 1` instead", + Applicability::MaybeIncorrect, + [sugg1, sugg2].into_iter(), + ) } } Err(err) @@ -1316,61 +1337,46 @@ impl<'a> Parser<'a> { fn prefix_inc_dec_suggest( &mut self, base_src: String, - err: &mut DiagnosticBuilder<'a>, kind: IncDecRecovery, (pre_span, post_span): (Span, Span), - ) { - err.multipart_suggestion( - &format!("use `{}= 1` instead", kind.op.chr()), - vec![ + ) -> MultiSugg { + MultiSugg { + msg: format!("use `{}= 1` instead", kind.op.chr()), + patches: vec![ (pre_span, "{ ".to_string()), (post_span, format!(" {}= 1; {} }}", kind.op.chr(), base_src)), ], - Applicability::MachineApplicable, - ); + applicability: Applicability::MachineApplicable, + } } fn postfix_inc_dec_suggest( &mut self, base_src: String, - err: &mut DiagnosticBuilder<'a>, kind: IncDecRecovery, (pre_span, post_span): (Span, Span), - ) { + ) -> MultiSugg { let tmp_var = if base_src.trim() == "tmp" { "tmp_" } else { "tmp" }; - err.multipart_suggestion( - &format!("use `{}= 1` instead", kind.op.chr()), - vec![ + MultiSugg { + msg: format!("use `{}= 1` instead", kind.op.chr()), + patches: vec![ (pre_span, format!("{{ let {} = ", tmp_var)), (post_span, format!("; {} {}= 1; {} }}", base_src, kind.op.chr(), tmp_var)), ], - Applicability::HasPlaceholders, - ); + applicability: Applicability::HasPlaceholders, + } } - fn inc_dec_standalone_recovery( + fn inc_dec_standalone_suggest( &mut self, - err: &mut DiagnosticBuilder<'a>, kind: IncDecRecovery, (pre_span, post_span): (Span, Span), - maybe_not_standalone: bool, - ) { - let msg = if maybe_not_standalone { - "or, if you don't need to use it as an expression, change it to this".to_owned() - } else { - format!("use `{}= 1` instead", kind.op.chr()) - }; - let applicability = if maybe_not_standalone { - // FIXME: Unspecified isn't right, but it's the least wrong option - Applicability::Unspecified - } else { - Applicability::MachineApplicable - }; - err.multipart_suggestion( - &msg, - vec![(pre_span, String::new()), (post_span, format!(" {}= 1", kind.op.chr()))], - applicability, - ); + ) -> MultiSugg { + MultiSugg { + msg: format!("use `{}= 1` instead", kind.op.chr()), + patches: vec![(pre_span, String::new()), (post_span, format!(" {}= 1", kind.op.chr()))], + applicability: Applicability::MachineApplicable, + } } /// Tries to recover from associated item paths like `[T]::AssocItem` / `(T, U)::AssocItem`. |
