From 0c2a54d076cccdc57bb3edc01ad2391925bedde3 Mon Sep 17 00:00:00 2001 From: Mahmut Bulut Date: Fri, 14 Jun 2019 16:55:36 +0300 Subject: [PATCH] Organize intrinsics promotion checks --- src/libcore/intrinsics.rs | 1 + src/librustc/ty/constness.rs | 55 ++++++++++++++-- src/librustc_mir/transform/qualify_consts.rs | 68 +++----------------- src/libsyntax/feature_gate.rs | 3 - 4 files changed, 57 insertions(+), 70 deletions(-) diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 8d9a51742fd97..3a4c1f54a5562 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -913,6 +913,7 @@ extern "rust-intrinsic" { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_transmute")] pub fn transmute(e: T) -> U; /// Returns `true` if the actual type given as `T` requires drop diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs index 466cb353c85e4..edda8bc4f176b 100644 --- a/src/librustc/ty/constness.rs +++ b/src/librustc/ty/constness.rs @@ -2,7 +2,12 @@ use crate::ty::query::Providers; use crate::hir::def_id::DefId; use crate::hir; use crate::ty::TyCtxt; +<<<<<<< HEAD use syntax_pos::symbol::{sym, Symbol}; +======= +use syntax_pos::symbol::Symbol; +use rustc_target::spec::abi::Abi; +>>>>>>> Organize intrinsics promotion checks use crate::hir::map::blocks::FnLikeNode; use syntax::attr; @@ -68,16 +73,52 @@ impl<'tcx> TyCtxt<'tcx, 'tcx> { pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { - /// only checks whether the function has a `const` modifier - fn is_const_fn_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> bool { + fn is_intrinsic_promotable(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool { + // Intrinsics promotion whitelist is here to check const context at the top level beforehand. + match tcx.fn_sig(def_id).abi() { + Abi::RustIntrinsic | + Abi::PlatformIntrinsic => { + match &tcx.item_name(def_id).as_str()[..] { + | "size_of" + | "min_align_of" + | "needs_drop" + | "type_id" + | "bswap" + | "bitreverse" + | "ctpop" + | "cttz" + | "cttz_nonzero" + | "ctlz" + | "ctlz_nonzero" + | "overflowing_add" + | "overflowing_sub" + | "overflowing_mul" + | "unchecked_shl" + | "unchecked_shr" + | "rotate_left" + | "rotate_right" + | "add_with_overflow" + | "sub_with_overflow" + | "mul_with_overflow" + | "saturating_add" + | "saturating_sub" + | "transmute" + => true, + + _ => false + } + } + _ => false + } + } + + /// Checks whether the function has a `const` modifier and intrinsics can be promotable in it + fn is_const_fn_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool { let hir_id = tcx.hir().as_local_hir_id(def_id) .expect("Non-local call to local provider is_const_fn"); - let node = tcx.hir().get_by_hir_id(hir_id); - if let Some(fn_like) = FnLikeNode::from_node(node) { - fn_like.constness() == hir::Constness::Const - } else if let hir::Node::Ctor(_) = node { - true + if let Some(fn_like) = FnLikeNode::from_node(tcx.hir().get_by_hir_id(hir_id)) { + (fn_like.constness() == hir::Constness::Const) || is_intrinsic_promotable(tcx, def_id) } else { false } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 125411a717d1e..b33a00ea01fdc 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -489,49 +489,12 @@ impl Qualif for IsNotPromotable { let fn_ty = callee.ty(cx.body, cx.tcx); match fn_ty.sty { ty::FnDef(def_id, _) => { - match cx.tcx.fn_sig(def_id).abi() { - Abi::RustIntrinsic | - Abi::PlatformIntrinsic => { - assert!(!cx.tcx.is_const_fn(def_id)); - match &cx.tcx.item_name(def_id).as_str()[..] { - | "size_of" - | "min_align_of" - | "needs_drop" - | "type_id" - | "bswap" - | "bitreverse" - | "ctpop" - | "cttz" - | "cttz_nonzero" - | "ctlz" - | "ctlz_nonzero" - | "overflowing_add" - | "overflowing_sub" - | "overflowing_mul" - | "unchecked_shl" - | "unchecked_shr" - | "rotate_left" - | "rotate_right" - | "add_with_overflow" - | "sub_with_overflow" - | "mul_with_overflow" - | "saturating_add" - | "saturating_sub" - | "transmute" - => return true, - - _ => {} - } - } - _ => { - let is_const_fn = - cx.tcx.is_const_fn(def_id) || - cx.tcx.is_unstable_const_fn(def_id).is_some() || - cx.is_const_panic_fn(def_id); - if !is_const_fn { - return true; - } - } + let is_const_fn = + cx.tcx.is_const_fn(def_id) || + cx.tcx.is_unstable_const_fn(def_id).is_some() || + cx.is_const_panic_fn(def_id); + if !is_const_fn { + return true; } } _ => return true, @@ -1251,21 +1214,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { Abi::PlatformIntrinsic => { assert!(!self.tcx.is_const_fn(def_id)); match &self.tcx.item_name(def_id).as_str()[..] { - // special intrinsic that can be called diretly without an intrinsic - // feature gate needs a language feature gate - "transmute" => { - if self.mode.requires_const_checking() { - // const eval transmute calls only with the feature gate - if !self.tcx.features().const_transmute { - emit_feature_err( - &self.tcx.sess.parse_sess, sym::const_transmute, - self.span, GateIssue::Language, - &format!("The use of std::mem::transmute() \ - is gated in {}s", self.mode)); - } - } - } - name if name.starts_with("simd_shuffle") => { is_shuffle = true; } @@ -1276,8 +1224,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { } } _ => { - // In normal functions no calls are feature-gated. - if self.mode.requires_const_checking() { + // Apply normal functions' rules which are not feature-gated. + if self.mode != Mode::Fn { let unleash_miri = self .tcx .sess diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 004323301a22a..75aaa56e653f1 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -489,9 +489,6 @@ declare_features! ( // This will likely be removed prior to stabilization of async/await. (active, await_macro, "1.28.0", Some(50547), None), - // Allows reinterpretation of the bits of a value of one type as another type during const eval. - (active, const_transmute, "1.29.0", Some(53605), None), - // Allows using `try {...}` expressions. (active, try_blocks, "1.29.0", Some(31436), None),