From 6bddc7554902c406e2e840acce905a814ca60d17 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Tue, 3 Oct 2023 13:19:00 +0300 Subject: [PATCH 1/2] normalize opaque alias type --- .../src/transform/validate.rs | 9 +++++- .../normalize-alias-type.rs | 32 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/ui/type-alias-impl-trait/normalize-alias-type.rs diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 4711f7b47cccc..2343227e02ce6 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -687,7 +687,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let kind = match parent_ty.ty.kind() { &ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { - self.tcx.type_of(def_id).instantiate(self.tcx, args).kind() + let ty = self.tcx.type_of(def_id).instantiate(self.tcx, args); + // If the type we get is opaque, we want to normalize it. + if ty.is_impl_trait() { + let inner_ty = self.tcx.expand_opaque_types(ty).kind(); + inner_ty + } else { + ty.kind() + } } kind => kind, }; diff --git a/tests/ui/type-alias-impl-trait/normalize-alias-type.rs b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs new file mode 100644 index 0000000000000..7c62002b931be --- /dev/null +++ b/tests/ui/type-alias-impl-trait/normalize-alias-type.rs @@ -0,0 +1,32 @@ +// check-pass +// compile-flags: -Z mir-opt-level=3 +#![feature(type_alias_impl_trait)] +#![crate_type = "lib"] +pub trait Tr { + fn get(&self) -> u32; +} + +impl Tr for (u32,) { + #[inline] + fn get(&self) -> u32 { self.0 } +} + +pub fn tr1() -> impl Tr { + (32,) +} + +pub fn tr2() -> impl Tr { + struct Inner { + x: X, + } + type X = impl Tr; + impl Tr for Inner { + fn get(&self) -> u32 { + self.x.get() + } + } + + Inner { + x: tr1(), + } +} From 85c61f98f341b8f13d43c72bd0af8ce5f6b79db5 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Tue, 3 Oct 2023 17:09:07 +0300 Subject: [PATCH 2/2] use normalize_erasing_regions and fix other issue --- .../src/transform/validate.rs | 3 ++- .../src/impls/initialized.rs | 20 +++++++++++++------ .../type-alias-impl-trait/tait-normalize.rs | 14 +++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 tests/ui/type-alias-impl-trait/tait-normalize.rs diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 2343227e02ce6..6143fc2031009 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -690,7 +690,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let ty = self.tcx.type_of(def_id).instantiate(self.tcx, args); // If the type we get is opaque, we want to normalize it. if ty.is_impl_trait() { - let inner_ty = self.tcx.expand_opaque_types(ty).kind(); + let inner_ty = + self.tcx.normalize_erasing_regions(self.param_env, ty).kind(); inner_ty } else { ty.kind() diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index e6d383d626ad5..fb09e79a809f8 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -1,8 +1,3 @@ -use rustc_index::bit_set::{BitSet, ChunkedBitSet}; -use rustc_index::Idx; -use rustc_middle::mir::{self, Body, CallReturnPlaces, Location, TerminatorEdges}; -use rustc_middle::ty::{self, TyCtxt}; - use crate::drop_flag_effects_for_function_entry; use crate::drop_flag_effects_for_location; use crate::elaborate_drops::DropFlagState; @@ -12,6 +7,11 @@ use crate::on_lookup_result_bits; use crate::MoveDataParamEnv; use crate::{drop_flag_effects, on_all_children_bits, on_all_drop_children_bits}; use crate::{lattice, AnalysisDomain, GenKill, GenKillAnalysis, MaybeReachable}; +use rustc_index::bit_set::{BitSet, ChunkedBitSet}; +use rustc_index::Idx; +use rustc_middle::mir::{self, Body, CallReturnPlaces, Location, TerminatorEdges}; +use rustc_middle::ty::ParamEnv; +use rustc_middle::ty::{self, TyCtxt}; /// `MaybeInitializedPlaces` tracks all places that might be /// initialized upon reaching a particular point in the control flow @@ -759,7 +759,15 @@ fn switch_on_enum_discriminant<'mir, 'tcx>( mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(discriminated))) if *lhs == switch_on => { - match discriminated.ty(body, tcx).ty.kind() { + let mut kind = discriminated.ty(body, tcx).ty.kind(); + if discriminated.ty(body, tcx).ty.is_impl_trait() { + let ty = tcx.normalize_erasing_regions( + ParamEnv::reveal_all(), + discriminated.ty(body, tcx).ty, + ); + kind = ty.kind(); + } + match kind { ty::Adt(def, _) => return Some((*discriminated, *def)), // `Rvalue::Discriminant` is also used to get the active yield point for a diff --git a/tests/ui/type-alias-impl-trait/tait-normalize.rs b/tests/ui/type-alias-impl-trait/tait-normalize.rs new file mode 100644 index 0000000000000..26d94dbb42a36 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/tait-normalize.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +fn enum_upvar() { + type T = impl Copy; + let foo: T = Some((1u32, 2u32)); + let x = move || match foo { + None => (), + Some((a, b)) => (), + }; +} + +fn main(){}