diff options
| author | Michael Goulet <michael@errs.io> | 2022-12-09 19:58:46 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-01-13 23:06:29 +0000 |
| commit | 333c6bf523019fd1565a5236d3c727172ec844f2 (patch) | |
| tree | 52c2c222e1e2a1a830855aef85614b06c1021eb7 | |
| parent | 8cf7f40a895f476ecd3216b11ff673389135b652 (diff) | |
| download | rust-333c6bf523019fd1565a5236d3c727172ec844f2.tar.gz rust-333c6bf523019fd1565a5236d3c727172ec844f2.zip | |
copy self type is implied wf
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/misc.rs | 15 | ||||
| -rw-r--r-- | src/test/ui/traits/copy-requires-self-wf.rs | 14 |
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() {} |
