mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
honor rustc_const_stable_indirect in non-staged_api crate with -Zforce-unstable-if-unmarked
This commit is contained in:
parent
668959740f
commit
686eeb83e9
@ -381,6 +381,26 @@ pub fn find_const_stability(
|
||||
const_stab
|
||||
}
|
||||
|
||||
/// Calculates the const stability for a const function in a `-Zforce-unstable-if-unmarked` crate
|
||||
/// without the `staged_api` feature.
|
||||
pub fn unmarked_crate_const_stab(
|
||||
_sess: &Session,
|
||||
attrs: &[Attribute],
|
||||
regular_stab: Stability,
|
||||
) -> ConstStability {
|
||||
assert!(regular_stab.level.is_unstable());
|
||||
// The only attribute that matters here is `rustc_const_stable_indirect`.
|
||||
// We enforce recursive const stability rules for those functions.
|
||||
let const_stable_indirect =
|
||||
attrs.iter().any(|a| a.name_or_empty() == sym::rustc_const_stable_indirect);
|
||||
ConstStability {
|
||||
feature: Some(regular_stab.feature),
|
||||
const_stable_indirect,
|
||||
promotable: false,
|
||||
level: regular_stab.level,
|
||||
}
|
||||
}
|
||||
|
||||
/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
|
||||
/// Returns `None` if no stability attributes are found.
|
||||
pub fn find_body_stability(
|
||||
|
@ -53,10 +53,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn enforce_recursive_const_stability(&self) -> bool {
|
||||
// We can skip this if `staged_api` is not enabled, since in such crates
|
||||
// `lookup_const_stability` will always be `None`.
|
||||
// We can skip this if neither `staged_api` nor `-Zforrce-unstable-if-unmarked` are enabled,
|
||||
// since in such crates `lookup_const_stability` will always be `None`.
|
||||
self.const_kind == Some(hir::ConstContext::ConstFn)
|
||||
&& self.tcx.features().staged_api()
|
||||
&& (self.tcx.features().staged_api()
|
||||
|| self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked)
|
||||
&& is_safe_to_expose_on_stable_const_fn(self.tcx, self.def_id().to_def_id())
|
||||
}
|
||||
|
||||
|
@ -149,6 +149,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
||||
if let Some(stab) = self.parent_stab {
|
||||
if inherit_deprecation.yes() && stab.is_unstable() {
|
||||
self.index.stab_map.insert(def_id, stab);
|
||||
if fn_sig.is_some_and(|s| s.header.is_const()) {
|
||||
let const_stab =
|
||||
attr::unmarked_crate_const_stab(self.tcx.sess, attrs, stab);
|
||||
self.index.const_stab_map.insert(def_id, const_stab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,6 +391,11 @@
|
||||
#![feature(stdarch_internal)]
|
||||
// tidy-alphabetical-end
|
||||
//
|
||||
// Library features (crates without staged_api):
|
||||
// tidy-alphabetical-start
|
||||
#![feature(rustc_private)]
|
||||
// tidy-alphabetical-end
|
||||
//
|
||||
// Only for re-exporting:
|
||||
// tidy-alphabetical-start
|
||||
#![feature(assert_matches)]
|
||||
|
@ -0,0 +1 @@
|
||||
pub const fn just_a_fn() {}
|
@ -0,0 +1,8 @@
|
||||
//@ compile-flags: -Zforce-unstable-if-unmarked
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
pub const fn not_stably_const() {}
|
||||
|
||||
#[rustc_const_stable_indirect]
|
||||
pub const fn expose_on_stable() {}
|
@ -0,0 +1,23 @@
|
||||
//@ aux-build:unstable_if_unmarked_const_fn_crate.rs
|
||||
//@ aux-build:unmarked_const_fn_crate.rs
|
||||
#![feature(staged_api, rustc_private)]
|
||||
#![stable(since="1.0.0", feature = "stable")]
|
||||
|
||||
extern crate unstable_if_unmarked_const_fn_crate;
|
||||
extern crate unmarked_const_fn_crate;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
|
||||
const fn stable_fn() {
|
||||
// This one is fine.
|
||||
unstable_if_unmarked_const_fn_crate::expose_on_stable();
|
||||
// This one is not.
|
||||
unstable_if_unmarked_const_fn_crate::not_stably_const();
|
||||
//~^ERROR: cannot use `#[feature(rustc_private)]`
|
||||
unmarked_const_fn_crate::just_a_fn();
|
||||
//~^ERROR: cannot be (indirectly) exposed to stable
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
error: const function that might be (indirectly) exposed to stable cannot use `#[feature(rustc_private)]`
|
||||
--> $DIR/recursive_const_stab_unmarked_crate_imports.rs:15:5
|
||||
|
|
||||
LL | unstable_if_unmarked_const_fn_crate::not_stably_const();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
|
||||
help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
|
||||
|
|
||||
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
|
||||
LL | const fn stable_fn() {
|
||||
|
|
||||
help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
|
||||
|
|
||||
LL + #[rustc_allow_const_fn_unstable(rustc_private)]
|
||||
LL | const fn stable_fn() {
|
||||
|
|
||||
|
||||
error: `just_a_fn` cannot be (indirectly) exposed to stable
|
||||
--> $DIR/recursive_const_stab_unmarked_crate_imports.rs:17:5
|
||||
|
|
||||
LL | unmarked_const_fn_crate::just_a_fn();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -0,0 +1,24 @@
|
||||
//@ compile-flags: -Zforce-unstable-if-unmarked
|
||||
//@ edition: 2021
|
||||
#![feature(const_async_blocks, rustc_attrs, rustc_private)]
|
||||
|
||||
pub const fn not_stably_const() {
|
||||
// We need to do something const-unstable here.
|
||||
// For now we use `async`, eventually we might have to add a auxiliary crate
|
||||
// as a dependency just to be sure we have something const-unstable.
|
||||
let _x = async { 15 };
|
||||
}
|
||||
|
||||
#[rustc_const_stable_indirect]
|
||||
pub const fn expose_on_stable() {
|
||||
// Calling `not_stably_const` here is *not* okay.
|
||||
not_stably_const();
|
||||
//~^ERROR: cannot use `#[feature(rustc_private)]`
|
||||
// Also directly using const-unstable things is not okay.
|
||||
let _x = async { 15 };
|
||||
//~^ERROR: cannot use `#[feature(const_async_blocks)]`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
const { expose_on_stable() };
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
error: const function that might be (indirectly) exposed to stable cannot use `#[feature(rustc_private)]`
|
||||
--> $DIR/recursive_const_stab_unstable_if_unmarked.rs:15:5
|
||||
|
|
||||
LL | not_stably_const();
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unsafe features
|
||||
help: if the caller is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
|
||||
|
|
||||
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
|
||||
LL | pub const fn expose_on_stable() {
|
||||
|
|
||||
help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
|
||||
|
|
||||
LL + #[rustc_allow_const_fn_unstable(rustc_private)]
|
||||
LL | pub const fn expose_on_stable() {
|
||||
|
|
||||
|
||||
error: const function that might be (indirectly) exposed to stable cannot use `#[feature(const_async_blocks)]`
|
||||
--> $DIR/recursive_const_stab_unstable_if_unmarked.rs:18:14
|
||||
|
|
||||
LL | let _x = async { 15 };
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
help: if the function is not (yet) meant to be exposed to stable, add `#[rustc_const_unstable]` (this is what you probably want to do)
|
||||
|
|
||||
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
|
||||
LL | pub const fn expose_on_stable() {
|
||||
|
|
||||
help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (this requires team approval)
|
||||
|
|
||||
LL + #[rustc_allow_const_fn_unstable(const_async_blocks)]
|
||||
LL | pub const fn expose_on_stable() {
|
||||
|
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user