Skip to content

Commit be1ed00

Browse files
committed
Add additional type info to mismatch err
1 parent 3f5aee2 commit be1ed00

File tree

4 files changed

+79
-32
lines changed

4 files changed

+79
-32
lines changed

compiler/rustc_typeck/src/astconv/generics.rs

+39-12
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2424
tcx: TyCtxt<'_>,
2525
arg: &GenericArg<'_>,
2626
param: &GenericParamDef,
27+
// DefId of the function
28+
//body_def_id: DefId,
2729
possible_ordering_error: bool,
2830
help: Option<&str>,
2931
) {
@@ -46,19 +48,44 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
4648
// Specific suggestion set for diagnostics
4749
match (arg, &param.kind) {
4850
(
49-
GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. }),
50-
GenericParamDefKind::Const { .. },
51+
GenericArg::Type(hir::Ty {
52+
kind: hir::TyKind::Path(rustc_hir::QPath::Resolved(_, path)),
53+
..
54+
}),
55+
GenericParamDefKind::Const,
5156
) => {
52-
let suggestions = vec![
53-
(arg.span().shrink_to_lo(), String::from("{ ")),
54-
(arg.span().shrink_to_hi(), String::from(" }")),
55-
];
56-
err.multipart_suggestion(
57-
"if this generic argument was intended as a const parameter, \
58-
try surrounding it with braces:",
59-
suggestions,
60-
Applicability::MaybeIncorrect,
61-
);
57+
use rustc_hir::def::{DefKind, Res};
58+
match path.res {
59+
Res::Err => {}
60+
Res::Def(DefKind::TyParam, src_def_id) => (|| {
61+
let param_hir_id = match param.def_id.as_local() {
62+
Some(x) => tcx.hir().local_def_id_to_hir_id(x),
63+
None => return,
64+
};
65+
let param_name = tcx.hir().ty_param_name(param_hir_id);
66+
let param_type = tcx.type_of(param.def_id);
67+
if param_type.is_suggestable() {
68+
err.span_suggestion(
69+
tcx.def_span(src_def_id),
70+
&format!("try changing to a const-generic parameter:"),
71+
format!("const {}: {}", param_name, param_type),
72+
Applicability::MaybeIncorrect,
73+
);
74+
}
75+
})(),
76+
_ => {
77+
let suggestions = vec![
78+
(arg.span().shrink_to_lo(), String::from("{ ")),
79+
(arg.span().shrink_to_hi(), String::from(" }")),
80+
];
81+
err.multipart_suggestion(
82+
"if this generic argument was intended as a const parameter, \
83+
try surrounding it with braces:",
84+
suggestions,
85+
Applicability::MaybeIncorrect,
86+
);
87+
}
88+
}
6289
}
6390
(
6491
GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![crate_type="lib"]
2+
#![feature(const_generics)]
3+
#![allow(incomplete_features)]
4+
5+
struct A<const N: u8>;
6+
trait Foo {}
7+
impl Foo for A<N> {}
8+
//~^ ERROR type provided when a constant
9+
//~| ERROR cannot find type
10+
11+
struct B<const N: u8>;
12+
impl<N> Foo for B<N> {}
13+
//~^ ERROR type provided when a constant
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0412]: cannot find type `N` in this scope
2+
--> $DIR/diagnostics.rs:7:16
3+
|
4+
LL | struct A<const N: u8>;
5+
| ---------------------- similarly named struct `A` defined here
6+
LL | trait Foo {}
7+
LL | impl Foo for A<N> {}
8+
| ^ help: a struct with a similar name exists: `A`
9+
10+
error[E0747]: type provided when a constant was expected
11+
--> $DIR/diagnostics.rs:7:16
12+
|
13+
LL | impl Foo for A<N> {}
14+
| ^
15+
16+
error[E0747]: type provided when a constant was expected
17+
--> $DIR/diagnostics.rs:12:19
18+
|
19+
LL | impl<N> Foo for B<N> {}
20+
| - ^
21+
| |
22+
| help: try changing to a const-generic parameter:: `const N: u8`
23+
24+
error: aborting due to 3 previous errors
25+
26+
Some errors have detailed explanations: E0412, E0747.
27+
For more information about an error, try `rustc --explain E0412`.

src/test/ui/const-generics/invalid-enum.stderr

-20
Original file line numberDiff line numberDiff line change
@@ -30,44 +30,24 @@ error[E0747]: type provided when a constant was expected
3030
|
3131
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
3232
| ^^^^^^^^^^^^^^
33-
|
34-
help: if this generic argument was intended as a const parameter, try surrounding it with braces:
35-
|
36-
LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
37-
| ^ ^
3833

3934
error[E0747]: type provided when a constant was expected
4035
--> $DIR/invalid-enum.rs:33:18
4136
|
4237
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
4338
| ^^^^^^^^^^^^^^^^^^^
44-
|
45-
help: if this generic argument was intended as a const parameter, try surrounding it with braces:
46-
|
47-
LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
48-
| ^ ^
4939

5040
error[E0747]: type provided when a constant was expected
5141
--> $DIR/invalid-enum.rs:21:12
5242
|
5343
LL | test_1::<CompileFlag::A>();
5444
| ^^^^^^^^^^^^^^
55-
|
56-
help: if this generic argument was intended as a const parameter, try surrounding it with braces:
57-
|
58-
LL | test_1::<{ CompileFlag::A }>();
59-
| ^ ^
6045

6146
error[E0747]: type provided when a constant was expected
6247
--> $DIR/invalid-enum.rs:25:15
6348
|
6449
LL | test_2::<_, CompileFlag::A>(0);
6550
| ^^^^^^^^^^^^^^
66-
|
67-
help: if this generic argument was intended as a const parameter, try surrounding it with braces:
68-
|
69-
LL | test_2::<_, { CompileFlag::A }>(0);
70-
| ^ ^
7151

7252
error: aborting due to 7 previous errors
7353

0 commit comments

Comments
 (0)