Skip to content

Commit 96bb2c8

Browse files
committed
Add further tests and liberalize type checking
1 parent 8d91875 commit 96bb2c8

File tree

3 files changed

+139
-47
lines changed

3 files changed

+139
-47
lines changed

compiler/rustc_typeck/src/astconv/generics.rs

+31-30
Original file line numberDiff line numberDiff line change
@@ -445,15 +445,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
445445
assert_ne!(bound, provided);
446446
Err((bound as i32 - provided as i32, Some(err)))
447447
};
448-
let emit_correct =
449-
|correct: Result<(), (_, Option<rustc_errors::DiagnosticBuilder<'_>>)>| match correct {
450-
Ok(()) => Ok(()),
451-
Err((_, None)) => Err(()),
452-
Err((_, Some(mut err))) => {
453-
err.emit();
454-
Err(())
455-
}
456-
};
457448

458449
let mut unexpected_spans = vec![];
459450

@@ -501,31 +492,41 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
501492

502493
// Emit a help message if it's possible that a type could be surrounded in braces
503494
if let Err((c_mismatch, Some(ref mut _const_err))) = const_count_correct {
504-
if let Err((t_mismatch, Some(ref mut type_err))) = type_count_correct {
505-
if c_mismatch == -t_mismatch && t_mismatch < 0 {
506-
for i in 0..c_mismatch as usize {
507-
let arg = &args.args[arg_counts.lifetimes + i];
508-
match arg {
509-
GenericArg::Type(hir::Ty {
510-
kind: hir::TyKind::Path { .. }, ..
511-
}) => {}
512-
_ => continue,
513-
}
514-
let suggestions = vec![
515-
(arg.span().shrink_to_lo(), String::from("{ ")),
516-
(arg.span().shrink_to_hi(), String::from(" }")),
517-
];
518-
type_err.multipart_suggestion(
519-
"If this generic argument was intended as a const parameter, \
520-
try surrounding it with braces:",
521-
suggestions,
522-
Applicability::MaybeIncorrect,
523-
);
524-
}
495+
if let Err((_, Some(ref mut type_err))) = type_count_correct {
496+
let possible_matches = args.args[arg_counts.lifetimes..]
497+
.iter()
498+
.filter(|arg| {
499+
matches!(
500+
arg,
501+
GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. })
502+
)
503+
})
504+
.take(c_mismatch.max(0) as usize);
505+
for arg in possible_matches {
506+
let suggestions = vec![
507+
(arg.span().shrink_to_lo(), String::from("{ ")),
508+
(arg.span().shrink_to_hi(), String::from(" }")),
509+
];
510+
type_err.multipart_suggestion(
511+
"If this generic argument was intended as a const parameter, \
512+
try surrounding it with braces:",
513+
suggestions,
514+
Applicability::MaybeIncorrect,
515+
);
525516
}
526517
}
527518
}
528519

520+
let emit_correct =
521+
|correct: Result<(), (_, Option<rustc_errors::DiagnosticBuilder<'_>>)>| match correct {
522+
Ok(()) => Ok(()),
523+
Err((_, None)) => Err(()),
524+
Err((_, Some(mut err))) => {
525+
err.emit();
526+
Err(())
527+
}
528+
};
529+
529530
let arg_count_correct = emit_correct(lifetime_count_correct)
530531
.and(emit_correct(const_count_correct))
531532
.and(emit_correct(type_count_correct));

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

+24-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,33 @@ enum CompileFlag {
77
B,
88
}
99

10-
pub fn test<const CF: CompileFlag>() {}
10+
pub fn test_1<const CF: CompileFlag>() {}
11+
pub fn test_2<T, const CF: CompileFlag>(x: T) {}
12+
pub struct Example<const CF: CompileFlag, T=u32>{
13+
x: T,
14+
}
15+
16+
impl<const CF: CompileFlag, T> Example<CF, T> {
17+
const ASSOC_FLAG: CompileFlag = CompileFlag::A;
18+
}
1119

