Implement jackh726's suggestions
This commit is contained in:
parent
48d07d1326
commit
572bb13ae5
7 changed files with 137 additions and 14 deletions
|
@ -689,14 +689,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
// Blacklist traits for which it would be nonsensical to suggest borrowing.
|
||||
// For instance, immutable references are always Copy, so suggesting to
|
||||
// borrow would always succeed, but it's probably not what the user wanted.
|
||||
let blacklist: Vec<_> = [
|
||||
LangItem::Copy,
|
||||
LangItem::Clone,
|
||||
LangItem::Pin,
|
||||
LangItem::Unpin,
|
||||
LangItem::Sized,
|
||||
LangItem::Send,
|
||||
]
|
||||
let blacklist: Vec<_> =
|
||||
[LangItem::Copy, LangItem::Clone, LangItem::Unpin, LangItem::Sized, LangItem::Send]
|
||||
.iter()
|
||||
.filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok())
|
||||
.collect();
|
||||
|
@ -771,7 +765,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
err.span_suggestion(
|
||||
span,
|
||||
&format!(
|
||||
"consider borrowing{} here",
|
||||
"consider{} borrowing here",
|
||||
if mtbl { " mutably" } else { "" }
|
||||
),
|
||||
format!("&{}{}", if mtbl { "mut " } else { "" }, snippet),
|
||||
|
|
|
@ -24,7 +24,7 @@ LL | foo(s);
|
|||
| ^
|
||||
| |
|
||||
| expected an implementor of trait `Trait`
|
||||
| help: consider borrowing mutably here: `&mut s`
|
||||
| help: consider mutably borrowing here: `&mut s`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | foo(a);
|
|||
| ^
|
||||
| |
|
||||
| expected an implementor of trait `Tr`
|
||||
| help: consider borrowing mutably here: `&mut a`
|
||||
| help: consider mutably borrowing here: `&mut a`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
29
src/test/ui/suggestions/issue-84973-blacklist.rs
Normal file
29
src/test/ui/suggestions/issue-84973-blacklist.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Checks that certain traits for which we don't want to suggest borrowing
|
||||
// are blacklisted and don't cause the suggestion to be issued.
|
||||
|
||||
#![feature(generators)]
|
||||
|
||||
fn f_copy<T: Copy>(t: T) {}
|
||||
fn f_clone<T: Clone>(t: T) {}
|
||||
fn f_unpin<T: Unpin>(t: T) {}
|
||||
fn f_sized<T: Sized>(t: T) {}
|
||||
fn f_send<T: Send>(t: T) {}
|
||||
|
||||
struct S;
|
||||
|
||||
fn main() {
|
||||
f_copy("".to_string()); //~ ERROR: the trait bound `String: Copy` is not satisfied [E0277]
|
||||
f_clone(S); //~ ERROR: the trait bound `S: Clone` is not satisfied [E0277]
|
||||
f_unpin(static || { yield; });
|
||||
//~^ ERROR: cannot be unpinned [E0277]
|
||||
|
||||
let cl = || ();
|
||||
let ref_cl: &dyn Fn() -> () = &cl;
|
||||
f_sized(*ref_cl);
|
||||
//~^ ERROR: the size for values of type `dyn Fn()` cannot be known at compilation time [E0277]
|
||||
//~| ERROR: the size for values of type `dyn Fn()` cannot be known at compilation time [E0277]
|
||||
|
||||
use std::rc::Rc;
|
||||
let rc = Rc::new(0);
|
||||
f_send(rc); //~ ERROR: `Rc<{integer}>` cannot be sent between threads safely [E0277]
|
||||
}
|
64
src/test/ui/suggestions/issue-84973-blacklist.stderr
Normal file
64
src/test/ui/suggestions/issue-84973-blacklist.stderr
Normal file
|
@ -0,0 +1,64 @@
|
|||
error[E0277]: the trait bound `String: Copy` is not satisfied
|
||||
--> $DIR/issue-84973-blacklist.rs:15:12
|
||||
|
|
||||
LL | fn f_copy<T: Copy>(t: T) {}
|
||||
| ---- required by this bound in `f_copy`
|
||||
...
|
||||
LL | f_copy("".to_string());
|
||||
| ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
||||
|
||||
error[E0277]: the trait bound `S: Clone` is not satisfied
|
||||
--> $DIR/issue-84973-blacklist.rs:16:13
|
||||
|
|
||||
LL | fn f_clone<T: Clone>(t: T) {}
|
||||
| ----- required by this bound in `f_clone`
|
||||
...
|
||||
LL | f_clone(S);
|
||||
| ^ the trait `Clone` is not implemented for `S`
|
||||
|
||||
error[E0277]: `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:33]` cannot be unpinned
|
||||
--> $DIR/issue-84973-blacklist.rs:17:5
|
||||
|
|
||||
LL | fn f_unpin<T: Unpin>(t: T) {}
|
||||
| ----- required by this bound in `f_unpin`
|
||||
...
|
||||
LL | f_unpin(static || { yield; });
|
||||
| ^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:33]`
|
||||
|
|
||||
= note: consider using `Box::pin`
|
||||
|
||||
error[E0277]: the size for values of type `dyn Fn()` cannot be known at compilation time
|
||||
--> $DIR/issue-84973-blacklist.rs:22:13
|
||||
|
|
||||
LL | fn f_sized<T: Sized>(t: T) {}
|
||||
| - required by this bound in `f_sized`
|
||||
...
|
||||
LL | f_sized(*ref_cl);
|
||||
| ^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `dyn Fn()`
|
||||
|
||||
error[E0277]: `Rc<{integer}>` cannot be sent between threads safely
|
||||
--> $DIR/issue-84973-blacklist.rs:28:12
|
||||
|
|
||||
LL | fn f_send<T: Send>(t: T) {}
|
||||
| ---- required by this bound in `f_send`
|
||||
...
|
||||
LL | f_send(rc);
|
||||
| ^^ `Rc<{integer}>` cannot be sent between threads safely
|
||||
|
|
||||
= help: the trait `Send` is not implemented for `Rc<{integer}>`
|
||||
|
||||
error[E0277]: the size for values of type `dyn Fn()` cannot be known at compilation time
|
||||
--> $DIR/issue-84973-blacklist.rs:22:5
|
||||
|
|
||||
LL | f_sized(*ref_cl);
|
||||
| ^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `dyn Fn()`
|
||||
= note: all function arguments must have a statically known size
|
||||
= help: unsized fn params are gated as an unstable feature
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
12
src/test/ui/suggestions/issue-84973-negative.rs
Normal file
12
src/test/ui/suggestions/issue-84973-negative.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Checks that we only suggest borrowing if &T actually implements the trait.
|
||||
|
||||
trait Tr {}
|
||||
impl Tr for &f32 {}
|
||||
fn bar<T: Tr>(t: T) {}
|
||||
|
||||
fn main() {
|
||||
let a = 0i32;
|
||||
let b = 0.0f32;
|
||||
bar(a); //~ ERROR: the trait bound `i32: Tr` is not satisfied [E0277]
|
||||
bar(b); //~ ERROR: the trait bound `f32: Tr` is not satisfied [E0277]
|
||||
}
|
24
src/test/ui/suggestions/issue-84973-negative.stderr
Normal file
24
src/test/ui/suggestions/issue-84973-negative.stderr
Normal file
|
@ -0,0 +1,24 @@
|
|||
error[E0277]: the trait bound `i32: Tr` is not satisfied
|
||||
--> $DIR/issue-84973-negative.rs:10:9
|
||||
|
|
||||
LL | fn bar<T: Tr>(t: T) {}
|
||||
| -- required by this bound in `bar`
|
||||
...
|
||||
LL | bar(a);
|
||||
| ^ the trait `Tr` is not implemented for `i32`
|
||||
|
||||
error[E0277]: the trait bound `f32: Tr` is not satisfied
|
||||
--> $DIR/issue-84973-negative.rs:11:9
|
||||
|
|
||||
LL | fn bar<T: Tr>(t: T) {}
|
||||
| -- required by this bound in `bar`
|
||||
...
|
||||
LL | bar(b);
|
||||
| ^
|
||||
| |
|
||||
| expected an implementor of trait `Tr`
|
||||
| help: consider borrowing here: `&b`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue