Skip to content

Commit 199d1ae

Browse files
committed
Auto merge of #86754 - estebank:use-multispans-more, r=varkor
Use `multipart_suggestions` more Built on top of #86532
2 parents 1f0a591 + 0b8f192 commit 199d1ae

File tree

61 files changed

+661
-442
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+661
-442
lines changed

compiler/rustc_errors/src/diagnostic.rs

+24
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,30 @@ impl Diagnostic {
444444
self
445445
}
446446

447+
/// Prints out a message with multiple suggested edits of the code.
448+
/// See also [`Diagnostic::span_suggestion()`].
449+
pub fn multipart_suggestions(
450+
&mut self,
451+
msg: &str,
452+
suggestions: impl Iterator<Item = Vec<(Span, String)>>,
453+
applicability: Applicability,
454+
) -> &mut Self {
455+
self.suggestions.push(CodeSuggestion {
456+
substitutions: suggestions
457+
.map(|sugg| Substitution {
458+
parts: sugg
459+
.into_iter()
460+
.map(|(span, snippet)| SubstitutionPart { snippet, span })
461+
.collect(),
462+
})
463+
.collect(),
464+
msg: msg.to_owned(),
465+
style: SuggestionStyle::ShowCode,
466+
applicability,
467+
tool_metadata: Default::default(),
468+
});
469+
self
470+
}
447471
/// Prints out a message with a suggested edit of the code. If the suggestion is presented
448472
/// inline, it will only show the message and not the suggestion.
449473
///

compiler/rustc_errors/src/diagnostic_builder.rs

+14
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,20 @@ impl<'a> DiagnosticBuilder<'a> {
301301
self
302302
}
303303

