Skip to content

Commit 97816a2

Browse files
committed
Lint unstable functions that are const stable
1 parent 00d5e42 commit 97816a2

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed

compiler/rustc_lint/src/internal.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,3 +358,47 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword {
358358
}
359359
}
360360
}
361+
362+
declare_tool_lint! {
363+
pub rustc::INCOMPATIBLE_STABILITY,
364+
Deny,
365+
"check that an unstable item is not const-stable"
366+
}
367+
368+
declare_lint_pass!(IncompatibleStability => [INCOMPATIBLE_STABILITY]);
369+
370+
impl LateLintPass<'_> for IncompatibleStability {
371+
fn check_fn(
372+
&mut self,
373+
cx: &LateContext<'_>,
374+
kind: rustc_hir::intravisit::FnKind<'_>,
375+
_: &FnDecl<'_>,
376+
_: &Body<'_>,
377+
span: rustc_span::Span,
378+
hir_id: HirId,
379+
) {
380+
use rustc_attr::{ConstStability, Stability, StabilityLevel};
381+
382+
// Perform a cheap check up-front to avoid unnecessary querying.
383+
if kind.constness() == rustc_hir::Constness::NotConst {
384+
return;
385+
}
386+
387+
if !matches!(
388+
cx.tcx.lookup_stability(hir_id.owner),
389+
Some(Stability { level: StabilityLevel::Unstable { .. }, .. })
390+
) {
391+
return;
392+
}
393+
if !matches!(
394+
cx.tcx.lookup_const_stability(hir_id.owner),
395+
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. })
396+
) {
397+
return;
398+
}
399+
400+
cx.struct_span_lint(INCOMPATIBLE_STABILITY, span, |lint| {
401+
lint.build("functions cannot be const-stable if they are unstable").emit();
402+
});
403+
}
404+
}

compiler/rustc_lint/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,8 @@ fn register_internals(store: &mut LintStore) {
492492
store.register_late_pass(|| Box::new(ExistingDocKeyword));
493493
store.register_lints(&TyTyKind::get_lints());
494494
store.register_late_pass(|| Box::new(TyTyKind));
495+
store.register_lints(&IncompatibleStability::get_lints());
496+
store.register_late_pass(|| Box::new(IncompatibleStability));
495497
store.register_group(
496498
false,
497499
"rustc::internal",
@@ -504,6 +506,7 @@ fn register_internals(store: &mut LintStore) {
504506
LintId::of(TY_PASS_BY_REFERENCE),
505507
LintId::of(USAGE_OF_QUALIFIED_TY),
506508
LintId::of(EXISTING_DOC_KEYWORD),
509+
LintId::of(INCOMPATIBLE_STABILITY),
507510
],
508511
);
509512
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// compile-flags: -Zunstable-options
2+
#![stable(feature = "stable", since = "1.0.0")]
3+
#![feature(staged_api, rustc_attrs)]
4+
5+
#[unstable(feature = "unstable", issue = "none")]
6+
#[rustc_const_stable(feature = "stable", since = "1.0.0")]
7+
const fn foo() {} //~ ERROR functions cannot be const-stable if they are unstable
8+
9+
mod bar {
10+
#![unstable(feature = "unstable", issue = "none")]
11+
12+
#[rustc_const_stable(feature = "stable", since = "1.0.0")]
13+
const fn foo() {} //~ ERROR functions cannot be const-stable if they are unstable
14+
}
15+
16+
fn main() {}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: functions cannot be const-stable if they are unstable
2+
--> $DIR/incompatible_stability.rs:7:1
3+
|
4+
LL | const fn foo() {}
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[deny(rustc::incompatible_stability)]` on by default
8+
9+
error: functions cannot be const-stable if they are unstable
10+
--> $DIR/incompatible_stability.rs:13:5
11+
|
12+
LL | const fn foo() {}
13+
| ^^^^^^^^^^^^^^^^^
14+
15+
error: aborting due to 2 previous errors
16+

0 commit comments

Comments
 (0)