Skip to content

Commit 8e9e9c8

Browse files
committed
Slightly tweak the diagnostic for uncovered type parameters
The diagnostic is generally very noisy. This commit tries to make it slightly less cluttered and more legible by 1. stopping to reuse the lengthy primary message as the primary label. This duplication didn't increase the information content and only turned the diagnostic into a letter and symbol soup. Instead, we now pick a succinct label ("uncovered type parameter") that immediately(!) signals to the users in red what is wrong with the highlighted type parameter. 2. breaking some information-dense notes into multiple lines. Finally, this rephrases the slightly awkward and confusing "type parameter […] must be used as a type parameter for […] type" to "type parameter […] must be used as an argument to […] type".
1 parent b3ec1e7 commit 8e9e9c8

56 files changed

Lines changed: 225 additions & 167 deletions

File tree

Some content is hidden

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

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,28 +1992,37 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for UncoveredTyParams<'_> {
19921992
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
19931993
let Self { param, local_ty } = self;
19941994

1995-
let mut diag = Diag::new(dcx, level, "").with_span(param.span);
1995+
let mut diag = Diag::new(dcx, level, "")
1996+
.with_span(param.span)
1997+
.with_span_label(param.span, "uncovered type parameter");
19961998
if diag.is_error() {
19971999
diag.code(E0210);
19982000
}
19992001

