From ddd01455e9eb7d6356c43e7802337d3e4202d846 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 6 Sep 2017 10:09:25 +0200 Subject: [PATCH] Suggest changing literals instead of calling methods (fixes #44307) --- src/librustc_typeck/check/demand.rs | 24 +++++++++++++++++- src/test/ui/str-lit-type-mismatch.rs | 16 ++++++++++++ src/test/ui/str-lit-type-mismatch.stderr | 32 ++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/str-lit-type-mismatch.rs create mode 100644 src/test/ui/str-lit-type-mismatch.stderr diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index fc241c023cdaf..65900dc3f36e7 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -207,7 +207,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { expected: Ty<'tcx>) -> Option { match (&expected.sty, &checked_ty.sty) { - (&ty::TyRef(_, _), &ty::TyRef(_, _)) => None, + (&ty::TyRef(_, exp), &ty::TyRef(_, check)) => match (&exp.ty.sty, &check.ty.sty) { + (&ty::TyStr, &ty::TyArray(arr, _)) | + (&ty::TyStr, &ty::TySlice(arr)) if arr == self.tcx.types.u8 => { + if let hir::ExprLit(_) = expr.node { + let sp = self.sess().codemap().call_span_if_macro(expr.span); + if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) { + return Some(format!("try `{}`", &src[1..])); + } + } + None + }, + (&ty::TyArray(arr, _), &ty::TyStr) | + (&ty::TySlice(arr), &ty::TyStr) if arr == self.tcx.types.u8 => { + if let hir::ExprLit(_) = expr.node { + let sp = self.sess().codemap().call_span_if_macro(expr.span); + if let Ok(src) = self.tcx.sess.codemap().span_to_snippet(sp) { + return Some(format!("try `b{}`", src)); + } + } + None + } + _ => None, + }, (&ty::TyRef(_, mutability), _) => { // Check if it can work when put into a ref. For example: // diff --git a/src/test/ui/str-lit-type-mismatch.rs b/src/test/ui/str-lit-type-mismatch.rs new file mode 100644 index 0000000000000..0fd7d3a9d869e --- /dev/null +++ b/src/test/ui/str-lit-type-mismatch.rs @@ -0,0 +1,16 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + + +fn main() { + let x: &[u8] = "foo"; + let y: &[u8; 4] = "baaa"; + let z: &str = b"foo"; +} diff --git a/src/test/ui/str-lit-type-mismatch.stderr b/src/test/ui/str-lit-type-mismatch.stderr new file mode 100644 index 0000000000000..47418522df8ac --- /dev/null +++ b/src/test/ui/str-lit-type-mismatch.stderr @@ -0,0 +1,32 @@ +error[E0308]: mismatched types + --> $DIR/str-lit-type-mismatch.rs:13:20 + | +13 | let x: &[u8] = "foo"; + | ^^^^^ expected slice, found str + | + = note: expected type `&[u8]` + found type `&'static str` + = help: try `b"foo"` + +error[E0308]: mismatched types + --> $DIR/str-lit-type-mismatch.rs:14:23 + | +14 | let y: &[u8; 4] = "baaa"; + | ^^^^^^ expected array of 4 elements, found str + | + = note: expected type `&[u8; 4]` + found type `&'static str` + = help: try `b"baaa"` + +error[E0308]: mismatched types + --> $DIR/str-lit-type-mismatch.rs:15:19 + | +15 | let z: &str = b"foo"; + | ^^^^^^ expected str, found array of 3 elements + | + = note: expected type `&str` + found type `&'static [u8; 3]` + = help: try `"foo"` + +error: aborting due to 3 previous errors +