Skip to content

Rollup of 15 pull requests #48520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Feb 25, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e6376a1
Added test for #45157
davidtwco Jan 24, 2018
467b5cf
stabilize (version: 1.26.0) Box::leak, cc #46179
Centril Feb 10, 2018
4861603
stabilize Box::leak: remove #![feature(box_leak)] in docs
Centril Feb 10, 2018
3118cbe
Allow two-phase borrows of &mut self in ops
sapphire-arches Feb 14, 2018
7062955
Fix arguments specified by lxl in two-phase-bin-ops test
sapphire-arches Feb 15, 2018
cf6e2f5
Add nonstandard_style alias for bad_style.
Feb 20, 2018
6fe5f42
Fix carets.
Feb 20, 2018
21e2a5e
Fix filepath in lint test.
Feb 20, 2018
5949d8b
Fix internal references to bad_style in test code.
Feb 20, 2018
20bc72e
Handle custom diagnostic for `&str + String`
estebank Feb 21, 2018
ef48e0f
Update the book to promote second edition
steveklabnik Feb 21, 2018
d98449d
manually release `cx.external_traits` while building the new trait
QuietMisdreavus Feb 21, 2018
ef30a8f
track extern traits being inlined
QuietMisdreavus Feb 22, 2018
bca3b31
proper early-bail condition
QuietMisdreavus Feb 22, 2018
8872e7b
add test for issue 48414 ICE
QuietMisdreavus Feb 22, 2018
0e26bb7
Revert "Implement Ord as necessary"
ishitatsuyuki Feb 18, 2018
93e6b0d
Remove needless dedup from projection
ishitatsuyuki Feb 18, 2018
619ad71
Fix exponential blowup on nested types
ishitatsuyuki Feb 18, 2018
5a2bec9
impl_or_trait_obligations: deduplicate obligations
ishitatsuyuki Feb 18, 2018
98eb4dd
Fix parsing of extern paths in types and poly-traits
petrochenkov Feb 22, 2018
31f66a0
reset default binding mode when we pass through a `&` pattern
nikomatsakis Feb 23, 2018
8b2037c
Introduce UnpackedKind
varkor Feb 23, 2018
bdccbcf
parse `dyn (Foo)` as a trait object
Manishearth Feb 23, 2018
4c73f82
Add test
Manishearth Feb 23, 2018
f2b9686
Bad tags are unreachable
varkor Feb 23, 2018
8640a51
Implement multiple patterns with `|` in `if let` and `while let`
petrochenkov Feb 24, 2018
e3e1c8f
Fix capitalisation in Path#file_name's docs
dwijnand Feb 24, 2018
aafebbc
Remove directory `src/rt`
petrochenkov Feb 24, 2018
edfdfc2
Rollup merge of #47689 - davidtwco:issue-45157, r=nikomatsakis
Manishearth Feb 24, 2018
dd890d8
Rollup merge of #48110 - Centril:stabilize/box_leak, r=alexcrichton
Manishearth Feb 24, 2018
0957572
Rollup merge of #48197 - bobtwinkles:two_phase_borrow_on_ops, r=nikom…
Manishearth Feb 24, 2018
58af0c7
Rollup merge of #48296 - ishitatsuyuki:exp-unblow, r=nikomatsakis
Manishearth Feb 24, 2018
d45c4a6
Rollup merge of #48386 - withoutboats:nonstandard-style, r=Manishearth
Manishearth Feb 24, 2018
7738eb4
Rollup merge of #48392 - estebank:string, r=petrochenkov
Manishearth Feb 24, 2018
9901bef
Rollup merge of #48404 - steveklabnik:second-edition-is-the-best-edit…
Manishearth Feb 24, 2018
43d1d6e
Rollup merge of #48415 - QuietMisdreavus:traits-on-traits-on-traits, …
Manishearth Feb 24, 2018
69757c5
Rollup merge of #48441 - petrochenkov:exty, r=estebank
Manishearth Feb 24, 2018
90f21d4
Rollup merge of #48448 - nikomatsakis:default-binding-mode-issue-4668…
Manishearth Feb 24, 2018
2dba874
Rollup merge of #48452 - varkor:unpacked-kind, r=eddyb
Manishearth Feb 24, 2018
7e68299
Rollup merge of #48481 - Manishearth:dyn-paren, r=petrochenkov
Manishearth Feb 24, 2018
9523c82
Rollup merge of #48490 - petrochenkov:orpat, r=eddyb
Manishearth Feb 24, 2018
0a72101
Rollup merge of #48499 - dwijnand:patch-1, r=BurntSushi
Manishearth Feb 24, 2018
7ba4afc
Rollup merge of #48503 - petrochenkov:nort, r=Mark-Simulacrum
Manishearth Feb 24, 2018
52047f0
ignore-pretty on dyn trait test
Manishearth Feb 25, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Handle custom diagnostic for &str + String
  • Loading branch information
estebank committed Feb 21, 2018
commit 20bc72e693372940183e97a32e7d07d2f9180182
69 changes: 43 additions & 26 deletions src/librustc_typeck/check/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use super::{FnCtxt, Needs};
use super::method::MethodCallee;
use rustc::ty::{self, Ty, TypeFoldable, TypeVariants};
use rustc::ty::TypeVariants::{TyStr, TyRef};
use rustc::ty::TypeVariants::{TyStr, TyRef, TyAdt};
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow, AutoBorrowMutability};
use rustc::infer::type_variable::TypeVariableOrigin;
use errors;
Expand Down Expand Up @@ -301,7 +301,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {

if let Some(missing_trait) = missing_trait {
if missing_trait == "std::ops::Add" &&
self.check_str_addition(expr, lhs_expr, lhs_ty,
self.check_str_addition(expr, lhs_expr, rhs_expr, lhs_ty,
rhs_ty, &mut err) {
// This has nothing here because it means we did string
// concatenation (e.g. "Hello " + "World!"). This means
Expand Down Expand Up @@ -330,37 +330,54 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn check_str_addition(&self,
expr: &'gcx hir::Expr,
lhs_expr: &'gcx hir::Expr,
rhs_expr: &'gcx hir::Expr,
lhs_ty: Ty<'tcx>,
rhs_ty: Ty<'tcx>,
err: &mut errors::DiagnosticBuilder) -> bool {
let codemap = self.tcx.sess.codemap();
let msg = "`to_owned()` can be used to create an owned `String` \
from a string reference. String concatenation \
appends the string on the right to the string \
on the left and may require reallocation. This \
requires ownership of the string on the left";
// If this function returns true it means a note was printed, so we don't need
// to print the normal "implementation of `std::ops::Add` might be missing" note
let mut is_string_addition = false;
if let TyRef(_, l_ty) = lhs_ty.sty {
if let TyRef(_, r_ty) = rhs_ty.sty {
if l_ty.ty.sty == TyStr && r_ty.ty.sty == TyStr {
err.span_label(expr.span,
"`+` can't be used to concatenate two `&str` strings");
let codemap = self.tcx.sess.codemap();
let suggestion =
match codemap.span_to_snippet(lhs_expr.span) {
Ok(lstring) => format!("{}.to_owned()", lstring),
_ => format!("<expression>")
};
err.span_suggestion(lhs_expr.span,
&format!("`to_owned()` can be used to create an owned `String` \
from a string reference. String concatenation \
appends the string on the right to the string \
on the left and may require reallocation. This \
requires ownership of the string on the left"), suggestion);
is_string_addition = true;
}

match (&lhs_ty.sty, &rhs_ty.sty) {
(&TyRef(_, ref l_ty), &TyRef(_, ref r_ty))
if l_ty.ty.sty == TyStr && r_ty.ty.sty == TyStr => {
err.span_label(expr.span,
"`+` can't be used to concatenate two `&str` strings");
match codemap.span_to_snippet(lhs_expr.span) {
Ok(lstring) => err.span_suggestion(lhs_expr.span,
msg,
format!("{}.to_owned()", lstring)),
_ => err.help(msg),
};
true
}

(&TyRef(_, ref l_ty), &TyAdt(..))
if l_ty.ty.sty == TyStr && &format!("{:?}", rhs_ty) == "std::string::String" => {
err.span_label(expr.span,
"`+` can't be used to concatenate a `&str` with a `String`");
match codemap.span_to_snippet(lhs_expr.span) {
Ok(lstring) => err.span_suggestion(lhs_expr.span,
msg,
format!("{}.to_owned()", lstring)),
_ => err.help(msg),
};
match codemap.span_to_snippet(rhs_expr.span) {
Ok(rstring) => {
err.span_suggestion(rhs_expr.span,
"you also need to borrow the `String` on the right to \
get a `&str`",
format!("&{}", rstring));
}
_ => {}
};
true
}
_ => false,
}

is_string_addition
}

pub fn check_user_unop(&self,
Expand Down
3 changes: 3 additions & 0 deletions src/test/ui/span/issue-39018.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ pub fn main() {
// that won't output for the above string concatenation
let y = World::Hello + World::Goodbye;
//~^ ERROR cannot be applied to type

let x = "Hello " + "World!".to_owned();
//~^ ERROR cannot be applied to type
}

enum World {
Expand Down
16 changes: 15 additions & 1 deletion src/test/ui/span/issue-39018.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,19 @@ error[E0369]: binary operation `+` cannot be applied to type `World`
|
= note: an implementation of `std::ops::Add` might be missing for `World`

error: aborting due to 2 previous errors
error[E0369]: binary operation `+` cannot be applied to type `&str`
--> $DIR/issue-39018.rs:21:13
|
21 | let x = "Hello " + "World!".to_owned();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `+` can't be used to concatenate a `&str` with a `String`
help: `to_owned()` can be used to create an owned `String` from a string reference. String concatenation appends the string on the right to the string on the left and may require reallocation. This requires ownership of the string on the left
|
21 | let x = "Hello ".to_owned() + "World!".to_owned();
| ^^^^^^^^^^^^^^^^^^^
help: you also need to borrow the `String` on the right to get a `&str`
|
21 | let x = "Hello " + &"World!".to_owned();
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors