Update w/ comments

This commit is contained in:
kadmin 2021-02-14 04:35:18 +00:00
parent be1ed00712
commit b97951b50f
6 changed files with 101 additions and 43 deletions

View File

@ -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, &param.kind) { match (arg, &param.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 { .. },

View File

@ -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 }> {
| ^ ^ | ^ ^

View File

@ -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

View File

@ -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`.

View File

@ -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

View File

@ -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