Add further tests and liberalize type checking

This commit is contained in:
kadmin 2020-08-31 17:12:53 +00:00
parent 8d9187597a
commit 96bb2c86f2
3 changed files with 140 additions and 48 deletions

View file

@ -445,15 +445,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
assert_ne!(bound, provided); assert_ne!(bound, provided);
Err((bound as i32 - provided as i32, Some(err))) Err((bound as i32 - provided as i32, Some(err)))
}; };
let emit_correct =
|correct: Result<(), (_, Option<rustc_errors::DiagnosticBuilder<'_>>)>| match correct {
Ok(()) => Ok(()),
Err((_, None)) => Err(()),
Err((_, Some(mut err))) => {
err.emit();
Err(())
}
};
let mut unexpected_spans = vec![]; let mut unexpected_spans = vec![];
@ -501,31 +492,41 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Emit a help message if it's possible that a type could be surrounded in braces // Emit a help message if it's possible that a type could be surrounded in braces
if let Err((c_mismatch, Some(ref mut _const_err))) = const_count_correct { if let Err((c_mismatch, Some(ref mut _const_err))) = const_count_correct {
if let Err((t_mismatch, Some(ref mut type_err))) = type_count_correct { if let Err((_, Some(ref mut type_err))) = type_count_correct {
if c_mismatch == -t_mismatch && t_mismatch < 0 { let possible_matches = args.args[arg_counts.lifetimes..]
for i in 0..c_mismatch as usize { .iter()
let arg = &args.args[arg_counts.lifetimes + i]; .filter(|arg| {
match arg { matches!(
GenericArg::Type(hir::Ty { arg,
kind: hir::TyKind::Path { .. }, .. GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. })
}) => {} )
_ => continue, })
} .take(c_mismatch.max(0) as usize);
let suggestions = vec![ for arg in possible_matches {
(arg.span().shrink_to_lo(), String::from("{ ")), let suggestions = vec![
(arg.span().shrink_to_hi(), String::from(" }")), (arg.span().shrink_to_lo(), String::from("{ ")),
]; (arg.span().shrink_to_hi(), String::from(" }")),
type_err.multipart_suggestion( ];
"If this generic argument was intended as a const parameter, \ type_err.multipart_suggestion(
try surrounding it with braces:", "If this generic argument was intended as a const parameter, \
suggestions, try surrounding it with braces:",
Applicability::MaybeIncorrect, suggestions,
); Applicability::MaybeIncorrect,
} );
} }
} }
} }
let emit_correct =
|correct: Result<(), (_, Option<rustc_errors::DiagnosticBuilder<'_>>)>| match correct {
Ok(()) => Ok(()),
Err((_, None)) => Err(()),
Err((_, Some(mut err))) => {
err.emit();
Err(())
}
};
let arg_count_correct = emit_correct(lifetime_count_correct) let arg_count_correct = emit_correct(lifetime_count_correct)
.and(emit_correct(const_count_correct)) .and(emit_correct(const_count_correct))
.and(emit_correct(type_count_correct)); .and(emit_correct(type_count_correct));

View file

@ -7,11 +7,33 @@ enum CompileFlag {
B, B,
} }
pub fn test<const CF: CompileFlag>() {} pub fn test_1<const CF: CompileFlag>() {}
pub fn test_2<T, const CF: CompileFlag>(x: T) {}
pub struct Example<const CF: CompileFlag, T=u32>{
x: T,
}
impl<const CF: CompileFlag, T> Example<CF, T> {
const ASSOC_FLAG: CompileFlag = CompileFlag::A;
}
pub fn main() { pub fn main() {
test::<CompileFlag::A>(); test_1::<CompileFlag::A>();
//~^ ERROR: expected type, found variant //~^ ERROR: expected type, found variant
//~| ERROR: wrong number of const arguments //~| ERROR: wrong number of const arguments
//~| ERROR: wrong number of type arguments //~| ERROR: wrong number of type arguments
test_2::<_, CompileFlag::A>(0);
//~^ ERROR: expected type, found variant
//~| ERROR: wrong number of const arguments
//~| ERROR: wrong number of type arguments
let _: Example<CompileFlag::A, _> = Example { x: 0 };
//~^ ERROR: expected type, found variant
//~| ERROR: wrong number of const arguments
//~| ERROR: wrong number of type arguments
let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
//~^ ERROR: wrong number of const arguments
//~| ERROR: wrong number of type arguments
} }

View file

@ -1,30 +1,99 @@
error[E0573]: expected type, found variant `CompileFlag::A` error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:13:10 --> $DIR/invalid-enum.rs:21:12
| |
LL | test::<CompileFlag::A>(); LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
| | | |
| not a type | not a type
| help: try using the variant's enum: `CompileFlag` | help: try using the variant's enum: `CompileFlag`
error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:26:15
|
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^
| |
| not a type
| help: try using the variant's enum: `CompileFlag`
error[E0573]: expected type, found variant `CompileFlag::A`
--> $DIR/invalid-enum.rs:31:18
|
LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^
| |
| not a type
| help: try using the variant's enum: `CompileFlag`
error[E0107]: wrong number of const arguments: expected 1, found 0 error[E0107]: wrong number of const arguments: expected 1, found 0
--> $DIR/invalid-enum.rs:13:3 --> $DIR/invalid-enum.rs:31:10
| |
LL | test::<CompileFlag::A>(); LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
error[E0107]: wrong number of type arguments: expected 0, found 1 error[E0107]: wrong number of type arguments: expected at most 1, found 2
--> $DIR/invalid-enum.rs:13:10 --> $DIR/invalid-enum.rs:31:10
| |
LL | test::<CompileFlag::A>(); LL | let _: Example<CompileFlag::A, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^ unexpected type argument | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
| |
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, try surrounding it with braces:
| |
LL | test::<{ CompileFlag::A }>(); LL | let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
| ^ ^ | ^ ^
error: aborting due to 3 previous errors error[E0107]: wrong number of const arguments: expected 1, found 0
--> $DIR/invalid-enum.rs:36:10
|
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
error[E0107]: wrong number of type arguments: expected at most 1, found 2
--> $DIR/invalid-enum.rs:36:10
|
LL | let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected at most 1 type argument
|
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[E0107]: wrong number of const arguments: expected 1, found 0
--> $DIR/invalid-enum.rs:21:3
|
LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
error[E0107]: wrong number of type arguments: expected 0, found 1
--> $DIR/invalid-enum.rs:21:12
|
LL | test_1::<CompileFlag::A>();
| ^^^^^^^^^^^^^^ unexpected type argument
|
help: If this generic argument was intended as a const parameter, try surrounding it with braces:
|
LL | test_1::<{ CompileFlag::A }>();
| ^ ^
error[E0107]: wrong number of const arguments: expected 1, found 0
--> $DIR/invalid-enum.rs:26:3
|
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 1 const argument
error[E0107]: wrong number of type arguments: expected 1, found 2
--> $DIR/invalid-enum.rs:26:15
|
LL | test_2::<_, CompileFlag::A>(0);
| ^^^^^^^^^^^^^^ unexpected type argument
|
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 11 previous errors
Some errors have detailed explanations: E0107, E0573. Some errors have detailed explanations: E0107, E0573.
For more information about an error, try `rustc --explain E0107`. For more information about an error, try `rustc --explain E0107`.