Skip to content

Properly emit const fn UnstableInStable lint when reasonable #117571

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions compiler/rustc_const_eval/src/transform/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,17 +295,19 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
let gate = match op.status_in_item(self.ccx) {
Status::Allowed => return,

Status::Unstable(gate) if self.tcx.features().active(gate) => {
Status::Unstable(gate) => {
let unstable_in_stable = self.ccx.is_const_stable_const_fn()
&& !super::rustc_allow_const_fn_unstable(self.tcx, self.def_id(), gate);
if unstable_in_stable {
emit_unstable_in_stable_error(self.ccx, span, gate);
return;
} else if self.tcx.features().declared(gate) && self.tcx.features().active(gate) {
return;
} else {
Some(gate)
}

return;
}

Status::Unstable(gate) => Some(gate),
Status::Forbidden => None,
};

Expand Down
10 changes: 9 additions & 1 deletion compiler/rustc_const_eval/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
pub struct FnCallUnstable(pub DefId, pub Option<Symbol>);

impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
if let Some(symbol) = self.1 { Status::Unstable(symbol) } else { Status::Forbidden }
}

fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let FnCallUnstable(def_id, feature) = *self;

Expand All @@ -327,7 +331,11 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
// FIXME: make this translatable
#[allow(rustc::untranslatable_diagnostic)]
if ccx.is_const_stable_const_fn() {
err.help("const-stable functions can only call other const-stable functions");
if self.1.is_some() {
bug!("this should be triggering the UnstableInStable lint instead");
} else {
err.help("const-stable functions can only call other const-stable functions");
}
} else if ccx.tcx.sess.is_nightly_build() {
if let Some(feature) = feature {
err.help(format!("add `#![feature({feature})]` to the crate attributes to enable"));
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const fn foo() -> u32 { 42 }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const fn bar() -> u32 { foo() } //~ ERROR not yet stable as a const fn
const fn bar() -> u32 { foo() } //~ ERROR const-stable function cannot use `#[feature(foo)]`

#[unstable(feature = "foo2", issue = "none")]
const fn foo2() -> u32 { 42 }

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
const fn bar2() -> u32 { foo2() } //~ ERROR const-stable function cannot use `#[feature(foo2)]`

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -36,6 +36,6 @@ const fn foo2_gated() -> u32 { 42 }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR not yet stable as a const fn
const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR const-stable function cannot use `#[feature(foo2)]`

fn main() {}
13 changes: 11 additions & 2 deletions tests/ui/consts/min_const_fn/min_const_fn_libstd_stability.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
error: `foo` is not yet stable as a const fn
error: const-stable function cannot use `#[feature(foo)]`
--> $DIR/min_const_fn_libstd_stability.rs:16:25
|
LL | const fn bar() -> u32 { foo() }
| ^^^^^
|
= help: const-stable functions can only call other const-stable functions
help: if it is not part of the public API, make this function unstably const
|
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
LL | const fn bar() -> u32 { foo() }
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL + #[rustc_allow_const_fn_unstable(foo)]
LL | const fn bar() -> u32 { foo() }
|

error: `foo2` is not yet stable as a const fn
--> $DIR/min_const_fn_libstd_stability.rs:24:26
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const unsafe fn foo() -> u32 { 42 }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR not yet stable as a const fn
const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR const-stable function cannot use `#[feature(foo)]`

#[unstable(feature = "foo2", issue = "none")]
const unsafe fn foo2() -> u32 { 42 }

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR not yet stable as a const fn
const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR const-stable function cannot use `#[feature(foo2)]`

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -37,6 +37,6 @@ const unsafe fn foo2_gated() -> u32 { 42 }
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } }
//~^ ERROR not yet stable as a const fn
//~^ ERROR const-stable function cannot use `#[feature(foo2)]`

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
error: `foo` is not yet stable as a const fn
error: const-stable function cannot use `#[feature(foo)]`
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:16:41
|
LL | const unsafe fn bar() -> u32 { unsafe { foo() } }
| ^^^^^
|
= help: const-stable functions can only call other const-stable functions
help: if it is not part of the public API, make this function unstably const
|
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
LL | const unsafe fn bar() -> u32 { unsafe { foo() } }
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL + #[rustc_allow_const_fn_unstable(foo)]
LL | const unsafe fn bar() -> u32 { unsafe { foo() } }
|

error: `foo2` is not yet stable as a const fn
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:24:42
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const fn foo() -> u32 { 42 }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const unsafe fn bar() -> u32 { foo() } //~ ERROR not yet stable as a const fn
const unsafe fn bar() -> u32 { foo() } //~ ERROR const-stable function cannot use `#[feature(foo)]`

