From 333c6bf523019fd1565a5236d3c727172ec844f2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 9 Dec 2022 19:58:46 +0000 Subject: [PATCH] copy self type is implied wf --- compiler/rustc_trait_selection/src/traits/misc.rs | 15 ++++++++++++++- src/test/ui/traits/copy-requires-self-wf.rs | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/traits/copy-requires-self-wf.rs diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index b87412f7de16..46eea628a344 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 000000000000..9abfdfab9d06 --- /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 Copy for B<'_, T> {} + +fn main() {}