Skip to content

Commit c1c09be

Browse files
committedJan 8, 2020
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.
1 parent 588296a commit c1c09be

File tree

11 files changed

+86
-84
lines changed

11 files changed

+86
-84
lines changed
 

‎src/librustc/ty/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ pub mod cast;
9797
#[macro_use]
9898
pub mod codec;
9999
pub mod _match;
100-
mod constness;
101100
mod erase_regions;
102101
pub mod error;
103102
pub mod fast_reject;
@@ -3318,7 +3317,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
33183317
context::provide(providers);
33193318
erase_regions::provide(providers);
33203319
layout::provide(providers);
3321-
constness::provide(providers);
33223320
*providers = ty::query::Providers {
33233321
asyncness,
33243322
associated_item,

‎src/librustc_mir/const_eval.rs

+2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ use crate::interpret::{intern_const_alloc_recursive, ConstValue, InterpCx};
99

1010
mod error;
1111
mod eval_queries;
12+
mod fn_queries;
1213
mod machine;
1314

1415
pub use error::*;
1516
pub use eval_queries::*;
17+
pub use fn_queries::*;
1618
pub use machine::*;
1719

1820
/// Extracts a field of a (variant of a) const.

‎src/librustc_mir/const_eval/fn_queries.rs

+67-72
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,84 @@
1-
use crate::hir::map::blocks::FnLikeNode;
2-
use crate::ty::query::Providers;
3-
use crate::ty::TyCtxt;
1+
use rustc::hir::map::blocks::FnLikeNode;
2+
use rustc::ty::query::Providers;
3+
use rustc::ty::TyCtxt;
44
use rustc_hir as hir;
55
use rustc_hir::def_id::DefId;
66
use rustc_span::symbol::Symbol;
77
use rustc_target::spec::abi::Abi;
88
use syntax::attr;
99

10-
impl<'tcx> TyCtxt<'tcx> {
11-
/// Whether the `def_id` counts as const fn in your current crate, considering all active
12-
/// feature gates
13-
pub fn is_const_fn(self, def_id: DefId) -> bool {
14-
self.is_const_fn_raw(def_id)
15-
&& match self.is_unstable_const_fn(def_id) {
16-
Some(feature_name) => {
17-
// has a `rustc_const_unstable` attribute, check whether the user enabled the
18-
// corresponding feature gate.
19-
self.features()
20-
.declared_lib_features
21-
.iter()
22-
.any(|&(sym, _)| sym == feature_name)
23-
}
24-
// functions without const stability are either stable user written
25-
// const fn or the user is using feature gates and we thus don't
26-
// care what they do
27-
None => true,
10+
/// Whether the `def_id` counts as const fn in your current crate, considering all active
11+
/// feature gates
12+
pub fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
13+
tcx.is_const_fn_raw(def_id)
14+
&& match is_unstable_const_fn(tcx, def_id) {
15+
Some(feature_name) => {
16+
// has a `rustc_const_unstable` attribute, check whether the user enabled the
17+
// corresponding feature gate.
18+
tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == feature_name)
2819
}
29-
}
30-
31-
/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
32-
pub fn is_unstable_const_fn(self, def_id: DefId) -> Option<Symbol> {
33-
if self.is_const_fn_raw(def_id) {
34-
let const_stab = self.lookup_const_stability(def_id)?;
35-
if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None }
36-
} else {
37-
None
20+
// functions without const stability are either stable user written
21+
// const fn or the user is using feature gates and we thus don't
22+
// care what they do
23+
None => true,
3824
}
25+
}
26+
27+
/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
28+
pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
29+
if tcx.is_const_fn_raw(def_id) {
30+
let const_stab = tcx.lookup_const_stability(def_id)?;
31+
if const_stab.level.is_unstable() { Some(const_stab.feature) } else { None }
32+
} else {
33+
None
3934
}
35+
}
4036

41-
/// Returns `true` if this function must conform to `min_const_fn`
42-
pub fn is_min_const_fn(self, def_id: DefId) -> bool {
43-
// Bail out if the signature doesn't contain `const`
44-
if !self.is_const_fn_raw(def_id) {
45-
return false;
46-
}
37+
/// Returns `true` if this function must conform to `min_const_fn`
38+
pub fn is_min_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
39+
// Bail out if the signature doesn't contain `const`
40+
if !tcx.is_const_fn_raw(def_id) {
41+
return false;
42+
}
4743

48-
if self.features().staged_api {
49-
// In order for a libstd function to be considered min_const_fn
50-
// it needs to be stable and have no `rustc_const_unstable` attribute.
51-
match self.lookup_const_stability(def_id) {
52-
// `rustc_const_unstable` functions don't need to conform.
53-
Some(&attr::ConstStability { ref level, .. }) if level.is_unstable() => false,
54-
None => {
55-
if let Some(stab) = self.lookup_stability(def_id) {
56-
if stab.level.is_stable() {
57-
self.sess.span_err(
58-
self.def_span(def_id),
59-
"stable const functions must have either `rustc_const_stable` or \
60-
`rustc_const_unstable` attribute",
61-
);
62-
// While we errored above, because we don't know if we need to conform, we
63-
// err on the "safe" side and require min_const_fn.
64-
true
65-
} else {
66-
// Unstable functions need not conform to min_const_fn.
67-
false
68-
}
69-
} else {
70-
// Internal functions are forced to conform to min_const_fn.
71-
// Annotate the internal function with a const stability attribute if
72-
// you need to use unstable features.
73-
// Note: this is an arbitrary choice that does not affect stability or const
74-
// safety or anything, it just changes whether we need to annotate some
75-
// internal functions with `rustc_const_stable` or with `rustc_const_unstable`
44+
if tcx.features().staged_api {
45+
// In order for a libstd function to be considered min_const_fn
46+
// it needs to be stable and have no `rustc_const_unstable` attribute.
47+
match tcx.lookup_const_stability(def_id) {
48+
// `rustc_const_unstable` functions don't need to conform.
49+
Some(&attr::ConstStability { ref level, .. }) if level.is_unstable() => false,
50+
None => {
51+
if let Some(stab) = tcx.lookup_stability(def_id) {
52+
if stab.level.is_stable() {
53+
tcx.sess.span_err(
54+
tcx.def_span(def_id),
55+
"stable const functions must have either `rustc_const_stable` or \
56+
`rustc_const_unstable` attribute",
57+
);
58+
// While we errored above, because we don't know if we need to conform, we
59+
// err on the "safe" side and require min_const_fn.
7660
true
61+
} else {
62+
// Unstable functions need not conform to min_const_fn.
63+
false
7764
}
65+
} else {
66+
// Internal functions are forced to conform to min_const_fn.
67+
// Annotate the internal function with a const stability attribute if
68+
// you need to use unstable features.
69+
// Note: this is an arbitrary choice that does not affect stability or const
70+
// safety or anything, it just changes whether we need to annotate some
71+
// internal functions with `rustc_const_stable` or with `rustc_const_unstable`
72+
true
7873
}
79-
// Everything else needs to conform, because it would be callable from
80-
// other `min_const_fn` functions.
81-
_ => true,
8274
}
83-
} else {
84-
// users enabling the `const_fn` feature gate can do what they want
85-
!self.features().const_fn
75+
// Everything else needs to conform, because it would be callable from
76+
// other `min_const_fn` functions.
77+
_ => true,
8678
}
79+
} else {
80+
// users enabling the `const_fn` feature gate can do what they want
81+
!tcx.features().const_fn
8782
}
8883
}
8984

@@ -121,7 +116,7 @@ pub fn provide(providers: &mut Providers<'_>) {
121116
}
122117

123118
fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
124-
tcx.is_const_fn(def_id)
119+
is_const_fn(tcx, def_id)
125120
&& match tcx.lookup_const_stability(def_id) {
126121
Some(stab) => {
127122
if cfg!(debug_assertions) && stab.promotable {
@@ -140,7 +135,7 @@ pub fn provide(providers: &mut Providers<'_>) {
140135
}
141136

142137
fn const_fn_is_allowed_fn_ptr(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
143-
tcx.is_const_fn(def_id)
138+
is_const_fn(tcx, def_id)
144139
&& tcx
145140
.lookup_const_stability(def_id)
146141
.map(|stab| stab.allow_const_fn_ptr)

‎src/librustc_mir/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ use rustc::ty::query::Providers;
5454

5555
pub fn provide(providers: &mut Providers<'_>) {
5656
borrow_check::provide(providers);
57+
const_eval::provide(providers);
5758
shim::provide(providers);
5859
transform::provide(providers);
5960
monomorphize::partitioning::provide(providers);

‎src/librustc_mir/transform/check_consts/validation.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use super::ops::{self, NonConstOp};
2020
use super::qualifs::{self, HasMutInterior, NeedsDrop};
2121
use super::resolver::FlowSensitiveAnalysis;
2222
use super::{is_lang_panic_fn, ConstKind, Item, Qualif};
23+
use crate::const_eval::{is_const_fn, is_unstable_const_fn};
2324
use crate::dataflow::{self as old_dataflow, generic as dataflow};
2425

2526
pub type IndirectlyMutableResults<'mir, 'tcx> =
@@ -172,7 +173,7 @@ impl Validator<'a, 'mir, 'tcx> {
172173
let Item { tcx, body, def_id, const_kind, .. } = *self.item;
173174

174175
let use_min_const_fn_checks = (const_kind == Some(ConstKind::ConstFn)
175-
&& tcx.is_min_const_fn(def_id))
176+
&& crate::const_eval::is_min_const_fn(tcx, def_id))
176177
&& !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you;
177178

178179
if use_min_const_fn_checks {
@@ -559,13 +560,13 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
559560
};
560561

561562
// At this point, we are calling a function whose `DefId` is known...
562-
if self.tcx.is_const_fn(def_id) {
563+
if is_const_fn(self.tcx, def_id) {
563564
return;
564565
}
565566

566567
if is_lang_panic_fn(self.tcx, def_id) {
567568
self.check_op(ops::Panic);
568-
} else if let Some(feature) = self.tcx.is_unstable_const_fn(def_id) {
569+
} else if let Some(feature) = is_unstable_const_fn(self.tcx, def_id) {
569570
// Exempt unstable const fns inside of macros with
570571
// `#[allow_internal_unstable]`.
571572
if !self.span.allows_unstable(feature) {

‎src/librustc_mir/transform/check_unsafety.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_span::symbol::{sym, Symbol};
1313

1414
use std::ops::Bound;
1515

16+
use crate::const_eval::{is_const_fn, is_min_const_fn};
1617
use crate::util;
1718

1819
use rustc_error_codes::*;
@@ -522,7 +523,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult
522523
let id = tcx.hir().as_local_hir_id(def_id).unwrap();
523524
let (const_context, min_const_fn) = match tcx.hir().body_owner_kind(id) {
524525
hir::BodyOwnerKind::Closure => (false, false),
525-
hir::BodyOwnerKind::Fn => (tcx.is_const_fn(def_id), tcx.is_min_const_fn(def_id)),
526+
hir::BodyOwnerKind::Fn => (is_const_fn(tcx, def_id), is_min_const_fn(tcx, def_id)),
526527
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => (true, false),
527528
};
528529
let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env);

‎src/librustc_mir/transform/promote_consts.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_target::spec::abi::Abi;
2929
use std::cell::Cell;
3030
use std::{iter, mem, usize};
3131

32+
use crate::const_eval::{is_const_fn, is_unstable_const_fn};
3233
use crate::transform::check_consts::{is_lang_panic_fn, qualifs, ConstKind, Item};
3334
use crate::transform::{MirPass, MirSource};
3435

@@ -702,8 +703,8 @@ impl<'tcx> Validator<'_, 'tcx> {
702703

703704
let is_const_fn = match fn_ty.kind {
704705
ty::FnDef(def_id, _) => {
705-
self.tcx.is_const_fn(def_id)
706-
|| self.tcx.is_unstable_const_fn(def_id).is_some()
706+
is_const_fn(self.tcx, def_id)
707+
|| is_unstable_const_fn(self.tcx, def_id).is_some()
707708
|| is_lang_panic_fn(self.tcx, self.def_id)
708709
}
709710
_ => false,

‎src/librustc_mir/transform/qualify_min_const_fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ fn check_terminator(
327327
TerminatorKind::Call { func, args, from_hir_call: _, destination: _, cleanup: _ } => {
328328
let fn_ty = func.ty(body, tcx);
329329
if let ty::FnDef(def_id, _) = fn_ty.kind {
330-
if !tcx.is_min_const_fn(def_id) {
330+
if !crate::const_eval::is_min_const_fn(tcx, def_id) {
331331
return Err((
332332
span,
333333
format!(

‎src/librustdoc/clean/inline.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
99
use rustc_hir::def_id::DefId;
1010
use rustc_hir::Mutability;
1111
use rustc_metadata::creader::LoadedMacro;
12+
use rustc_mir::const_eval::is_min_const_fn;
1213
use rustc_span::hygiene::MacroKind;
1314
use rustc_span::symbol::sym;
1415
use rustc_span::Span;
@@ -212,7 +213,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
212213
let sig = cx.tcx.fn_sig(did);
213214

214215
let constness =
215-
if cx.tcx.is_min_const_fn(did) { hir::Constness::Const } else { hir::Constness::NotConst };
216+
if is_min_const_fn(cx.tcx, did) { hir::Constness::Const } else { hir::Constness::NotConst };
216217
let asyncness = cx.tcx.asyncness(did);
217218
let predicates = cx.tcx.predicates_of(did);
218219
let (generics, decl) = clean::enter_impl_trait(cx, || {

‎src/librustdoc/clean/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_hir as hir;
2121
use rustc_hir::def::{CtorKind, DefKind, Res};
2222
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
2323
use rustc_index::vec::{Idx, IndexVec};
24+
use rustc_mir::const_eval::is_min_const_fn;
2425
use rustc_span::hygiene::MacroKind;
2526
use rustc_span::symbol::{kw, sym};
2627
use rustc_span::{self, Pos};
@@ -895,7 +896,7 @@ impl Clean<Item> for doctree::Function<'_> {
895896
enter_impl_trait(cx, || (self.generics.clean(cx), (self.decl, self.body).clean(cx)));
896897

897898
let did = cx.tcx.hir().local_def_id(self.id);
898-
let constness = if cx.tcx.is_min_const_fn(did) {
899+
let constness = if is_min_const_fn(cx.tcx, did) {
899900
hir::Constness::Const
900901
} else {
901902
hir::Constness::NotConst
@@ -1187,7 +1188,7 @@ impl Clean<Item> for ty::AssocItem {
11871188
};
11881189
let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
11891190
if provided {
1190-
let constness = if cx.tcx.is_min_const_fn(self.def_id) {
1191+
let constness = if is_min_const_fn(cx.tcx, self.def_id) {
11911192
hir::Constness::Const
11921193
} else {
11931194
hir::Constness::NotConst

‎src/librustdoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ extern crate rustc_interface;
3232
extern crate rustc_lexer;
3333
extern crate rustc_lint;
3434
extern crate rustc_metadata;
35+
extern crate rustc_mir;
3536
extern crate rustc_parse;
3637
extern crate rustc_resolve;
3738
extern crate rustc_span as rustc_span;

0 commit comments

Comments
 (0)
Please sign in to comment.