Rollup merge of #106859 - tialaramex:master, r=Nilstrieb
Suggestion for type mismatch when we need a u8 but the programmer wrote a char literal Today Rust just points out that we have a char and we need a u8, but if I wrote 'A' then I could fix this by just writing b'A' instead. This code should detect the case where we're about to report a type mismatch of this kind, and the programmer wrote a char literal, and the char they wrote is ASCII, so therefore just prefixing b to make a byte literal will do what they meant. I have definitely written this mistake more than once, it's not difficult to figure out what to do, but the compiler might as well tell us anyway. I provided a test with two simple examples where the suggestion is appropriate, and one where it is not because the char literal is not ASCII, showing that the suggestion is only triggered in the former cases. I have contributed only a small typo doc fix before, so this is my first substantive rustc change.
This commit is contained in:
commit
980bf1979e
3 changed files with 76 additions and 0 deletions
|
@ -1923,6 +1923,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
(ty::Tuple(fields), _) => {
|
||||
self.emit_tuple_wrap_err(&mut err, span, found, fields)
|
||||
}
|
||||
// If a byte was expected and the found expression is a char literal
|
||||
// containing a single ASCII character, perhaps the user meant to write `b'c'` to
|
||||
// specify a byte literal
|
||||
(ty::Uint(ty::UintTy::U8), ty::Char) => {
|
||||
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
|
||||
&& let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
|
||||
&& code.chars().next().map_or(false, |c| c.is_ascii())
|
||||
{
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"if you meant to write a byte literal, prefix with `b`",
|
||||
format!("b'{}'", escape_literal(code)),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
// If a character was expected and the found expression is a string literal
|
||||
// containing a single character, perhaps the user meant to write `'c'` to
|
||||
// specify a character literal (issue #92479)
|
||||
|
|
18
tests/ui/suggestions/type-mismatch-byte-literal.rs
Normal file
18
tests/ui/suggestions/type-mismatch-byte-literal.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Tests that a suggestion is issued for type mismatch errors when a
|
||||
// u8 is expected and a char literal which is ASCII is supplied.
|
||||
|
||||
fn foo(_t: u8) {}
|
||||
|
||||
fn main() {
|
||||
let _x: u8 = 'X';
|
||||
//~^ ERROR: mismatched types [E0308]
|
||||
//~| HELP: if you meant to write a byte literal, prefix with `b`
|
||||
|
||||
foo('#');
|
||||
//~^ ERROR: mismatched types [E0308]
|
||||
//~| HELP: if you meant to write a byte literal, prefix with `b`
|
||||
|
||||
// Do not issue the suggestion if the char literal isn't ASCII
|
||||
let _t: u8 = '€';
|
||||
//~^ ERROR: mismatched types [E0308]
|
||||
}
|
42
tests/ui/suggestions/type-mismatch-byte-literal.stderr
Normal file
42
tests/ui/suggestions/type-mismatch-byte-literal.stderr
Normal file
|
@ -0,0 +1,42 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch-byte-literal.rs:7:18
|
||||
|
|
||||
LL | let _x: u8 = 'X';
|
||||
| -- ^^^ expected `u8`, found `char`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
help: if you meant to write a byte literal, prefix with `b`
|
||||
|
|
||||
LL | let _x: u8 = b'X';
|
||||
| ~~~~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch-byte-literal.rs:11:9
|
||||
|
|
||||
LL | foo('#');
|
||||
| --- ^^^ expected `u8`, found `char`
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
|
|
||||
note: function defined here
|
||||
--> $DIR/type-mismatch-byte-literal.rs:4:4
|
||||
|
|
||||
LL | fn foo(_t: u8) {}
|
||||
| ^^^ ------
|
||||
help: if you meant to write a byte literal, prefix with `b`
|
||||
|
|
||||
LL | foo(b'#');
|
||||
| ~~~~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch-byte-literal.rs:16:18
|
||||
|
|
||||
LL | let _t: u8 = '€';
|
||||
| -- ^^^ expected `u8`, found `char`
|
||||
| |
|
||||
| expected due to this
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Reference in a new issue