提交 f6d59207 编写于 作者: B bors

Auto merge of #76850 - ecstatic-morse:const-checking-refactor, r=oli-obk

Remove `qualify_min_const_fn`

~~Blocked on #76807 (the first six commits).~~

With this PR, all checks in `qualify_min_const_fn` are replicated in `check_consts`, and the former is no longer invoked. My goal was to have as few changes to test output as possible, since making sweeping changes to the code *while* doing big batches of diagnostics updates turned out to be a headache. To this end, there's a few `HACK`s in `check_consts` to achieve parity with `qualify_min_const_fn`.

The new system that replaces `is_min_const_fn` is referred to as "const-stability"  My end goal for the const-stability rules is this:
* Const-stability is only applicable to functions defined in `staged_api` crates.
* All functions not marked `rustc_const_unstable` are considered "const-stable".
    - NB. This is currently not implemented. `#[unstable]` functions are also const-unstable. This causes problems when searching for feature gates.
    - All "const-unstable" functions have an associated feature gate
* const-stable functions can only call other const-stable functions
     - `allow_internal_unstable` can be used to circumvent this.
* All const-stable functions are subject to some additional checks (the ones that were unique to `qualify_min_const_fn`)

The plan is to remove each `HACK` individually in subsequent PRs. That way, changes to error message output can be reviewed in isolation.
......@@ -7,6 +7,7 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
#![feature(box_syntax)]
#![feature(const_fn)] // For the `transmute` in `P::new`
#![feature(const_fn_transmute)]
#![feature(const_panic)]
#![feature(crate_visibility_modifier)]
#![feature(label_break_value)]
......
......@@ -51,6 +51,12 @@ pub fn new_with_param_env(
pub fn const_kind(&self) -> hir::ConstContext {
self.const_kind.expect("`const_kind` must not be called on a non-const fn")
}
pub fn is_const_stable_const_fn(&self) -> bool {
self.const_kind == Some(hir::ConstContext::ConstFn)
&& self.tcx.features().staged_api
&& is_const_stable_const_fn(self.tcx, self.def_id.to_def_id())
}
}
/// Returns `true` if this `DefId` points to one of the official `panic` lang items.
......@@ -63,3 +69,37 @@ pub fn allow_internal_unstable(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: S
attr::allow_internal_unstable(&tcx.sess, attrs)
.map_or(false, |mut features| features.any(|name| name == feature_gate))
}
// Returns `true` if the given `const fn` is "const-stable".
//
// Panics if the given `DefId` does not refer to a `const fn`.
//
// Const-stability is only relevant for `const fn` within a `staged_api` crate. Only "const-stable"
// functions can be called in a const-context by users of the stable compiler. "const-stable"
// functions are subject to more stringent restrictions than "const-unstable" functions: They
// cannot use unstable features and can only call other "const-stable" functions.
pub fn is_const_stable_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
use attr::{ConstStability, Stability, StabilityLevel};
// Const-stability is only relevant for `const fn`.
assert!(tcx.is_const_fn_raw(def_id));
// Functions with `#[rustc_const_unstable]` are const-unstable.
match tcx.lookup_const_stability(def_id) {
Some(ConstStability { level: StabilityLevel::Unstable { .. }, .. }) => return false,
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => return true,
None => {}
}
// Functions with `#[unstable]` are const-unstable.
//
// FIXME(ecstaticmorse): We should keep const-stability attributes wholly separate from normal stability
// attributes. `#[unstable]` should be irrelevant.
if let Some(Stability { level: StabilityLevel::Unstable { .. }, .. }) =
tcx.lookup_stability(def_id)
{
return false;
}
true
}
......@@ -10,33 +10,34 @@
use super::ConstCx;
/// Emits an error if `op` is not allowed in the given const context.
pub fn non_const<O: NonConstOp>(ccx: &ConstCx<'_, '_>, op: O, span: Span) {
/// Emits an error and returns `true` if `op` is not allowed in the given const context.
pub fn non_const<O: NonConstOp>(ccx: &ConstCx<'_, '_>, op: O, span: Span) -> bool {
debug!("illegal_op: op={:?}", op);
let gate = match op.status_in_item(ccx) {
Status::Allowed => return,
Status::Allowed => return false,
Status::Unstable(gate) if ccx.tcx.features().enabled(gate) => {
let unstable_in_stable = ccx.const_kind() == hir::ConstContext::ConstFn
&& ccx.tcx.features().enabled(sym::staged_api)
&& !ccx.tcx.has_attr(ccx.def_id.to_def_id(), sym::rustc_const_unstable)
let unstable_in_stable = ccx.is_const_stable_const_fn()
&& !super::allow_internal_unstable(ccx.tcx, ccx.def_id.to_def_id(), gate);
if unstable_in_stable {
ccx.tcx.sess
.struct_span_err(span, &format!("`#[feature({})]` cannot be depended on in a const-stable function", gate.as_str()))
.struct_span_err(
span,
&format!("const-stable function cannot use `#[feature({})]`", gate.as_str()),
)
.span_suggestion(
ccx.body.span,
"if it is not part of the public API, make this function unstably const",
concat!(r#"#[rustc_const_unstable(feature = "...", issue = "...")]"#, '\n').to_owned(),
Applicability::HasPlaceholders,
)
.help("otherwise `#[allow_internal_unstable]` can be used to bypass stability checks")
.note("otherwise `#[allow_internal_unstable]` can be used to bypass stability checks")
.emit();
}
return;
return unstable_in_stable;
}
Status::Unstable(gate) => Some(gate),
......@@ -45,12 +46,14 @@ pub fn non_const<O: NonConstOp>(ccx: &ConstCx<'_, '_>, op: O, span: Span) {
if ccx.tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
ccx.tcx.sess.miri_unleashed_feature(span, gate);
return;
return false;
}
op.emit_error(ccx, span);
true
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Status {
Allowed,
Unstable(Symbol),
......@@ -59,6 +62,8 @@ pub enum Status {
/// An operation that is not *always* allowed in a const context.
pub trait NonConstOp: std::fmt::Debug {
const STOPS_CONST_CHECKING: bool = false;
/// Returns an enum indicating whether this operation is allowed within the given item.
fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status {
Status::Forbidden
......@@ -93,6 +98,34 @@ fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
}
}
#[derive(Debug)]
pub struct Abort;
impl NonConstOp for Abort {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
mcf_status_in_item(ccx)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "abort is not stable in const fn")
}
}
#[derive(Debug)]
pub struct NonPrimitiveOp;
impl NonConstOp for NonPrimitiveOp {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
mcf_status_in_item(ccx)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "only int, `bool` and `char` operations are stable in const fn")
}
}
/// A function call where the callee is a pointer.
#[derive(Debug)]
pub struct FnCallIndirect;
......@@ -125,7 +158,8 @@ fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
///
/// Contains the name of the feature that would allow the use of this function.
#[derive(Debug)]
pub struct FnCallUnstable(pub DefId, pub Symbol);
pub struct FnCallUnstable(pub DefId, pub Option<Symbol>);
impl NonConstOp for FnCallUnstable {
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
let FnCallUnstable(def_id, feature) = *self;
......@@ -134,13 +168,51 @@ fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
span,
&format!("`{}` is not yet stable as a const fn", ccx.tcx.def_path_str(def_id)),
);
if nightly_options::is_nightly_build() {
err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
if ccx.is_const_stable_const_fn() {
err.help("Const-stable functions can only call other const-stable functions");
} else if nightly_options::is_nightly_build() {
if let Some(feature) = feature {
err.help(&format!(
"add `#![feature({})]` to the crate attributes to enable",
feature
));
}
}
err.emit();
}
}
#[derive(Debug)]
pub struct FnPtrCast;
impl NonConstOp for FnPtrCast {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
mcf_status_in_item(ccx)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "function pointer casts are not allowed in const fn");
}
}
#[derive(Debug)]
pub struct Generator;
impl NonConstOp for Generator {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
// FIXME: This means generator-only MIR is only forbidden in const fn. This is for
// compatibility with the old code. Such MIR should be forbidden everywhere.
mcf_status_in_item(ccx)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "const fn generators are unstable");
}
}
#[derive(Debug)]
pub struct HeapAllocation;
impl NonConstOp for HeapAllocation {
......@@ -403,6 +475,24 @@ fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
}
}
#[derive(Debug)]
pub struct Transmute;
impl NonConstOp for Transmute {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
if ccx.const_kind() != hir::ConstContext::ConstFn {
Status::Allowed
} else {
Status::Unstable(sym::const_fn_transmute)
}
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "can only call `transmute` from const items, not `const fn`");
}
}
#[derive(Debug)]
pub struct UnionAccess;
impl NonConstOp for UnionAccess {
......@@ -425,3 +515,131 @@ fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
.emit();
}
}
/// See [#64992].
///
/// [#64992]: https://github.com/rust-lang/rust/issues/64992
#[derive(Debug)]
pub struct UnsizingCast;
impl NonConstOp for UnsizingCast {
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
mcf_status_in_item(ccx)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(
ccx,
span,
"unsizing casts to types besides slices are not allowed in const fn",
);
}
}
pub mod ty {
use super::*;
#[derive(Debug)]
pub struct MutRef;
impl NonConstOp for MutRef {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status {
Status::Unstable(sym::const_mut_refs)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "mutable references in const fn are unstable");
}
}
#[derive(Debug)]
pub struct FnPtr;
impl NonConstOp for FnPtr {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
// FIXME: This attribute a hack to allow the specialization of the `futures` API. See
// #59739. We should have a proper feature gate for this.
if ccx.tcx.has_attr(ccx.def_id.to_def_id(), sym::rustc_allow_const_fn_ptr) {
Status::Allowed
} else {
mcf_status_in_item(ccx)
}
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "function pointers in const fn are unstable");
}
}
#[derive(Debug)]
pub struct ImplTrait;
impl NonConstOp for ImplTrait {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
mcf_status_in_item(ccx)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(ccx, span, "`impl Trait` in const fn is unstable");
}
}
#[derive(Debug)]
pub struct TraitBound;
impl NonConstOp for TraitBound {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
mcf_status_in_item(ccx)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
mcf_emit_error(
ccx,
span,
"trait bounds other than `Sized` on const fn parameters are unstable",
);
}
}
/// A trait bound with the `?const Trait` opt-out
#[derive(Debug)]
pub struct TraitBoundNotConst;
impl NonConstOp for TraitBoundNotConst {
const STOPS_CONST_CHECKING: bool = true;
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
Status::Unstable(sym::const_trait_bound_opt_out)
}
fn emit_error(&self, ccx: &ConstCx<'_, '_>, span: Span) {
feature_err(
&ccx.tcx.sess.parse_sess,
sym::const_trait_bound_opt_out,
span,
"`?const Trait` syntax is unstable",
)
.emit()
}
}
}
fn mcf_status_in_item(ccx: &ConstCx<'_, '_>) -> Status {
if ccx.const_kind() != hir::ConstContext::ConstFn {
Status::Allowed
} else {
Status::Unstable(sym::const_fn)
}
}
fn mcf_emit_error(ccx: &ConstCx<'_, '_>, span: Span, msg: &str) {
struct_span_err!(ccx.tcx.sess, span, E0723, "{}", msg)
.note(
"see issue #57563 <https://github.com/rust-lang/rust/issues/57563> \
for more information",
)
.help("add `#![feature(const_fn)]` to the crate attributes to enable")
.emit();
}
......@@ -2,7 +2,7 @@
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, BasicBlock, Location};
use rustc_middle::ty::TyCtxt;
use rustc_span::{sym, Span};
use rustc_span::Span;
use super::ops;
use super::qualifs::{NeedsDrop, Qualif};
......@@ -11,13 +11,13 @@
/// Returns `true` if we should use the more precise live drop checker that runs after drop
/// elaboration.
pub fn checking_enabled(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
pub fn checking_enabled(ccx: &ConstCx<'_, '_>) -> bool {
// Const-stable functions must always use the stable live drop checker.
if tcx.features().staged_api && !tcx.has_attr(def_id.to_def_id(), sym::rustc_const_unstable) {
if ccx.is_const_stable_const_fn() {
return false;
}
tcx.features().const_precise_live_drops
ccx.tcx.features().const_precise_live_drops
}
/// Look for live drops in a const context.
......@@ -30,12 +30,11 @@ pub fn check_live_drops(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &mir::Body<
return;
}
if !checking_enabled(tcx, def_id) {
let ccx = ConstCx { body, tcx, def_id, const_kind, param_env: tcx.param_env(def_id) };
if !checking_enabled(&ccx) {
return;
}
let ccx = ConstCx { body, tcx, def_id, const_kind, param_env: tcx.param_env(def_id) };
let mut visitor = CheckLiveDrops { ccx: &ccx, qualifs: Qualifs::default() };
visitor.visit_body(body);
......
......@@ -217,6 +217,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
/// assert!(!bull.is_borrowed());
/// ```
#[unstable(feature = "cow_is_borrowed", issue = "65143")]
#[rustc_const_unstable(feature = "const_cow_is_borrowed", issue = "65143")]
pub const fn is_borrowed(&self) -> bool {
match *self {
Borrowed(_) => true,
......@@ -239,6 +240,7 @@ pub const fn is_borrowed(&self) -> bool {
/// assert!(!bull.is_owned());
/// ```
#[unstable(feature = "cow_is_borrowed", issue = "65143")]
#[rustc_const_unstable(feature = "const_cow_is_borrowed", issue = "65143")]
pub const fn is_owned(&self) -> bool {
!self.is_borrowed()
}
......
......@@ -86,9 +86,11 @@
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
#![feature(const_btree_new)]
#![feature(const_fn)]
#![feature(const_generics)]
#![feature(const_in_array_repeat_expressions)]
#![feature(cow_is_borrowed)]
#![feature(const_cow_is_borrowed)]
#![feature(dispatch_from_dyn)]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
......
......@@ -150,6 +150,7 @@ pub unsafe fn into_box(self, len: usize) -> Box<[MaybeUninit<T>]> {
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)]
pub const fn new_in(alloc: A) -> Self {
// `cap: 0` means "unallocated". zero-sized types are ignored.
Self { ptr: Unique::dangling(), cap: 0, alloc }
......
#![feature(allocator_api)]
#![feature(box_syntax)]
#![feature(cow_is_borrowed)]
#![feature(const_cow_is_borrowed)]
#![feature(drain_filter)]
#![feature(exact_size_is_empty)]
#![feature(new_uninit)]
......
......@@ -177,6 +177,7 @@ pub unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
/// sentinel value. Types that lazily allocate must track initialization by
/// some other means.
#[unstable(feature = "alloc_layout_extra", issue = "55724")]
#[rustc_const_unstable(feature = "alloc_layout_extra", issue = "55724")]
#[inline]
pub const fn dangling(&self) -> NonNull<u8> {
// SAFETY: align is guaranteed to be non-zero
......
......@@ -56,6 +56,7 @@ unsafe impl Sync for ResumeTy {}
#[lang = "from_generator"]
#[doc(hidden)]
#[unstable(feature = "gen_future", issue = "50547")]
#[rustc_const_unstable(feature = "gen_future", issue = "50547")]
#[inline]
pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
where
......
......@@ -75,11 +75,13 @@
#![feature(const_float_bits_conv)]
#![feature(const_overflowing_int_methods)]
#![feature(const_int_unchecked_arith)]
#![feature(const_mut_refs)]
#![feature(const_int_pow)]
#![feature(constctlz)]
#![feature(const_panic)]
#![feature(const_pin)]
#![feature(const_fn_union)]
#![feature(const_fn)]
#![feature(const_generics)]
#![feature(const_option)]
#![feature(const_precise_live_drops)]
......
......@@ -401,6 +401,7 @@ fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
}
impl Client<fn(crate::TokenStream) -> crate::TokenStream> {
#[allow_internal_unstable(const_fn)]
pub const fn expand1(f: fn(crate::TokenStream) -> crate::TokenStream) -> Self {
extern "C" fn run(
bridge: Bridge<'_>,
......@@ -413,6 +414,7 @@ extern "C" fn run(
}
impl Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream> {
#[allow_internal_unstable(const_fn)]
pub const fn expand2(
f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream,
) -> Self {
......@@ -457,6 +459,7 @@ pub fn name(&self) -> &'static str {
}
}
#[allow_internal_unstable(const_fn)]
pub const fn custom_derive(
trait_name: &'static str,
attributes: &'static [&'static str],
......@@ -465,6 +468,7 @@ pub const fn custom_derive(
ProcMacro::CustomDerive { trait_name, attributes, client: Client::expand1(expand) }
}
#[allow_internal_unstable(const_fn)]
pub const fn attr(
name: &'static str,
expand: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream,
......@@ -472,6 +476,7 @@ pub const fn attr(
ProcMacro::Attr { name, client: Client::expand2(expand) }
}
#[allow_internal_unstable(const_fn)]
pub const fn bang(
name: &'static str,
expand: fn(crate::TokenStream) -> crate::TokenStream,
......
......@@ -35,6 +35,7 @@ fn deref_mut(&mut self) -> &mut Self::Target {
pub struct ScopedCell<T: LambdaL>(Cell<<T as ApplyL<'static>>::Out>);
impl<T: LambdaL> ScopedCell<T> {
#[allow_internal_unstable(const_fn)]
pub const fn new(value: <T as ApplyL<'static>>::Out) -> Self {
ScopedCell(Cell::new(value))
}
......
......@@ -20,6 +20,7 @@
)]
#![feature(nll)]
#![feature(staged_api)]
#![feature(const_fn)]
#![feature(allow_internal_unstable)]
#![feature(decl_macro)]
#![feature(extern_types)]
......
......@@ -237,6 +237,7 @@
#![feature(concat_idents)]
#![feature(const_cstr_unchecked)]
#![feature(const_fn_transmute)]
#![feature(const_fn)]
#![feature(const_ipv6)]
#![feature(const_raw_ptr_deref)]
#![feature(const_ipv4)]
......@@ -306,6 +307,7 @@
#![feature(str_internals)]
#![feature(test)]
#![feature(thread_local)]
#![feature(thread_local_internals)]
#![feature(toowned_clone_into)]
#![feature(total_cmp)]
#![feature(trace_macros)]
......
......@@ -117,6 +117,7 @@ pub struct Key {
pub const INIT: StaticKey = StaticKey::new(None);
impl StaticKey {
#[rustc_const_unstable(feature = "thread_local_internals", issue = "none")]
pub const fn new(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> StaticKey {
StaticKey { key: atomic::AtomicUsize::new(0), dtor }
}
......
......@@ -225,6 +225,7 @@ impl<T: 'static> LocalKey<T> {
reason = "recently added to create a key",
issue = "none"
)]
#[rustc_const_unstable(feature = "thread_local_internals", issue = "none")]
pub const unsafe fn new(inner: unsafe fn() -> Option<&'static T>) -> LocalKey<T> {
LocalKey { inner }
}
......@@ -497,6 +498,7 @@ struct Value<T: 'static> {
}
impl<T: 'static> Key<T> {
#[rustc_const_unstable(feature = "thread_local_internals", issue = "none")]
pub const fn new() -> Key<T> {
Key { os: OsStaticKey::new(Some(destroy_value::<T>)), marker: marker::PhantomData }
}
......
......@@ -5,9 +5,7 @@
const fn f(x: usize) -> usize {
let mut sum = 0;
for i in 0..x {
//~^ ERROR E0015
//~| ERROR E0015
//~| ERROR E0658
//~^ ERROR mutable references
//~| ERROR E0080
//~| ERROR E0744
sum += i;
......
......@@ -7,7 +7,7 @@
const extern fn bar() {
unsafe {
regular_in_block();
//~^ ERROR: can only call other `const fn` within a `const fn`
//~^ ERROR: calls in constant functions
}
}
......@@ -16,7 +16,7 @@
const extern fn foo() {
unsafe {
regular();
//~^ ERROR: can only call other `const fn` within a `const fn`
//~^ ERROR: calls in constant functions
}
}
......
error[E0723]: can only call other `const fn` within a `const fn`, but `regular_in_block` is not stable as `const fn`
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/const-extern-fn-call-extern-fn.rs:9:9
|
LL | regular_in_block();
| ^^^^^^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: can only call other `const fn` within a `const fn`, but `regular` is not stable as `const fn`
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/const-extern-fn-call-extern-fn.rs:18:9
|
LL | regular();
| ^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0723`.
For more information about this error, try `rustc --explain E0015`.
......@@ -6,7 +6,7 @@
const unsafe extern fn use_float() { 1.0 + 1.0; }
//~^ ERROR only int, `bool` and `char` operations are stable in const fn
const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
//~^ ERROR casting pointers to ints is unstable in const fn
//~^ ERROR casting pointers to integers
fn main() {}
......@@ -16,15 +16,16 @@ LL | const unsafe extern fn use_float() { 1.0 + 1.0; }
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: casting pointers to ints is unstable in const fn
error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/const-extern-fn-min-const-fn.rs:8:48
|
LL | const extern "C" fn ptr_cast(val: *const u8) { val as usize; }
| ^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0723`.
Some errors have detailed explanations: E0658, E0723.
For more information about an error, try `rustc --explain E0658`.
// Test that we can't call random fns in a const fn or do other bad things.
#![feature(const_fn, const_transmute)]
#![feature(const_fn, const_fn_transmute)]
use std::mem::transmute;
......
......@@ -2,6 +2,7 @@ fn main() {
foo(&mut 5);
}
const fn foo(x: &mut i32) -> i32 { //~ ERROR mutable references in const fn are unstable
const fn foo(x: &mut i32) -> i32 { //~ ERROR mutable references in const fn
*x + 1
}
......@@ -6,8 +6,8 @@ struct S {
impl S {
const fn foo(&mut self, x: u32) {
//~^ ERROR mutable references
self.state = x;
//~^ contains unimplemented expression
}
}
......
error[E0019]: constant function contains unimplemented expression type
--> $DIR/const_let_assign3.rs:9:9
error[E0723]: mutable references in const fn are unstable
--> $DIR/const_let_assign3.rs:8:18
|
LL | self.state = x;
| ^^^^^^^^^^^^^^
LL | const fn foo(&mut self, x: u32) {
| ^^^^^^^^^
|
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0764]: mutable references are not allowed in constants
--> $DIR/const_let_assign3.rs:16:5
......@@ -28,5 +29,5 @@ LL | *y = 42;
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0019, E0764.
Some errors have detailed explanations: E0019, E0723, E0764.
For more information about an error, try `rustc --explain E0019`.
const fn foo(a: i32) -> Vec<i32> {
vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn
vec![1, 2, 3]
//~^ ERROR allocations are not allowed
//~| ERROR unimplemented expression type
//~| ERROR calls in constant functions
}
fn main() {}
error[E0723]: heap allocations are not allowed in const fn
error[E0010]: allocations are not allowed in constant functions
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
LL | vec![1, 2, 3]
| ^^^^^^^^^^^^^ allocation not allowed in constant functions
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0019]: constant function contains unimplemented expression type
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
LL | vec![1, 2, 3]
| ^^^^^^^^^^^^^
|
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
LL | vec![1, 2, 3]
| ^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0723`.
Some errors have detailed explanations: E0010, E0015, E0019.
For more information about an error, try `rustc --explain E0010`.
......@@ -78,25 +78,25 @@ const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
const fn foo11_2<T: Send>(t: T) -> T { t }
//~^ ERROR trait bounds other than `Sized` on const fn parameters are unstable
const fn foo19(f: f32) -> f32 { f * 2.0 }
//~^ ERROR only int, `bool` and `char` operations are stable in const fn
//~^ ERROR int, `bool` and `char` operations
const fn foo19_2(f: f32) -> f32 { 2.0 - f }
//~^ ERROR only int, `bool` and `char` operations are stable in const fn
//~^ ERROR int, `bool` and `char` operations
const fn foo19_3(f: f32) -> f32 { -f }
//~^ ERROR only int and `bool` operations are stable in const fn
//~^ ERROR int, `bool` and `char` operations
const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
//~^ ERROR only int, `bool` and `char` operations are stable in const fn
//~^ ERROR int, `bool` and `char` operations
static BAR: u32 = 42;
const fn foo25() -> u32 { BAR } //~ ERROR cannot access `static` items in const fn
const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot access `static` items
const fn foo25() -> u32 { BAR } //~ ERROR cannot refer to statics
const fn foo26() -> &'static u32 { &BAR } //~ ERROR cannot refer to statics
const fn foo30(x: *const u32) -> usize { x as usize }
//~^ ERROR casting pointers to ints is unstable
//~^ ERROR casting pointers to integers
const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
//~^ ERROR casting pointers to ints is unstable
//~^ ERROR casting pointers to integers
const fn foo30_2(x: *mut u32) -> usize { x as usize }
//~^ ERROR casting pointers to ints is unstable
//~^ ERROR casting pointers to integers
const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
//~^ ERROR casting pointers to ints is unstable
//~^ ERROR casting pointers to integers
const fn foo30_6() -> bool { let x = true; x }
const fn inc(x: &mut i32) { *x += 1 }
//~^ ERROR mutable references in const fn are unstable
......
......@@ -94,7 +94,7 @@ LL | const fn foo19_2(f: f32) -> f32 { 2.0 - f }
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: only int and `bool` operations are stable in const fn
error[E0723]: only int, `bool` and `char` operations are stable in const fn
--> $DIR/min_const_fn.rs:84:35
|
LL | const fn foo19_3(f: f32) -> f32 { -f }
......@@ -112,59 +112,57 @@ LL | const fn foo19_4(f: f32, g: f32) -> f32 { f / g }
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: cannot access `static` items in const fn
error[E0013]: constant functions cannot refer to statics
--> $DIR/min_const_fn.rs:90:27
|
LL | const fn foo25() -> u32 { BAR }
| ^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0723]: cannot access `static` items in const fn
error[E0013]: constant functions cannot refer to statics
--> $DIR/min_const_fn.rs:91:37
|
LL | const fn foo26() -> &'static u32 { &BAR }
| ^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: consider extracting the value of the `static` to a `const`, and referring to that
error[E0723]: casting pointers to ints is unstable in const fn
error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/min_const_fn.rs:92:42
|
LL | const fn foo30(x: *const u32) -> usize { x as usize }
| ^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error[E0723]: casting pointers to ints is unstable in const fn
error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/min_const_fn.rs:94:63
|
LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
| ^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error[E0723]: casting pointers to ints is unstable in const fn
error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/min_const_fn.rs:96:42
|
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
| ^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error[E0723]: casting pointers to ints is unstable in const fn
error[E0658]: casting pointers to integers in constant functions is unstable
--> $DIR/min_const_fn.rs:98:63
|
LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
| ^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: see issue #51910 <https://github.com/rust-lang/rust/issues/51910> for more information
= help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable
error[E0723]: mutable references in const fn are unstable
--> $DIR/min_const_fn.rs:101:14
......@@ -267,5 +265,5 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
error: aborting due to 30 previous errors
Some errors have detailed explanations: E0493, E0723.
For more information about an error, try `rustc --explain E0493`.
Some errors have detailed explanations: E0013, E0493, E0658, E0723.
For more information about an error, try `rustc --explain E0013`.
......@@ -13,7 +13,7 @@ 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 can only call other `const fn`
const fn bar() -> u32 { foo() } //~ ERROR not yet stable as a const fn
#[unstable(feature = "rust1", issue = "none")]
const fn foo2() -> u32 { 42 }
......@@ -21,12 +21,13 @@ 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 can only call other `const fn`
const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// conformity is required, even with `const_fn` feature gate
const fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` operations
const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
//~^ ERROR const-stable function cannot use `#[feature(const_fn)]`
// check whether this function cannot be called even with the feature gate active
#[unstable(feature = "foo2", issue = "none")]
......@@ -35,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 can only call other `const fn`
const fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR not yet stable as a const fn
fn main() {}
error[E0723]: can only call other `const fn` within a `const fn`, but `foo` is not stable as `const fn`
error: `foo` is not yet stable as a const fn
--> $DIR/min_const_fn_libstd_stability.rs:16:25
|
LL | const fn bar() -> u32 { foo() }
| ^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error[E0723]: can only call other `const fn` within a `const fn`, but `foo2` is not stable as `const fn`
error: `foo2` is not yet stable as a const fn
--> $DIR/min_const_fn_libstd_stability.rs:24:26
|
LL | const fn bar2() -> u32 { foo2() }
| ^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error[E0723]: only int, `bool` and `char` operations are stable in const fn
error: const-stable function cannot use `#[feature(const_fn)]`
--> $DIR/min_const_fn_libstd_stability.rs:29:26
|
LL | const fn bar3() -> u32 { (5f32 + 6f32) as u32 }
| ^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
help: if it is not part of the public API, make this function unstably const
|
LL | #[rustc_const_unstable(feature = "...", issue = "...")]
|
error[E0723]: can only call other `const fn` within a `const fn`, but `foo2_gated` is not stable as `const fn`
--> $DIR/min_const_fn_libstd_stability.rs:38:32
error: `foo2_gated` is not yet stable as a const fn
--> $DIR/min_const_fn_libstd_stability.rs:39:32
|
LL | const fn bar2_gated() -> u32 { foo2_gated() }
| ^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0723`.
......@@ -12,5 +12,5 @@ fn main() {}
const unsafe fn no_union() {
union Foo { x: (), y: () }
Foo { x: () }.y
//~^ accessing union fields is unstable
//~^ unions in const fn
}
......@@ -25,16 +25,15 @@ LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static u
= note: see issue #51911 <https://github.com/rust-lang/rust/issues/51911> for more information
= help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable
error[E0723]: accessing union fields is unstable
error[E0658]: unions in const fn are unstable
--> $DIR/min_const_fn_unsafe_bad.rs:14:5
|
LL | Foo { x: () }.y
| ^^^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: see issue #51909 <https://github.com/rust-lang/rust/issues/51909> for more information
= help: add `#![feature(const_fn_union)]` to the crate attributes to enable
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0658, E0723.
For more information about an error, try `rustc --explain E0658`.
For more information about this error, try `rustc --explain E0658`.
......@@ -13,7 +13,7 @@
#[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 can only call other `const fn`
const unsafe fn bar() -> u32 { unsafe { foo() } } //~ ERROR not yet stable as a const fn
#[unstable(feature = "rust1", issue = "none")]
const unsafe fn foo2() -> u32 { 42 }
......@@ -21,12 +21,13 @@
#[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 can only call other `const fn`
const unsafe fn bar2() -> u32 { unsafe { foo2() } } //~ ERROR not yet stable as a const fn
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// conformity is required, even with `const_fn` feature gate
const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 } //~ ERROR only int, `bool` and `char` op
const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
//~^ ERROR const-stable function cannot use `#[feature(const_fn)]`
// check whether this function cannot be called even with the feature gate active
#[unstable(feature = "foo2", issue = "none")]
......@@ -36,6 +37,6 @@
#[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 can only call other `const fn`
//~^ ERROR not yet stable as a const fn
fn main() {}
error[E0723]: can only call other `const fn` within a `const fn`, but `foo` is not stable as `const fn`
error: `foo` is not yet stable as a const fn
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:16:41
|
LL | const unsafe fn bar() -> u32 { unsafe { foo() } }
| ^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error[E0723]: can only call other `const fn` within a `const fn`, but `foo2` is not stable as `const fn`
error: `foo2` is not yet stable as a const fn
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:24:42
|
LL | const unsafe fn bar2() -> u32 { unsafe { foo2() } }
| ^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error[E0723]: only int, `bool` and `char` operations are stable in const fn
error: const-stable function cannot use `#[feature(const_fn)]`
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:29:33
|
LL | const unsafe fn bar3() -> u32 { (5f32 + 6f32) as u32 }
| ^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= note: otherwise `#[allow_internal_unstable]` can be used to bypass stability checks
help: if it is not part of the public API, make this function unstably const
|
LL | #[rustc_const_unstable(feature = "...", issue = "...")]
|
error[E0723]: can only call other `const fn` within a `const fn`, but `foo2_gated` is not stable as `const fn`
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:38:48
error: `foo2_gated` is not yet stable as a const fn
--> $DIR/min_const_unsafe_fn_libstd_stability.rs:39:48
|
LL | const unsafe fn bar2_gated() -> u32 { unsafe { foo2_gated() } }
| ^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0723`.
......@@ -13,7 +13,7 @@ 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 can only call other `const fn`
const unsafe fn bar() -> u32 { foo() } //~ ERROR not yet stable as a const fn
#[unstable(feature = "rust1", issue = "none")]
const fn foo2() -> u32 { 42 }
......@@ -21,7 +21,7 @@ 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 can only call other `const fn`
const unsafe fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
// check whether this function cannot be called even with the feature gate active
#[unstable(feature = "foo2", issue = "none")]
......@@ -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 can only call other `const fn`
const unsafe fn bar2_gated() -> u32 { foo2_gated() } //~ ERROR not yet stable as a const fn
fn main() {}
error[E0723]: can only call other `const fn` within a `const fn`, but `foo` is not stable as `const fn`
error: `foo` is not yet stable as a const fn
--> $DIR/min_const_unsafe_fn_libstd_stability2.rs:16:32
|
LL | const unsafe fn bar() -> u32 { foo() }
| ^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error[E0723]: can only call other `const fn` within a `const fn`, but `foo2` is not stable as `const fn`
error: `foo2` is not yet stable as a const fn
--> $DIR/min_const_unsafe_fn_libstd_stability2.rs:24:33
|
LL | const unsafe fn bar2() -> u32 { foo2() }
| ^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error[E0723]: can only call other `const fn` within a `const fn`, but `foo2_gated` is not stable as `const fn`
error: `foo2_gated` is not yet stable as a const fn
--> $DIR/min_const_unsafe_fn_libstd_stability2.rs:33:39
|
LL | const unsafe fn bar2_gated() -> u32 { foo2_gated() }
| ^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0723`.
......@@ -12,6 +12,16 @@ LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "
warning: skipping const checks
|
help: skipping check for `const_fn` feature
--> $DIR/abi-mismatch.rs:9:23
|
LL | const fn call_rust_fn(my_fn: extern "Rust" fn()) {
| ^^^^^
help: skipping check for `const_fn` feature
--> $DIR/abi-mismatch.rs:10:5
|
LL | my_fn();
| ^^^^^
help: skipping check that does not even have a feature gate
--> $DIR/abi-mismatch.rs:10:5
|
......
......@@ -4,7 +4,7 @@
pub const fn dangling_slice<T>() -> NonNull<[T]> {
NonNull::<[T; 0]>::dangling()
//~^ ERROR: unsizing casts are only allowed for references right now
//~^ ERROR: unsizing casts to types besides slices
}
fn main() {}
error[E0723]: unsizing casts are only allowed for references right now
error[E0723]: unsizing casts to types besides slices are not allowed in const fn
--> $DIR/unsizing-cast-non-null.rs:6:5
|
LL | NonNull::<[T; 0]>::dangling()
......
......@@ -6,6 +6,7 @@
#![stable(feature = "core", since = "1.6.0")]
#![feature(rustc_const_unstable)]
#![feature(staged_api)]
#![feature(const_fn)]
enum Opt<T> {
Some(T),
......
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/unstable-const-fn-in-libcore.rs:23:26
--> $DIR/unstable-const-fn-in-libcore.rs:24:26
|
LL | Opt::None => f(),
| ^^^
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:18:53
--> $DIR/unstable-const-fn-in-libcore.rs:19:53
|
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
| ^ constant functions cannot evaluate destructors
......@@ -14,7 +14,7 @@ LL | }
| - value is dropped here
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/unstable-const-fn-in-libcore.rs:18:47
--> $DIR/unstable-const-fn-in-libcore.rs:19:47
|
LL | const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
| ^^^^ constant functions cannot evaluate destructors
......
......@@ -12,6 +12,7 @@ const fn ff3() {} // OK.
extern "C" fn ff4() {} // OK.
const async unsafe extern "C" fn ff5() {} // OK.
//~^ ERROR functions cannot be both `const` and `async`
//~| ERROR `from_generator` is not yet stable as a const fn
trait X {
async fn ft1(); //~ ERROR functions in traits cannot be declared `async`
......@@ -34,6 +35,7 @@ extern "C" fn ft4() {}
const async unsafe extern "C" fn ft5() {}
//~^ ERROR functions in traits cannot be declared `async`
//~| ERROR functions in traits cannot be declared const
//~| ERROR `from_generator` is not yet stable as a const fn
//~| ERROR method `ft5` has an incompatible type for trait
//~| ERROR functions cannot be both `const` and `async`
}
......@@ -45,6 +47,7 @@ const fn fi3() {} // OK.
extern "C" fn fi4() {} // OK.
const async unsafe extern "C" fn fi5() {}
//~^ ERROR functions cannot be both `const` and `async`
//~| ERROR `from_generator` is not yet stable as a const fn
}
extern {
......
......@@ -8,7 +8,7 @@ LL | const async unsafe extern "C" fn ff5() {} // OK.
| `const` because of this
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:17:9
--> $DIR/fn-header-semantic-fail.rs:18:9
|
LL | async fn ft1();
| -----^^^^^^^^^^
......@@ -19,19 +19,19 @@ LL | async fn ft1();
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:19:9
--> $DIR/fn-header-semantic-fail.rs:20:9
|
LL | const fn ft3();
| ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:21:9
--> $DIR/fn-header-semantic-fail.rs:22:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^ functions in traits cannot be const
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:21:9
--> $DIR/fn-header-semantic-fail.rs:22:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -42,7 +42,7 @@ LL | const async unsafe extern "C" fn ft5();
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:21:9
--> $DIR/fn-header-semantic-fail.rs:22:9
|
LL | const async unsafe extern "C" fn ft5();
| ^^^^^-^^^^^----------------------------
......@@ -51,7 +51,7 @@ LL | const async unsafe extern "C" fn ft5();
| `const` because of this
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:29:9
--> $DIR/fn-header-semantic-fail.rs:30:9
|
LL | async fn ft1() {}
| -----^^^^^^^^^^^^
......@@ -62,19 +62,19 @@ LL | async fn ft1() {}
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:32:9
--> $DIR/fn-header-semantic-fail.rs:33:9
|
LL | const fn ft3() {}
| ^^^^^ functions in traits cannot be const
error[E0379]: functions in traits cannot be declared const
--> $DIR/fn-header-semantic-fail.rs:34:9
--> $DIR/fn-header-semantic-fail.rs:35:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^ functions in traits cannot be const
error[E0706]: functions in traits cannot be declared `async`
--> $DIR/fn-header-semantic-fail.rs:34:9
--> $DIR/fn-header-semantic-fail.rs:35:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......@@ -85,7 +85,7 @@ LL | const async unsafe extern "C" fn ft5() {}
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:34:9
--> $DIR/fn-header-semantic-fail.rs:35:9
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^^^^-^^^^^------------------------------
......@@ -94,7 +94,7 @@ LL | const async unsafe extern "C" fn ft5() {}
| `const` because of this
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:46:9
--> $DIR/fn-header-semantic-fail.rs:48:9
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^^^^-^^^^^------------------------------
......@@ -103,7 +103,7 @@ LL | const async unsafe extern "C" fn fi5() {}
| `const` because of this
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:51:18
--> $DIR/fn-header-semantic-fail.rs:54:18
|
LL | extern {
| ------ in this `extern` block
......@@ -113,7 +113,7 @@ LL | async fn fe1();
| help: remove the qualifiers: `fn`
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:52:19
--> $DIR/fn-header-semantic-fail.rs:55:19
|
LL | extern {
| ------ in this `extern` block
......@@ -124,7 +124,7 @@ LL | unsafe fn fe2();
| help: remove the qualifiers: `fn`
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:53:18
--> $DIR/fn-header-semantic-fail.rs:56:18
|
LL | extern {
| ------ in this `extern` block
......@@ -135,7 +135,7 @@ LL | const fn fe3();
| help: remove the qualifiers: `fn`
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:54:23
--> $DIR/fn-header-semantic-fail.rs:57:23
|
LL | extern {
| ------ in this `extern` block
......@@ -146,7 +146,7 @@ LL | extern "C" fn fe4();
| help: remove the qualifiers: `fn`
error: functions in `extern` blocks cannot have qualifiers
--> $DIR/fn-header-semantic-fail.rs:55:42
--> $DIR/fn-header-semantic-fail.rs:58:42
|
LL | extern {
| ------ in this `extern` block
......@@ -157,7 +157,7 @@ LL | const async unsafe extern "C" fn fe5();
| help: remove the qualifiers: `fn`
error: functions cannot be both `const` and `async`
--> $DIR/fn-header-semantic-fail.rs:55:9
--> $DIR/fn-header-semantic-fail.rs:58:9
|
LL | const async unsafe extern "C" fn fe5();
| ^^^^^-^^^^^----------------------------
......@@ -165,8 +165,16 @@ LL | const async unsafe extern "C" fn fe5();
| | `async` because of this
| `const` because of this
error: `from_generator` is not yet stable as a const fn
--> $DIR/fn-header-semantic-fail.rs:13:44
|
LL | const async unsafe extern "C" fn ff5() {} // OK.
| ^^
|
= help: add `#![feature(gen_future)]` to the crate attributes to enable
error[E0053]: method `ft1` has an incompatible type for trait
--> $DIR/fn-header-semantic-fail.rs:29:24
--> $DIR/fn-header-semantic-fail.rs:30:24
|
LL | async fn ft1();
| - type in trait
......@@ -181,7 +189,7 @@ LL | async fn ft1() {}
found fn pointer `fn() -> impl Future`
error[E0053]: method `ft5` has an incompatible type for trait
--> $DIR/fn-header-semantic-fail.rs:34:48
--> $DIR/fn-header-semantic-fail.rs:35:48
|
LL | const async unsafe extern "C" fn ft5();
| - type in trait
......@@ -195,7 +203,23 @@ LL | const async unsafe extern "C" fn ft5() {}
= note: expected fn pointer `unsafe extern "C" fn()`
found fn pointer `unsafe extern "C" fn() -> impl Future`
error: aborting due to 20 previous errors
error: `from_generator` is not yet stable as a const fn
--> $DIR/fn-header-semantic-fail.rs:35:48
|
LL | const async unsafe extern "C" fn ft5() {}
| ^^
|
= help: add `#![feature(gen_future)]` to the crate attributes to enable
error: `from_generator` is not yet stable as a const fn
--> $DIR/fn-header-semantic-fail.rs:48:48
|
LL | const async unsafe extern "C" fn fi5() {}
| ^^
|
= help: add `#![feature(gen_future)]` to the crate attributes to enable
error: aborting due to 23 previous errors
Some errors have detailed explanations: E0053, E0379, E0706.
For more information about an error, try `rustc --explain E0053`.
......@@ -10,7 +10,7 @@ fn non_const() {}
impl const T for S {
fn foo() { non_const() }
//~^ ERROR can only call other `const fn`
//~^ ERROR calls in constant functions
}
fn main() {}
error[E0723]: can only call other `const fn` within a `const fn`, but `non_const` is not stable as `const fn`
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/const-check-fns-in-const-impl.rs:12:16
|
LL | fn foo() { non_const() }
| ^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0723`.
For more information about this error, try `rustc --explain E0015`.
error: fatal error triggered by #[rustc_error]
--> $DIR/feature-gate.rs:16:1
--> $DIR/feature-gate.rs:17:1
|
LL | fn main() {}
| ^^^^^^^^^
......
......@@ -4,6 +4,7 @@
#![cfg_attr(gated, feature(const_trait_bound_opt_out))]
#![allow(incomplete_features)]
#![feature(rustc_attrs)]
#![feature(const_fn)]
trait T {
const CONST: i32;
......
error[E0658]: `?const` on trait bounds is experimental
--> $DIR/feature-gate.rs:12:29
--> $DIR/feature-gate.rs:13:29
|
LL | const fn get_assoc_const<S: ?const T>() -> i32 { <S as T>::CONST }
| ^^^^^^
......
......@@ -30,7 +30,7 @@ fn add(self, rhs: Self) -> Self {
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
pub const fn foo() -> Int {
Int(1i32) + Int(2i32)
//~^ ERROR can only call other `const fn` within a `const fn`
//~^ ERROR not yet stable as a const fn
}
// ok
......
......@@ -6,18 +6,14 @@ LL | |
LL | | Int(self.0 - rhs.0)
LL | | }
| |_____^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
error[E0723]: can only call other `const fn` within a `const fn`, but `<Int as Add>::add` is not stable as `const fn`
error: `<Int as Add>::add` is not yet stable as a const fn
--> $DIR/stability.rs:32:5
|
LL | Int(1i32) + Int(2i32)
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= help: add `#![feature(const_fn)]` to the crate attributes to enable
= help: Const-stable functions can only call other const-stable functions
error: aborting due to 2 previous errors
......
......@@ -8,13 +8,13 @@ fn main() {
const fn foo() -> NonZero<u32> {
let mut x = unsafe { NonZero(1) };
let y = &mut x.0; //~ ERROR references in const fn are unstable
let y = &mut x.0; //~ ERROR mutable references
//~^ ERROR mutation of layout constrained field is unsafe
unsafe { NonZero(1) }
}
const fn bar() -> NonZero<u32> {
let mut x = unsafe { NonZero(1) };
let y = unsafe { &mut x.0 }; //~ ERROR mutable references in const fn are unstable
let y = unsafe { &mut x.0 }; //~ ERROR mutable references
unsafe { NonZero(1) }
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册