1
Fork 0

Implement jackh726's suggestions

This commit is contained in:
Fabian Wolff 2021-05-17 22:58:09 +02:00
parent 48d07d1326
commit 572bb13ae5
7 changed files with 137 additions and 14 deletions

View file

@ -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),

View file

@ -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

View file

@ -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

View 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]
}

View 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`.

View 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]
}

View 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`.