diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index eb98e3b538051..ba579e25f036a 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,12 +1,8 @@ -use std::ops::ControlFlow; - use rustc_hir::def_id::LocalDefId; use rustc_middle::mir; use rustc_middle::mir::interpret::{AllocInit, Allocation, InterpResult, Pointer}; use rustc_middle::ty::layout::TyAndLayout; -use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, -}; +use rustc_middle::ty::{TyCtxt, TypeVisitable, TypeVisitableExt}; use tracing::debug; use super::{InterpCx, MPlaceTy, MemoryKind, interp_ok, throw_inval}; @@ -20,44 +16,10 @@ where T: TypeVisitable>, { debug!("ensure_monomorphic_enough: ty={:?}", ty); - if !ty.has_param() { - return interp_ok(()); - } - - struct FoundParam; - struct UsedParamsNeedInstantiationVisitor {} - - impl<'tcx> TypeVisitor> for UsedParamsNeedInstantiationVisitor { - type Result = ControlFlow; - - fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { - if !ty.has_param() { - return ControlFlow::Continue(()); - } - - match *ty.kind() { - ty::Param(_) => ControlFlow::Break(FoundParam), - ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) | ty::FnDef(..) => { - ControlFlow::Continue(()) - } - _ => ty.super_visit_with(self), - } - } - - fn visit_const(&mut self, c: ty::Const<'tcx>) -> Self::Result { - match c.kind() { - ty::ConstKind::Param(..) => ControlFlow::Break(FoundParam), - _ => c.super_visit_with(self), - } - } - } - - let mut vis = UsedParamsNeedInstantiationVisitor {}; - if matches!(ty.visit_with(&mut vis), ControlFlow::Break(FoundParam)) { + if ty.has_param() { throw_inval!(TooGeneric); - } else { - interp_ok(()) } + interp_ok(()) } impl<'tcx> InterpretationResult<'tcx> for mir::interpret::ConstAllocation<'tcx> { diff --git a/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff b/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff new file mode 100644 index 0000000000000..2f83f54d2afdb --- /dev/null +++ b/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff @@ -0,0 +1,12 @@ +- // MIR for `cursed_is_i32` before GVN ++ // MIR for `cursed_is_i32` after GVN + + fn cursed_is_i32() -> bool { + let mut _0: bool; + + bb0: { + _0 = Eq(const cursed_is_i32::::{constant#0}, const cursed_is_i32::::{constant#1}); + return; + } + } + diff --git a/tests/mir-opt/gvn_type_id_polymorphic.rs b/tests/mir-opt/gvn_type_id_polymorphic.rs new file mode 100644 index 0000000000000..39bc5c24ecc68 --- /dev/null +++ b/tests/mir-opt/gvn_type_id_polymorphic.rs @@ -0,0 +1,22 @@ +//@ test-mir-pass: GVN +//@ compile-flags: -C opt-level=2 + +#![feature(core_intrinsics)] + +fn generic() {} + +const fn type_id_of_val(_: &T) -> u128 { + std::intrinsics::type_id::() +} + +// EMIT_MIR gvn_type_id_polymorphic.cursed_is_i32.GVN.diff +fn cursed_is_i32() -> bool { + // CHECK-LABEL: fn cursed_is_i32( + // CHECK: _0 = Eq(const cursed_is_i32::::{constant#0}, const cursed_is_i32::::{constant#1}); + // CHECK-NEXT: return; + (const { type_id_of_val(&generic::) } == const { type_id_of_val(&generic::) }) +} + +fn main() { + dbg!(cursed_is_i32::()); +}