about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-12-09 19:58:46 +0000
committerMichael Goulet <michael@errs.io>2023-01-13 23:06:29 +0000
commit333c6bf523019fd1565a5236d3c727172ec844f2 (patch)
tree52c2c222e1e2a1a830855aef85614b06c1021eb7
parent8cf7f40a895f476ecd3216b11ff673389135b652 (diff)
downloadrust-333c6bf523019fd1565a5236d3c727172ec844f2.tar.gz
rust-333c6bf523019fd1565a5236d3c727172ec844f2.zip
copy self type is implied wf
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs15
-rw-r--r--src/test/ui/traits/copy-requires-self-wf.rs14
2 files changed, 28 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index b87412f7de1..46eea628a34 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -2,6 +2,7 @@
 
 use crate::traits::{self, ObligationCause};
 
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir as hir;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::TyCtxtInferExt;
@@ -9,6 +10,8 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
 
 use crate::traits::error_reporting::TypeErrCtxtExt;
 
+use super::outlives_bounds::InferCtxtExt;
+
 #[derive(Clone)]
 pub enum CopyImplementationError<'tcx> {
     InfrigingFields(Vec<(&'tcx ty::FieldDef, Ty<'tcx>)>),
@@ -45,6 +48,7 @@ pub fn type_allowed_to_implement_copy<'tcx>(
     };
 
     let copy_def_id = tcx.require_lang_item(hir::LangItem::Copy, Some(parent_cause.span));
+
     let mut infringing = Vec::new();
     for variant in adt.variants() {
         for field in &variant.fields {
@@ -85,7 +89,16 @@ pub fn type_allowed_to_implement_copy<'tcx>(
                 infringing.push((field, ty));
             }
 
-            let outlives_env = OutlivesEnvironment::new(param_env);
+            // Check regions assuming the self type of the impl is WF
+            let outlives_env = OutlivesEnvironment::with_bounds(
+                param_env,
+                Some(&infcx),
+                infcx.implied_bounds_tys(
+                    param_env,
+                    parent_cause.body_id,
+                    FxIndexSet::from_iter([self_type]),
+                ),
+            );
             infcx.process_registered_region_obligations(
                 outlives_env.region_bound_pairs(),
                 param_env,
diff --git a/src/test/ui/traits/copy-requires-self-wf.rs b/src/test/ui/traits/copy-requires-self-wf.rs
new file mode 100644
index 00000000000..9abfdfab9d0
--- /dev/null
+++ b/src/test/ui/traits/copy-requires-self-wf.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#[derive(Clone)]
+struct A<'a, T>(&'a T);
+
+impl<'a, T: Copy + 'a> Copy for A<'a, T> {}
+
+#[derive(Clone)]
+struct B<'a, T>(A<'a, T>);
+
+// `T: '_` should be implied by `WF(B<'_, T>)`.
+impl<T: Copy> Copy for B<'_, T> {}
+
+fn main() {}