Update w/ comments
This commit is contained in:
parent
be1ed00712
commit
b97951b50f
@ -6,8 +6,9 @@ use crate::astconv::{
|
|||||||
use crate::errors::AssocTypeBindingNotAllowed;
|
use crate::errors::AssocTypeBindingNotAllowed;
|
||||||
use crate::structured_errors::{StructuredDiagnostic, WrongNumberOfGenericArgs};
|
use crate::structured_errors::{StructuredDiagnostic, WrongNumberOfGenericArgs};
|
||||||
use rustc_ast::ast::ParamKindOrd;
|
use rustc_ast::ast::ParamKindOrd;
|
||||||
use rustc_errors::{struct_span_err, Applicability, ErrorReported};
|
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::GenericArg;
|
use rustc_hir::GenericArg;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
@ -24,8 +25,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
arg: &GenericArg<'_>,
|
arg: &GenericArg<'_>,
|
||||||
param: &GenericParamDef,
|
param: &GenericParamDef,
|
||||||
// DefId of the function
|
|
||||||
//body_def_id: DefId,
|
|
||||||
possible_ordering_error: bool,
|
possible_ordering_error: bool,
|
||||||
help: Option<&str>,
|
help: Option<&str>,
|
||||||
) {
|
) {
|
||||||
@ -45,6 +44,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut DiagnosticBuilder<'_>| {
|
||||||
|
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, \
|
||||||
|
surround it with braces",
|
||||||
|
suggestions,
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
// Specific suggestion set for diagnostics
|
// Specific suggestion set for diagnostics
|
||||||
match (arg, ¶m.kind) {
|
match (arg, ¶m.kind) {
|
||||||
(
|
(
|
||||||
@ -53,40 +65,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
GenericParamDefKind::Const,
|
GenericParamDefKind::Const,
|
||||||
) => {
|
) => match path.res {
|
||||||
use rustc_hir::def::{DefKind, Res};
|
Res::Err => {
|
||||||
match path.res {
|
add_braces_suggestion(arg, &mut err);
|
||||||
Res::Err => {}
|
err.set_primary_message(
|
||||||
Res::Def(DefKind::TyParam, src_def_id) => (|| {
|
"unresolved item provided when a constant was expected",
|
||||||
let param_hir_id = match param.def_id.as_local() {
|
);
|
||||||
Some(x) => tcx.hir().local_def_id_to_hir_id(x),
|
}
|
||||||
None => return,
|
Res::Def(DefKind::TyParam, src_def_id) => {
|
||||||
};
|
if let Some(param_local_id) = param.def_id.as_local() {
|
||||||
|
let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id);
|
||||||
let param_name = tcx.hir().ty_param_name(param_hir_id);
|
let param_name = tcx.hir().ty_param_name(param_hir_id);
|
||||||
let param_type = tcx.type_of(param.def_id);
|
let param_type = tcx.type_of(param.def_id);
|
||||||
if param_type.is_suggestable() {
|
if param_type.is_suggestable() {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
tcx.def_span(src_def_id),
|
tcx.def_span(src_def_id),
|
||||||
&format!("try changing to a const-generic parameter:"),
|
"consider changing this type paramater to a `const`-generic",
|
||||||
format!("const {}: {}", param_name, param_type),
|
format!("const {}: {}", param_name, param_type),
|
||||||
Applicability::MaybeIncorrect,
|
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,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
_ => add_braces_suggestion(arg, &mut err),
|
||||||
|
},
|
||||||
|
(
|
||||||
|
GenericArg::Type(hir::Ty { kind: hir::TyKind::Path(_), .. }),
|
||||||
|
GenericParamDefKind::Const,
|
||||||
|
) => add_braces_suggestion(arg, &mut err),
|
||||||
(
|
(
|
||||||
GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
|
GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
|
||||||
GenericParamDefKind::Const { .. },
|
GenericParamDefKind::Const { .. },
|
||||||
|
@ -4,7 +4,7 @@ error[E0747]: type provided when a constant was expected
|
|||||||
LL | fn test<const N: usize>() -> Foo<N> {
|
LL | fn test<const N: usize>() -> Foo<N> {
|
||||||
| ^
|
| ^
|
||||||
|
|
|
|
||||||
help: if this generic argument was intended as a const parameter, try surrounding it with braces:
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
||||||
|
|
|
|
||||||
LL | fn test<const N: usize>() -> Foo<{ N }> {
|
LL | fn test<const N: usize>() -> Foo<{ N }> {
|
||||||
| ^ ^
|
| ^ ^
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
#![crate_type="lib"]
|
#![crate_type="lib"]
|
||||||
#![feature(const_generics)]
|
#![feature(min_const_generics)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
struct A<const N: u8>;
|
struct A<const N: u8>;
|
||||||
trait Foo {}
|
trait Foo {}
|
||||||
impl Foo for A<N> {}
|
impl Foo for A<N> {}
|
||||||
//~^ ERROR type provided when a constant
|
//~^ ERROR cannot find type
|
||||||
//~| ERROR cannot find type
|
//~| unresolved item provided when a constant
|
||||||
|
|
||||||
struct B<const N: u8>;
|
struct B<const N: u8>;
|
||||||
impl<N> Foo for B<N> {}
|
impl<N> Foo for B<N> {}
|
||||||
//~^ ERROR type provided when a constant
|
//~^ ERROR type provided when a constant
|
||||||
|
|
||||||
|
struct C<const C: u8, const N: u8>;
|
||||||
|
impl<const N: u8> Foo for C<N, T> {}
|
||||||
|
//~^ ERROR cannot find type
|
||||||
|
//~| unresolved item provided when a constant
|
||||||
|
@ -7,11 +7,25 @@ LL | trait Foo {}
|
|||||||
LL | impl Foo for A<N> {}
|
LL | impl Foo for A<N> {}
|
||||||
| ^ help: a struct with a similar name exists: `A`
|
| ^ help: a struct with a similar name exists: `A`
|
||||||
|
|
||||||
error[E0747]: type provided when a constant was expected
|
error[E0412]: cannot find type `T` in this scope
|
||||||
|
--> $DIR/diagnostics.rs:16:32
|
||||||
|
|
|
||||||
|
LL | struct A<const N: u8>;
|
||||||
|
| ---------------------- similarly named struct `A` defined here
|
||||||
|
...
|
||||||
|
LL | impl<const N: u8> Foo for C<N, T> {}
|
||||||
|
| ^ help: a struct with a similar name exists: `A`
|
||||||
|
|
||||||
|
error[E0747]: unresolved item provided when a constant was expected
|
||||||
--> $DIR/diagnostics.rs:7:16
|
--> $DIR/diagnostics.rs:7:16
|
||||||
|
|
|
|
||||||
LL | impl Foo for A<N> {}
|
LL | impl Foo for A<N> {}
|
||||||
| ^
|
| ^
|
||||||
|
|
|
||||||
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
||||||
|
|
|
||||||
|
LL | impl Foo for A<{ N }> {}
|
||||||
|
| ^ ^
|
||||||
|
|
||||||
error[E0747]: type provided when a constant was expected
|
error[E0747]: type provided when a constant was expected
|
||||||
--> $DIR/diagnostics.rs:12:19
|
--> $DIR/diagnostics.rs:12:19
|
||||||
@ -19,9 +33,22 @@ error[E0747]: type provided when a constant was expected
|
|||||||
LL | impl<N> Foo for B<N> {}
|
LL | impl<N> Foo for B<N> {}
|
||||||
| - ^
|
| - ^
|
||||||
| |
|
| |
|
||||||
| help: try changing to a const-generic parameter:: `const N: u8`
|
| help: consider changing this type paramater to a `const`-generic: `const N: u8`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0747]: unresolved item provided when a constant was expected
|
||||||
|
--> $DIR/diagnostics.rs:16:32
|
||||||
|
|
|
||||||
|
LL | impl<const N: u8> Foo for C<N, T> {}
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
= note: type arguments must be provided before constant arguments
|
||||||
|
= help: reorder the arguments: consts: `<C, N>`
|
||||||
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
||||||
|
|
|
||||||
|
LL | impl<const N: u8> Foo for C<N, { T }> {}
|
||||||
|
| ^ ^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0412, E0747.
|
Some errors have detailed explanations: E0412, E0747.
|
||||||
For more information about an error, try `rustc --explain E0412`.
|
For more information about an error, try `rustc --explain E0412`.
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
enum CompileFlag {
|
enum CompileFlag {
|
||||||
A,
|
A,
|
||||||
B,
|
B,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_1<const CF: CompileFlag>() {}
|
pub fn test_1<const CF: CompileFlag>() {}
|
||||||
pub fn test_2<T, const CF: CompileFlag>(x: T) {}
|
pub fn test_2<T, const CF: CompileFlag>(x: T) {}
|
||||||
pub struct Example<const CF: CompileFlag, T=u32>{
|
pub struct Example<const CF: CompileFlag, T=u32>{
|
||||||
x: T,
|
x: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<const CF: CompileFlag, T> Example<CF, T> {
|
impl<const CF: CompileFlag, T> Example<CF, T> {
|
||||||
@ -20,15 +20,15 @@ impl<const CF: CompileFlag, T> Example<CF, T> {
|
|||||||
pub fn main() {
|
pub fn main() {
|
||||||
test_1::<CompileFlag::A>();
|
test_1::<CompileFlag::A>();
|
||||||
//~^ ERROR: expected type, found variant
|
//~^ ERROR: expected type, found variant
|
||||||
//~| ERROR: type provided when a constant was expected
|
//~| ERROR: unresolved item provided when a constant was expected
|
||||||
|
|
||||||
test_2::<_, CompileFlag::A>(0);
|
test_2::<_, CompileFlag::A>(0);
|
||||||
//~^ ERROR: expected type, found variant
|
//~^ ERROR: expected type, found variant
|
||||||
//~| ERROR: type provided when a constant was expected
|
//~| ERROR: unresolved item provided when a constant was expected
|
||||||
|
|
||||||
let _: Example<CompileFlag::A, _> = Example { x: 0 };
|
let _: Example<CompileFlag::A, _> = Example { x: 0 };
|
||||||
//~^ ERROR: expected type, found variant
|
//~^ ERROR: expected type, found variant
|
||||||
//~| ERROR: type provided when a constant was expected
|
//~| ERROR: unresolved item provided when a constant was expected
|
||||||
|
|
||||||
let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
|
let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
|
||||||
//~^ ERROR: type provided when a constant was expected
|
//~^ ERROR: type provided when a constant was expected
|
||||||
|
@ -25,29 +25,49 @@ LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
|
|||||||
| not a type
|
| not a type
|
||||||
| help: try using the variant's enum: `CompileFlag`
|
| help: try using the variant's enum: `CompileFlag`
|
||||||
|
|
||||||
error[E0747]: type provided when a constant was expected
|
error[E0747]: unresolved item provided when a constant was expected
|
||||||
--> $DIR/invalid-enum.rs:29:18
|
--> $DIR/invalid-enum.rs:29:18
|
||||||
|
|
|
|
||||||
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
|
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
||||||
|
|
|
||||||
|
LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
|
||||||
|
| ^ ^
|
||||||
|
|
||||||
error[E0747]: type provided when a constant was expected
|
error[E0747]: type provided when a constant was expected
|
||||||
--> $DIR/invalid-enum.rs:33:18
|
--> $DIR/invalid-enum.rs:33:18
|
||||||
|
|
|
|
||||||
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
|
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
||||||
|
|
|
||||||
|
LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
|
||||||
|
| ^ ^
|
||||||
|
|
||||||
error[E0747]: type provided when a constant was expected
|
error[E0747]: unresolved item provided when a constant was expected
|
||||||
--> $DIR/invalid-enum.rs:21:12
|
--> $DIR/invalid-enum.rs:21:12
|
||||||
|
|
|
|
||||||
LL | test_1::<CompileFlag::A>();
|
LL | test_1::<CompileFlag::A>();
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
||||||
|
|
|
||||||
|
LL | test_1::<{ CompileFlag::A }>();
|
||||||
|
| ^ ^
|
||||||
|
|
||||||
error[E0747]: type provided when a constant was expected
|
error[E0747]: unresolved item provided when a constant was expected
|
||||||
--> $DIR/invalid-enum.rs:25:15
|
--> $DIR/invalid-enum.rs:25:15
|
||||||
|
|
|
|
||||||
LL | test_2::<_, CompileFlag::A>(0);
|
LL | test_2::<_, CompileFlag::A>(0);
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
help: if this generic argument was intended as a const parameter, surround it with braces
|
||||||
|
|
|
||||||
|
LL | test_2::<_, { CompileFlag::A }>(0);
|
||||||
|
| ^ ^
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user