Skip to content

Commit 130d02b

Browse files
tialaramexNoratrieb
andcommitted
Improve E0308: suggest user meant to use byte literal, w/ tests and fix
suggested by Nilstrieb Co-authored-by: nils <[email protected]>
1 parent 44a500c commit 130d02b

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -1923,6 +1923,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19231923
(ty::Tuple(fields), _) => {
19241924
self.emit_tuple_wrap_err(&mut err, span, found, fields)
19251925
}
1926+
// If a byte was expected and the found expression is a char literal
1927+
// containing a single ASCII character, perhaps the user meant to write `b'c'` to
1928+
// specify a byte literal
1929+
(ty::Uint(ty::UintTy::U8), ty::Char) => {
1930+
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
1931+
&& let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
1932+
&& code.chars().next().map_or(false, |c| c.is_ascii())
1933+
{
1934+
err.span_suggestion(
1935+
span,
1936+
"if you meant to write a byte literal, prefix with `b`",
1937+
format!("b'{}'", escape_literal(code)),
1938+
Applicability::MachineApplicable,
1939+
);
1940+
}
1941+
}
19261942
// If a character was expected and the found expression is a string literal
19271943
// containing a single character, perhaps the user meant to write `'c'` to
19281944
// specify a character literal (issue #92479)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Tests that a suggestion is issued for type mismatch errors when a
2+
// u8 is expected and a char literal which is ASCII is supplied.
3+
4+
fn foo(_t: u8) {}
5+
6+
fn main() {
7+
let _x: u8 = 'X';
8+
//~^ ERROR: mismatched types [E0308]
9+
//~| HELP: if you meant to write a byte literal, prefix with `b`
10+
11+
foo('#');
12+
//~^ ERROR: mismatched types [E0308]
13+
//~| HELP: if you meant to write a byte literal, prefix with `b`
14+
15+
// Do not issue the suggestion if the char literal isn't ASCII
16+
let _t: u8 = '€';
17+
//~^ ERROR: mismatched types [E0308]
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/type-mismatch-byte-literal.rs:7:18
3+
|
4+
LL | let _x: u8 = 'X';
5+
| -- ^^^ expected `u8`, found `char`
6+
| |
7+
| expected due to this
8+
|
9+
help: if you meant to write a byte literal, prefix with `b`
10+
|
11+
LL | let _x: u8 = b'X';
12+
| ~~~~
13+
14+
error[E0308]: mismatched types
15+
--> $DIR/type-mismatch-byte-literal.rs:11:9
16+
|
17+
LL | foo('#');
18+
| --- ^^^ expected `u8`, found `char`
19+
| |
20+
| arguments to this function are incorrect
21+
|
22+
note: function defined here
23+
--> $DIR/type-mismatch-byte-literal.rs:4:4
24+
|
25+
LL | fn foo(_t: u8) {}
26+
| ^^^ ------
27+
help: if you meant to write a byte literal, prefix with `b`
28+
|
29+
LL | foo(b'#');
30+
| ~~~~
31+
32+
error[E0308]: mismatched types
33+
--> $DIR/type-mismatch-byte-literal.rs:16:18
34+
|
35+
LL | let _t: u8 = '€';
36+
| -- ^^^ expected `u8`, found `char`
37+
| |
38+
| expected due to this
39+
40+
error: aborting due to 3 previous errors
41+
42+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)