Skip to content

Commit ddd0145

Browse files
committed
Suggest changing literals instead of calling methods (fixes #44307)
1 parent 2f1ef9e commit ddd0145

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

src/librustc_typeck/check/demand.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
207207
expected: Ty<'tcx>)
208208
-> Option<String> {
209209
match (&expected.sty, &checked_ty.sty) {
210-
(&ty::TyRef(_, _), &ty::TyRef(_, _)) => None,
210+
(&ty::TyRef(_, exp), &ty::TyRef(_, check)) => match (&exp.ty.sty, &check.ty.sty) {
211+
(&ty::TyStr, &ty::TyArray(arr, _)) |
212+
(&ty::TyStr, &ty::TySlice(arr)) if arr == self.tcx.types.u8 => {
213+
if let hir::ExprLit(_) = expr.node {
214+
let sp = self.sess().codemap().call_span_if_macro(expr.span);
215+
if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) {
216+
return Some(format!("try `{}`", &src[1..]));
217+
}
218+
}
219+
None
220+
},
221+
(&ty::TyArray(arr, _), &ty::TyStr) |
222+
(&ty::TySlice(arr), &ty::TyStr) if arr == self.tcx.types.u8 => {
223+
if let hir::ExprLit(_) = expr.node {
224+
let sp = self.sess().codemap().call_span_if_macro(expr.span);
225+
if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) {
226+
return Some(format!("try `b{}`", src));
227+
}
228+
}
229+
None
230+
}
231+
_ => None,
232+
},
211233
(&ty::TyRef(_, mutability), _) => {
212234
// Check if it can work when put into a ref. For example:
213235
//

src/test/ui/str-lit-type-mismatch.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
12+
fn main() {
13+
let x: &[u8] = "foo";
14+
let y: &[u8; 4] = "baaa";
15+
let z: &str = b"foo";
16+
}
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/str-lit-type-mismatch.rs:13:20
3+
|
4+
13 | let x: &[u8] = "foo";
5+
| ^^^^^ expected slice, found str
6+
|
7+
= note: expected type `&[u8]`
8+
found type `&'static str`
9+
= help: try `b"foo"`
10+
11+
error[E0308]: mismatched types
12+
--> $DIR/str-lit-type-mismatch.rs:14:23
13+
|
14+
14 | let y: &[u8; 4] = "baaa";
15+
| ^^^^^^ expected array of 4 elements, found str
16+
|
17+
= note: expected type `&[u8; 4]`
18+
found type `&'static str`
19+
= help: try `b"baaa"`
20+
21+
error[E0308]: mismatched types
22+
--> $DIR/str-lit-type-mismatch.rs:15:19
23+
|
24+
15 | let z: &str = b"foo";
25+
| ^^^^^^ expected str, found array of 3 elements
26+
|
27+
= note: expected type `&str`
28+
found type `&'static [u8; 3]`
29+
= help: try `"foo"`
30+
31+
error: aborting due to 3 previous errors
32+

0 commit comments

Comments
 (0)