Add additional type info to mismatch err
This commit is contained in:
parent
3f5aee2d52
commit
be1ed00712
|
@ -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>,
|
||||
) {
|
||||
|
@ -46,19 +48,44 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// Specific suggestion set for diagnostics
|
||||
match (arg, ¶m.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), .. }),
|
||||
|
|
|
@ -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
|
|
@ -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`.
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue