diff options
| author | kennytm <kennytm@gmail.com> | 2017-11-28 03:16:46 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-28 03:16:46 +0800 |
| commit | a60ffa06aebeb87acfd6c3226a91ed508b124e21 (patch) | |
| tree | 629a74176b58c1acf0800857cf6596f3221cbe0e | |
| parent | 840e6c12ba0b6ab500040b65c10b611ef201f8af (diff) | |
| parent | fa44927d2c017359a7d4b14a31e96ee35472b406 (diff) | |
| download | rust-a60ffa06aebeb87acfd6c3226a91ed508b124e21.tar.gz rust-a60ffa06aebeb87acfd6c3226a91ed508b124e21.zip | |
Rollup merge of #46249 - estebank:suggest-slice, r=arielb1
Suggest using slice when encountering `let x = ""[..];` Fix #26319.
| -rw-r--r-- | src/librustc/traits/error_reporting.rs | 23 | ||||
| -rw-r--r-- | src/test/ui/suggestions/str-array-assignment.rs | 32 | ||||
| -rw-r--r-- | src/test/ui/suggestions/str-array-assignment.stderr | 44 |
3 files changed, 99 insertions, 0 deletions
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 46ec2be4a1f..5703c5c870e 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -581,6 +581,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { trait_ref.self_ty())); } + self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); + // Try to report a help message if !trait_ref.has_infer_types() && self.predicate_can_apply(obligation.param_env, trait_ref) { @@ -821,6 +823,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.emit(); } + /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a + /// suggestion to borrow the initializer in order to use have a slice instead. + fn suggest_borrow_on_unsized_slice(&self, + code: &ObligationCauseCode<'tcx>, + err: &mut DiagnosticBuilder<'tcx>) { + if let &ObligationCauseCode::VariableType(node_id) = code { + let parent_node = self.tcx.hir.get_parent_node(node_id); + if let Some(hir::map::NodeLocal(ref local)) = self.tcx.hir.find(parent_node) { + if let Some(ref expr) = local.init { + if let hir::ExprIndex(_, _) = expr.node { + if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(expr.span) { + err.span_suggestion(expr.span, + "consider borrowing here", + format!("&{}", snippet)); + } + } + } + } + } + } + fn report_arg_count_mismatch( &self, span: Span, diff --git a/src/test/ui/suggestions/str-array-assignment.rs b/src/test/ui/suggestions/str-array-assignment.rs new file mode 100644 index 00000000000..6c7f4852a4a --- /dev/null +++ b/src/test/ui/suggestions/str-array-assignment.rs @@ -0,0 +1,32 @@ +// Copyright 2017 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 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { //~ NOTE expected `()` because of default return type + let s = "abc"; + let t = if true { s[..2] } else { s }; + //~^ ERROR if and else have incompatible types + //~| NOTE expected str, found &str + //~| NOTE expected type + let u: &str = if true { s[..2] } else { s }; + //~^ ERROR mismatched types + //~| NOTE expected &str, found str + //~| NOTE expected type + let v = s[..2]; + //~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied + //~| HELP consider borrowing here + //~| NOTE `str` does not have a constant size known at compile-time + //~| HELP the trait `std::marker::Sized` is not implemented for `str` + //~| NOTE all local variables must have a statically known size + let w: &str = s[..2]; + //~^ ERROR mismatched types + //~| NOTE expected &str, found str + //~| NOTE expected type + //~| HELP try with `&s[..2]` +} diff --git a/src/test/ui/suggestions/str-array-assignment.stderr b/src/test/ui/suggestions/str-array-assignment.stderr new file mode 100644 index 00000000000..14b744c2e46 --- /dev/null +++ b/src/test/ui/suggestions/str-array-assignment.stderr @@ -0,0 +1,44 @@ +error[E0308]: if and else have incompatible types + --> $DIR/str-array-assignment.rs:13:11 + | +13 | let t = if true { s[..2] } else { s }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected str, found &str + | + = note: expected type `str` + found type `&str` + +error[E0308]: mismatched types + --> $DIR/str-array-assignment.rs:17:27 + | +11 | fn main() { //~ NOTE expected `()` because of default return type + | - expected `()` because of default return type +... +17 | let u: &str = if true { s[..2] } else { s }; + | ^^^^^^ expected &str, found str + | + = note: expected type `&str` + found type `str` + +error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied + --> $DIR/str-array-assignment.rs:21:7 + | +21 | let v = s[..2]; + | ^ ------ help: consider borrowing here: `&s[..2]` + | | + | `str` does not have a constant size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `str` + = note: all local variables must have a statically known size + +error[E0308]: mismatched types + --> $DIR/str-array-assignment.rs:27:17 + | +27 | let w: &str = s[..2]; + | ^^^^^^ expected &str, found str + | + = note: expected type `&str` + found type `str` + = help: try with `&s[..2]` + +error: aborting due to 4 previous errors + |
