Skip to content

Commit b97951b

Browse files
committed
Update w/ comments
1 parent be1ed00 commit b97951b

File tree

6 files changed

+101
-43
lines changed

6 files changed

+101
-43
lines changed

compiler/rustc_typeck/src/astconv/generics.rs

+33-27
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use crate::astconv::{
66
use crate::errors::AssocTypeBindingNotAllowed;
77
use crate::structured_errors::{StructuredDiagnostic, WrongNumberOfGenericArgs};
88
use rustc_ast::ast::ParamKindOrd;
9-
use rustc_errors::{struct_span_err, Applicability, ErrorReported};
9+
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
1010
use rustc_hir as hir;
11+
use rustc_hir::def::{DefKind, Res};
1112
use rustc_hir::def_id::DefId;
1213
use rustc_hir::GenericArg;
1314
use rustc_middle::ty::{
@@ -24,8 +25,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2425
tcx: TyCtxt<'_>,
2526
arg: &GenericArg<'_>,
2627
param: &GenericParamDef,
27-
// DefId of the function
28-
//body_def_id: DefId,
2928
possible_ordering_error: bool,
3029
help: Option<&str>,
3130
) {
@@ -45,6 +44,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
4544
}
4645
}
4746

47+
let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut DiagnosticBuilder<'_>| {
48+
let suggestions = vec![
49+
(arg.span().shrink_to_lo(), String::from("{ ")),
50+
(arg.span().shrink_to_hi(), String::from(" }")),
51+
];
52+
err.multipart_suggestion(
53+
"if this generic argument was intended as a const parameter, \
54+
surround it with braces",
55+
suggestions,
56+
Applicability::MaybeIncorrect,
57+
);
58+
};
59+
4860
// Specific suggestion set for diagnostics
4961
match (arg, &param.kind) {
5062
(
@@ -53,40 +65,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
5365
..
5466
}),
5567
GenericParamDefKind::Const,
56-
) => {
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-
};
68+
) => match path.res {
69+
Res::Err => {
70+
add_braces_suggestion(arg, &mut err);
71+
err.set_primary_message(
72+
"unresolved item provided when a constant was expected",
73+
);
74+
}
75+
Res::Def(DefKind::TyParam, src_def_id) => {
76+
if let Some(param_local_id) = param.def_id.as_local() {
77+
let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id);
6578
let param_name = tcx.hir().ty_param_name(param_hir_id);
6679
let param_type = tcx.type_of(param.def_id);
6780
if param_type.is_suggestable() {
6881
err.span_suggestion(
6982
tcx.def_span(src_def_id),
70-
&format!("try changing to a const-generic parameter:"),
83+
"consider changing this type paramater to a `const`-generic",
7184
format!("const {}: {}", param_name, param_type),
7285
Applicability::MaybeIncorrect,
7386
);
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+
};
8788
}
8889
}
89-
}
90+
_ => add_braces_suggestion(arg, &mut err),
91+
},
92+
(
93+
GenericArg::Type(hir::Ty { kind: hir::TyKind::Path(_), .. }),
94+
GenericParamDefKind::Const,
95+
) => add_braces_suggestion(arg, &mut err),
9096
(
9197
GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }),
9298
GenericParamDefKind::Const { .. },

