Rollup merge of #67781 - cjgillot:passes-const, r=oli-obk
Move `is_min_const_fn` query to librustc_mir. The only two uses of the associated methods are in `librustc_mir` and `librustdoc`. Please tell me if there is a better choice. cc #65031
This commit is contained in:
commit
b85b1dd465
|
@ -1,156 +0,0 @@
|
||||||
use crate::hir::map::blocks::FnLikeNode;
|
|
||||||
use crate::ty::query::Providers;
|
|
||||||
use crate::ty::TyCtxt;
|
|
||||||
use rustc_hir as hir;
|
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_span::symbol::Symbol;
|
|
||||||
use rustc_target::spec::abi::Abi;
|
|
||||||
use syntax::attr;
|
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
|
||||||
/// Whether the `def_id` counts as const fn in your current crate, considering all active
|
|
||||||
/// feature gates
|
|
||||||
pub fn is_const_fn(self, def_id: DefId) -> bool {
|
|
||||||
self.is_const_fn_raw(def_id)
|
|
||||||
&& match self.is_unstable_const_fn(def_id) {
|
|
||||||
Some(feature_name) => {
|
|
||||||
// has a `rustc_const_unstable` attribute, check whether the user enabled the
|
|
||||||
// corresponding feature gate.
|
|
||||||
self.features()
|
|
||||||
.declared_lib_features
|
|
||||||
.iter()
|
|
||||||
.any(|&(sym, _)| sym == feature_name)
|
|
||||||
}
|
|
||||||
// functions without const stability are either stable user written
|
|
||||||
// const fn or the user is using feature gates and we thus don't
|
|
||||||
// care what they do
|
|
||||||
None => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
|
|
||||||
pub fn is_unstable_const_fn(self, def_id: DefId) -> Option<Symbol> {
|
|
||||||
if self.is_const_fn_raw(def_id) {
|
|
||||||
let const_stab = self.lookup_const_stability(def_id)?;
|
|
||||||
if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None }
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns `true` if this function must conform to `min_const_fn`
|
|
||||||
pub fn is_min_const_fn(self, def_id: DefId) -> bool {
|
|
||||||
// Bail out if the signature doesn't contain `const`
|
|
||||||
if !self.is_const_fn_raw(def_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.features().staged_api {
|
|
||||||
// In order for a libstd function to be considered min_const_fn
|
|
||||||
// it needs to be stable and have no `rustc_const_unstable` attribute.
|
|
||||||
match self.lookup_const_stability(def_id) {
|
|
||||||
// `rustc_const_unstable` functions don't need to conform.
|
|
||||||
Some(&attr::ConstStability { ref level, .. }) if level.is_unstable() => false,
|
|
||||||
None => {
|
|
||||||
if let Some(stab) = self.lookup_stability(def_id) {
|
|
||||||
if stab.level.is_stable() {
|
|
||||||
self.sess.span_err(
|
|
||||||
self.def_span(def_id),
|
|
||||||
"stable const functions must have either `rustc_const_stable` or \
|
|
||||||
`rustc_const_unstable` attribute",
|
|
||||||
);
|
|
||||||
// While we errored above, because we don't know if we need to conform, we
|
|
||||||
// err on the "safe" side and require min_const_fn.
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
// Unstable functions need not conform to min_const_fn.
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Internal functions are forced to conform to min_const_fn.
|
|
||||||
// Annotate the internal function with a const stability attribute if
|
|
||||||
// you need to use unstable features.
|
|
||||||
// Note: this is an arbitrary choice that does not affect stability or const
|
|
||||||
// safety or anything, it just changes whether we need to annotate some
|
|
||||||
// internal functions with `rustc_const_stable` or with `rustc_const_unstable`
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Everything else needs to conform, because it would be callable from
|
|
||||||
// other `min_const_fn` functions.
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// users enabling the `const_fn` feature gate can do what they want
|
|
||||||
!self.features().const_fn
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers<'_>) {
|
|
||||||
/// Const evaluability whitelist is here to check evaluability at the
|
|
||||||
/// top level beforehand.
|
|
||||||
fn is_const_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> Option<bool> {
|
|
||||||
match tcx.fn_sig(def_id).abi() {
|
|
||||||
Abi::RustIntrinsic | Abi::PlatformIntrinsic => {
|
|
||||||
Some(tcx.lookup_const_stability(def_id).is_some())
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether
|
|
||||||
/// said intrinsic is on the whitelist for being const callable.
|
|
||||||
fn is_const_fn_raw(tcx: TyCtxt<'_>, 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(hir_id);
|
|
||||||
|
|
||||||
if let Some(whitelisted) = is_const_intrinsic(tcx, def_id) {
|
|
||||||
whitelisted
|
|
||||||
} else if let Some(fn_like) = FnLikeNode::from_node(node) {
|
|
||||||
fn_like.constness() == hir::Constness::Const
|
|
||||||
} else if let hir::Node::Ctor(_) = node {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|
||||||
tcx.is_const_fn(def_id)
|
|
||||||
&& match tcx.lookup_const_stability(def_id) {
|
|
||||||
Some(stab) => {
|
|
||||||
if cfg!(debug_assertions) && stab.promotable {
|
|
||||||
let sig = tcx.fn_sig(def_id);
|
|
||||||
assert_eq!(
|
|
||||||
sig.unsafety(),
|
|
||||||
hir::Unsafety::Normal,
|
|
||||||
"don't mark const unsafe fns as promotable",
|
|
||||||
// https://github.com/rust-lang/rust/pull/53851#issuecomment-418760682
|
|
||||||
);
|
|
||||||
}
|
|
||||||
stab.promotable
|
|
||||||
}
|
|
||||||
None => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn const_fn_is_allowed_fn_ptr(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|
||||||
tcx.is_const_fn(def_id)
|
|
||||||
&& tcx
|
|
||||||
.lookup_const_stability(def_id)
|
|
||||||
.map(|stab| stab.allow_const_fn_ptr)
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
*providers = Providers {
|
|
||||||
is_const_fn_raw,
|
|
||||||
is_promotable_const_fn,
|
|
||||||
const_fn_is_allowed_fn_ptr,
|
|
||||||
..*providers
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -97,7 +97,6 @@ pub mod cast;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod codec;
|
pub mod codec;
|
||||||
pub mod _match;
|
pub mod _match;
|
||||||
mod constness;
|
|
||||||
mod erase_regions;
|
mod erase_regions;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod fast_reject;
|
pub mod fast_reject;
|
||||||
|
@ -3318,7 +3317,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
|
||||||
context::provide(providers);
|
context::provide(providers);
|
||||||
erase_regions::provide(providers);
|
erase_regions::provide(providers);
|
||||||
layout::provide(providers);
|
layout::provide(providers);
|
||||||
constness::provide(providers);
|
|
||||||
*providers = ty::query::Providers {
|
*providers = ty::query::Providers {
|
||||||
asyncness,
|
asyncness,
|
||||||
associated_item,
|
associated_item,
|
||||||
|
|
|
@ -9,10 +9,12 @@ use crate::interpret::{intern_const_alloc_recursive, ConstValue, InterpCx};
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod eval_queries;
|
mod eval_queries;
|
||||||
|
mod fn_queries;
|
||||||
mod machine;
|
mod machine;
|
||||||
|
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
pub use eval_queries::*;
|
pub use eval_queries::*;
|
||||||
|
pub use fn_queries::*;
|
||||||
pub use machine::*;
|
pub use machine::*;
|
||||||
|
|
||||||
/// Extracts a field of a (variant of a) const.
|
/// Extracts a field of a (variant of a) const.
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
use rustc::hir::map::blocks::FnLikeNode;
|
||||||
|
use rustc::ty::query::Providers;
|
||||||
|
use rustc::ty::TyCtxt;
|
||||||
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_span::symbol::Symbol;
|
||||||
|
use rustc_target::spec::abi::Abi;
|
||||||
|
use syntax::attr;
|
||||||
|
|
||||||
|
/// Whether the `def_id` counts as const fn in your current crate, considering all active
|
||||||
|
/// feature gates
|
||||||
|
pub fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
|
tcx.is_const_fn_raw(def_id)
|
||||||
|
&& match is_unstable_const_fn(tcx, def_id) {
|
||||||
|
Some(feature_name) => {
|
||||||
|
// has a `rustc_const_unstable` attribute, check whether the user enabled the
|
||||||
|
// corresponding feature gate.
|
||||||
|
tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == feature_name)
|
||||||
|
}
|
||||||
|
// functions without const stability are either stable user written
|
||||||
|
// const fn or the user is using feature gates and we thus don't
|
||||||
|
// care what they do
|
||||||
|
None => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
|
||||||
|
pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
|
||||||
|
if tcx.is_const_fn_raw(def_id) {
|
||||||
|
let const_stab = tcx.lookup_const_stability(def_id)?;
|
||||||
|
if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None }
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if this function must conform to `min_const_fn`
|
||||||
|
pub fn is_min_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
|
// Bail out if the signature doesn't contain `const`
|
||||||
|
if !tcx.is_const_fn_raw(def_id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if tcx.features().staged_api {
|
||||||
|
// In order for a libstd function to be considered min_const_fn
|
||||||
|
// it needs to be stable and have no `rustc_const_unstable` attribute.
|
||||||
|
match tcx.lookup_const_stability(def_id) {
|
||||||
|
// `rustc_const_unstable` functions don't need to conform.
|
||||||
|
Some(&attr::ConstStability { ref level, .. }) if level.is_unstable() => false,
|
||||||
|
None => {
|
||||||
|
if let Some(stab) = tcx.lookup_stability(def_id) {
|
||||||
|
if stab.level.is_stable() {
|
||||||
|
tcx.sess.span_err(
|
||||||
|
tcx.def_span(def_id),
|
||||||
|
"stable const functions must have either `rustc_const_stable` or \
|
||||||
|
`rustc_const_unstable` attribute",
|
||||||
|
);
|
||||||
|
// While we errored above, because we don't know if we need to conform, we
|
||||||
|
// err on the "safe" side and require min_const_fn.
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
// Unstable functions need not conform to min_const_fn.
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Internal functions are forced to conform to min_const_fn.
|
||||||
|
// Annotate the internal function with a const stability attribute if
|
||||||
|
// you need to use unstable features.
|
||||||
|
// Note: this is an arbitrary choice that does not affect stability or const
|
||||||
|
// safety or anything, it just changes whether we need to annotate some
|
||||||
|
// internal functions with `rustc_const_stable` or with `rustc_const_unstable`
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Everything else needs to conform, because it would be callable from
|
||||||
|
// other `min_const_fn` functions.
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// users enabling the `const_fn` feature gate can do what they want
|
||||||
|
!tcx.features().const_fn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn provide(providers: &mut Providers<'_>) {
|
||||||
|
/// Const evaluability whitelist is here to check evaluability at the
|
||||||
|
/// top level beforehand.
|
||||||
|
fn is_const_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> Option<bool> {
|
||||||
|
match tcx.fn_sig(def_id).abi() {
|
||||||
|
Abi::RustIntrinsic | Abi::PlatformIntrinsic => {
|
||||||
|
Some(tcx.lookup_const_stability(def_id).is_some())
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether
|
||||||
|
/// said intrinsic is on the whitelist for being const callable.
|
||||||
|
fn is_const_fn_raw(tcx: TyCtxt<'_>, 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(hir_id);
|
||||||
|
|
||||||
|
if let Some(whitelisted) = is_const_intrinsic(tcx, def_id) {
|
||||||
|
whitelisted
|
||||||
|
} else if let Some(fn_like) = FnLikeNode::from_node(node) {
|
||||||
|
fn_like.constness() == hir::Constness::Const
|
||||||
|
} else if let hir::Node::Ctor(_) = node {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
|
is_const_fn(tcx, def_id)
|
||||||
|
&& match tcx.lookup_const_stability(def_id) {
|
||||||
|
Some(stab) => {
|
||||||
|
if cfg!(debug_assertions) && stab.promotable {
|
||||||
|
let sig = tcx.fn_sig(def_id);
|
||||||
|
assert_eq!(
|
||||||
|
sig.unsafety(),
|
||||||
|
hir::Unsafety::Normal,
|
||||||
|
"don't mark const unsafe fns as promotable",
|
||||||
|
// https://github.com/rust-lang/rust/pull/53851#issuecomment-418760682
|
||||||
|
);
|
||||||
|
}
|
||||||
|
stab.promotable
|
||||||
|
}
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn const_fn_is_allowed_fn_ptr(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
|
is_const_fn(tcx, def_id)
|
||||||
|
&& tcx
|
||||||
|
.lookup_const_stability(def_id)
|
||||||
|
.map(|stab| stab.allow_const_fn_ptr)
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
*providers = Providers {
|
||||||
|
is_const_fn_raw,
|
||||||
|
is_promotable_const_fn,
|
||||||
|
const_fn_is_allowed_fn_ptr,
|
||||||
|
..*providers
|
||||||
|
};
|
||||||
|
}
|
|
@ -52,6 +52,7 @@ use rustc::ty::query::Providers;
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers<'_>) {
|
pub fn provide(providers: &mut Providers<'_>) {
|
||||||
borrow_check::provide(providers);
|
borrow_check::provide(providers);
|
||||||
|
const_eval::provide(providers);
|
||||||
shim::provide(providers);
|
shim::provide(providers);
|
||||||
transform::provide(providers);
|
transform::provide(providers);
|
||||||
monomorphize::partitioning::provide(providers);
|
monomorphize::partitioning::provide(providers);
|
||||||
|
|
|
@ -21,6 +21,7 @@ use super::ops::{self, NonConstOp};
|
||||||
use super::qualifs::{self, HasMutInterior, NeedsDrop};
|
use super::qualifs::{self, HasMutInterior, NeedsDrop};
|
||||||
use super::resolver::FlowSensitiveAnalysis;
|
use super::resolver::FlowSensitiveAnalysis;
|
||||||
use super::{is_lang_panic_fn, ConstKind, Item, Qualif};
|
use super::{is_lang_panic_fn, ConstKind, Item, Qualif};
|
||||||
|
use crate::const_eval::{is_const_fn, is_unstable_const_fn};
|
||||||
use crate::dataflow::{self as old_dataflow, generic as dataflow};
|
use crate::dataflow::{self as old_dataflow, generic as dataflow};
|
||||||
|
|
||||||
pub type IndirectlyMutableResults<'mir, 'tcx> =
|
pub type IndirectlyMutableResults<'mir, 'tcx> =
|
||||||
|
@ -173,7 +174,7 @@ impl Validator<'a, 'mir, 'tcx> {
|
||||||
let Item { tcx, body, def_id, const_kind, .. } = *self.item;
|
let Item { tcx, body, def_id, const_kind, .. } = *self.item;
|
||||||
|
|
||||||
let use_min_const_fn_checks = (const_kind == Some(ConstKind::ConstFn)
|
let use_min_const_fn_checks = (const_kind == Some(ConstKind::ConstFn)
|
||||||
&& tcx.is_min_const_fn(def_id))
|
&& crate::const_eval::is_min_const_fn(tcx, def_id))
|
||||||
&& !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you;
|
&& !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you;
|
||||||
|
|
||||||
if use_min_const_fn_checks {
|
if use_min_const_fn_checks {
|
||||||
|
@ -560,13 +561,13 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// At this point, we are calling a function whose `DefId` is known...
|
// At this point, we are calling a function whose `DefId` is known...
|
||||||
if self.tcx.is_const_fn(def_id) {
|
if is_const_fn(self.tcx, def_id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_lang_panic_fn(self.tcx, def_id) {
|
if is_lang_panic_fn(self.tcx, def_id) {
|
||||||
self.check_op(ops::Panic);
|
self.check_op(ops::Panic);
|
||||||
} else if let Some(feature) = self.tcx.is_unstable_const_fn(def_id) {
|
} else if let Some(feature) = is_unstable_const_fn(self.tcx, def_id) {
|
||||||
// Exempt unstable const fns inside of macros with
|
// Exempt unstable const fns inside of macros with
|
||||||
// `#[allow_internal_unstable]`.
|
// `#[allow_internal_unstable]`.
|
||||||
if !self.span.allows_unstable(feature) {
|
if !self.span.allows_unstable(feature) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ use rustc_span::symbol::{sym, Symbol};
|
||||||
|
|
||||||
use std::ops::Bound;
|
use std::ops::Bound;
|
||||||
|
|
||||||
|
use crate::const_eval::{is_const_fn, is_min_const_fn};
|
||||||
use crate::util;
|
use crate::util;
|
||||||
|
|
||||||
use rustc_error_codes::*;
|
use rustc_error_codes::*;
|
||||||
|
@ -523,7 +524,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult
|
||||||
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
|
||||||
let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) {
|
let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) {
|
||||||
hir::BodyOwnerKind::Closure => (false, false),
|
hir::BodyOwnerKind::Closure => (false, false),
|
||||||
hir::BodyOwnerKind::Fn => (tcx.is_const_fn(def_id), tcx.is_min_const_fn(def_id)),
|
hir::BodyOwnerKind::Fn => (is_const_fn(tcx, def_id), is_min_const_fn(tcx, def_id)),
|
||||||
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false),
|
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false),
|
||||||
};
|
};
|
||||||
let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env);
|
let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env);
|
||||||
|
|
|
@ -29,6 +29,7 @@ use rustc_target::spec::abi::Abi;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::{iter, mem, usize};
|
use std::{iter, mem, usize};
|
||||||
|
|
||||||
|
use crate::const_eval::{is_const_fn, is_unstable_const_fn};
|
||||||
use crate::transform::check_consts::{is_lang_panic_fn, qualifs, ConstKind, Item};
|
use crate::transform::check_consts::{is_lang_panic_fn, qualifs, ConstKind, Item};
|
||||||
use crate::transform::{MirPass, MirSource};
|
use crate::transform::{MirPass, MirSource};
|
||||||
|
|
||||||
|
@ -702,8 +703,8 @@ impl<'tcx> Validator<'_, 'tcx> {
|
||||||
|
|
||||||
let is_const_fn = match fn_ty.kind {
|
let is_const_fn = match fn_ty.kind {
|
||||||
ty::FnDef(def_id, _) => {
|
ty::FnDef(def_id, _) => {
|
||||||
self.tcx.is_const_fn(def_id)
|
is_const_fn(self.tcx, def_id)
|
||||||
|| self.tcx.is_unstable_const_fn(def_id).is_some()
|
|| is_unstable_const_fn(self.tcx, def_id).is_some()
|
||||||
|| is_lang_panic_fn(self.tcx, self.def_id)
|
|| is_lang_panic_fn(self.tcx, self.def_id)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
@ -327,7 +327,7 @@ fn check_terminator(
|
||||||
TerminatorKind::Call { func, args, from_hir_call: _, destination: _, cleanup: _ } => {
|
TerminatorKind::Call { func, args, from_hir_call: _, destination: _, cleanup: _ } => {
|
||||||
let fn_ty = func.ty(body, tcx);
|
let fn_ty = func.ty(body, tcx);
|
||||||
if let ty::FnDef(def_id, _) = fn_ty.kind {
|
if let ty::FnDef(def_id, _) = fn_ty.kind {
|
||||||
if !tcx.is_min_const_fn(def_id) {
|
if !crate::const_eval::is_min_const_fn(tcx, def_id) {
|
||||||
return Err((
|
return Err((
|
||||||
span,
|
span,
|
||||||
format!(
|
format!(
|
||||||
|
|
|
@ -9,6 +9,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::Mutability;
|
use rustc_hir::Mutability;
|
||||||
use rustc_metadata::creader::LoadedMacro;
|
use rustc_metadata::creader::LoadedMacro;
|
||||||
|
use rustc_mir::const_eval::is_min_const_fn;
|
||||||
use rustc_span::hygiene::MacroKind;
|
use rustc_span::hygiene::MacroKind;
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
@ -212,7 +213,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
|
||||||
let sig = cx.tcx.fn_sig(did);
|
let sig = cx.tcx.fn_sig(did);
|
||||||
|
|
||||||
let constness =
|
let constness =
|
||||||
if cx.tcx.is_min_const_fn(did) { hir::Constness::Const } else { hir::Constness::NotConst };
|
if is_min_const_fn(cx.tcx, did) { hir::Constness::Const } else { hir::Constness::NotConst };
|
||||||
let asyncness = cx.tcx.asyncness(did);
|
let asyncness = cx.tcx.asyncness(did);
|
||||||
let predicates = cx.tcx.predicates_of(did);
|
let predicates = cx.tcx.predicates_of(did);
|
||||||
let (generics, decl) = clean::enter_impl_trait(cx, || {
|
let (generics, decl) = clean::enter_impl_trait(cx, || {
|
||||||
|
|
|
@ -21,6 +21,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, DefKind, Res};
|
use rustc_hir::def::{CtorKind, DefKind, Res};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
|
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
use rustc_index::vec::{Idx, IndexVec};
|
||||||
|
use rustc_mir::const_eval::is_min_const_fn;
|
||||||
use rustc_span::hygiene::MacroKind;
|
use rustc_span::hygiene::MacroKind;
|
||||||
use rustc_span::symbol::{kw, sym};
|
use rustc_span::symbol::{kw, sym};
|
||||||
use rustc_span::{self, Pos};
|
use rustc_span::{self, Pos};
|
||||||
|
@ -895,7 +896,7 @@ impl Clean<Item> for doctree::Function<'_> {
|
||||||
enter_impl_trait(cx, || (self.generics.clean(cx), (self.decl, self.body).clean(cx)));
|
enter_impl_trait(cx, || (self.generics.clean(cx), (self.decl, self.body).clean(cx)));
|
||||||
|
|
||||||
let did = cx.tcx.hir().local_def_id(self.id);
|
let did = cx.tcx.hir().local_def_id(self.id);
|
||||||
let constness = if cx.tcx.is_min_const_fn(did) {
|
let constness = if is_min_const_fn(cx.tcx, did) {
|
||||||
hir::Constness::Const
|
hir::Constness::Const
|
||||||
} else {
|
} else {
|
||||||
hir::Constness::NotConst
|
hir::Constness::NotConst
|
||||||
|
@ -1187,7 +1188,7 @@ impl Clean<Item> for ty::AssocItem {
|
||||||
};
|
};
|
||||||
let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
|
let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
|
||||||
if provided {
|
if provided {
|
||||||
let constness = if cx.tcx.is_min_const_fn(self.def_id) {
|
let constness = if is_min_const_fn(cx.tcx, self.def_id) {
|
||||||
hir::Constness::Const
|
hir::Constness::Const
|
||||||
} else {
|
} else {
|
||||||
hir::Constness::NotConst
|
hir::Constness::NotConst
|
||||||
|
|
|
@ -32,6 +32,7 @@ extern crate rustc_interface;
|
||||||
extern crate rustc_lexer;
|
extern crate rustc_lexer;
|
||||||
extern crate rustc_lint;
|
extern crate rustc_lint;
|
||||||
extern crate rustc_metadata;
|
extern crate rustc_metadata;
|
||||||
|
extern crate rustc_mir;
|
||||||
extern crate rustc_parse;
|
extern crate rustc_parse;
|
||||||
extern crate rustc_resolve;
|
extern crate rustc_resolve;
|
||||||
extern crate rustc_span as rustc_span;
|
extern crate rustc_span as rustc_span;
|
||||||
|
|
Loading…
Reference in New Issue