Skip to content

Commit 61edf25

Browse files
committedMar 14, 2020
Tweak suggest_constraining_type_param
Some of the bound restriction structured suggestions were incorrect while others had subpar output.
1 parent 131772c commit 61edf25

File tree

66 files changed

+408
-570
lines changed

Some content is hidden

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

66 files changed

+408
-570
lines changed
 

‎src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs

-2
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
222222
&mut err,
223223
&param.name.as_str(),
224224
"Copy",
225-
tcx.sess.source_map(),
226-
span,
227225
None,
228226
);
229227
}

‎src/librustc_trait_selection/traits/error_reporting/mod.rs

+46-73
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}
2525
use rustc_hir as hir;
2626
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
2727
use rustc_hir::{Node, QPath, TyKind, WhereBoundPredicate, WherePredicate};
28-
use rustc_span::source_map::SourceMap;
29-
use rustc_span::{ExpnKind, Span, DUMMY_SP};
28+
use rustc_span::{BytePos, ExpnKind, Span, DUMMY_SP};
3029
use std::fmt;
3130

3231
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -1680,14 +1679,8 @@ pub fn suggest_constraining_type_param(
16801679
err: &mut DiagnosticBuilder<'_>,
16811680
param_name: &str,
16821681
constraint: &str,
1683-
source_map: &SourceMap,
1684-
span: Span,
16851682
def_id: Option<DefId>,
16861683
) -> bool {
1687-
const MSG_RESTRICT_BOUND_FURTHER: &str = "consider further restricting this bound with";
1688-
const MSG_RESTRICT_TYPE: &str = "consider restricting this type parameter with";
1689-
const MSG_RESTRICT_TYPE_FURTHER: &str = "consider further restricting this type parameter with";
1690-
16911684
let param = generics.params.iter().find(|p| p.name.ident().as_str() == param_name);
16921685

16931686
let param = if let Some(param) = param {
@@ -1696,6 +1689,11 @@ pub fn suggest_constraining_type_param(
16961689
return false;
16971690
};
16981691

1692+
const MSG_RESTRICT_BOUND_FURTHER: &str = "consider further restricting this bound";
1693+
let msg_restrict_type = format!("consider restricting type parameter `{}`", param_name);
1694+
let msg_restrict_type_further =
1695+
format!("consider further restricting type parameter `{}`", param_name);
1696+
16991697
if def_id == tcx.lang_items().sized_trait() {
17001698
// Type parameters are already `Sized` by default.
17011699
err.span_label(param.span, &format!("this type parameter needs to be `{}`", constraint));
@@ -1718,19 +1716,21 @@ pub fn suggest_constraining_type_param(
17181716
// |
17191717
// replace with: `impl Foo + Bar`
17201718

1721-
err.span_help(param.span, &format!("{} `+ {}`", MSG_RESTRICT_BOUND_FURTHER, constraint));
1722-
1723-
err.tool_only_span_suggestion(
1724-
param.span,
1719+
err.span_suggestion_verbose(
1720+
param.span.shrink_to_hi(),
17251721
MSG_RESTRICT_BOUND_FURTHER,
1726-
format!("{} + {}", param_name, constraint),
1722+
format!(" + {}", constraint),
17271723
Applicability::MachineApplicable,
17281724
);
17291725

17301726
return true;
17311727
}
17321728

1733-
if generics.where_clause.predicates.is_empty() {
1729+
if generics.where_clause.predicates.is_empty()
1730+
// Given `trait Base<T = String>: Super<T>` where `T: Copy`, suggest restricting in the
1731+
// `where` clause in stead of `trait Base<T: Copy = String>: Super<T>`.
1732+
&& !matches!(param.kind, hir::GenericParamKind::Type { default: Some(_), .. })
1733+
{
17341734
if let Some(bounds_span) = param.bounds_span() {
17351735
// If user has provided some bounds, suggest restricting them:
17361736
//
@@ -1746,37 +1746,21 @@ pub fn suggest_constraining_type_param(
17461746
// |
17471747
// replace with: `T: Bar +`
17481748

1749-
err.span_help(
1750-
bounds_span,
1751-
&format!("{} `+ {}`", MSG_RESTRICT_BOUND_FURTHER, constraint),
1749+
err.span_suggestion_verbose(
1750+
bounds_span.shrink_to_hi(),
1751+
MSG_RESTRICT_BOUND_FURTHER,
1752+
format!(" + {}", constraint),
1753+
Applicability::MachineApplicable,
17521754
);
1753-
1754-
let span_hi = param.span.with_hi(span.hi());
1755-
let span_with_colon = source_map.span_through_char(span_hi, ':');
1756-
1757-
if span_hi != param.span && span_with_colon != span_hi {
1758-
err.tool_only_span_suggestion(
1759-
span_with_colon,
1760-
MSG_RESTRICT_BOUND_FURTHER,
1761-
format!("{}: {} + ", param_name, constraint),
1762-
Applicability::MachineApplicable,
1763-
);
1764-
}
17651755
} else {
17661756
// If user hasn't provided any bounds, suggest adding a new one:
17671757
//
17681758
// fn foo<T>(t: T) { ... }
17691759
// - help: consider restricting this type parameter with `T: Foo`
1770-
1771-
err.span_help(
1772-
param.span,
1773-
&format!("{} `{}: {}`", MSG_RESTRICT_TYPE, param_name, constraint),
1774-
);
1775-
1776-
err.tool_only_span_suggestion(
1777-
param.span,
1778-
MSG_RESTRICT_TYPE,
1779-
format!("{}: {}", param_name, constraint),
1760+
err.span_suggestion_verbose(
1761+
param.span.shrink_to_hi(),
1762+
&msg_restrict_type,
1763+
format!(": {}", constraint),
17801764
Applicability::MachineApplicable,
17811765
);
17821766
}
@@ -1840,55 +1824,44 @@ pub fn suggest_constraining_type_param(
18401824
}
18411825
}
18421826

1843-
let where_clause_span =
1844-
generics.where_clause.span_for_predicates_or_empty_place().shrink_to_hi();
1827+
let where_clause_span = generics.where_clause.span_for_predicates_or_empty_place();
1828+
// Account for `fn foo<T>(t: T) where T: Foo,` so we don't suggest two trailing commas.
1829+
let mut trailing_comma = false;
1830+
if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(where_clause_span) {
1831+
if snippet.ends_with(",") {
1832+
trailing_comma = true;
1833+
}
1834+
}
1835+
let where_clause_span = if trailing_comma {
1836+
let hi = where_clause_span.hi();
1837+
Span::new(hi - BytePos(1), hi, where_clause_span.ctxt())
1838+
} else {
1839+
where_clause_span.shrink_to_hi()
1840+
};
18451841

18461842
match &param_spans[..] {
18471843
&[] => {
1848-
err.span_help(
1849-
param.span,
1850-
&format!("{} `where {}: {}`", MSG_RESTRICT_TYPE, param_name, constraint),
1851-
);
1852-
1853-
err.tool_only_span_suggestion(
1844+
err.span_suggestion_verbose(
18541845
where_clause_span,
1855-
MSG_RESTRICT_TYPE,
1846+
&msg_restrict_type_further,
18561847
format!(", {}: {}", param_name, constraint),
18571848
Applicability::MachineApplicable,
18581849
);
18591850
}
18601851

18611852
&[&param_span] => {
1862-
err.span_help(
1863-
param_span,
1864-
&format!("{} `+ {}`", MSG_RESTRICT_BOUND_FURTHER, constraint),
1853+
err.span_suggestion_verbose(
1854+
param_span.shrink_to_hi(),
1855+
MSG_RESTRICT_BOUND_FURTHER,
1856+
format!(" + {}", constraint),
1857+
Applicability::MachineApplicable,
18651858
);
1866-
1867-
let span_hi = param_span.with_hi(span.hi());
1868-
let span_with_colon = source_map.span_through_char(span_hi, ':');
1869-
1870-
if span_hi != param_span && span_with_colon != span_hi {
1871-
err.tool_only_span_suggestion(
1872-
span_with_colon,
1873-
MSG_RESTRICT_BOUND_FURTHER,
1874-
format!("{}: {} +", param_name, constraint),
1875-
Applicability::MachineApplicable,
1876-
);
1877-
}
18781859
}
18791860

18801861
_ => {
1881-
err.span_help(
1882-
param.span,
1883-
&format!(
1884-
"{} `where {}: {}`",
1885-
MSG_RESTRICT_TYPE_FURTHER, param_name, constraint,
1886-
),
1887-
);
1888-
1889-
err.tool_only_span_suggestion(
1862+
err.span_suggestion_verbose(
18901863
where_clause_span,
1891-
MSG_RESTRICT_BOUND_FURTHER,
1864+
&msg_restrict_type_further,
18921865
format!(", {}: {}", param_name, constraint),
18931866
Applicability::MachineApplicable,
18941867
);

0 commit comments

Comments
 (0)