2000-
let note = "implementing a foreign trait is only possible if at least one of the types for which it is implemented is local";
2002+
let note = "\
2003+
implementing a foreign trait is only possible if \
2004+
at least one of the types for which it is implemented is local";
2005+
20012006
if let Some(local_ty) = local_ty {
2002-
let msg = format!(
2003-
"type parameter `{param}` must be covered by another type when it appears before the first local type (`{local_ty}`)"
2004-
);
2005-
diag.primary_message(msg.clone());
2006-
diag.span_label(param.span, msg);
2007+
diag.primary_message(format!(
2008+
"type parameter `{param}` must be covered by another type when \
2009+
it appears before the first local type (`{local_ty}`)"
2010+
));
2011+
20072012
diag.note(format!(
2008-
"{note}, and no uncovered type parameters appear before that first local type"
2013+
"{note},\nand no uncovered type parameters appear before that first local type"
20092014
));
2010-
diag.note("in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last");
2011-
} else {
2012-
let msg = format!(
2013-
"type parameter `{param}` must be used as the type parameter for some local type"
2015+
diag.note(
2016+
"in this case, 'before' refers to the following order: \
2017+
`impl<..> ForeignTrait<T1, ..., Tn> for T0`,\n\
2018+
where `T0` is the first and `Tn` is the last",
20142019
);
2015-
diag.primary_message(format!("{msg} (e.g., `MyStruct<{param}>`)"));
2016-
diag.span_label(param.span, msg);
2020+
} else {
2021+
diag.primary_message(format!(
2022+
"type parameter `{param}` must be used as an argument to \
2023+
some local type (e.g., `MyStruct<{param}>`)"
2024+
));
2025+
20172026
diag.note(note);
20182027
diag.note(
20192028
"only traits defined in the current crate can be implemented for a type parameter",

tests/ui/coercion/invalid-blanket-coerce-unsized-impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#![feature(coerce_unsized)]
66

77
impl<A> std::ops::CoerceUnsized<A> for A {}
8-
//~^ ERROR type parameter `A` must be used as the type parameter for some local type
8+
//~^ ERROR type parameter `A` must be used as an argument to some local type
99
//~| ERROR the trait `CoerceUnsized` may only be implemented for a coercion between structures
1010

1111
const C: usize = 1;

tests/ui/coercion/invalid-blanket-coerce-unsized-impl.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct<A>`)
1+
error[E0210]: type parameter `A` must be used as an argument to some local type (e.g., `MyStruct<A>`)
22
--> $DIR/invalid-blanket-coerce-unsized-impl.rs:7:6
33
|
44
LL | impl<A> std::ops::CoerceUnsized<A> for A {}
5-
| ^ type parameter `A` must be used as the type parameter for some local type
5+
| ^ uncovered type parameter
66
|
77
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
88
= note: only traits defined in the current crate can be implemented for a type parameter

tests/ui/coherence/coherence-all-remote.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
1+
error[E0210]: type parameter `T` must be used as an argument to some local type (e.g., `MyStruct<T>`)
22
--> $DIR/coherence-all-remote.rs:6:6
33
|
44
LL | impl<T> Remote1<T> for isize { }
5-
| ^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ uncovered type parameter
66
|
77
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
88
= note: only traits defined in the current crate can be implemented for a type parameter

tests/ui/coherence/coherence-bigint-param.stderr

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0210]: type parameter `T` must be covered by another type when it appears
22
--> $DIR/coherence-bigint-param.rs:8:6
33
|
44
LL | impl<T> Remote1<BigInt> for T { }
5-
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`BigInt`)
5+
| ^ uncovered type parameter
66
|
7-
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
8-
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
7+
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local,
8+
and no uncovered type parameters appear before that first local type
9+
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`,
10+
where `T0` is the first and `Tn` is the last
911

1012
error: aborting due to 1 previous error
1113

tests/ui/coherence/coherence-cross-crate-conflict.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct<A>`)
1+
error[E0210]: type parameter `A` must be used as an argument to some local type (e.g., `MyStruct<A>`)
22
--> $DIR/coherence-cross-crate-conflict.rs:9:6
33
|
44
LL | impl<A> Foo for A {
5-
| ^ type parameter `A` must be used as the type parameter for some local type
5+
| ^ uncovered type parameter
66
|
77
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
88
= note: only traits defined in the current crate can be implemented for a type parameter

tests/ui/coherence/coherence-lone-type-parameter.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
1+
error[E0210]: type parameter `T` must be used as an argument to some local type (e.g., `MyStruct<T>`)
22
--> $DIR/coherence-lone-type-parameter.rs:6:6
33
|
44
LL | impl<T> Remote for T { }
5-
| ^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ uncovered type parameter
66
|
77
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
88
= note: only traits defined in the current crate can be implemented for a type parameter

tests/ui/coherence/impl[t]-foreign-for-fundamental[t].rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ use std::rc::Rc;
88
struct Local;
99

1010
impl<T> Remote for Box<T> {
11-
//~^ ERROR type parameter `T` must be used as the type parameter for
12-
// | some local type (e.g., `MyStruct<T>`)
11+
//~^ ERROR type parameter `T` must be used as an argument to some local type
1312
}
1413

1514
fn main() {}

tests/ui/coherence/impl[t]-foreign-for-fundamental[t].stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
1+
error[E0210]: type parameter `T` must be used as an argument to some local type (e.g., `MyStruct<T>`)
22
--> $DIR/impl[t]-foreign-for-fundamental[t].rs:10:6
33
|
44
LL | impl<T> Remote for Box<T> {
5-
| ^ type parameter `T` must be used as the type parameter for some local type
5+
| ^ uncovered type parameter
66
|
77
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
88
= note: only traits defined in the current crate can be implemented for a type parameter

tests/ui/coherence/impl[t]-foreign[foreign]-for-fundamental[t].rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ use std::rc::Rc;
88
struct Local;
99

1010
impl<T> Remote1<u32> for Box<T> {
11-
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
11+
//~^ ERROR type parameter `T` must be used as an argument to some local type
1212
}
1313

1414
impl<'a, T> Remote1<u32> for &'a T {
15-
//~^ ERROR type parameter `T` must be used as the type parameter for some local type
15+
//~^ ERROR type parameter `T` must be used as an argument to some local type
1616
}
1717

1818
fn main() {}

0 commit comments

Comments
 (0)