Implement jackh726's suggestions
This commit is contained in:
parent
48d07d1326
commit
572bb13ae5
7 changed files with 137 additions and 14 deletions
|
@ -689,17 +689,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
// Blacklist traits for which it would be nonsensical to suggest borrowing.
|
// Blacklist traits for which it would be nonsensical to suggest borrowing.
|
||||||
// For instance, immutable references are always Copy, so suggesting to
|
// For instance, immutable references are always Copy, so suggesting to
|
||||||
// borrow would always succeed, but it's probably not what the user wanted.
|
// borrow would always succeed, but it's probably not what the user wanted.
|
||||||
let blacklist: Vec<_> = [
|
let blacklist: Vec<_> =
|
||||||
LangItem::Copy,
|
[LangItem::Copy, LangItem::Clone, LangItem::Unpin, LangItem::Sized, LangItem::Send]
|
||||||
LangItem::Clone,
|
.iter()
|
||||||
LangItem::Pin,
|
.filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok())
|
||||||
LangItem::Unpin,
|
.collect();
|
||||||
LangItem::Sized,
|
|
||||||
LangItem::Send,
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
.filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let span = obligation.cause.span;
|
let span = obligation.cause.span;
|
||||||
let param_env = obligation.param_env;
|
let param_env = obligation.param_env;
|
||||||
|
@ -771,7 +765,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
"consider borrowing{} here",
|
"consider{} borrowing here",
|
||||||
if mtbl { " mutably" } else { "" }
|
if mtbl { " mutably" } else { "" }
|
||||||
),
|
),
|
||||||
format!("&{}{}", if mtbl { "mut " } else { "" }, snippet),
|
format!("&{}{}", if mtbl { "mut " } else { "" }, snippet),
|
||||||
|
|
|
@ -24,7 +24,7 @@ LL | foo(s);
|
||||||
| ^
|
| ^
|
||||||
| |
|
| |
|
||||||
| expected an implementor of trait `Trait`
|
| 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
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ LL | foo(a);
|
||||||
| ^
|
| ^
|
||||||
| |
|
| |
|
||||||
| expected an implementor of trait `Tr`
|
| 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
|
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