Skip to content

Commit 9c34481

Browse files
authored
Rollup merge of #71829 - kper:issue71136, r=matthewjasper
Fix suggestion to borrow in struct The corresponding issue is #71136. The compiler suggests that borrowing `the_foos` might solve the problem. This is obviously incorrect. ``` struct Foo(u8); #[derive(Clone)] struct FooHolster { the_foos: Vec<Foo>, } ``` I propose as fix to check if there is any colon in the span. However, there might a case where `my_method(B { a: 1, b : foo })` would be appropriate to show a suggestion for `&B ...`. To fix that too, we can simply check if there is a bracket in the span. This is only possible because both spans are different. Issue's span: `the_foos: Vec<Foo>` other's span: `B { a : 1, b : foo }`
2 parents a9ca1ec + e776121 commit 9c34481

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -631,13 +631,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
631631
param_env,
632632
new_trait_ref.without_const().to_predicate(self.tcx),
633633
);
634+
634635
if self.predicate_must_hold_modulo_regions(&new_obligation) {
635636
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
636637
// We have a very specific type of error, where just borrowing this argument
637638
// might solve the problem. In cases like this, the important part is the
638639
// original type obligation, not the last one that failed, which is arbitrary.
639640
// Because of this, we modify the error to refer to the original obligation and
640641
// return early in the caller.
642+
641643
let msg = format!(
642644
"the trait bound `{}: {}` is not satisfied",
643645
found,
@@ -660,12 +662,23 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
660662
obligation.parent_trait_ref.skip_binder().print_only_trait_path(),
661663
),
662664
);
663-
err.span_suggestion(
664-
span,
665-
"consider borrowing here",
666-
format!("&{}", snippet),
667-
Applicability::MaybeIncorrect,
668-
);
665+
666+
// This if is to prevent a special edge-case
667+
if !span.from_expansion() {
668+
// We don't want a borrowing suggestion on the fields in structs,
669+
// ```
670+
// struct Foo {
671+
// the_foos: Vec<Foo>
672+
// }
673+
// ```
674+
675+
err.span_suggestion(
676+
span,
677+
"consider borrowing here",
678+
format!("&{}", snippet),
679+
Applicability::MaybeIncorrect,
680+
);
681+
}
669682
return true;
670683
}
671684
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
struct Foo(u8);
2+
3+
#[derive(Clone)]
4+
struct FooHolster {
5+
the_foos: Vec<Foo>, //~ERROR Clone
6+
}
7+
8+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0277]: the trait bound `Foo: std::clone::Clone` is not satisfied
2+
--> $DIR/traits-issue-71136.rs:5:5
3+
|
4+
LL | the_foos: Vec<Foo>,
5+
| ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `std::clone::Clone`
6+
|
7+
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec<Foo>`
8+
= note: required by `std::clone::Clone::clone`
9+
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
10+
11+
error: aborting due to previous error
12+
13+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)