Skip to content

Commit a60ffa0

Browse files
authored
Rollup merge of rust-lang#46249 - estebank:suggest-slice, r=arielb1
Suggest using slice when encountering `let x = ""[..];` Fix rust-lang#26319.
2 parents 840e6c1 + fa44927 commit a60ffa0

File tree

3 files changed

+99
-0
lines changed

3 files changed

+99
-0
lines changed

src/librustc/traits/error_reporting.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
581581
trait_ref.self_ty()));
582582
}
583583

584+
self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
585+
584586
// Try to report a help message
585587
if !trait_ref.has_infer_types() &&
586588
self.predicate_can_apply(obligation.param_env, trait_ref) {
@@ -821,6 +823,27 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
821823
err.emit();
822824
}
823825

826+
/// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a
827+
/// suggestion to borrow the initializer in order to use have a slice instead.
828+
fn suggest_borrow_on_unsized_slice(&self,
829+
code: &ObligationCauseCode<'tcx>,
830+
err: &mut DiagnosticBuilder<'tcx>) {
831+
if let &ObligationCauseCode::VariableType(node_id) = code {
832+
let parent_node = self.tcx.hir.get_parent_node(node_id);
833+
if let Some(hir::map::NodeLocal(ref local)) = self.tcx.hir.find(parent_node) {
834+
if let Some(ref expr) = local.init {
835+
if let hir::ExprIndex(_, _) = expr.node {
836+
if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
837+
err.span_suggestion(expr.span,
838+
"consider borrowing here",
839+
format!("&{}", snippet));
840+
}
841+
}
842+
}
843+
}
844+
}
845+
}
846+
824847
fn report_arg_count_mismatch(
825848
&self,
826849
span: Span,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2017 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+
fn main() { //~ NOTE expected `()` because of default return type
12+
let s = "abc";
13+
let t = if true { s[..2] } else { s };
14+
//~^ ERROR if and else have incompatible types
15+
//~| NOTE expected str, found &str
16+
//~| NOTE expected type
17+
let u: &str = if true { s[..2] } else { s };
18+
//~^ ERROR mismatched types
19+
//~| NOTE expected &str, found str
20+
//~| NOTE expected type
21+
let v = s[..2];
22+
//~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied
23+
//~| HELP consider borrowing here
24+
//~| NOTE `str` does not have a constant size known at compile-time
25+
//~| HELP the trait `std::marker::Sized` is not implemented for `str`
26+
//~| NOTE all local variables must have a statically known size
27+
let w: &str = s[..2];
28+
//~^ ERROR mismatched types
29+
//~| NOTE expected &str, found str
30+
//~| NOTE expected type
31+
//~| HELP try with `&s[..2]`
32+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error[E0308]: if and else have incompatible types
2+
--> $DIR/str-array-assignment.rs:13:11
3+
|
4+
13 | let t = if true { s[..2] } else { s };
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected str, found &str
6+
|
7+
= note: expected type `str`
8+
found type `&str`
9+
10+
error[E0308]: mismatched types
11+
--> $DIR/str-array-assignment.rs:17:27
12+
|
13+
11 | fn main() { //~ NOTE expected `()` because of default return type
14+
| - expected `()` because of default return type
15+
...
16+
17 | let u: &str = if true { s[..2] } else { s };
17+
| ^^^^^^ expected &str, found str
18+
|
19+
= note: expected type `&str`
20+
found type `str`
21+
22+
error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
23+
--> $DIR/str-array-assignment.rs:21:7
24+
|
25+
21 | let v = s[..2];
26+
| ^ ------ help: consider borrowing here: `&s[..2]`
27+
| |
28+
| `str` does not have a constant size known at compile-time
29+
|
30+
= help: the trait `std::marker::Sized` is not implemented for `str`
31+
= note: all local variables must have a statically known size
32+
33+
error[E0308]: mismatched types
34+
--> $DIR/str-array-assignment.rs:27:17
35+
|
36+
27 | let w: &str = s[..2];
37+
| ^^^^^^ expected &str, found str
38+
|
39+
= note: expected type `&str`
40+
found type `str`
41+
= help: try with `&s[..2]`
42+
43+
error: aborting due to 4 previous errors
44+

0 commit comments

Comments
 (0)