Add const_eval_select intrinsic

This commit is contained in:
Deadbeef
2021-10-12 05:06:37 +00:00
parent 0c87288f92
commit 5387b6542f
20 changed files with 334 additions and 38 deletions

View File

@@ -24,7 +24,7 @@ use std::ops::Deref;
use super::ops::{self, NonConstOp, Status};
use super::qualifs::{self, CustomEq, HasMutInterior, NeedsNonConstDrop};
use super::resolver::FlowSensitiveAnalysis;
use super::{is_lang_panic_fn, ConstCx, Qualif};
use super::{is_lang_special_const_fn, ConstCx, Qualif};
use crate::const_eval::is_unstable_const_fn;
// We are using `MaybeMutBorrowedLocals` as a proxy for whether an item may have been mutated
@@ -259,7 +259,9 @@ impl Checker<'mir, 'tcx> {
self.check_local_or_return_ty(return_ty.skip_binder(), RETURN_PLACE);
}
self.visit_body(&body);
if !tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
self.visit_body(&body);
}
// Ensure that the end result is `Sync` in a non-thread local `static`.
let should_check_for_sync = self.const_kind()
@@ -886,7 +888,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
}
// At this point, we are calling a function, `callee`, whose `DefId` is known...
if is_lang_panic_fn(tcx, callee) {
if is_lang_special_const_fn(tcx, callee) {
// `begin_panic` and `panic_display` are generic functions that accept
// types other than str. Check to enforce that only str can be used in
// const-eval.

View File

@@ -74,9 +74,6 @@ impl ConstCx<'mir, 'tcx> {
/// Returns `true` if this `DefId` points to one of the official `panic` lang items.
pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
// We can allow calls to these functions because `hook_panic_fn` in
// `const_eval/machine.rs` ensures the calls are handled specially.
// Keep in sync with what that function handles!
Some(def_id) == tcx.lang_items().panic_fn()
|| Some(def_id) == tcx.lang_items().panic_str()
|| Some(def_id) == tcx.lang_items().panic_display()
@@ -85,6 +82,15 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
|| Some(def_id) == tcx.lang_items().begin_panic_fmt()
}
/// Returns `true` if this `DefId` points to one of the lang items that will be handled differently
/// in const_eval.
pub fn is_lang_special_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
// We can allow calls to these functions because `hook_special_const_fn` in
// `const_eval/machine.rs` ensures the calls are handled specially.
// Keep in sync with what that function handles!
is_lang_panic_fn(tcx, def_id) || Some(def_id) == tcx.lang_items().const_eval_select()
}
pub fn rustc_allow_const_fn_unstable(
tcx: TyCtxt<'tcx>,
def_id: DefId,

View File

@@ -1,7 +1,7 @@
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, BasicBlock, Location};
use rustc_middle::ty::TyCtxt;
use rustc_span::Span;
use rustc_span::{symbol::sym, Span};
use super::check::Qualifs;
use super::ops::{self, NonConstOp};
@@ -30,6 +30,10 @@ pub fn check_live_drops(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) {
return;
}
if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) {
return;
}
let ccx = ConstCx { body, tcx, const_kind, param_env: tcx.param_env(def_id) };
if !checking_enabled(&ccx) {
return;