use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
+use rustc_target::spec::abi::Abi::RustIntrinsic;
use std::borrow::Cow;
type McfResult = Result<(), (Span, Cow<'static, str>)>;
loop {
let predicates = tcx.predicates_of(current);
for (predicate, _) in predicates.predicates {
- match predicate.kind() {
- ty::PredicateKind::RegionOutlives(_)
- | ty::PredicateKind::TypeOutlives(_)
- | ty::PredicateKind::WellFormed(_)
- | ty::PredicateKind::Projection(_)
- | ty::PredicateKind::ConstEvaluatable(..)
- | ty::PredicateKind::ConstEquate(..) => continue,
- ty::PredicateKind::ObjectSafe(_) => {
+ match predicate.skip_binders() {
+ ty::PredicateAtom::RegionOutlives(_)
+ | ty::PredicateAtom::TypeOutlives(_)
+ | ty::PredicateAtom::WellFormed(_)
+ | ty::PredicateAtom::Projection(_)
+ | ty::PredicateAtom::ConstEvaluatable(..)
+ | ty::PredicateAtom::ConstEquate(..) => continue,
+ ty::PredicateAtom::ObjectSafe(_) => {
bug!("object safe predicate on function: {:#?}", predicate)
}
- ty::PredicateKind::ClosureKind(..) => {
+ ty::PredicateAtom::ClosureKind(..) => {
bug!("closure kind predicate on function: {:#?}", predicate)
}
- ty::PredicateKind::Subtype(_) => {
+ ty::PredicateAtom::Subtype(_) => {
bug!("subtype predicate on function: {:#?}", predicate)
}
- &ty::PredicateKind::Trait(pred, constness) => {
+ ty::PredicateAtom::Trait(pred, constness) => {
if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
continue;
}
- match pred.skip_binder().self_ty().kind {
+ match pred.self_ty().kind {
ty::Param(ref p) => {
// Allow `T: ?const Trait`
if constness == hir::Constness::NotConst
));
}
+ // HACK: This is to "unstabilize" the `transmute` intrinsic
+ // within const fns. `transmute` is allowed in all other const contexts.
+ // This won't really scale to more intrinsics or functions. Let's allow const
+ // transmutes in const fn before we add more hacks to this.
+ if tcx.fn_sig(fn_def_id).abi() == RustIntrinsic
+ && tcx.item_name(fn_def_id) == sym::transmute
+ && !feature_allowed(tcx, def_id, sym::const_fn_transmute)
+ {
+ return Err((
+ span,
+ "can only call `transmute` from const items, not `const fn`".into(),
+ ));
+ }
+
check_operand(tcx, func, span, fn_def_id, body)?;
for arg in args {