1220
pub fn main() {
13-
test::<CompileFlag::A>();
21+
test_1::<CompileFlag::A>();
22+
//~^ ERROR: expected type, found variant
23+
//~| ERROR: wrong number of const arguments
24+
//~| ERROR: wrong number of type arguments
25+
26+
test_2::<_, CompileFlag::A>(0);
1427
//~^ ERROR: expected type, found variant
1528
//~| ERROR: wrong number of const arguments
1629
//~| ERROR: wrong number of type arguments
30+
31+
let _: Example<CompileFlag::A, _> = Example { x: 0 };
32+
//~^ ERROR: expected type, found variant
33+
//~| ERROR: wrong number of const arguments
34+
//~| ERROR: wrong number of type arguments
35+
36+
let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
37+
//~^ ERROR: wrong number of const arguments
38+
//~| ERROR: wrong number of type arguments
1739
}
+84-15
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,99 @@
11
error[E0573]: expected type, found variant `CompileFlag::A`
2-
--> $DIR/invalid-enum.rs:13:10
2+
--> $DIR/invalid-enum.rs:21:12
33
|
4-
LL | test::<CompileFlag::A>();
5-
| ^^^^^^^^^^^^^^
6-
| |
7-
| not a type
8-
| help: try using the variant's enum: `CompileFlag`
4+
LL | test_1::<CompileFlag::A>();
5+
| ^^^^^^^^^^^^^^
6+
| |
7+
| not a type
8+
| help: try using the variant's enum: `CompileFlag`
9+
10+
error[E0573]: expected type, found variant `CompileFlag::A`
11+
--> $DIR/invalid-enum.rs:26:15
12+
|
13+
LL | test_2::<_, CompileFlag::A>(0);
14+
| ^^^^^^^^^^^^^^
15+
| |
16+
| not a type
17+
| help: try using the variant's enum: `CompileFlag`
18+
19+
error[E0573]: expected type, found variant `CompileFlag::A`
20+
--> $DIR/invalid-enum.rs:31:18
21+
|
22+
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
23+
| ^^^^^^^^^^^^^^
24+
| |
25+
| not a type
26+
| help: try using the variant's enum: `CompileFlag`
27+
28+
error[E0107]: wrong number of const arguments: expected 1, found 0
29+
--> $DIR/invalid-enum.rs:31:10
30+
|
31+
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
33+
34+
error[E0107]: wrong number of type arguments: expected at most 1, found 2
35+
--> $DIR/invalid-enum.rs:31:10
36+
|
37+
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
38+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
39+
|
40+
help: If this generic argument was intended as a const parameter, try surrounding it with braces:
41+
|
42+
LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
43+
| ^ ^
44+
45+
error[E0107]: wrong number of const arguments: expected 1, found 0
46+
--> $DIR/invalid-enum.rs:36:10
47+
|
48+
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
50+
51+
error[E0107]: wrong number of type arguments: expected at most 1, found 2
52+
--> $DIR/invalid-enum.rs:36:10
53+
|
54+
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
55+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
56+
|
57+
help: If this generic argument was intended as a const parameter, try surrounding it with braces:
58+
|
59+
LL | let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
60+
| ^ ^
961

1062
error[E0107]: wrong number of const arguments: expected 1, found 0
11-
--> $DIR/invalid-enum.rs:13:3
63+
--> $DIR/invalid-enum.rs:21:3
1264
|
13-
LL | test::<CompileFlag::A>();
14-
| ^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
65+
LL | test_1::<CompileFlag::A>();
66+
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
1567

1668
error[E0107]: wrong number of type arguments: expected 0, found 1
17-
--> $DIR/invalid-enum.rs:13:10
69+
--> $DIR/invalid-enum.rs:21:12
70+
|
71+
LL | test_1::<CompileFlag::A>();
72+
| ^^^^^^^^^^^^^^ unexpected type argument
73+
|
74+
help: If this generic argument was intended as a const parameter, try surrounding it with braces:
75+
|
76+
LL | test_1::<{ CompileFlag::A }>();
77+
| ^ ^
78+
79+
error[E0107]: wrong number of const arguments: expected 1, found 0
80+
--> $DIR/invalid-enum.rs:26:3
81+
|
82+
LL | test_2::<_, CompileFlag::A>(0);
83+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
84+
85+
error[E0107]: wrong number of type arguments: expected 1, found 2
86+
--> $DIR/invalid-enum.rs:26:15
1887
|
19-
LL | test::<CompileFlag::A>();
20-
| ^^^^^^^^^^^^^^ unexpected type argument
88+
LL | test_2::<_, CompileFlag::A>(0);
89+
| ^^^^^^^^^^^^^^ unexpected type argument
2190
|
2291
help: If this generic argument was intended as a const parameter, try surrounding it with braces:
2392
|
24-
LL | test::<{ CompileFlag::A }>();
25-
| ^ ^
93+
LL | test_2::<_, { CompileFlag::A }>(0);
94+
| ^ ^
2695

27-
error: aborting due to 3 previous errors
96+
error: aborting due to 11 previous errors
2897

2998
Some errors have detailed explanations: E0107, E0573.
3099
For more information about an error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)