about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-08-02 06:22:49 +0200
committerGitHub <noreply@github.com>2023-08-02 06:22:49 +0200
commit1778c58905ed4d17a352a1d3d7ff05e382a15a04 (patch)
tree01f0cf2746b3f800b5e838b49553c52b70b7720d
parent3d29ce748469dfea713345d12e5aea6d24b3e871 (diff)
parenta40829498ed9d11547c81aeb9d084af38e438357 (diff)
Rollup merge of #114322 - Urgau:fix-issue-110063, r=compiler-errors
Fix invalid slice coercion suggestion reported in turbofish

This PR fixes the invalid slice coercion suggestion reported in turbofish and inferred generics by not emitting them.

Fixes https://github.com/rust-lang/rust/issues/110063
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs12
-rw-r--r--tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs13
-rw-r--r--tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr29
4 files changed, 54 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 14020c05251..95485850d0e 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -3030,8 +3030,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 self.report_similar_impl_candidates_for_root_obligation(&obligation, *trait_predicate, body_def_id, err);
             }
 
-            self.maybe_suggest_convert_to_slice(
+            self.suggest_convert_to_slice(
                 err,
+                obligation,
                 trait_ref,
                 impl_candidates.as_slice(),
                 span,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 31f70bbd34d..46c31c77613 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -398,9 +398,10 @@ pub trait TypeErrCtxtExt<'tcx> {
         param_env: ty::ParamEnv<'tcx>,
     ) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>>;
 
-    fn maybe_suggest_convert_to_slice(
+    fn suggest_convert_to_slice(
         &self,
         err: &mut Diagnostic,
+        obligation: &PredicateObligation<'tcx>,
         trait_ref: ty::PolyTraitRef<'tcx>,
         candidate_impls: &[ImplCandidate<'tcx>],
         span: Span,
@@ -3944,13 +3945,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     /// If the type that failed selection is an array or a reference to an array,
     /// but the trait is implemented for slices, suggest that the user converts
     /// the array into a slice.
-    fn maybe_suggest_convert_to_slice(
+    fn suggest_convert_to_slice(
         &self,
         err: &mut Diagnostic,
+        obligation: &PredicateObligation<'tcx>,
         trait_ref: ty::PolyTraitRef<'tcx>,
         candidate_impls: &[ImplCandidate<'tcx>],
         span: Span,
     ) {
+        // We can only suggest the slice coersion for function arguments since the suggestion
+        // would make no sense in turbofish or call
+        let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else {
+            return;
+        };
+
         // Three cases where we can make a suggestion:
         // 1. `[T; _]` (array of T)
         // 2. `&[T; _]` (reference to array of T)
diff --git a/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs
new file mode 100644
index 00000000000..c6ef8379f45
--- /dev/null
+++ b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs
@@ -0,0 +1,13 @@
+trait Test {}
+impl Test for &[u8] {}
+
+fn needs_test<T: Test>() -> T {
+    panic!()
+}
+
+fn main() {
+    needs_test::<[u8; 1]>();
+    //~^ ERROR the trait bound
+    let x: [u8; 1] = needs_test();
+    //~^ ERROR the trait bound
+}
diff --git a/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr
new file mode 100644
index 00000000000..6752a484448
--- /dev/null
+++ b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr
@@ -0,0 +1,29 @@
+error[E0277]: the trait bound `[u8; 1]: Test` is not satisfied
+  --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:9:18
+   |
+LL |     needs_test::<[u8; 1]>();
+   |                  ^^^^^^^ the trait `Test` is not implemented for `[u8; 1]`
+   |
+   = help: the trait `Test` is implemented for `&[u8]`
+note: required by a bound in `needs_test`
+  --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:4:18
+   |
+LL | fn needs_test<T: Test>() -> T {
+   |                  ^^^^ required by this bound in `needs_test`
+
+error[E0277]: the trait bound `[u8; 1]: Test` is not satisfied
+  --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:11:22
+   |
+LL |     let x: [u8; 1] = needs_test();
+   |                      ^^^^^^^^^^ the trait `Test` is not implemented for `[u8; 1]`
+   |
+   = help: the trait `Test` is implemented for `&[u8]`
+note: required by a bound in `needs_test`
+  --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:4:18
+   |
+LL | fn needs_test<T: Test>() -> T {
+   |                  ^^^^ required by this bound in `needs_test`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.