Skip to content

Commit 8849ac6

Browse files
committed
tcx.is_const_fn doesn't work the way it is described, remove it
Then we can rename the _raw functions to drop their suffix, and instead explicitly use is_stable_const_fn for the few cases where that is really what you want.
1 parent 36dda45 commit 8849ac6

File tree

21 files changed

+55
-64
lines changed

21 files changed

+55
-64
lines changed

compiler/rustc_const_eval/src/check_consts/check.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
731731
}
732732

733733
// Trait functions are not `const fn` so we have to skip them here.
734-
if !tcx.is_const_fn_raw(callee) && !is_trait {
734+
if !tcx.is_const_fn(callee) && !is_trait {
735735
self.check_op(ops::FnCallNonConst {
736736
caller,
737737
callee,

compiler/rustc_const_eval/src/check_consts/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub fn is_safe_to_expose_on_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> b
112112
}
113113

114114
// Const-stability is only relevant for `const fn`.
115-
assert!(tcx.is_const_fn_raw(def_id));
115+
assert!(tcx.is_const_fn(def_id));
116116

117117
match tcx.lookup_const_stability(def_id) {
118118
None => {

compiler/rustc_const_eval/src/check_consts/ops.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
122122

123123
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
124124
// FIXME(effects) revisit this
125-
if !tcx.is_const_trait_impl_raw(data.impl_def_id) {
125+
if !tcx.is_const_trait_impl(data.impl_def_id) {
126126
let span = tcx.def_span(data.impl_def_id);
127127
err.subdiagnostic(errors::NonConstImplNote { span });
128128
}
@@ -174,7 +174,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
174174
let note = match self_ty.kind() {
175175
FnDef(def_id, ..) => {
176176
let span = tcx.def_span(*def_id);
177-
if ccx.tcx.is_const_fn_raw(*def_id) {
177+
if ccx.tcx.is_const_fn(*def_id) {
178178
span_bug!(span, "calling const FnDef errored when it shouldn't");
179179
}
180180

compiler/rustc_const_eval/src/const_eval/machine.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,8 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
431431
// sensitive check here. But we can at least rule out functions that are not const at
432432
// all. That said, we have to allow calling functions inside a trait marked with
433433
// #[const_trait]. These *are* const-checked!
434-
// FIXME: why does `is_const_fn_raw` not classify them as const?
435-
if (!ecx.tcx.is_const_fn_raw(def) && !ecx.tcx.is_const_default_method(def))
434+
// FIXME(effects): why does `is_const_fn` not classify them as const?
435+
if (!ecx.tcx.is_const_fn(def) && !ecx.tcx.is_const_default_method(def))
436436
|| ecx.tcx.has_attr(def, sym::rustc_do_not_const_check)
437437
{
438438
// We certainly do *not* want to actually call the fn

compiler/rustc_hir_analysis/src/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai
15971597
impl_.of_trait.as_ref().map(|ast_trait_ref| {
15981598
let selfty = tcx.type_of(def_id).instantiate_identity();
15991599

1600-
check_impl_constness(tcx, tcx.is_const_trait_impl_raw(def_id.to_def_id()), ast_trait_ref);
1600+
check_impl_constness(tcx, tcx.is_const_trait_impl(def_id.to_def_id()), ast_trait_ref);
16011601

16021602
let trait_ref = icx.lowerer().lower_impl_trait_ref(ast_trait_ref, selfty);
16031603

compiler/rustc_hir_typeck/src/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
537537
//
538538
// This check is here because there is currently no way to express a trait bound for `FnDef` types only.
539539
if let ty::FnDef(def_id, _args) = *arg_ty.kind() {
540-
if idx == 0 && !self.tcx.is_const_fn_raw(def_id) {
540+
if idx == 0 && !self.tcx.is_const_fn(def_id) {
541541
self.dcx().emit_err(errors::ConstSelectMustBeConst { span });
542542
}
543543
} else {

compiler/rustc_hir_typeck/src/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1751,7 +1751,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17511751
// to tell them that in the diagnostic. Does not affect typeck.
17521752
let is_constable = match element.kind {
17531753
hir::ExprKind::Call(func, _args) => match *self.node_ty(func.hir_id).kind() {
1754-
ty::FnDef(def_id, _) if tcx.is_const_fn(def_id) => traits::IsConstable::Fn,
1754+
ty::FnDef(def_id, _) if tcx.is_stable_const_fn(def_id) => traits::IsConstable::Fn,
17551755
_ => traits::IsConstable::No,
17561756
},
17571757
hir::ExprKind::Path(qpath) => {

compiler/rustc_metadata/src/rmeta/encoder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ fn should_encode_mir(
10811081
&& (generics.requires_monomorphization(tcx)
10821082
|| tcx.cross_crate_inlinable(def_id)));
10831083
// The function has a `const` modifier or is in a `#[const_trait]`.
1084-
let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id())
1084+
let is_const_fn = tcx.is_const_fn(def_id.to_def_id())
10851085
|| tcx.is_const_default_method(def_id.to_def_id());
10861086
(is_const_fn, opt)
10871087
}

compiler/rustc_middle/src/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ impl<'hir> Map<'hir> {
329329
BodyOwnerKind::Static(mutability) => ConstContext::Static(mutability),
330330

331331
BodyOwnerKind::Fn if self.tcx.is_constructor(def_id) => return None,
332-
BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn_raw(def_id) => {
332+
BodyOwnerKind::Fn | BodyOwnerKind::Closure if self.tcx.is_const_fn(def_id) => {
333333
ConstContext::ConstFn
334334
}
335335
BodyOwnerKind::Fn if self.tcx.is_const_default_method(def_id) => ConstContext::ConstFn,

compiler/rustc_middle/src/mir/graphviz.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ where
1717
let mirs = def_ids
1818
.iter()
1919
.flat_map(|def_id| {
20-
if tcx.is_const_fn_raw(*def_id) {
20+
if tcx.is_const_fn(*def_id) {
2121
vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)]
2222
} else {
2323
vec![tcx.instance_mir(ty::InstanceKind::Item(*def_id))]

compiler/rustc_middle/src/mir/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ pub fn write_mir_pretty<'tcx>(
317317
};
318318

319319
// For `const fn` we want to render both the optimized MIR and the MIR for ctfe.
320-
if tcx.is_const_fn_raw(def_id) {
320+
if tcx.is_const_fn(def_id) {
321321
render_body(w, tcx.optimized_mir(def_id))?;
322322
writeln!(w)?;
323323
writeln!(w, "// MIR FOR CTFE")?;

compiler/rustc_middle/src/query/mod.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -741,12 +741,11 @@ rustc_queries! {
741741
desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) }
742742
}
743743

744-
/// Returns `true` if this is a const fn, use the `is_const_fn` to know whether your crate
745-
/// actually sees it as const fn (e.g., the const-fn-ness might be unstable and you might
746-
/// not have the feature gate active).
744+
/// Returns `true` if this is a const fn / const impl.
747745
///
748746
/// **Do not call this function manually.** It is only meant to cache the base data for the
749-
/// `is_const_fn` function. Consider using `is_const_fn` or `is_const_fn_raw` instead.
747+
/// higher-level functions. Consider using `is_const_fn` or `is_const_trait_impl` instead.
748+
/// Also note that neither of them takes into account feature gates and stability.
750749
query constness(key: DefId) -> hir::Constness {
751750
desc { |tcx| "checking if item is const: `{}`", tcx.def_path_str(key) }
752751
separate_provide_extern

compiler/rustc_middle/src/ty/context.rs

+13-28
Original file line numberDiff line numberDiff line change
@@ -3120,39 +3120,24 @@ impl<'tcx> TyCtxt<'tcx> {
31203120
}
31213121
}
31223122

3123-
/// Whether the `def_id` counts as const fn in the current crate, considering all active
3124-
/// feature gates
3125-
pub fn is_const_fn(self, def_id: DefId) -> bool {
3126-
if self.is_const_fn_raw(def_id) {
3127-
match self.lookup_const_stability(def_id) {
3128-
Some(stability) if stability.is_const_unstable() => {
3129-
// has a `rustc_const_unstable` attribute, check whether the user enabled the
3130-
// corresponding feature gate.
3131-
stability.feature.is_some_and(|f| self.features().enabled(f))
3132-
}
3133-
// functions without const stability are either stable user written
3134-
// const fn or the user is using feature gates and we thus don't
3135-
// care what they do
3136-
_ => true,
3123+
/// Whether `def_id` is a stable const fn (i.e., doesn't need any feature gates to be called).
3124+
///
3125+
/// When this is `false`, the function may still be callable as a `const fn` due to features
3126+
/// being enabled!
3127+
pub fn is_stable_const_fn(self, def_id: DefId) -> bool {
3128+
self.is_const_fn(def_id)
3129+
&& match self.lookup_const_stability(def_id) {
3130+
None => true, // a fn in a non-staged_api crate
3131+
Some(stability) if stability.is_const_stable() => true,
3132+
_ => false,
31373133
}
3138-
} else {
3139-
false
3140-
}
31413134
}
31423135

31433136
// FIXME(effects): Please remove this. It's a footgun.
31443137
/// Whether the trait impl is marked const. This does not consider stability or feature gates.
3145-
pub fn is_const_trait_impl_raw(self, def_id: DefId) -> bool {
3146-
let Some(local_def_id) = def_id.as_local() else { return false };
3147-
let node = self.hir_node_by_def_id(local_def_id);
3148-
3149-
matches!(
3150-
node,
3151-
hir::Node::Item(hir::Item {
3152-
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
3153-
..
3154-
}) if matches!(constness, hir::Constness::Const)
3155-
)
3138+
pub fn is_const_trait_impl(self, def_id: DefId) -> bool {
3139+
self.def_kind(def_id) == DefKind::Impl { of_trait: true }
3140+
&& self.constness(def_id) == hir::Constness::Const
31563141
}
31573142

31583143
pub fn intrinsic(self, def_id: impl IntoQueryParam<DefId> + Copy) -> Option<ty::IntrinsicDef> {

compiler/rustc_middle/src/ty/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1995,8 +1995,11 @@ impl<'tcx> TyCtxt<'tcx> {
19951995
(ident, scope)
19961996
}
19971997

1998+
/// Checks whether this is a `const fn`. Returns `false` for non-functions.
1999+
///
2000+
/// Even if this returns `true`, constness may still be unstable!
19982001
#[inline]
1999-
pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
2002+
pub fn is_const_fn(self, def_id: DefId) -> bool {
20002003
matches!(
20012004
self.def_kind(def_id),
20022005
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Closure

compiler/rustc_mir_transform/src/promote_consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ impl<'tcx> Validator<'_, 'tcx> {
673673
}
674674
// Make sure the callee is a `const fn`.
675675
let is_const_fn = match *fn_ty.kind() {
676-
ty::FnDef(def_id, _) => self.tcx.is_const_fn_raw(def_id),
676+
ty::FnDef(def_id, _) => self.tcx.is_const_fn(def_id),
677677
_ => false,
678678
};
679679
if !is_const_fn {

compiler/rustc_passes/src/check_attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1997,7 +1997,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19971997
) {
19981998
match target {
19991999
Target::Fn | Target::Method(_)
2000-
if self.tcx.is_const_fn_raw(hir_id.expect_owner().to_def_id()) => {}
2000+
if self.tcx.is_const_fn(hir_id.expect_owner().to_def_id()) => {}
20012001
// FIXME(#80564): We permit struct fields and match arms to have an
20022002
// `#[allow_internal_unstable]` attribute with just a lint, because we previously
20032003
// erroneously allowed it and some crates used it accidentally, to be compatible

compiler/rustc_passes/src/stability.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
179179
// their ABI; `fn_sig.abi` is *not* correct for foreign functions.
180180
&& !is_foreign_item
181181
&& const_stab.is_some()
182-
&& (!self.in_trait_impl || !self.tcx.is_const_fn_raw(def_id.to_def_id()))
182+
&& (!self.in_trait_impl || !self.tcx.is_const_fn(def_id.to_def_id()))
183183
{
184184
self.tcx.dcx().emit_err(errors::MissingConstErr { fn_sig_span: fn_sig.span });
185185
}
@@ -597,8 +597,8 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
597597
return;
598598
}
599599

600-
let is_const = self.tcx.is_const_fn_raw(def_id.to_def_id())
601-
|| self.tcx.is_const_trait_impl_raw(def_id.to_def_id());
600+
let is_const = self.tcx.is_const_fn(def_id.to_def_id())
601+
|| self.tcx.is_const_trait_impl(def_id.to_def_id());
602602
let is_stable =
603603
self.tcx.lookup_stability(def_id).is_some_and(|stability| stability.level.is_stable());
604604
let missing_const_stability_attribute =
@@ -820,7 +820,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
820820
// `#![feature(const_trait_impl)]` is unstable, so any impl declared stable
821821
// needs to have an error emitted.
822822
if features.const_trait_impl()
823-
&& self.tcx.is_const_trait_impl_raw(item.owner_id.to_def_id())
823+
&& self.tcx.is_const_trait_impl(item.owner_id.to_def_id())
824824
&& const_stab.is_some_and(|(stab, _)| stab.is_const_stable())
825825
{
826826
self.tcx.dcx().emit_err(errors::TraitImplConstStable { span: item.span });

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
393393
let self_ty = obligation.self_ty().skip_binder();
394394
match *self_ty.kind() {
395395
ty::Closure(def_id, _) => {
396-
let is_const = self.tcx().is_const_fn_raw(def_id);
396+
let is_const = self.tcx().is_const_fn(def_id);
397397
debug!(?kind, ?obligation, "assemble_unboxed_candidates");
398398
match self.infcx.closure_kind(self_ty) {
399399
Some(closure_kind) => {
@@ -413,7 +413,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
413413
}
414414
ty::CoroutineClosure(def_id, args) => {
415415
let args = args.as_coroutine_closure();
416-
let is_const = self.tcx().is_const_fn_raw(def_id);
416+
let is_const = self.tcx().is_const_fn(def_id);
417417
if let Some(closure_kind) = self.infcx.closure_kind(self_ty)
418418
// Ambiguity if upvars haven't been constrained yet
419419
&& !args.tupled_upvars_ty().is_ty_var()

src/librustdoc/clean/types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ impl Item {
640640
asyncness: ty::Asyncness,
641641
) -> hir::FnHeader {
642642
let sig = tcx.fn_sig(def_id).skip_binder();
643-
let constness = if tcx.is_const_fn_raw(def_id) {
643+
let constness = if tcx.is_const_fn(def_id) {
644644
hir::Constness::Const
645645
} else {
646646
hir::Constness::NotConst
@@ -662,7 +662,7 @@ impl Item {
662662
safety
663663
},
664664
abi,
665-
constness: if tcx.is_const_fn_raw(def_id) {
665+
constness: if tcx.is_const_fn(def_id) {
666666
hir::Constness::Const
667667
} else {
668668
hir::Constness::NotConst

src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ fn check_terminator<'tcx>(
334334
| TerminatorKind::TailCall { func, args, fn_span: _ } => {
335335
let fn_ty = func.ty(body, tcx);
336336
if let ty::FnDef(fn_def_id, _) = *fn_ty.kind() {
337-
if !is_const_fn(tcx, fn_def_id, msrv) {
337+
if !is_stable_const_fn(tcx, fn_def_id, msrv) {
338338
return Err((
339339
span,
340340
format!(
@@ -377,12 +377,12 @@ fn check_terminator<'tcx>(
377377
}
378378
}
379379

380-
fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
380+
fn is_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
381381
tcx.is_const_fn(def_id)
382-
&& tcx.lookup_const_stability(def_id).map_or(true, |const_stab| {
382+
&& tcx.lookup_const_stability(def_id).is_none_or(|const_stab| {
383383
if let rustc_attr::StabilityLevel::Stable { since, .. } = const_stab.level {
384384
// Checking MSRV is manually necessary because `rustc` has no such concept. This entire
385-
// function could be removed if `rustc` provided a MSRV-aware version of `is_const_fn`.
385+
// function could be removed if `rustc` provided a MSRV-aware version of `is_stable_const_fn`.
386386
// as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
387387

388388
let const_stab_rust_version = match since {
@@ -393,8 +393,12 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
393393

394394
msrv.meets(const_stab_rust_version)
395395
} else {
396-
// Unstable const fn with the feature enabled.
397-
msrv.current().is_none()
396+
// Unstable const fn, check if the feature is enabled. We need both the regular stability
397+
// feature and (if set) the const stability feature to const-call this function.
398+
let stab = tcx.lookup_stability(def_id);
399+
let is_enabled = stab.is_some_and(|s| s.is_stable() || tcx.features().enabled(s.feature))
400+
&& const_stab.feature.is_none_or(|f| tcx.features().enabled(f));
401+
is_enabled && msrv.current().is_none()
398402
}
399403
})
400404
}

src/tools/clippy/clippy_utils/src/visitors.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,13 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
346346
.cx
347347
.qpath_res(p, hir_id)
348348
.opt_def_id()
349-
.map_or(false, |id| self.cx.tcx.is_const_fn_raw(id)) => {},
349+
.map_or(false, |id| self.cx.tcx.is_const_fn(id)) => {},
350350
ExprKind::MethodCall(..)
351351
if self
352352
.cx
353353
.typeck_results()
354354
.type_dependent_def_id(e.hir_id)
355-
.map_or(false, |id| self.cx.tcx.is_const_fn_raw(id)) => {},
355+
.map_or(false, |id| self.cx.tcx.is_const_fn(id)) => {},
356356
ExprKind::Binary(_, lhs, rhs)
357357
if self.cx.typeck_results().expr_ty(lhs).peel_refs().is_primitive_ty()
358358
&& self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},

0 commit comments

Comments
 (0)