From dfbc143e65dd4dc8499f7296ddc7889854a8cc7d Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Sun, 3 May 2020 11:00:25 +0200 Subject: [PATCH 1/4] Adding if to prevent borrowing suggestion in structs #71136 --- .../traits/error_reporting/suggestions.rs | 52 ++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 5ec2d68ab2a7d..37f567401b74a 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -562,6 +562,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { param_env, new_trait_ref.without_const().to_predicate(), ); + if self.predicate_must_hold_modulo_regions(&new_obligation) { if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { // We have a very specific type of error, where just borrowing this argument @@ -569,6 +570,34 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // original type obligation, not the last one that failed, which is arbitrary. // Because of this, we modify the error to refer to the original obligation and // return early in the caller. + + + let has_colon = self + .tcx + .sess + .source_map() + .span_to_snippet(span) + .map(|w| w.contains(":")) + .unwrap_or(false); + + let has_double_colon = self + .tcx + .sess + .source_map() + .span_to_snippet(span) + .map(|w| w.contains("::")) + .unwrap_or(false); + + let has_bracket = self + .tcx + .sess + .source_map() + .span_to_snippet(span) + .map(|w| w.contains("{")) + .unwrap_or(false); + + + let msg = format!( "the trait bound `{}: {}` is not satisfied", found, @@ -591,12 +620,23 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { obligation.parent_trait_ref.skip_binder().print_only_trait_path(), ), ); - err.span_suggestion( - span, - "consider borrowing here", - format!("&{}", snippet), - Applicability::MaybeIncorrect, - ); + + // This if is to prevent a special edge-case + if !has_colon || has_double_colon || has_bracket { + // We don't want a borrowing suggestion on the fields in structs, + // ``` + // struct Foo { + // the_foos: Vec + // } + // ``` + + err.span_suggestion( + span, + "consider borrowing here", + format!("&{}", snippet), + Applicability::MaybeIncorrect, + ); + } return true; } } From bc29f1d062feeb68207c961d254652d6bff9fd9b Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Sun, 3 May 2020 11:11:23 +0200 Subject: [PATCH 2/4] Adding new test #71136 --- src/test/ui/traits/traits-issue-71136.rs | 8 ++++++++ src/test/ui/traits/traits-issue-71136.stderr | 13 +++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/test/ui/traits/traits-issue-71136.rs create mode 100644 src/test/ui/traits/traits-issue-71136.stderr diff --git a/src/test/ui/traits/traits-issue-71136.rs b/src/test/ui/traits/traits-issue-71136.rs new file mode 100644 index 0000000000000..b21756e2b637f --- /dev/null +++ b/src/test/ui/traits/traits-issue-71136.rs @@ -0,0 +1,8 @@ +struct Foo(u8); + +#[derive(Clone)] +struct FooHolster { + the_foos: Vec, //~ERROR Clone +} + +fn main() {} diff --git a/src/test/ui/traits/traits-issue-71136.stderr b/src/test/ui/traits/traits-issue-71136.stderr new file mode 100644 index 0000000000000..4c0a43062f60d --- /dev/null +++ b/src/test/ui/traits/traits-issue-71136.stderr @@ -0,0 +1,13 @@ +error[E0277]: the trait bound `Foo: std::clone::Clone` is not satisfied + --> $DIR/traits-issue-71136.rs:5:5 + | +LL | the_foos: Vec, + | ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `std::clone::Clone` + | + = note: required because of the requirements on the impl of `std::clone::Clone` for `std::vec::Vec` + = note: required by `std::clone::Clone::clone` + = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From d232be80f82b052fd023eb2f4904ccad0aa42d7a Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Sun, 3 May 2020 13:56:46 +0200 Subject: [PATCH 3/4] Fix tidy checks --- .../traits/error_reporting/suggestions.rs | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 37f567401b74a..c90769c66556d 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -570,33 +570,30 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // original type obligation, not the last one that failed, which is arbitrary. // Because of this, we modify the error to refer to the original obligation and // return early in the caller. - let has_colon = self - .tcx - .sess - .source_map() - .span_to_snippet(span) - .map(|w| w.contains(":")) - .unwrap_or(false); + .tcx + .sess + .source_map() + .span_to_snippet(span) + .map(|w| w.contains(":")) + .unwrap_or(false); let has_double_colon = self - .tcx - .sess - .source_map() - .span_to_snippet(span) - .map(|w| w.contains("::")) - .unwrap_or(false); + .tcx + .sess + .source_map() + .span_to_snippet(span) + .map(|w| w.contains("::")) + .unwrap_or(false); let has_bracket = self - .tcx - .sess - .source_map() - .span_to_snippet(span) - .map(|w| w.contains("{")) - .unwrap_or(false); - - + .tcx + .sess + .source_map() + .span_to_snippet(span) + .map(|w| w.contains("{")) + .unwrap_or(false); let msg = format!( "the trait bound `{}: {}` is not satisfied", @@ -620,7 +617,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { obligation.parent_trait_ref.skip_binder().print_only_trait_path(), ), ); - + // This if is to prevent a special edge-case if !has_colon || has_double_colon || has_bracket { // We don't want a borrowing suggestion on the fields in structs, From e776121431dc73b6e1782d5ddcc4e8d6d714f8e4 Mon Sep 17 00:00:00 2001 From: Kevin Per Date: Fri, 22 May 2020 10:52:06 +0200 Subject: [PATCH 4/4] Using `!span.from_expansion()` instead of snippets --- .../traits/error_reporting/suggestions.rs | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index c90769c66556d..24ca5ade59719 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -571,30 +571,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // Because of this, we modify the error to refer to the original obligation and // return early in the caller. - let has_colon = self - .tcx - .sess - .source_map() - .span_to_snippet(span) - .map(|w| w.contains(":")) - .unwrap_or(false); - - let has_double_colon = self - .tcx - .sess - .source_map() - .span_to_snippet(span) - .map(|w| w.contains("::")) - .unwrap_or(false); - - let has_bracket = self - .tcx - .sess - .source_map() - .span_to_snippet(span) - .map(|w| w.contains("{")) - .unwrap_or(false); - let msg = format!( "the trait bound `{}: {}` is not satisfied", found, @@ -619,7 +595,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); // This if is to prevent a special edge-case - if !has_colon || has_double_colon || has_bracket { + if !span.from_expansion() { // We don't want a borrowing suggestion on the fields in structs, // ``` // struct Foo {