Skip to content

Commit

Permalink
Add additional type info to mismatch err
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianKnodt committed Feb 13, 2021
1 parent 3f5aee2 commit be1ed00
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 32 deletions.
51 changes: 39 additions & 12 deletions compiler/rustc_typeck/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx: TyCtxt<'_>,
arg: &GenericArg<'_>,
param: &GenericParamDef,
// DefId of the function
//body_def_id: DefId,
possible_ordering_error: bool,
help: Option<&str>,
) {
Expand All @@ -46,19 +48,44 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Specific suggestion set for diagnostics
match (arg, &param.kind) {
(
GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. }),
GenericParamDefKind::Const { .. },
GenericArg::Type(hir::Ty {
kind: hir::TyKind::Path(rustc_hir::QPath::Resolved(_, path)),
..
}),
GenericParamDefKind::Const,
) => {
let suggestions = vec![
(arg.span().shrink_to_lo(), String::from("{ ")),
(arg.span().shrink_to_hi(), String::from(" }")),
];
err.multipart_suggestion(
"if this generic argument was intended as a const parameter, \
try surrounding it with braces:",
suggestions,
Applicability::MaybeIncorrect,
);
use rustc_hir::def::{DefKind, Res};
match path.res {
Res::Err => {}
Res::Def(DefKind::TyParam, src_def_id) => (|| {
let param_hir_id = match param.def_id.as_local() {
Some(x) => tcx.hir().local_def_id_to_hir_id(x),
None => return,
};
let param_name = tcx.hir().ty_param_name(param_hir_id);
let param_type = tcx.type_of(param.def_id);
if param_type.is_suggestable() {
err.span_suggestion(
tcx.def_span(src_def_id),
&format!("try changing to a const-generic parameter:"),
format!("const {}: {}", param_name, param_type),
Applicability::MaybeIncorrect,
);
}
})(),
_ => {
let suggestions = vec![
(arg.span().shrink_to_lo(), String::from("{ ")),
(arg.span().shrink_to_hi(), String::from(" }")),
];
err.multipart_suggestion(
"if this generic argument was intended as a const parameter, \
try surrounding it with braces:",
suggestions,
Applicability::MaybeIncorrect,
);
}
}
}
(
GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/const-generics/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![crate_type="lib"]
#![feature(const_generics)]
#![allow(incomplete_features)]

struct A<const N: u8>;
trait Foo {}
impl Foo for A<N> {}
//~^ ERROR type provided when a constant
//~| ERROR cannot find type

struct B<const N: u8>;
impl<N> Foo for B<N> {}
//~^ ERROR type provided when a constant
27 changes: 27 additions & 0 deletions src/test/ui/const-generics/diagnostics.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0412]: cannot find type `N` in this scope
--> $DIR/diagnostics.rs:7:16
|
LL | struct A<const N: u8>;
| ---------------------- similarly named struct `A` defined here
LL | trait Foo {}
LL | impl Foo for A<N> {}
| ^ help: a struct with a similar name exists: `A`

error[E0747]: type provided when a constant was expected
--> $DIR/diagnostics.rs:7:16
|
LL | impl Foo for A<N> {}
| ^

error[E0747]: type provided when a constant was expected
--> $DIR/diagnostics.rs:12:19
|
LL | impl<N> Foo for B<N> {}
| - ^
| |
| help: try changing to a const-generic parameter:: `const N: u8`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0412, E0747.
For more information about an error, try `rustc --explain E0412`.
20 changes: 0 additions & 20 deletions src/test/ui/const-generics/invalid-enum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,24 @@ error[E0747]: type provided when a constant was expected
|
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^
|
help: if this generic argument was intended as a const parameter, try surrounding it with braces:
|
LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
| ^ ^

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

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

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

error: aborting due to 7 previous errors

Expand Down

0 comments on commit be1ed00

Please sign in to comment.