#[unstable(feature = "foo2", issue = "none")]
const fn foo2() -> u32 { 42 }

#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const unsafe fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
const unsafe fn bar2() -> u32 { foo2() } //~ ERROR const-stable function cannot use `#[feature(foo)]`

// check whether this function cannot be called even with the feature gate active
#[unstable(feature = "foo2", issue = "none")]
Expand All @@ -30,6 +30,6 @@ const fn foo2_gated() -> u32 { 42 }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// can't call non-min_const_fn
const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR not yet stable as a const fn
const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR const-stable function cannot use `#[feature(foo)]`

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
error: `foo` is not yet stable as a const fn
error: const-stable function cannot use `#[feature(foo)]`
--> $DIR/min_const_unsafe_fn_libstd_stability2.rs:16:32
|
LL | const unsafe fn bar() -> u32 { foo() }
| ^^^^^
|
= help: const-stable functions can only call other const-stable functions
help: if it is not part of the public API, make this function unstably const
|
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
LL | const unsafe fn bar() -> u32 { foo() }
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL + #[rustc_allow_const_fn_unstable(foo)]
LL | const unsafe fn bar() -> u32 { foo() }
|

error: `foo2` is not yet stable as a const fn
--> $DIR/min_const_unsafe_fn_libstd_stability2.rs:24:33
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/intrinsics/const-eval-select-stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const fn nothing(){}
#[rustc_const_stable(since = "1.0", feature = "const_hey")]
pub const unsafe fn hey() {
const_eval_select((), nothing, log);
//~^ ERROR `const_eval_select` is not yet stable as a const fn
//~^ ERROR const-stable function cannot use `#[feature(const_eval_select)]`
}

fn main() {}
13 changes: 11 additions & 2 deletions tests/ui/intrinsics/const-eval-select-stability.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
error: `const_eval_select` is not yet stable as a const fn
error: const-stable function cannot use `#[feature(const_eval_select)]`
--> $DIR/const-eval-select-stability.rs:17:5
|
LL | const_eval_select((), nothing, log);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: const-stable functions can only call other const-stable functions
help: if it is not part of the public API, make this function unstably const
|
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
LL | pub const unsafe fn hey() {
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL + #[rustc_allow_const_fn_unstable(const_eval_select)]
LL | pub const unsafe fn hey() {
|

error: aborting due to 1 previous error

6 changes: 3 additions & 3 deletions tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ pub const fn const_context_not_const_stable() {
#[rustc_const_stable(feature = "cheese", since = "1.0.0")]
const fn stable_const_context() {
Unstable::func();
//~^ ERROR not yet stable as a const fn
//~^ ERROR const-stable function cannot use `#[feature(unstable)]`
Foo::func();
//[unstable]~^ ERROR not yet stable as a const fn
//[unstable]~^ ERROR const-stable function cannot use `#[feature(foo)]`
const_context_not_const_stable()
//[unstable]~^ ERROR not yet stable as a const fn
//[unstable]~^ ERROR const-stable function cannot use `#[feature(foo)]`
}

fn main() {}
46 changes: 36 additions & 10 deletions tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,55 @@ LL | Foo::func();
|
= help: add `#![feature(foo)]` to the crate attributes to enable

error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
--> $DIR/staged-api.rs:53:5
error: const-stable function cannot use `#[feature(unstable)]`
--> $DIR/staged-api.rs:55:5
|
LL | Unstable::func();
| ^^^^^^^^^^^^^^^^
|
= help: const-stable functions can only call other const-stable functions
help: if it is not part of the public API, make this function unstably const
|
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
LL | const fn stable_const_context() {
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL + #[rustc_allow_const_fn_unstable(unstable)]
LL | const fn stable_const_context() {
|

error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
--> $DIR/staged-api.rs:55:5
error: const-stable function cannot use `#[feature(foo)]`
--> $DIR/staged-api.rs:57:5
|
LL | Foo::func();
| ^^^^^^^^^^^
|
= help: const-stable functions can only call other const-stable functions
help: if it is not part of the public API, make this function unstably const
|
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
LL | const fn stable_const_context() {
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL + #[rustc_allow_const_fn_unstable(foo)]
LL | const fn stable_const_context() {
|

error: `const_context_not_const_stable` is not yet stable as a const fn
--> $DIR/staged-api.rs:57:5
error: const-stable function cannot use `#[feature(foo)]`
--> $DIR/staged-api.rs:59:5
|
LL | const_context_not_const_stable()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: const-stable functions can only call other const-stable functions
help: if it is not part of the public API, make this function unstably const
|
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
LL | const fn stable_const_context() {
|
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
LL + #[rustc_allow_const_fn_unstable(foo)]
LL | const fn stable_const_context() {
|

error: aborting due to 5 previous errors