Skip to content

Commit 9bb77da

Browse files
committed
Auto merge of #87915 - estebank:fancy-spans, r=oli-obk
Use smaller spans for some structured suggestions Use more accurate suggestion spans for * argument parse error * fully qualified path * missing code block type * numeric casts
2 parents b0ee495 + 34d1963 commit 9bb77da

File tree

60 files changed

+1200
-958
lines changed

Some content is hidden

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

60 files changed

+1200
-958
lines changed

compiler/rustc_errors/src/diagnostic.rs

+15
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,21 @@ impl Diagnostic {
304304
)
305305
}
306306

307+
/// Show a suggestion that has multiple parts to it, always as it's own subdiagnostic.
308+
/// In other words, multiple changes need to be applied as part of this suggestion.
309+
pub fn multipart_suggestion_verbose(
310+
&mut self,
311+
msg: &str,
312+
suggestion: Vec<(Span, String)>,
313+
applicability: Applicability,
314+
) -> &mut Self {
315+
self.multipart_suggestion_with_style(
316+
msg,
317+
suggestion,
318+
applicability,
319+
SuggestionStyle::ShowAlways,
320+
)
321+
}
307322
/// [`Diagnostic::multipart_suggestion()`] but you can set the [`SuggestionStyle`].
308323
pub fn multipart_suggestion_with_style(
309324
&mut self,

compiler/rustc_errors/src/diagnostic_builder.rs

+14
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,20 @@ impl<'a> DiagnosticBuilder<'a> {
258258
self
259259
}
260260

261+
/// See [`Diagnostic::multipart_suggestion()`].
262+
pub fn multipart_suggestion_verbose(
263+
&mut self,
264+
msg: &str,
265+
suggestion: Vec<(Span, String)>,
266+
applicability: Applicability,
267+
) -> &mut Self {
268+
if !self.0.allow_suggestions {
269+
return self;
270+
}
271+
self.0.diagnostic.multipart_suggestion_verbose(msg, suggestion, applicability);
272+
self
273+
}
274+
261275
/// See [`Diagnostic::tool_only_multipart_suggestion()`].
262276
pub fn tool_only_multipart_suggestion(
263277
&mut self,

compiler/rustc_parse/src/parser/diagnostics.rs

+46-39
Original file line numberDiff line numberDiff line change
@@ -1633,50 +1633,57 @@ impl<'a> Parser<'a> {
16331633
{
16341634
let rfc_note = "anonymous parameters are removed in the 2018 edition (see RFC 1685)";
16351635

1636-
let (ident, self_sugg, param_sugg, type_sugg) = match pat.kind {
1637-
PatKind::Ident(_, ident, _) => (
1638-
ident,
1639-
format!("self: {}", ident),
1640-
format!("{}: TypeName", ident),
1641-
format!("_: {}", ident),
1642-
),
1643-
// Also catches `fn foo(&a)`.
1644-
PatKind::Ref(ref pat, mutab)
1645-
if matches!(pat.clone().into_inner().kind, PatKind::Ident(..)) =>
1646-
{
1647-
match pat.clone().into_inner().kind {
1648-
PatKind::Ident(_, ident, _) => {
1649-
let mutab = mutab.prefix_str();
1650-
(
1651-
ident,
1652-
format!("self: &{}{}", mutab, ident),
1653-
format!("{}: &{}TypeName", ident, mutab),
1654-
format!("_: &{}{}", mutab, ident),
1655-
)
1636+
let (ident, self_sugg, param_sugg, type_sugg, self_span, param_span, type_span) =
1637+
match pat.kind {
1638+
PatKind::Ident(_, ident, _) => (
1639+
ident,
1640+
"self: ".to_string(),
1641+
": TypeName".to_string(),
1642+
"_: ".to_string(),
1643+
pat.span.shrink_to_lo(),
1644+
pat.span.shrink_to_hi(),
1645+
pat.span.shrink_to_lo(),
1646+
),
1647+
// Also catches `fn foo(&a)`.
1648+
PatKind::Ref(ref inner_pat, mutab)
1649+
if matches!(inner_pat.clone().into_inner().kind, PatKind::Ident(..)) =>
1650+
{
1651+
match inner_pat.clone().into_inner().kind {
1652+
PatKind::Ident(_, ident, _) => {
1653+
let mutab = mutab.prefix_str();
1654+
(
1655+
ident,
1656+
"self: ".to_string(),
1657+
format!("{}: &{}TypeName", ident, mutab),
1658+
"_: ".to_string(),
1659+
pat.span.shrink_to_lo(),
1660+
pat.span,
1661+
pat.span.shrink_to_lo(),
1662+
)
1663+
}
1664+
_ => unreachable!(),
16561665
}
1657-
_ => unreachable!(),
1658-
}
1659-
}
1660-
_ => {
1661-
// Otherwise, try to get a type and emit a suggestion.
1662-
if let Some(ty) = pat.to_ty() {
1663-
err.span_suggestion_verbose(
1664-
pat.span,
1665-
"explicitly ignore the parameter name",
1666-
format!("_: {}", pprust::ty_to_string(&ty)),
1667-
Applicability::MachineApplicable,
1668-
);
1669-
err.note(rfc_note);
16701666
}
1667+
_ => {
1668+
// Otherwise, try to get a type and emit a suggestion.
1669+
if let Some(ty) = pat.to_ty() {
1670+
err.span_suggestion_verbose(
1671+
pat.span,
1672+
"explicitly ignore the parameter name",
1673+
format!("_: {}", pprust::ty_to_string(&ty)),
1674+
Applicability::MachineApplicable,
1675+
);
1676+
err.note(rfc_note);
1677+
}
16711678

1672-
return None;
1673-
}
1674-
};
1679+
return None;
1680+
}
1681+
};
16751682

16761683
// `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
16771684
if first_param {
16781685
err.span_suggestion(
1679-
pat.span,
1686+
self_span,
16801687
"if this is a `self` type, give it a parameter name",
16811688
self_sugg,
16821689
Applicability::MaybeIncorrect,
@@ -1686,14 +1693,14 @@ impl<'a> Parser<'a> {
16861693
// `fn foo(HashMap: TypeName<u32>)`.
16871694
if self.token != token::Lt {
16881695
err.span_suggestion(
1689-
pat.span,
1696+
param_span,
16901697
"if this is a parameter name, give it a type",
16911698
param_sugg,
16921699
Applicability::HasPlaceholders,
16931700
);
16941701
}
16951702
err.span_suggestion(
1696-
pat.span,
1703+
type_span,
16971704
"if this is a type, explicitly ignore the parameter name",
16981705
type_sugg,
16991706
Applicability::MachineApplicable,

compiler/rustc_resolve/src/late/diagnostics.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_ast::{
1212
};
1313
use rustc_ast_pretty::pprust::path_segment_to_string;
1414
use rustc_data_structures::fx::FxHashSet;
15-
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, SuggestionStyle};
15+
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
1616
use rustc_hir as hir;
1717
use rustc_hir::def::Namespace::{self, *};
1818
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
@@ -1960,11 +1960,10 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
19601960
introduce_suggestion.push((*span, formatter(&lt_name)));
19611961
}
19621962
}
1963-
err.multipart_suggestion_with_style(
1963+
err.multipart_suggestion_verbose(
19641964
&msg,
19651965
introduce_suggestion,
19661966
Applicability::MaybeIncorrect,
1967-
SuggestionStyle::ShowAlways,
19681967
);
19691968
}
19701969

@@ -1976,14 +1975,13 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
19761975
})
19771976
.map(|(formatter, span)| (*span, formatter(name)))
19781977
.collect();
1979-
err.multipart_suggestion_with_style(
1978+
err.multipart_suggestion_verbose(
19801979
&format!(
19811980
"consider using the `{}` lifetime",
19821981
lifetime_names.iter().next().unwrap()
19831982
),
19841983
spans_suggs,
19851984
Applicability::MaybeIncorrect,
1986-
SuggestionStyle::ShowAlways,
19871985
);
19881986
};
19891987
let suggest_new = |err: &mut DiagnosticBuilder<'_>, suggs: Vec<Option<String>>| {
@@ -2074,11 +2072,10 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
20742072
};
20752073
spans_suggs.push((span, sugg.to_string()));
20762074
}
2077-
err.multipart_suggestion_with_style(
2075+
err.multipart_suggestion_verbose(
20782076
"consider using the `'static` lifetime",
20792077
spans_suggs,
20802078
Applicability::MaybeIncorrect,
2081-
SuggestionStyle::ShowAlways,
20822079
);
20832080
continue;
20842081
}
@@ -2163,11 +2160,10 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
21632160
.unwrap_or((span, sugg));
21642161
introduce_suggestion.push((span, sugg.to_string()));
21652162
}
2166-
err.multipart_suggestion_with_style(
2163+
err.multipart_suggestion_verbose(
21672164
&msg,
21682165
introduce_suggestion,
21692166
Applicability::MaybeIncorrect,
2170-
SuggestionStyle::ShowAlways,
21712167
);
21722168
if should_break {
21732169
break;
@@ -2243,11 +2239,10 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
22432239
if spans_suggs.len() > 0 {
22442240
// This happens when we have `Foo<T>` where we point at the space before `T`,
22452241
// but this can be confusing so we give a suggestion with placeholders.
2246-
err.multipart_suggestion_with_style(
2242+
err.multipart_suggestion_verbose(
22472243
"consider using one of the available lifetimes here",
22482244
spans_suggs,
22492245
Applicability::HasPlaceholders,
2250-
SuggestionStyle::ShowAlways,
22512246
);
22522247
}
22532248
}

compiler/rustc_typeck/src/astconv/mod.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1687,14 +1687,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16871687
constraint=constraint,
16881688
));
16891689
} else {
1690-
err.span_suggestion(
1691-
span,
1690+
err.span_suggestion_verbose(
1691+
span.with_hi(assoc_name.span.lo()),
16921692
"use fully qualified syntax to disambiguate",
16931693
format!(
1694-
"<{} as {}>::{}",
1694+
"<{} as {}>::",
16951695
ty_param_name(),
16961696
bound.print_only_trait_path(),
1697-
assoc_name,
16981697
),
16991698
Applicability::MaybeIncorrect,
17001699
);

0 commit comments

Comments
 (0)