Skip to content

Commit 572bb13

Browse files
committed
Implement jackh726's suggestions
1 parent 48d07d1 commit 572bb13

File tree

7 files changed

+137
-14
lines changed

7 files changed

+137
-14
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -689,17 +689,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
689689
// Blacklist traits for which it would be nonsensical to suggest borrowing.
690690
// For instance, immutable references are always Copy, so suggesting to
691691
// borrow would always succeed, but it's probably not what the user wanted.
692-
let blacklist: Vec<_> = [
693-
LangItem::Copy,
694-
LangItem::Clone,
695-
LangItem::Pin,
696-
LangItem::Unpin,
697-
LangItem::Sized,
698-
LangItem::Send,
699-
]
700-
.iter()
701-
.filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok())
702-
.collect();
692+
let blacklist: Vec<_> =
693+
[LangItem::Copy, LangItem::Clone, LangItem::Unpin, LangItem::Sized, LangItem::Send]
694+
.iter()
695+
.filter_map(|lang_item| self.tcx.lang_items().require(*lang_item).ok())
696+
.collect();
703697

704698
let span = obligation.cause.span;
705699
let param_env = obligation.param_env;
@@ -771,7 +765,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
771765
err.span_suggestion(
772766
span,
773767
&format!(
774-
"consider borrowing{} here",
768+
"consider{} borrowing here",
775769
if mtbl { " mutably" } else { "" }
776770
),
777771
format!("&{}{}", if mtbl { "mut " } else { "" }, snippet),

src/test/ui/suggestions/imm-ref-trait-object-literal.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ LL | foo(s);
2424
| ^
2525
| |
2626
| expected an implementor of trait `Trait`
27-
| help: consider borrowing mutably here: `&mut s`
27+
| help: consider mutably borrowing here: `&mut s`
2828

2929
error: aborting due to 2 previous errors
3030

src/test/ui/suggestions/issue-84973-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | foo(a);
88
| ^
99
| |
1010
| expected an implementor of trait `Tr`
11-
| help: consider borrowing mutably here: `&mut a`
11+
| help: consider mutably borrowing here: `&mut a`
1212

1313
error: aborting due to previous error
1414

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Checks that certain traits for which we don't want to suggest borrowing
2+
// are blacklisted and don't cause the suggestion to be issued.
3+
4+
#![feature(generators)]
5+
6+
fn f_copy<T: Copy>(t: T) {}
7+
fn f_clone<T: Clone>(t: T) {}
8+
fn f_unpin<T: Unpin>(t: T) {}
9+
fn f_sized<T: Sized>(t: T) {}
10+
fn f_send<T: Send>(t: T) {}
11+
12+
struct S;
13+
14+
fn main() {
15+
f_copy("".to_string()); //~ ERROR: the trait bound `String: Copy` is not satisfied [E0277]
16+
f_clone(S); //~ ERROR: the trait bound `S: Clone` is not satisfied [E0277]
17+
f_unpin(static || { yield; });
18+
//~^ ERROR: cannot be unpinned [E0277]
19+
20+
let cl = || ();
21+
let ref_cl: &dyn Fn() -> () = &cl;
22+
f_sized(*ref_cl);
23+
//~^ ERROR: the size for values of type `dyn Fn()` cannot be known at compilation time [E0277]
24+
//~| ERROR: the size for values of type `dyn Fn()` cannot be known at compilation time [E0277]
25+
26+
use std::rc::Rc;
27+
let rc = Rc::new(0);
28+
f_send(rc); //~ ERROR: `Rc<{integer}>` cannot be sent between threads safely [E0277]
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
error[E0277]: the trait bound `String: Copy` is not satisfied
2+
--> $DIR/issue-84973-blacklist.rs:15:12
3+
|
4+
LL | fn f_copy<T: Copy>(t: T) {}
5+
| ---- required by this bound in `f_copy`
6+
...
7+
LL | f_copy("".to_string());
8+
| ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
9+
10+
error[E0277]: the trait bound `S: Clone` is not satisfied
11+
--> $DIR/issue-84973-blacklist.rs:16:13
12+
|
13+
LL | fn f_clone<T: Clone>(t: T) {}
14+
| ----- required by this bound in `f_clone`
15+
...
16+
LL | f_clone(S);
17+
| ^ the trait `Clone` is not implemented for `S`
18+
19+
error[E0277]: `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:33]` cannot be unpinned
20+
--> $DIR/issue-84973-blacklist.rs:17:5
21+
|
22+
LL | fn f_unpin<T: Unpin>(t: T) {}
23+
| ----- required by this bound in `f_unpin`
24+
...
25+
LL | f_unpin(static || { yield; });
26+
| ^^^^^^^ the trait `Unpin` is not implemented for `[static generator@$DIR/issue-84973-blacklist.rs:17:13: 17:33]`
27+
|
28+
= note: consider using `Box::pin`
29+
30+
error[E0277]: the size for values of type `dyn Fn()` cannot be known at compilation time
31+
--> $DIR/issue-84973-blacklist.rs:22:13
32+
|
33+
LL | fn f_sized<T: Sized>(t: T) {}
34+
| - required by this bound in `f_sized`
35+
...
36+
LL | f_sized(*ref_cl);
37+
| ^^^^^^^ doesn't have a size known at compile-time
38+
|
39+
= help: the trait `Sized` is not implemented for `dyn Fn()`
40+
41+
error[E0277]: `Rc<{integer}>` cannot be sent between threads safely
42+
--> $DIR/issue-84973-blacklist.rs:28:12
43+
|
44+
LL | fn f_send<T: Send>(t: T) {}
45+
| ---- required by this bound in `f_send`
46+
...
47+
LL | f_send(rc);
48+
| ^^ `Rc<{integer}>` cannot be sent between threads safely
49+
|
50+
= help: the trait `Send` is not implemented for `Rc<{integer}>`
51+
52+
error[E0277]: the size for values of type `dyn Fn()` cannot be known at compilation time
53+
--> $DIR/issue-84973-blacklist.rs:22:5
54+
|
55+
LL | f_sized(*ref_cl);
56+
| ^^^^^^^ doesn't have a size known at compile-time
57+
|
58+
= help: the trait `Sized` is not implemented for `dyn Fn()`
59+
= note: all function arguments must have a statically known size
60+
= help: unsized fn params are gated as an unstable feature
61+
62+
error: aborting due to 6 previous errors
63+
64+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Checks that we only suggest borrowing if &T actually implements the trait.
2+
3+
trait Tr {}
4+
impl Tr for &f32 {}
5+
fn bar<T: Tr>(t: T) {}
6+
7+
fn main() {
8+
let a = 0i32;
9+
let b = 0.0f32;
10+
bar(a); //~ ERROR: the trait bound `i32: Tr` is not satisfied [E0277]
11+
bar(b); //~ ERROR: the trait bound `f32: Tr` is not satisfied [E0277]
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0277]: the trait bound `i32: Tr` is not satisfied
2+
--> $DIR/issue-84973-negative.rs:10:9
3+
|
4+
LL | fn bar<T: Tr>(t: T) {}
5+
| -- required by this bound in `bar`
6+
...
7+
LL | bar(a);
8+
| ^ the trait `Tr` is not implemented for `i32`
9+
10+
error[E0277]: the trait bound `f32: Tr` is not satisfied
11+
--> $DIR/issue-84973-negative.rs:11:9
12+
|
13+
LL | fn bar<T: Tr>(t: T) {}
14+
| -- required by this bound in `bar`
15+
...
16+
LL | bar(b);
17+
| ^
18+
| |
19+
| expected an implementor of trait `Tr`
20+
| help: consider borrowing here: `&b`
21+
22+
error: aborting due to 2 previous errors
23+
24+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)