Skip to content

Commit 9f086fc

Browse files
Rollup merge of #77203 - ecstatic-morse:const-stability-attr-checks, r=oli-obk
Check for missing const-stability attributes in `rustc_passes` Currently, this happens as a side effect of `is_min_const_fn`, which is non-obvious. Also adds a test for this case, since we didn't seem to have one before.
2 parents ec1766c + 6ce178f commit 9f086fc

File tree

5 files changed

+52
-11
lines changed

5 files changed

+52
-11
lines changed

compiler/rustc_mir/src/const_eval/fn_queries.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
5050
None => {
5151
if let Some(stab) = tcx.lookup_stability(def_id) {
5252
if stab.level.is_stable() {
53-
tcx.sess.span_err(
53+
tcx.sess.delay_span_bug(
5454
tcx.def_span(def_id),
5555
"stable const functions must have either `rustc_const_stable` or \
5656
`rustc_const_unstable` attribute",

compiler/rustc_mir/src/transform/check_consts/validation.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,6 @@ impl Validator<'mir, 'tcx> {
204204
pub fn check_body(&mut self) {
205205
let ConstCx { tcx, body, def_id, .. } = *self.ccx;
206206

207-
// HACK: This function has side-effects???? Make sure we call it.
208-
let _ = crate::const_eval::is_min_const_fn(tcx, def_id.to_def_id());
209-
210207
// The local type and predicate checks are not free and only relevant for `const fn`s.
211208
if self.const_kind() == hir::ConstContext::ConstFn {
212209
// Prevent const trait methods from being annotated as `stable`.

compiler/rustc_passes/src/stability.rs

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,21 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
459459
self.tcx.sess.span_err(span, &format!("{} has missing stability attribute", descr));
460460
}
461461
}
462+
463+
fn check_missing_const_stability(&self, hir_id: HirId, span: Span) {
464+
let stab_map = self.tcx.stability();
465+
let stab = stab_map.local_stability(hir_id);
466+
if stab.map_or(false, |stab| stab.level.is_stable()) {
467+
let const_stab = stab_map.local_const_stability(hir_id);
468+
if const_stab.is_none() {
469+
self.tcx.sess.span_err(
470+
span,
471+
"`#[stable]` const functions must also be either \
472+
`#[rustc_const_stable]` or `#[rustc_const_unstable]`",
473+
);
474+
}
475+
}
476+
}
462477
}
463478

464479
impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
@@ -469,14 +484,23 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
469484
}
470485

471486
fn visit_item(&mut self, i: &'tcx Item<'tcx>) {
472-
match i.kind {
473-
// Inherent impls and foreign modules serve only as containers for other items,
474-
// they don't have their own stability. They still can be annotated as unstable
475-
// and propagate this unstability to children, but this annotation is completely
476-
// optional. They inherit stability from their parents when unannotated.
477-
hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {}
487+
// Inherent impls and foreign modules serve only as containers for other items,
488+
// they don't have their own stability. They still can be annotated as unstable
489+
// and propagate this unstability to children, but this annotation is completely
490+
// optional. They inherit stability from their parents when unannotated.
491+
if !matches!(
492+
i.kind,
493+
hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..)
494+
) {
495+
self.check_missing_stability(i.hir_id, i.span);
496+
}
478497

479-
_ => self.check_missing_stability(i.hir_id, i.span),
498+
// Ensure `const fn` that are `stable` have one of `rustc_const_unstable` or
499+
// `rustc_const_stable`.
500+
if self.tcx.features().staged_api
501+
&& matches!(&i.kind, hir::ItemKind::Fn(sig, ..) if sig.header.is_const())
502+
{
503+
self.check_missing_const_stability(i.hir_id, i.span);
480504
}
481505

482506
intravisit::walk_item(self, i)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(staged_api)]
2+
3+
#![stable(feature = "rust1", since = "1.0.0")]
4+
5+
#[stable(feature = "foo", since = "1.0.0")]
6+
pub const fn foo() {}
7+
//~^ ERROR rustc_const_stable
8+
9+
#[unstable(feature = "bar", issue = "none")]
10+
pub const fn bar() {} // ok
11+
12+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: `#[stable]` const functions must also be either `#[rustc_const_stable]` or `#[rustc_const_unstable]`
2+
--> $DIR/missing-const-stability.rs:6:1
3+
|
4+
LL | pub const fn foo() {}
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)