Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace #[allow_internal_unstable] with #[rustc_allow_const_fn_unstable] for const fns #78208

Merged
merged 7 commits into from
Oct 25, 2020
25 changes: 21 additions & 4 deletions compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,13 +1013,28 @@ pub fn allow_internal_unstable<'a>(
sess: &'a Session,
attrs: &'a [Attribute],
) -> Option<impl Iterator<Item = Symbol> + 'a> {
let attrs = sess.filter_by_name(attrs, sym::allow_internal_unstable);
allow_unstable(sess, attrs, sym::allow_internal_unstable)
}

pub fn rustc_allow_const_fn_unstable<'a>(
sess: &'a Session,
attrs: &'a [Attribute],
) -> Option<impl Iterator<Item = Symbol> + 'a> {
allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable)
}

fn allow_unstable<'a>(
sess: &'a Session,
attrs: &'a [Attribute],
symbol: Symbol,
) -> Option<impl Iterator<Item = Symbol> + 'a> {
let attrs = sess.filter_by_name(attrs, symbol);
let list = attrs
.filter_map(move |attr| {
attr.meta_item_list().or_else(|| {
sess.diagnostic().span_err(
attr.span,
"`allow_internal_unstable` expects a list of feature names",
&format!("`{}` expects a list of feature names", symbol.to_ident_string()),
);
None
})
Expand All @@ -1029,8 +1044,10 @@ pub fn allow_internal_unstable<'a>(
Some(list.into_iter().filter_map(move |it| {
let name = it.ident().map(|ident| ident.name);
if name.is_none() {
sess.diagnostic()
.span_err(it.span(), "`allow_internal_unstable` expects feature names");
sess.diagnostic().span_err(
it.span(),
&format!("`{}` expects feature names", symbol.to_ident_string()),
);
}
name
}))
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ declare_features! (
/// it is not on path for eventual stabilization).
(active, no_niche, "1.42.0", None, None),

/// Allows using `#[rustc_allow_const_fn_unstable]`.
/// This is an attribute on `const fn` for the same
/// purpose as `#[allow_internal_unstable]`.
(active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None),

// no-tracking-issue-end

// -------------------------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
allow_internal_unstable, AssumedUsed, template!(Word, List: "feat1, feat2, ..."),
"allow_internal_unstable side-steps feature gating and stability checks",
),
gated!(
rustc_allow_const_fn_unstable, AssumedUsed, template!(Word, List: "feat1, feat2, ..."),
"rustc_allow_const_fn_unstable side-steps feature gating and stability checks"
),
gated!(
allow_internal_unsafe, Normal, template!(Word),
"allow_internal_unsafe side-steps the unsafe_code lint",
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_mir/src/transform/check_consts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,13 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
Some(def_id) == tcx.lang_items().panic_fn() || Some(def_id) == tcx.lang_items().begin_panic_fn()
}

pub fn allow_internal_unstable(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
pub fn rustc_allow_const_fn_unstable(
tcx: TyCtxt<'tcx>,
def_id: DefId,
feature_gate: Symbol,
) -> bool {
let attrs = tcx.get_attrs(def_id);
attr::allow_internal_unstable(&tcx.sess, attrs)
attr::rustc_allow_const_fn_unstable(&tcx.sess, attrs)
.map_or(false, |mut features| features.any(|name| name == feature_gate))
}

Expand Down
14 changes: 9 additions & 5 deletions compiler/rustc_mir/src/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,11 @@ impl Validator<'mir, 'tcx> {

Status::Unstable(gate) if self.tcx.features().enabled(gate) => {
let unstable_in_stable = self.ccx.is_const_stable_const_fn()
&& !super::allow_internal_unstable(self.tcx, self.def_id().to_def_id(), gate);
&& !super::rustc_allow_const_fn_unstable(
self.tcx,
self.def_id().to_def_id(),
gate,
);
if unstable_in_stable {
emit_unstable_in_stable_error(self.ccx, span, gate);
}
Expand Down Expand Up @@ -805,7 +809,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
}

// Calling an unstable function *always* requires that the corresponding gate
// be enabled, even if the function has `#[allow_internal_unstable(the_gate)]`.
// be enabled, even if the function has `#[rustc_allow_const_fn_unstable(the_gate)]`.
if !tcx.features().declared_lib_features.iter().any(|&(sym, _)| sym == gate) {
self.check_op(ops::FnCallUnstable(callee, Some(gate)));
return;
Expand All @@ -819,7 +823,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {

// Otherwise, we are something const-stable calling a const-unstable fn.

if super::allow_internal_unstable(tcx, caller, gate) {
if super::rustc_allow_const_fn_unstable(tcx, caller, gate) {
return;
}

Expand Down Expand Up @@ -965,8 +969,8 @@ fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol
)
.span_suggestion(
attr_span,
"otherwise `#[allow_internal_unstable]` can be used to bypass stability checks",
format!("#[allow_internal_unstable({})]\n", gate),
"otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks",
format!("#[rustc_allow_const_fn_unstable({})]\n", gate),
Applicability::MaybeIncorrect,
)
.emit();
Expand Down
53 changes: 53 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ impl CheckAttrVisitor<'tcx> {
self.check_export_name(&attr, span, target)
} else if self.tcx.sess.check_name(attr, sym::rustc_args_required_const) {
self.check_rustc_args_required_const(&attr, span, target, item)
} else if self.tcx.sess.check_name(attr, sym::allow_internal_unstable) {
self.check_allow_internal_unstable(&attr, span, target, &attrs)
} else if self.tcx.sess.check_name(attr, sym::rustc_allow_const_fn_unstable) {
self.check_rustc_allow_const_fn_unstable(hir_id, &attr, span, target)
} else {
// lint-only checks
if self.tcx.sess.check_name(attr, sym::cold) {
Expand Down Expand Up @@ -762,6 +766,55 @@ impl CheckAttrVisitor<'tcx> {
}
}
}

/// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros.
/// (Allows proc_macro functions)
fn check_allow_internal_unstable(
&self,
attr: &Attribute,
span: &Span,
target: Target,
attrs: &[Attribute],
) -> bool {
debug!("Checking target: {:?}", target);
if target == Target::Fn {
for attr in attrs {
if self.tcx.sess.is_proc_macro_attr(attr) {
debug!("Is proc macro attr");
return true;
}
}
debug!("Is not proc macro attr");
}
self.tcx
.sess
.struct_span_err(attr.span, "attribute should be applied to a macro")
.span_label(*span, "not a macro")
.emit();
false
}

/// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros.
/// (Allows proc_macro functions)
fn check_rustc_allow_const_fn_unstable(
&self,
hir_id: HirId,
attr: &Attribute,
span: &Span,
target: Target,
) -> bool {
if let Target::Fn | Target::Method(_) = target {
if self.tcx.is_const_fn_raw(self.tcx.hir().local_def_id(hir_id)) {
return true;
}
}
self.tcx
.sess
.struct_span_err(attr.span, "attribute should be applied to `const fn`")
.span_label(*span, "not a `const fn`")
.emit();
false
}
}

impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_passes/src/check_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {

let is_feature_allowed = |feature_gate| {
// All features require that the corresponding gate be enabled,
// even if the function has `#[allow_internal_unstable(the_gate)]`.
// even if the function has `#[rustc_allow_const_fn_unstable(the_gate)]`.
if !tcx.features().enabled(feature_gate) {
return false;
}
Expand All @@ -105,8 +105,8 @@ impl<'tcx> CheckConstVisitor<'tcx> {
}

// However, we cannot allow stable `const fn`s to use unstable features without an explicit
// opt-in via `allow_internal_unstable`.
attr::allow_internal_unstable(&tcx.sess, &tcx.get_attrs(def_id))
// opt-in via `rustc_allow_const_fn_unstable`.
attr::rustc_allow_const_fn_unstable(&tcx.sess, &tcx.get_attrs(def_id))
.map_or(false, |mut features| features.any(|name| name == feature_gate))
};

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,7 @@ symbols! {
rustc,
rustc_allocator,
rustc_allocator_nounwind,
rustc_allow_const_fn_unstable,
rustc_args_required_const,
rustc_attrs,
rustc_builtin_macro,
Expand Down
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
#![allow(explicit_outlives_requirements)]
#![allow(incomplete_features)]
#![deny(unsafe_op_in_unsafe_fn)]
#![cfg_attr(not(bootstrap), feature(rustc_allow_const_fn_unstable))]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(test))]
#![cfg_attr(test, feature(new_uninit))]
Expand Down
3 changes: 2 additions & 1 deletion library/alloc/src/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ impl<T> RawVec<T, Global> {
impl<T, A: AllocRef> RawVec<T, A> {
/// Like `new`, but parameterized over the choice of allocator for
/// the returned `RawVec`.
#[allow_internal_unstable(const_fn)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn))]
pub const fn new_in(alloc: A) -> Self {
// `cap: 0` means "unallocated". zero-sized types are ignored.
Self { ptr: Unique::dangling(), cap: 0, alloc }
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
#![warn(missing_debug_implementations)]
#![allow(explicit_outlives_requirements)]
#![allow(incomplete_features)]
#![cfg_attr(not(bootstrap), feature(rustc_allow_const_fn_unstable))]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(asm)]
Expand Down
6 changes: 4 additions & 2 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2045,7 +2045,8 @@ assert_eq!(
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute them to arrays of bytes
#[allow_internal_unstable(const_fn_transmute)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn_transmute))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn_transmute))]
#[inline]
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
// SAFETY: integers are plain old datatypes so we can always transmute them to
Expand Down Expand Up @@ -2193,7 +2194,8 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute to them
#[allow_internal_unstable(const_fn_transmute)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn_transmute))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn_transmute))]
#[inline]
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
// SAFETY: integers are plain old datatypes so we can always transmute to them
Expand Down
6 changes: 4 additions & 2 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1803,7 +1803,8 @@ assert_eq!(
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute them to arrays of bytes
#[allow_internal_unstable(const_fn_transmute)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn_transmute))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn_transmute))]
#[inline]
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
// SAFETY: integers are plain old datatypes so we can always transmute them to
Expand Down Expand Up @@ -1951,7 +1952,8 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT),
#[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
// SAFETY: const sound because integers are plain old datatypes so we can always
// transmute to them
#[allow_internal_unstable(const_fn_transmute)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn_transmute))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn_transmute))]
#[inline]
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
// SAFETY: integers are plain old datatypes so we can always transmute to them
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ impl<T> [T] {
#[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")]
#[inline]
// SAFETY: const sound because we transmute out the length field as a usize (which it must be)
#[allow_internal_unstable(const_fn_union)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn_union))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn_union))]
pub const fn len(&self) -> usize {
// SAFETY: this is safe because `&[T]` and `FatPtr<T>` have the same layout.
// Only `std` can make this guarantee.
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/str/converts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_str_from_utf8_unchecked", issue = "75196")]
#[allow_internal_unstable(const_fn_transmute)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn_transmute))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn_transmute))]
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
// SAFETY: the caller must guarantee that the bytes `v` are valid UTF-8.
// Also relies on `&str` and `&[u8]` having the same layout.
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ impl str {
#[rustc_const_stable(feature = "str_as_bytes", since = "1.32.0")]
#[inline(always)]
#[allow(unused_attributes)]
#[allow_internal_unstable(const_fn_transmute)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn_transmute))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn_transmute))]
pub const fn as_bytes(&self) -> &[u8] {
// SAFETY: const sound because we transmute two types with the same layout
unsafe { mem::transmute(self) }
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/task/wake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ impl RawWakerVTable {
#[rustc_promotable]
#[stable(feature = "futures_api", since = "1.36.0")]
#[rustc_const_stable(feature = "futures_api", since = "1.36.0")]
#[allow_internal_unstable(const_fn_fn_ptr_basics)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn_fn_ptr_basics))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn_fn_ptr_basics))]
pub const fn new(
clone: unsafe fn(*const ()) -> RawWaker,
wake: unsafe fn(*const ()),
Expand Down
15 changes: 10 additions & 5 deletions library/proc_macro/src/bridge/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
}

impl Client<fn(crate::TokenStream) -> crate::TokenStream> {
#[allow_internal_unstable(const_fn)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn))]
pub const fn expand1(f: fn(crate::TokenStream) -> crate::TokenStream) -> Self {
extern "C" fn run(
bridge: Bridge<'_>,
Expand All @@ -414,7 +415,8 @@ impl Client<fn(crate::TokenStream) -> crate::TokenStream> {
}

impl Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream> {
#[allow_internal_unstable(const_fn)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn))]
pub const fn expand2(
f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream,
) -> Self {
Expand Down Expand Up @@ -459,7 +461,8 @@ impl ProcMacro {
}
}

#[allow_internal_unstable(const_fn)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn))]
pub const fn custom_derive(
trait_name: &'static str,
attributes: &'static [&'static str],
Expand All @@ -468,15 +471,17 @@ impl ProcMacro {
ProcMacro::CustomDerive { trait_name, attributes, client: Client::expand1(expand) }
}

#[allow_internal_unstable(const_fn)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn))]
pub const fn attr(
name: &'static str,
expand: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream,
) -> Self {
ProcMacro::Attr { name, client: Client::expand2(expand) }
}

#[allow_internal_unstable(const_fn)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn))]
pub const fn bang(
name: &'static str,
expand: fn(crate::TokenStream) -> crate::TokenStream,
Expand Down
3 changes: 2 additions & 1 deletion library/proc_macro/src/bridge/scoped_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ impl<'a, 'b, T: LambdaL> DerefMut for RefMutL<'a, 'b, T> {
pub struct ScopedCell<T: LambdaL>(Cell<<T as ApplyL<'static>>::Out>);

impl<T: LambdaL> ScopedCell<T> {
#[allow_internal_unstable(const_fn)]
#[cfg_attr(not(bootstrap), rustc_allow_const_fn_unstable(const_fn))]
#[cfg_attr(bootstrap, allow_internal_unstable(const_fn))]
pub const fn new(value: <T as ApplyL<'static>>::Out) -> Self {
ScopedCell(Cell::new(value))
}
Expand Down
1 change: 1 addition & 0 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
test(no_crate_inject, attr(deny(warnings))),
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
)]
#![cfg_attr(not(bootstrap), feature(rustc_allow_const_fn_unstable))]
#![feature(nll)]
#![feature(staged_api)]
#![feature(const_fn)]
Expand Down
Loading