Rollup merge of #78208 - liketechnik:issue-69399, r=oli-obk

replace `#[allow_internal_unstable]` with `#[rustc_allow_const_fn_unstable]` for `const fn`s

`#[allow_internal_unstable]` is currently used to side-step feature gate and stability checks.
While it was originally only meant to be used only on macros, its use was expanded to `const fn`s.

This pr adds stricter checks for the usage of `#[allow_internal_unstable]` (only on macros) and introduces the `#[rustc_allow_const_fn_unstable]` attribute for usage on `const fn`s.

This pr does not change any of the functionality associated with the use of `#[allow_internal_unstable]` on macros or the usage of `#[rustc_allow_const_fn_unstable]` (instead of `#[allow_internal_unstable]`) on `const fn`s (see https://github.com/rust-lang/rust/issues/69399#issuecomment-712911540).

Note: The check for `#[rustc_allow_const_fn_unstable]` currently only validates that the attribute is used on a function, because I don't know how I would check if the function is a `const fn` at the place of the check. I therefore openend this as a 'draft pull request'.

Closes rust-lang/rust#69399

r? @oli-obk
This commit is contained in:
Yuki Okushi 2020-10-25 18:43:40 +09:00 committed by GitHub
commit 72e02b015e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 177 additions and 41 deletions

View file

@ -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);
}
@ -807,7 +811,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;
@ -821,7 +825,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;
}
@ -967,8 +971,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();