src/test/ui/const-generics/const-param-shadowing.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0747]: type provided when a constant was expected
44
LL | fn test<const N: usize>() -> Foo<N> {
55
| ^
66
|
7-
help: if this generic argument was intended as a const parameter, try surrounding it with braces:
7+
help: if this generic argument was intended as a const parameter, surround it with braces
88
|
99
LL | fn test<const N: usize>() -> Foo<{ N }> {
1010
| ^ ^
+8-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
#![crate_type="lib"]
2-
#![feature(const_generics)]
2+
#![feature(min_const_generics)]
33
#![allow(incomplete_features)]
44

55
struct A<const N: u8>;
66
trait Foo {}
77
impl Foo for A<N> {}
8-
//~^ ERROR type provided when a constant
9-
//~| ERROR cannot find type
8+
//~^ ERROR cannot find type
9+
//~| unresolved item provided when a constant
1010

1111
struct B<const N: u8>;
1212
impl<N> Foo for B<N> {}
1313
//~^ ERROR type provided when a constant
14+
15+
struct C<const C: u8, const N: u8>;
16+
impl<const N: u8> Foo for C<N, T> {}
17+
//~^ ERROR cannot find type
18+
//~| unresolved item provided when a constant

src/test/ui/const-generics/diagnostics.stderr

+30-3
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,48 @@ LL | trait Foo {}
77
LL | impl Foo for A<N> {}
88
| ^ help: a struct with a similar name exists: `A`
99

10-
error[E0747]: type provided when a constant was expected
10+
error[E0412]: cannot find type `T` in this scope
11+
--> $DIR/diagnostics.rs:16:32
12+
|
13+
LL | struct A<const N: u8>;
14+
| ---------------------- similarly named struct `A` defined here
15+
...
16+
LL | impl<const N: u8> Foo for C<N, T> {}
17+
| ^ help: a struct with a similar name exists: `A`
18+
19+
error[E0747]: unresolved item provided when a constant was expected
1120
--> $DIR/diagnostics.rs:7:16
1221
|
1322
LL | impl Foo for A<N> {}
1423
| ^
24+
|
25+
help: if this generic argument was intended as a const parameter, surround it with braces
26+
|
27+
LL | impl Foo for A<{ N }> {}
28+
| ^ ^
1529

1630
error[E0747]: type provided when a constant was expected
1731
--> $DIR/diagnostics.rs:12:19
1832
|
1933
LL | impl<N> Foo for B<N> {}
2034
| - ^
2135
| |
22-
| help: try changing to a const-generic parameter:: `const N: u8`
36+
| help: consider changing this type paramater to a `const`-generic: `const N: u8`
37+
38+
error[E0747]: unresolved item provided when a constant was expected
39+
--> $DIR/diagnostics.rs:16:32
40+
|
41+
LL | impl<const N: u8> Foo for C<N, T> {}
42+
| ^
43+
|
44+
= note: type arguments must be provided before constant arguments
45+
= help: reorder the arguments: consts: `<C, N>`
46+
help: if this generic argument was intended as a const parameter, surround it with braces
47+
|
48+
LL | impl<const N: u8> Foo for C<N, { T }> {}
49+
| ^ ^
2350

24-
error: aborting due to 3 previous errors
51+
error: aborting due to 5 previous errors
2552

2653
Some errors have detailed explanations: E0412, E0747.
2754
For more information about an error, try `rustc --explain E0412`.

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
#[derive(PartialEq, Eq)]
55
enum CompileFlag {
6-
A,
7-
B,
6+
A,
7+
B,
88
}
99

1010
pub fn test_1<const CF: CompileFlag>() {}
1111
pub fn test_2<T, const CF: CompileFlag>(x: T) {}
1212
pub struct Example<const CF: CompileFlag, T=u32>{
13-
x: T,
13+
x: T,
1414
}
1515

1616
impl<const CF: CompileFlag, T> Example<CF, T> {
@@ -20,15 +20,15 @@ impl<const CF: CompileFlag, T> Example<CF, T> {
2020
pub fn main() {
2121
test_1::<CompileFlag::A>();
2222
//~^ ERROR: expected type, found variant
23-
//~| ERROR: type provided when a constant was expected
23+
//~| ERROR: unresolved item provided when a constant was expected
2424

2525
test_2::<_, CompileFlag::A>(0);
2626
//~^ ERROR: expected type, found variant
27-
//~| ERROR: type provided when a constant was expected
27+
//~| ERROR: unresolved item provided when a constant was expected
2828

2929
let _: Example<CompileFlag::A, _> = Example { x: 0 };
3030
//~^ ERROR: expected type, found variant
31-
//~| ERROR: type provided when a constant was expected
31+
//~| ERROR: unresolved item provided when a constant was expected
3232

3333
let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
3434
//~^ ERROR: type provided when a constant was expected

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

+23-3
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,49 @@ LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
2525
| not a type
2626
| help: try using the variant's enum: `CompileFlag`
2727

28-
error[E0747]: type provided when a constant was expected
28+
error[E0747]: unresolved item provided when a constant was expected
2929
--> $DIR/invalid-enum.rs:29:18
3030
|
3131
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
3232
| ^^^^^^^^^^^^^^
33+
|
34+
help: if this generic argument was intended as a const parameter, surround it with braces
35+
|
36+
LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
37+
| ^ ^
3338

3439
error[E0747]: type provided when a constant was expected
3540
--> $DIR/invalid-enum.rs:33:18
3641
|
3742
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
3843
| ^^^^^^^^^^^^^^^^^^^
44+
|
45+
help: if this generic argument was intended as a const parameter, surround it with braces
46+
|
47+
LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
48+
| ^ ^
3949

40-
error[E0747]: type provided when a constant was expected
50+
error[E0747]: unresolved item provided when a constant was expected
4151
--> $DIR/invalid-enum.rs:21:12
4252
|
4353
LL | test_1::<CompileFlag::A>();
4454
| ^^^^^^^^^^^^^^
55+
|
56+
help: if this generic argument was intended as a const parameter, surround it with braces
57+
|
58+
LL | test_1::<{ CompileFlag::A }>();
59+
| ^ ^
4560

46-
error[E0747]: type provided when a constant was expected
61+
error[E0747]: unresolved item provided when a constant was expected
4762
--> $DIR/invalid-enum.rs:25:15
4863
|
4964
LL | test_2::<_, CompileFlag::A>(0);
5065
| ^^^^^^^^^^^^^^
66+
|
67+
help: if this generic argument was intended as a const parameter, surround it with braces
68+
|
69+
LL | test_2::<_, { CompileFlag::A }>(0);
70+
| ^ ^
5171

5272
error: aborting due to 7 previous errors
5373

0 commit comments

Comments
 (0)