From 894b42c8616f352eacf54bc830c01e33b406fb8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Fri, 4 Jun 2021 00:00:00 +0000 Subject: [PATCH] Disallow non-monomorphic calls to `needs_drop` in interpreter otherwise evaluation could change after further substitutions. --- .../rustc_mir/src/interpret/intrinsics.rs | 5 ++++- .../ui/consts/const-needs_drop-monomorphic.rs | 17 ++++++++++++++++ .../const-needs_drop-monomorphic.stderr | 20 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/consts/const-needs_drop-monomorphic.rs create mode 100644 src/test/ui/consts/const-needs_drop-monomorphic.stderr diff --git a/compiler/rustc_mir/src/interpret/intrinsics.rs b/compiler/rustc_mir/src/interpret/intrinsics.rs index 99622fb310a..cdd1edbf286 100644 --- a/compiler/rustc_mir/src/interpret/intrinsics.rs +++ b/compiler/rustc_mir/src/interpret/intrinsics.rs @@ -56,7 +56,10 @@ crate fn eval_nullary_intrinsic<'tcx>( let alloc = type_name::alloc_type_name(tcx, tp_ty); ConstValue::Slice { data: alloc, start: 0, end: alloc.len() } } - sym::needs_drop => ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)), + sym::needs_drop => { + ensure_monomorphic_enough(tcx, tp_ty)?; + ConstValue::from_bool(tp_ty.needs_drop(tcx, param_env)) + } sym::min_align_of | sym::pref_align_of => { let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?; let n = match name { diff --git a/src/test/ui/consts/const-needs_drop-monomorphic.rs b/src/test/ui/consts/const-needs_drop-monomorphic.rs new file mode 100644 index 00000000000..9f66e3cfa23 --- /dev/null +++ b/src/test/ui/consts/const-needs_drop-monomorphic.rs @@ -0,0 +1,17 @@ +// Check that evaluation of needs_drop fails when T is not monomorphic. +#![feature(const_generics)] +#![allow(const_evaluatable_unchecked)] +#![allow(incomplete_features)] + +struct Bool {} +impl Bool { + fn assert() {} +} +fn f() { + Bool::<{ std::mem::needs_drop::() }>::assert(); + //~^ ERROR no function or associated item named `assert` found + //~| ERROR constant expression depends on a generic parameter +} +fn main() { + f::(); +} diff --git a/src/test/ui/consts/const-needs_drop-monomorphic.stderr b/src/test/ui/consts/const-needs_drop-monomorphic.stderr new file mode 100644 index 00000000000..0770d06e15b --- /dev/null +++ b/src/test/ui/consts/const-needs_drop-monomorphic.stderr @@ -0,0 +1,20 @@ +error[E0599]: no function or associated item named `assert` found for struct `Bool<{ std::mem::needs_drop::() }>` in the current scope + --> $DIR/const-needs_drop-monomorphic.rs:11:46 + | +LL | struct Bool {} + | -------------------------- function or associated item `assert` not found for this +... +LL | Bool::<{ std::mem::needs_drop::() }>::assert(); + | ^^^^^^ function or associated item cannot be called on `Bool<{ std::mem::needs_drop::() }>` due to unsatisfied trait bounds + +error: constant expression depends on a generic parameter + --> $DIR/const-needs_drop-monomorphic.rs:11:5 + | +LL | Bool::<{ std::mem::needs_drop::() }>::assert(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`.