]> git.lizzy.rs Git - rust.git/commitdiff
Use impl generics when suggesting fix on copy impl
authorMichael Goulet <michael@errs.io>
Tue, 26 Jul 2022 01:37:06 +0000 (01:37 +0000)
committerMichael Goulet <michael@errs.io>
Tue, 26 Jul 2022 01:48:34 +0000 (01:48 +0000)
compiler/rustc_typeck/src/coherence/builtin.rs
src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed [new file with mode: 0644]
src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs [new file with mode: 0644]
src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr [new file with mode: 0644]
src/test/ui/suggestions/missing-bound-in-manual-copy-impl.fixed [new file with mode: 0644]
src/test/ui/suggestions/missing-bound-in-manual-copy-impl.rs [new file with mode: 0644]
src/test/ui/suggestions/missing-bound-in-manual-copy-impl.stderr [new file with mode: 0644]

index d8e42729ff31d5ac53356b068534d1955a41dc34..c9138bcdab24677aa1ce5b0630353b972a013cc8 100644 (file)
@@ -94,14 +94,6 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
 
             // We'll try to suggest constraining type parameters to fulfill the requirements of
             // their `Copy` implementation.
-            let mut generics = None;
-            if let ty::Adt(def, _substs) = self_type.kind() {
-                let self_def_id = def.did();
-                if let Some(local) = self_def_id.as_local() {
-                    let self_item = tcx.hir().expect_item(local);
-                    generics = self_item.kind.generics();
-                }
-            }
             let mut errors: BTreeMap<_, Vec<_>> = Default::default();
             let mut bounds = vec![];
 
@@ -163,16 +155,14 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
                     &format!("the `Copy` impl for `{}` requires that `{}`", ty, error_predicate),
                 );
             }
-            if let Some(generics) = generics {
-                suggest_constraining_type_params(
-                    tcx,
-                    generics,
-                    &mut err,
-                    bounds.iter().map(|(param, constraint, def_id)| {
-                        (param.as_str(), constraint.as_str(), *def_id)
-                    }),
-                );
-            }
+            suggest_constraining_type_params(
+                tcx,
+                tcx.hir().get_generics(impl_did).expect("impls always have generics"),
+                &mut err,
+                bounds.iter().map(|(param, constraint, def_id)| {
+                    (param.as_str(), constraint.as_str(), *def_id)
+                }),
+            );
             err.emit();
         }
         Err(CopyImplementationError::NotAnAdt) => {
diff --git a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed
new file mode 100644 (file)
index 0000000..691e755
--- /dev/null
@@ -0,0 +1,19 @@
+// run-rustfix
+
+#[derive(Clone)]
+struct Wrapper<T>(T);
+
+struct OnlyCopyIfDisplay<T>(std::marker::PhantomData<T>);
+
+impl<T: std::fmt::Display> Clone for OnlyCopyIfDisplay<T> {
+    fn clone(&self) -> Self {
+        OnlyCopyIfDisplay(std::marker::PhantomData)
+    }
+}
+
+impl<T: std::fmt::Display> Copy for OnlyCopyIfDisplay<T> {}
+
+impl<S: std::fmt::Display> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs
new file mode 100644 (file)
index 0000000..e3185e7
--- /dev/null
@@ -0,0 +1,19 @@
+// run-rustfix
+
+#[derive(Clone)]
+struct Wrapper<T>(T);
+
+struct OnlyCopyIfDisplay<T>(std::marker::PhantomData<T>);
+
+impl<T: std::fmt::Display> Clone for OnlyCopyIfDisplay<T> {
+    fn clone(&self) -> Self {
+        OnlyCopyIfDisplay(std::marker::PhantomData)
+    }
+}
+
+impl<T: std::fmt::Display> Copy for OnlyCopyIfDisplay<T> {}
+
+impl<S> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr
new file mode 100644 (file)
index 0000000..e0f405e
--- /dev/null
@@ -0,0 +1,22 @@
+error[E0204]: the trait `Copy` may not be implemented for this type
+  --> $DIR/missing-bound-in-manual-copy-impl-2.rs:16:9
+   |
+LL | struct Wrapper<T>(T);
+   |                   - this field does not implement `Copy`
+...
+LL | impl<S> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
+   |         ^^^^
+   |
+note: the `Copy` impl for `OnlyCopyIfDisplay<S>` requires that `S: std::fmt::Display`
+  --> $DIR/missing-bound-in-manual-copy-impl-2.rs:4:19
+   |
+LL | struct Wrapper<T>(T);
+   |                   ^
+help: consider restricting type parameter `S`
+   |
+LL | impl<S: std::fmt::Display> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
+   |       +++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0204`.
diff --git a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.fixed b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.fixed
new file mode 100644 (file)
index 0000000..32a7215
--- /dev/null
@@ -0,0 +1,9 @@
+// run-rustfix
+
+#[derive(Clone)]
+struct Wrapper<T>(T);
+
+impl<S: Copy> Copy for Wrapper<S> {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.rs b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.rs
new file mode 100644 (file)
index 0000000..c688f4d
--- /dev/null
@@ -0,0 +1,9 @@
+// run-rustfix
+
+#[derive(Clone)]
+struct Wrapper<T>(T);
+
+impl<S> Copy for Wrapper<S> {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+fn main() {}
diff --git a/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.stderr b/src/test/ui/suggestions/missing-bound-in-manual-copy-impl.stderr
new file mode 100644 (file)
index 0000000..2189885
--- /dev/null
@@ -0,0 +1,17 @@
+error[E0204]: the trait `Copy` may not be implemented for this type
+  --> $DIR/missing-bound-in-manual-copy-impl.rs:6:9
+   |
+LL | struct Wrapper<T>(T);
+   |                   - this field does not implement `Copy`
+LL |
+LL | impl<S> Copy for Wrapper<S> {}
+   |         ^^^^
+   |
+help: consider restricting type parameter `S`
+   |
+LL | impl<S: Copy> Copy for Wrapper<S> {}
+   |       ++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0204`.