304+
/// See [`Diagnostic::multipart_suggestions()`].
305+
pub fn multipart_suggestions(
306+
&mut self,
307+
msg: &str,
308+
suggestions: impl Iterator<Item = Vec<(Span, String)>>,
309+
applicability: Applicability,
310+
) -> &mut Self {
311+
if !self.0.allow_suggestions {
312+
return self;
313+
}
314+
self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability);
315+
self
316+
}
317+
304318
/// See [`Diagnostic::span_suggestion_short()`].
305319
pub fn span_suggestion_short(
306320
&mut self,

compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_middle::mir::{
1212
use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
1313
use rustc_span::source_map::DesugaringKind;
1414
use rustc_span::symbol::sym;
15-
use rustc_span::{MultiSpan, Span, DUMMY_SP};
15+
use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
1616
use rustc_trait_selection::infer::InferCtxtExt;
1717

1818
use crate::dataflow::drop_flag_effects;
@@ -1393,18 +1393,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
13931393
let tcx = self.infcx.tcx;
13941394
let args_span = use_span.args_or_use();
13951395

1396-
let suggestion = match tcx.sess.source_map().span_to_snippet(args_span) {
1397-
Ok(mut string) => {
1396+
let (sugg_span, suggestion) = match tcx.sess.source_map().span_to_snippet(args_span) {
1397+
Ok(string) => {
13981398
if string.starts_with("async ") {
1399-
string.insert_str(6, "move ");
1399+
let pos = args_span.lo() + BytePos(6);
1400+
(args_span.with_lo(pos).with_hi(pos), "move ".to_string())
14001401
} else if string.starts_with("async|") {
1401-
string.insert_str(5, " move");
1402+
let pos = args_span.lo() + BytePos(5);
1403+
(args_span.with_lo(pos).with_hi(pos), " move".to_string())
14021404
} else {
1403-
string.insert_str(0, "move ");
1404-
};
1405-
string
1405+
(args_span.shrink_to_lo(), "move ".to_string())
1406+
}
14061407
}
1407-
Err(_) => "move |<args>| <body>".to_string(),
1408+
Err(_) => (args_span, "move |<args>| <body>".to_string()),
14081409
};
14091410
let kind = match use_span.generator_kind() {
14101411
Some(generator_kind) => match generator_kind {
@@ -1420,8 +1421,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
14201421

14211422
let mut err =
14221423
self.cannot_capture_in_long_lived_closure(args_span, kind, captured_var, var_span);
1423-
err.span_suggestion(
1424-
args_span,
1424+
err.span_suggestion_verbose(
1425+
sugg_span,
14251426
&format!(
14261427
"to force the {} to take ownership of {} (and any \
14271428
other referenced variables), use the `move` keyword",

compiler/rustc_parse/src/parser/diagnostics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1770,7 +1770,7 @@ impl<'a> Parser<'a> {
17701770
let mut err = self.struct_span_err(span, &msg);
17711771
let sp = self.sess.source_map().start_point(self.token.span);
17721772
if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
1773-
self.sess.expr_parentheses_needed(&mut err, *sp, None);
1773+
self.sess.expr_parentheses_needed(&mut err, *sp);
17741774
}
17751775
err.span_label(span, "expected expression");
17761776
err

compiler/rustc_parse/src/parser/expr.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ impl<'a> Parser<'a> {
358358
&format!("expected expression, found `{}`", pprust::token_to_string(&self.token),),
359359
);
360360
err.span_label(self.token.span, "expected expression");
361-
self.sess.expr_parentheses_needed(&mut err, lhs.span, Some(pprust::expr_to_string(&lhs)));
361+
self.sess.expr_parentheses_needed(&mut err, lhs.span);
362362
err.emit();
363363
}
364364

@@ -696,20 +696,18 @@ impl<'a> Parser<'a> {
696696
let expr =
697697
mk_expr(self, lhs, self.mk_ty(path.span, TyKind::Path(None, path)));
698698

699-
let expr_str = self
700-
.span_to_snippet(expr.span)
701-
.unwrap_or_else(|_| pprust::expr_to_string(&expr));
702-
703699
self.struct_span_err(self.token.span, &msg)
704700
.span_label(
705701
self.look_ahead(1, |t| t.span).to(span_after_type),
706702
"interpreted as generic arguments",
707703
)
708704
.span_label(self.token.span, format!("not interpreted as {}", op_noun))
709-
.span_suggestion(
710-
expr.span,
705+
.multipart_suggestion(
711706
&format!("try {} the cast value", op_verb),
712-
format!("({})", expr_str),
707+
vec![
708+
(expr.span.shrink_to_lo(), "(".to_string()),
709+
(expr.span.shrink_to_hi(), ")".to_string()),
710+
],
713711
Applicability::MachineApplicable,
714712
)
715713
.emit();

compiler/rustc_parse/src/parser/pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ impl<'a> Parser<'a> {
763763

764764
let sp = self.sess.source_map().start_point(self.token.span);
765765
if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
766-
self.sess.expr_parentheses_needed(&mut err, *sp, None);
766+
self.sess.expr_parentheses_needed(&mut err, *sp);
767767
}
768768

769769
Err(err)

compiler/rustc_session/src/parse.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -228,20 +228,12 @@ impl ParseSess {
228228

229229
/// Extend an error with a suggestion to wrap an expression with parentheses to allow the
230230
/// parser to continue parsing the following operation as part of the same expression.
231-
pub fn expr_parentheses_needed(
232-
&self,
233-
err: &mut DiagnosticBuilder<'_>,
234-
span: Span,
235-
alt_snippet: Option<String>,
236-
) {
237-
if let Some(snippet) = self.source_map().span_to_snippet(span).ok().or(alt_snippet) {
238-
err.span_suggestion(
239-
span,
240-
"parentheses are required to parse this as an expression",
241-
format!("({})", snippet),
242-
Applicability::MachineApplicable,
243-
);
244-
}
231+
pub fn expr_parentheses_needed(&self, err: &mut DiagnosticBuilder<'_>, span: Span) {
232+
err.multipart_suggestion(
233+
"parentheses are required to parse this as an expression",
234+
vec![(span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string())],
235+
Applicability::MachineApplicable,
236+
);
245237
}
246238

247239
pub fn save_proc_macro_span(&self, span: Span) -> usize {

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -1163,15 +1163,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
11631163
if is_object_safe {
11641164
// Suggest `-> Box<dyn Trait>` and `Box::new(returned_value)`.
11651165
// Get all the return values and collect their span and suggestion.
1166-
if let Some(mut suggestions) = visitor
1166+
let mut suggestions: Vec<_> = visitor
11671167
.returns
11681168
.iter()
1169-
.map(|expr| {
1170-
let snip = sm.span_to_snippet(expr.span).ok()?;
1171-
Some((expr.span, format!("Box::new({})", snip)))
1169+
.flat_map(|expr| {
1170+
vec![
1171+
(expr.span.shrink_to_lo(), "Box::new(".to_string()),
1172+
(expr.span.shrink_to_hi(), ")".to_string()),
1173+
]
1174+
.into_iter()
11721175
})
1173-
.collect::<Option<Vec<_>>>()
1174-
{
1176+
.collect();
1177+
if !suggestions.is_empty() {
11751178
// Add the suggestion for the return type.
11761179
suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
11771180
err.multipart_suggestion(

0 commit comments

Comments
 (0)