mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-28 17:53:56 +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
|
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`.
|
/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
|
||||||
/// Returns `None` if no stability attributes are found.
|
/// Returns `None` if no stability attributes are found.
|
||||||
pub fn find_body_stability(
|
pub fn find_body_stability(
|
||||||
|
@ -53,10 +53,11 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn enforce_recursive_const_stability(&self) -> bool {
|
pub fn enforce_recursive_const_stability(&self) -> bool {
|
||||||
// We can skip this if `staged_api` is not enabled, since in such crates
|
// We can skip this if neither `staged_api` nor `-Zforrce-unstable-if-unmarked` are enabled,
|
||||||
// `lookup_const_stability` will always be `None`.
|
// since in such crates `lookup_const_stability` will always be `None`.
|
||||||
self.const_kind == Some(hir::ConstContext::ConstFn)
|
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())
|
&& 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 let Some(stab) = self.parent_stab {
|
||||||
if inherit_deprecation.yes() && stab.is_unstable() {
|
if inherit_deprecation.yes() && stab.is_unstable() {
|
||||||
self.index.stab_map.insert(def_id, stab);
|
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)]
|
#![feature(stdarch_internal)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
//
|
//
|
||||||
|
// Library features (crates without staged_api):
|
||||||
|
// tidy-alphabetical-start
|
||||||
|
#![feature(rustc_private)]
|
||||||
|
// tidy-alphabetical-end
|
||||||
|
//
|
||||||
// Only for re-exporting:
|
// Only for re-exporting:
|
||||||
// tidy-alphabetical-start
|
// tidy-alphabetical-start
|
||||||
#![feature(assert_matches)]
|
#![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