Auto merge of #43870 - GuillaumeGomez:deref-suggestion, r=nikomatsakis
Add deref suggestion Fixes #34562.
This commit is contained in:
commit
a83c3e7771
@ -261,6 +261,39 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
None
|
||||
}
|
||||
(_, &ty::TyRef(_, checked)) => {
|
||||
// We have `&T`, check if what was expected was `T`. If so,
|
||||
// we may want to suggest adding a `*`, or removing
|
||||
// a `&`.
|
||||
//
|
||||
// (But, also check check the `expn_info()` to see if this is
|
||||
// a macro; if so, it's hard to extract the text and make a good
|
||||
// suggestion, so don't bother.)
|
||||
if self.infcx.can_sub(self.param_env, checked.ty, &expected).is_ok() &&
|
||||
expr.span.ctxt().outer().expn_info().is_none() {
|
||||
match expr.node {
|
||||
// Maybe remove `&`?
|
||||
hir::ExprAddrOf(_, ref expr) => {
|
||||
if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(expr.span) {
|
||||
return Some(format!("try with `{}`", code));
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe add `*`? Only if `T: Copy`.
|
||||
_ => {
|
||||
if !self.infcx.type_moves_by_default(self.param_env,
|
||||
checked.ty,
|
||||
expr.span) {
|
||||
let sp = self.sess().codemap().call_span_if_macro(expr.span);
|
||||
if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(sp) {
|
||||
return Some(format!("try with `*{}`", code));
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
34
src/test/ui/deref-suggestion.rs
Normal file
34
src/test/ui/deref-suggestion.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// 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.
|
||||
|
||||
macro_rules! borrow {
|
||||
($x:expr) => { &$x }
|
||||
}
|
||||
|
||||
fn foo(_: String) {}
|
||||
|
||||
fn foo2(s: &String) {
|
||||
foo(s);
|
||||
}
|
||||
|
||||
fn foo3(_: u32) {}
|
||||
fn foo4(u: &u32) {
|
||||
foo3(u);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = String::new();
|
||||
let r_s = &s;
|
||||
foo2(r_s);
|
||||
foo(&"aaa".to_owned());
|
||||
foo(&mut "aaa".to_owned());
|
||||
foo3(borrow!(0));
|
||||
foo4(&0);
|
||||
}
|
59
src/test/ui/deref-suggestion.stderr
Normal file
59
src/test/ui/deref-suggestion.stderr
Normal file
@ -0,0 +1,59 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:18:9
|
||||
|
|
||||
18 | foo(s);
|
||||
| ^ expected struct `std::string::String`, found reference
|
||||
|
|
||||
= note: expected type `std::string::String`
|
||||
found type `&std::string::String`
|
||||
= help: here are some functions which might fulfill your needs:
|
||||
- .escape_debug()
|
||||
- .escape_default()
|
||||
- .escape_unicode()
|
||||
- .to_lowercase()
|
||||
- .to_uppercase()
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:23:10
|
||||
|
|
||||
23 | foo3(u);
|
||||
| ^ expected u32, found &u32
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found type `&u32`
|
||||
= help: try with `*u`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:30:9
|
||||
|
|
||||
30 | foo(&"aaa".to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found reference
|
||||
|
|
||||
= note: expected type `std::string::String`
|
||||
found type `&std::string::String`
|
||||
= help: try with `"aaa".to_owned()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:31:9
|
||||
|
|
||||
31 | foo(&mut "aaa".to_owned());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found mutable reference
|
||||
|
|
||||
= note: expected type `std::string::String`
|
||||
found type `&mut std::string::String`
|
||||
= help: try with `"aaa".to_owned()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/deref-suggestion.rs:12:20
|
||||
|
|
||||
12 | ($x:expr) => { &$x }
|
||||
| ^^^ expected u32, found &{integer}
|
||||
...
|
||||
32 | foo3(borrow!(0));
|
||||
| ---------- in this macro invocation
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found type `&{integer}`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
Loading…
x
Reference in New Issue
Block a user