also stabilize const_refs_to_cell

This commit is contained in:
Ralf Jung 2024-08-26 14:51:16 +02:00
parent 544a6a7df3
commit 49316f871c
38 changed files with 130 additions and 324 deletions

View File

@ -134,9 +134,6 @@ const_eval_incompatible_return_types =
const_eval_incompatible_types = const_eval_incompatible_types =
calling a function with argument of type {$callee_ty} passing data of type {$caller_ty} calling a function with argument of type {$callee_ty} passing data of type {$caller_ty}
const_eval_interior_mutability_borrow =
cannot borrow here, since the borrowed element may contain interior mutability
const_eval_interior_mutable_data_refer = const_eval_interior_mutable_data_refer =
{const_eval_const_context}s cannot refer to interior mutable data {const_eval_const_context}s cannot refer to interior mutable data
.label = this borrow of an interior mutable value may end up in the final value .label = this borrow of an interior mutable value may end up in the final value

View File

@ -320,7 +320,10 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
self.check_op_spanned(ops::StaticAccess, span) self.check_op_spanned(ops::StaticAccess, span)
} }
fn check_mut_borrow(&mut self, place: &Place<'_>, kind: hir::BorrowKind) { /// Returns whether this place can possibly escape the evaluation of the current const/static
/// initializer. The check assumes that all already existing pointers and references point to
/// non-escaping places.
fn place_may_escape(&mut self, place: &Place<'_>) -> bool {
let is_transient = match self.const_kind() { let is_transient = match self.const_kind() {
// In a const fn all borrows are transient or point to the places given via // In a const fn all borrows are transient or point to the places given via
// references in the arguments (so we already checked them with // references in the arguments (so we already checked them with
@ -341,14 +344,16 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
// value of the constant. // value of the constant.
// Note: This is only sound if every local that has a `StorageDead` has a // Note: This is only sound if every local that has a `StorageDead` has a
// `StorageDead` in every control flow path leading to a `return` terminator. // `StorageDead` in every control flow path leading to a `return` terminator.
// The good news is that interning will detect if any unexpected mutable // If anything slips through, there's no safety net -- safe code can create
// pointer slips through. // references to variants of `!Freeze` enums as long as that variant is `Freeze`, so
// interning can't protect us here. (There *is* a safety net for mutable references
// though, interning will ICE if we miss something here.)
place.is_indirect() || self.local_is_transient(place.local) place.is_indirect() || self.local_is_transient(place.local)
} }
}; };
if !is_transient { // Transient places cannot possibly escape because the place doesn't exist any more at the
self.check_op(ops::EscapingMutBorrow(kind)); // end of evaluation.
} !is_transient
} }
} }
@ -406,15 +411,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let is_allowed = let is_allowed =
self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut); self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut);
if !is_allowed { if !is_allowed && self.place_may_escape(place) {
self.check_mut_borrow( self.check_op(ops::EscapingMutBorrow(if matches!(rvalue, Rvalue::Ref(..)) {
place, hir::BorrowKind::Ref
if matches!(rvalue, Rvalue::Ref(..)) { } else {
hir::BorrowKind::Ref hir::BorrowKind::Raw
} else { }));
hir::BorrowKind::Raw
},
);
} }
} }
@ -426,51 +428,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
place.as_ref(), place.as_ref(),
); );
// If the place is indirect, this is basically a reborrow. We have a reborrow if borrowed_place_has_mut_interior && self.place_may_escape(place) {
// special case above, but for raw pointers and pointers/references to `static` and self.check_op(ops::EscapingCellBorrow);
// when the `*` is not the first projection, `place_as_reborrow` does not recognize
// them as such, so we end up here. This should probably be considered a
// `TransientCellBorrow` (we consider the equivalent mutable case a
// `TransientMutBorrow`), but such reborrows got accidentally stabilized already and
// it is too much of a breaking change to take back.
// However, we only want to consider places that are obtained by dereferencing
// a *shared* reference. Mutable references to interior mutable data are stable,
// and we don't want `&*&mut interior_mut` to be accepted.
let is_indirect = place.iter_projections().any(|(base, proj)| {
matches!(proj, ProjectionElem::Deref)
&& matches!(
base.ty(self.body, self.tcx).ty.kind(),
ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not)
)
});
if borrowed_place_has_mut_interior && !is_indirect {
match self.const_kind() {
// In a const fn all borrows are transient or point to the places given via
// references in the arguments (so we already checked them with
// TransientCellBorrow/CellBorrow as appropriate).
// The borrow checker guarantees that no new non-transient borrows are created.
// NOTE: Once we have heap allocations during CTFE we need to figure out
// how to prevent `const fn` to create long-lived allocations that point
// to (interior) mutable memory.
hir::ConstContext::ConstFn => self.check_op(ops::TransientCellBorrow),
_ => {
// Locals with StorageDead are definitely not part of the final constant value, and
// it is thus inherently safe to permit such locals to have their
// address taken as we can't end up with a reference to them in the
// final value.
// Note: This is only sound if every local that has a `StorageDead` has a
// `StorageDead` in every control flow path leading to a `return` terminator.
// If anything slips through, there's no safety net -- safe code can create
// references to variants of `!Freeze` enums as long as that variant is `Freeze`,
// so interning can't protect us here.
if self.local_is_transient(place.local) {
self.check_op(ops::TransientCellBorrow);
} else {
self.check_op(ops::CellBorrow);
}
}
}
} }
} }

View File

@ -391,27 +391,12 @@ impl<'tcx> NonConstOp<'tcx> for LiveDrop<'tcx> {
} }
} }
#[derive(Debug)]
/// A borrow of a type that contains an `UnsafeCell` somewhere. The borrow never escapes to
/// the final value of the constant.
pub(crate) struct TransientCellBorrow;
impl<'tcx> NonConstOp<'tcx> for TransientCellBorrow {
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_refs_to_cell)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
ccx.tcx
.sess
.create_feature_err(errors::InteriorMutabilityBorrow { span }, sym::const_refs_to_cell)
}
}
#[derive(Debug)] #[derive(Debug)]
/// A borrow of a type that contains an `UnsafeCell` somewhere. The borrow might escape to /// A borrow of a type that contains an `UnsafeCell` somewhere. The borrow might escape to
/// the final value of the constant, and thus we cannot allow this (for now). We may allow /// the final value of the constant, and thus we cannot allow this (for now). We may allow
/// it in the future for static items. /// it in the future for static items.
pub(crate) struct CellBorrow; pub(crate) struct EscapingCellBorrow;
impl<'tcx> NonConstOp<'tcx> for CellBorrow { impl<'tcx> NonConstOp<'tcx> for EscapingCellBorrow {
fn importance(&self) -> DiagImportance { fn importance(&self) -> DiagImportance {
// Most likely the code will try to do mutation with these borrows, which // Most likely the code will try to do mutation with these borrows, which
// triggers its own errors. Only show this one if that does not happen. // triggers its own errors. Only show this one if that does not happen.

View File

@ -193,13 +193,6 @@ pub(crate) struct InteriorMutableDataRefer {
pub teach: bool, pub teach: bool,
} }
#[derive(Diagnostic)]
#[diag(const_eval_interior_mutability_borrow)]
pub(crate) struct InteriorMutabilityBorrow {
#[primary_span]
pub span: Span,
}
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(const_eval_long_running)] #[diag(const_eval_long_running)]
#[note] #[note]

View File

@ -149,6 +149,8 @@ declare_features! (
(accepted, const_panic, "1.57.0", Some(51999)), (accepted, const_panic, "1.57.0", Some(51999)),
/// Allows dereferencing raw pointers during const eval. /// Allows dereferencing raw pointers during const eval.
(accepted, const_raw_ptr_deref, "1.58.0", Some(51911)), (accepted, const_raw_ptr_deref, "1.58.0", Some(51911)),
/// Allows references to types with interior mutability within constants
(accepted, const_refs_to_cell, "CURRENT_RUSTC_VERSION", Some(80384)),
/// Allows implementing `Copy` for closures where possible (RFC 2132). /// Allows implementing `Copy` for closures where possible (RFC 2132).
(accepted, copy_closures, "1.26.0", Some(44490)), (accepted, copy_closures, "1.26.0", Some(44490)),
/// Allows `crate` in paths. /// Allows `crate` in paths.

View File

@ -405,8 +405,6 @@ declare_features! (
(unstable, const_for, "1.56.0", Some(87575)), (unstable, const_for, "1.56.0", Some(87575)),
/// Be more precise when looking for live drops in a const context. /// Be more precise when looking for live drops in a const context.
(unstable, const_precise_live_drops, "1.46.0", Some(73255)), (unstable, const_precise_live_drops, "1.46.0", Some(73255)),
/// Allows references to types with interior mutability within constants
(unstable, const_refs_to_cell, "1.51.0", Some(80384)),
/// Allows creating pointers and references to `static` items in constants. /// Allows creating pointers and references to `static` items in constants.
(unstable, const_refs_to_static, "1.78.0", Some(119618)), (unstable, const_refs_to_static, "1.78.0", Some(119618)),
/// Allows `impl const Trait for T` syntax. /// Allows `impl const Trait for T` syntax.

View File

@ -114,7 +114,6 @@
#![feature(const_maybe_uninit_write)] #![feature(const_maybe_uninit_write)]
#![feature(const_option)] #![feature(const_option)]
#![feature(const_pin)] #![feature(const_pin)]
#![feature(const_refs_to_cell)]
#![feature(const_size_of_val)] #![feature(const_size_of_val)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(deprecated_suggestion)] #![feature(deprecated_suggestion)]
@ -165,6 +164,7 @@
// Language features: // Language features:
// tidy-alphabetical-start // tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))] #![cfg_attr(bootstrap, feature(const_mut_refs))]
#![cfg_attr(bootstrap, feature(const_refs_to_cell))]
#![cfg_attr(not(test), feature(coroutine_trait))] #![cfg_attr(not(test), feature(coroutine_trait))]
#![cfg_attr(test, feature(panic_update_hook))] #![cfg_attr(test, feature(panic_update_hook))]
#![cfg_attr(test, feature(test))] #![cfg_attr(test, feature(test))]

View File

@ -192,6 +192,7 @@
// Language features: // Language features:
// tidy-alphabetical-start // tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))] #![cfg_attr(bootstrap, feature(const_mut_refs))]
#![cfg_attr(bootstrap, feature(const_refs_to_cell))]
#![feature(abi_unadjusted)] #![feature(abi_unadjusted)]
#![feature(adt_const_params)] #![feature(adt_const_params)]
#![feature(allow_internal_unsafe)] #![feature(allow_internal_unsafe)]
@ -203,7 +204,6 @@
#![feature(cfg_ub_checks)] #![feature(cfg_ub_checks)]
#![feature(const_for)] #![feature(const_for)]
#![feature(const_precise_live_drops)] #![feature(const_precise_live_drops)]
#![feature(const_refs_to_cell)]
#![feature(decl_macro)] #![feature(decl_macro)]
#![feature(deprecated_suggestion)] #![feature(deprecated_suggestion)]
#![feature(doc_cfg)] #![feature(doc_cfg)]

View File

@ -846,7 +846,7 @@ impl<T> [T] {
/// [`as_mut_ptr`]: slice::as_mut_ptr /// [`as_mut_ptr`]: slice::as_mut_ptr
#[stable(feature = "slice_ptr_range", since = "1.48.0")] #[stable(feature = "slice_ptr_range", since = "1.48.0")]
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
#[rustc_allow_const_fn_unstable(const_mut_refs, const_refs_to_cell)] #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs, const_refs_to_cell))]
#[inline] #[inline]
#[must_use] #[must_use]
pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> { pub const fn as_mut_ptr_range(&mut self) -> Range<*mut T> {

View File

@ -1,14 +1,15 @@
//@check-pass
use std::cell::Cell; use std::cell::Cell;
const A: () = { let x = Cell::new(2); &raw const x; }; //~ ERROR interior mutability const A: () = { let x = Cell::new(2); &raw const x; };
static B: () = { let x = Cell::new(2); &raw const x; }; //~ ERROR interior mutability static B: () = { let x = Cell::new(2); &raw const x; };
static mut C: () = { let x = Cell::new(2); &raw const x; }; //~ ERROR interior mutability static mut C: () = { let x = Cell::new(2); &raw const x; };
const fn foo() { const fn foo() {
let x = Cell::new(0); let x = Cell::new(0);
let y = &raw const x; //~ ERROR interior mutability let y = &raw const x;
} }
fn main() {} fn main() {}

View File

@ -1,43 +0,0 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/const-address-of-interior-mut.rs:3:39
|
LL | const A: () = { let x = Cell::new(2); &raw const x; };
| ^^^^^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/const-address-of-interior-mut.rs:5:40
|
LL | static B: () = { let x = Cell::new(2); &raw const x; };
| ^^^^^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/const-address-of-interior-mut.rs:7:44
|
LL | static mut C: () = { let x = Cell::new(2); &raw const x; };
| ^^^^^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/const-address-of-interior-mut.rs:11:13
|
LL | let y = &raw const x;
| ^^^^^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,5 +1,4 @@
//! Ensure we catch UB due to writing through a shared reference. //! Ensure we catch UB due to writing through a shared reference.
#![feature(const_refs_to_cell)]
#![allow(invalid_reference_casting)] #![allow(invalid_reference_casting)]
use std::mem; use std::mem;

View File

@ -1,11 +1,11 @@
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-write-through-immutable.rs:11:5 --> $DIR/ub-write-through-immutable.rs:10:5
| |
LL | *ptr = 0; LL | *ptr = 0;
| ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference | ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference
error[E0080]: evaluation of constant value failed error[E0080]: evaluation of constant value failed
--> $DIR/ub-write-through-immutable.rs:18:5 --> $DIR/ub-write-through-immutable.rs:17:5
| |
LL | *ptr = 0; LL | *ptr = 0;
| ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference | ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference

View File

@ -1,30 +1,20 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/const-promoted-opaque.rs:28:25
|
LL | let _: &'static _ = &FOO;
| ^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time
--> $DIR/const-promoted-opaque.rs:28:26 --> $DIR/const-promoted-opaque.rs:28:26
| |
LL | let _: &'static _ = &FOO; LL | let _: &'static _ = &FOO;
| ^^^ the destructor for this type cannot be evaluated in constants | ^^^ the destructor for this type cannot be evaluated in constants
... LL |
LL | }; LL | };
| - value is dropped here | - value is dropped here
error[E0492]: constants cannot refer to interior mutable data error[E0492]: constants cannot refer to interior mutable data
--> $DIR/const-promoted-opaque.rs:33:19 --> $DIR/const-promoted-opaque.rs:32:19
| |
LL | const BAZ: &Foo = &FOO; LL | const BAZ: &Foo = &FOO;
| ^^^^ this borrow of an interior mutable value may end up in the final value | ^^^^ this borrow of an interior mutable value may end up in the final value
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/const-promoted-opaque.rs:37:26 --> $DIR/const-promoted-opaque.rs:36:26
| |
LL | let _: &'static _ = &FOO; LL | let _: &'static _ = &FOO;
| ---------- ^^^ creates a temporary value which is freed while still in use | ---------- ^^^ creates a temporary value which is freed while still in use
@ -34,7 +24,7 @@ LL |
LL | } LL | }
| - temporary value is freed at the end of this statement | - temporary value is freed at the end of this statement
error: aborting due to 4 previous errors error: aborting due to 3 previous errors
Some errors have detailed explanations: E0492, E0493, E0658, E0716. Some errors have detailed explanations: E0492, E0493, E0716.
For more information about an error, try `rustc --explain E0492`. For more information about an error, try `rustc --explain E0492`.

View File

@ -27,7 +27,6 @@ use helper::*;
const BAR: () = { const BAR: () = {
let _: &'static _ = &FOO; let _: &'static _ = &FOO;
//[string,atomic]~^ ERROR: destructor of `helper::Foo` cannot be evaluated at compile-time //[string,atomic]~^ ERROR: destructor of `helper::Foo` cannot be evaluated at compile-time
//[atomic]~| ERROR: cannot borrow here
}; };
const BAZ: &Foo = &FOO; const BAZ: &Foo = &FOO;

View File

@ -3,12 +3,12 @@ error[E0493]: destructor of `helper::Foo` cannot be evaluated at compile-time
| |
LL | let _: &'static _ = &FOO; LL | let _: &'static _ = &FOO;
| ^^^ the destructor for this type cannot be evaluated in constants | ^^^ the destructor for this type cannot be evaluated in constants
... LL |
LL | }; LL | };
| - value is dropped here | - value is dropped here
error[E0716]: temporary value dropped while borrowed error[E0716]: temporary value dropped while borrowed
--> $DIR/const-promoted-opaque.rs:37:26 --> $DIR/const-promoted-opaque.rs:36:26
| |
LL | let _: &'static _ = &FOO; LL | let _: &'static _ = &FOO;
| ---------- ^^^ creates a temporary value which is freed while still in use | ---------- ^^^ creates a temporary value which is freed while still in use

View File

@ -1,10 +1,10 @@
//@compile-flags: --edition 2018
use std::cell::Cell; use std::cell::Cell;
const WRITE: () = unsafe { const WRITE: () = unsafe {
let x = Cell::new(0); let x = async { 13 };
let y = &x; //~^ ERROR `async` blocks
//~^ ERROR interior mutability //~| HELP add `#![feature(const_async_blocks)]` to the crate attributes to enable
//~| HELP add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
}; };
fn main() {} fn main() {}

View File

@ -1,11 +1,11 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability error[E0658]: `async` blocks are not allowed in constants
--> $DIR/const-suggest-feature.rs:5:13 --> $DIR/const-suggest-feature.rs:5:13
| |
LL | let y = &x; LL | let x = async { 13 };
| ^^ | ^^^^^^^^^^^^
| |
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -5,7 +5,6 @@
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(const_trait_impl)] #![feature(const_trait_impl)]
#![feature(const_cmp)] #![feature(const_cmp)]
#![feature(const_refs_to_cell)]
use std::marker::Destruct; use std::marker::Destruct;

View File

@ -11,19 +11,19 @@ LL | #![feature(const_cmp)]
| ^^^^^^^^^ | ^^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:14:15 --> $DIR/fn_trait_refs.rs:13:15
| |
LL | T: ~const Fn<()> + ~const Destruct, LL | T: ~const Fn<()> + ~const Destruct,
| ^^^^^^ | ^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:14:31 --> $DIR/fn_trait_refs.rs:13:31
| |
LL | T: ~const Fn<()> + ~const Destruct, LL | T: ~const Fn<()> + ~const Destruct,
| ^^^^^^^^ | ^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:14:15 --> $DIR/fn_trait_refs.rs:13:15
| |
LL | T: ~const Fn<()> + ~const Destruct, LL | T: ~const Fn<()> + ~const Destruct,
| ^^^^^^ | ^^^^^^
@ -31,19 +31,19 @@ LL | T: ~const Fn<()> + ~const Destruct,
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:21:15 --> $DIR/fn_trait_refs.rs:20:15
| |
LL | T: ~const FnMut<()> + ~const Destruct, LL | T: ~const FnMut<()> + ~const Destruct,
| ^^^^^^^^^ | ^^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:21:34 --> $DIR/fn_trait_refs.rs:20:34
| |
LL | T: ~const FnMut<()> + ~const Destruct, LL | T: ~const FnMut<()> + ~const Destruct,
| ^^^^^^^^ | ^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:21:15 --> $DIR/fn_trait_refs.rs:20:15
| |
LL | T: ~const FnMut<()> + ~const Destruct, LL | T: ~const FnMut<()> + ~const Destruct,
| ^^^^^^^^^ | ^^^^^^^^^
@ -51,13 +51,13 @@ LL | T: ~const FnMut<()> + ~const Destruct,
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:28:15 --> $DIR/fn_trait_refs.rs:27:15
| |
LL | T: ~const FnOnce<()>, LL | T: ~const FnOnce<()>,
| ^^^^^^^^^^ | ^^^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:28:15 --> $DIR/fn_trait_refs.rs:27:15
| |
LL | T: ~const FnOnce<()>, LL | T: ~const FnOnce<()>,
| ^^^^^^^^^^ | ^^^^^^^^^^
@ -65,19 +65,19 @@ LL | T: ~const FnOnce<()>,
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:35:15 --> $DIR/fn_trait_refs.rs:34:15
| |
LL | T: ~const Fn<()> + ~const Destruct, LL | T: ~const Fn<()> + ~const Destruct,
| ^^^^^^ | ^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:35:31 --> $DIR/fn_trait_refs.rs:34:31
| |
LL | T: ~const Fn<()> + ~const Destruct, LL | T: ~const Fn<()> + ~const Destruct,
| ^^^^^^^^ | ^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:35:15 --> $DIR/fn_trait_refs.rs:34:15
| |
LL | T: ~const Fn<()> + ~const Destruct, LL | T: ~const Fn<()> + ~const Destruct,
| ^^^^^^ | ^^^^^^
@ -85,19 +85,19 @@ LL | T: ~const Fn<()> + ~const Destruct,
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:49:15 --> $DIR/fn_trait_refs.rs:48:15
| |
LL | T: ~const FnMut<()> + ~const Destruct, LL | T: ~const FnMut<()> + ~const Destruct,
| ^^^^^^^^^ | ^^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:49:34 --> $DIR/fn_trait_refs.rs:48:34
| |
LL | T: ~const FnMut<()> + ~const Destruct, LL | T: ~const FnMut<()> + ~const Destruct,
| ^^^^^^^^ | ^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/fn_trait_refs.rs:49:15 --> $DIR/fn_trait_refs.rs:48:15
| |
LL | T: ~const FnMut<()> + ~const Destruct, LL | T: ~const FnMut<()> + ~const Destruct,
| ^^^^^^^^^ | ^^^^^^^^^
@ -105,7 +105,7 @@ LL | T: ~const FnMut<()> + ~const Destruct,
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0015]: cannot call non-const operator in constants error[E0015]: cannot call non-const operator in constants
--> $DIR/fn_trait_refs.rs:71:17 --> $DIR/fn_trait_refs.rs:70:17
| |
LL | assert!(test_one == (1, 1, 1)); LL | assert!(test_one == (1, 1, 1));
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
@ -117,7 +117,7 @@ LL + #![feature(effects)]
| |
error[E0015]: cannot call non-const operator in constants error[E0015]: cannot call non-const operator in constants
--> $DIR/fn_trait_refs.rs:74:17 --> $DIR/fn_trait_refs.rs:73:17
| |
LL | assert!(test_two == (2, 2)); LL | assert!(test_two == (2, 2));
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
@ -129,7 +129,7 @@ LL + #![feature(effects)]
| |
error[E0015]: cannot call non-const closure in constant functions error[E0015]: cannot call non-const closure in constant functions
--> $DIR/fn_trait_refs.rs:16:5 --> $DIR/fn_trait_refs.rs:15:5
| |
LL | f() LL | f()
| ^^^ | ^^^
@ -145,7 +145,7 @@ LL + #![feature(effects)]
| |
error[E0493]: destructor of `T` cannot be evaluated at compile-time error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/fn_trait_refs.rs:12:23 --> $DIR/fn_trait_refs.rs:11:23
| |
LL | const fn tester_fn<T>(f: T) -> T::Output LL | const fn tester_fn<T>(f: T) -> T::Output
| ^ the destructor for this type cannot be evaluated in constant functions | ^ the destructor for this type cannot be evaluated in constant functions
@ -154,7 +154,7 @@ LL | }
| - value is dropped here | - value is dropped here
error[E0015]: cannot call non-const closure in constant functions error[E0015]: cannot call non-const closure in constant functions
--> $DIR/fn_trait_refs.rs:23:5 --> $DIR/fn_trait_refs.rs:22:5
| |
LL | f() LL | f()
| ^^^ | ^^^
@ -170,7 +170,7 @@ LL + #![feature(effects)]
| |
error[E0493]: destructor of `T` cannot be evaluated at compile-time error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/fn_trait_refs.rs:19:27 --> $DIR/fn_trait_refs.rs:18:27
| |
LL | const fn tester_fn_mut<T>(mut f: T) -> T::Output LL | const fn tester_fn_mut<T>(mut f: T) -> T::Output
| ^^^^^ the destructor for this type cannot be evaluated in constant functions | ^^^^^ the destructor for this type cannot be evaluated in constant functions
@ -179,7 +179,7 @@ LL | }
| - value is dropped here | - value is dropped here
error[E0015]: cannot call non-const closure in constant functions error[E0015]: cannot call non-const closure in constant functions
--> $DIR/fn_trait_refs.rs:30:5 --> $DIR/fn_trait_refs.rs:29:5
| |
LL | f() LL | f()
| ^^^ | ^^^
@ -195,7 +195,7 @@ LL + #![feature(effects)]
| |
error[E0493]: destructor of `T` cannot be evaluated at compile-time error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/fn_trait_refs.rs:33:21 --> $DIR/fn_trait_refs.rs:32:21
| |
LL | const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output) LL | const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
| ^^^^^ the destructor for this type cannot be evaluated in constant functions | ^^^^^ the destructor for this type cannot be evaluated in constant functions
@ -204,7 +204,7 @@ LL | }
| - value is dropped here | - value is dropped here
error[E0493]: destructor of `T` cannot be evaluated at compile-time error[E0493]: destructor of `T` cannot be evaluated at compile-time
--> $DIR/fn_trait_refs.rs:47:25 --> $DIR/fn_trait_refs.rs:46:25
| |
LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output) LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
| ^^^^^ the destructor for this type cannot be evaluated in constant functions | ^^^^^ the destructor for this type cannot be evaluated in constant functions

View File

@ -1,10 +1,11 @@
//@ compile-flags: --edition 2018
#![unstable(feature = "humans", #![unstable(feature = "humans",
reason = "who ever let humans program computers, reason = "who ever let humans program computers,
we're apparently really bad at it", we're apparently really bad at it",
issue = "none")] issue = "none")]
#![feature(const_refs_to_cell, foo, foo2)] #![feature(foo, foo2)]
#![feature(staged_api)] #![feature(const_async_blocks, staged_api)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")] #[rustc_const_unstable(feature="foo", issue = "none")]
@ -27,10 +28,8 @@ const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
#[rustc_const_stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
// conformity is required // conformity is required
const fn bar3() -> u32 { const fn bar3() -> u32 {
let x = std::cell::Cell::new(0u32); let x = async { 13 };
x.get(); //~^ ERROR const-stable function cannot use `#[feature(const_async_blocks)]`
//~^ ERROR const-stable function cannot use `#[feature(const_refs_to_cell)]`
//~| ERROR cannot call non-const fn
foo() foo()
//~^ ERROR is not yet stable as a const fn //~^ ERROR is not yet stable as a const fn
} }

View File

@ -1,5 +1,5 @@
error: `foo` is not yet stable as a const fn error: `foo` is not yet stable as a const fn
--> $DIR/min_const_fn_libstd_stability.rs:16:25 --> $DIR/min_const_fn_libstd_stability.rs:17:25
| |
LL | const fn bar() -> u32 { foo() } LL | const fn bar() -> u32 { foo() }
| ^^^^^ | ^^^^^
@ -7,18 +7,18 @@ LL | const fn bar() -> u32 { foo() }
= help: const-stable functions can only call other const-stable functions = help: const-stable functions can only call other const-stable functions
error: `foo2` is not yet stable as a const fn error: `foo2` is not yet stable as a const fn
--> $DIR/min_const_fn_libstd_stability.rs:24:26 --> $DIR/min_const_fn_libstd_stability.rs:25:26
| |
LL | const fn bar2() -> u32 { foo2() } LL | const fn bar2() -> u32 { foo2() }
| ^^^^^^ | ^^^^^^
| |
= help: const-stable functions can only call other const-stable functions = help: const-stable functions can only call other const-stable functions
error: const-stable function cannot use `#[feature(const_refs_to_cell)]` error: const-stable function cannot use `#[feature(const_async_blocks)]`
--> $DIR/min_const_fn_libstd_stability.rs:31:5 --> $DIR/min_const_fn_libstd_stability.rs:31:13
| |
LL | x.get(); LL | let x = async { 13 };
| ^ | ^^^^^^^^^^^^
| |
help: if the function is not (yet) meant to be stable, make this function unstably const help: if the function is not (yet) meant to be stable, make this function unstably const
| |
@ -27,20 +27,12 @@ LL | const fn bar3() -> u32 {
| |
help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval) help: otherwise, as a last resort `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
| |
LL + #[rustc_allow_const_fn_unstable(const_refs_to_cell)] LL + #[rustc_allow_const_fn_unstable(const_async_blocks)]
LL | const fn bar3() -> u32 { LL | const fn bar3() -> u32 {
| |
error[E0015]: cannot call non-const fn `Cell::<u32>::get` in constant functions
--> $DIR/min_const_fn_libstd_stability.rs:31:7
|
LL | x.get();
| ^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
error: `foo` is not yet stable as a const fn error: `foo` is not yet stable as a const fn
--> $DIR/min_const_fn_libstd_stability.rs:34:5 --> $DIR/min_const_fn_libstd_stability.rs:33:5
| |
LL | foo() LL | foo()
| ^^^^^ | ^^^^^
@ -48,13 +40,12 @@ LL | foo()
= help: const-stable functions can only call other const-stable functions = help: const-stable functions can only call other const-stable functions
error: `foo2_gated` is not yet stable as a const fn error: `foo2_gated` is not yet stable as a const fn
--> $DIR/min_const_fn_libstd_stability.rs:45:32 --> $DIR/min_const_fn_libstd_stability.rs:44:32
| |
LL | const fn bar2_gated() -> u32 { foo2_gated() } LL | const fn bar2_gated() -> u32 { foo2_gated() }
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: const-stable functions can only call other const-stable functions = help: const-stable functions can only call other const-stable functions
error: aborting due to 6 previous errors error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0015`.

View File

@ -3,7 +3,7 @@
we're apparently really bad at it", we're apparently really bad at it",
issue = "none")] issue = "none")]
#![feature(const_refs_to_cell, foo, foo2)] #![feature(foo, foo2)]
#![feature(staged_api)] #![feature(staged_api)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]

View File

@ -1,8 +1,8 @@
#![feature(const_refs_to_cell)]
use std::cell::*; use std::cell::*;
struct SyncPtr<T> { x : *const T } struct SyncPtr<T> {
x: *const T,
}
unsafe impl<T> Sync for SyncPtr<T> {} unsafe impl<T> Sync for SyncPtr<T> {}
// These pass the lifetime checks because of the "tail expression" / "outer scope" rule. // These pass the lifetime checks because of the "tail expression" / "outer scope" rule.
@ -37,4 +37,13 @@ const NONE_EXPLICIT_PROMOTED: &'static Option<Cell<i32>> = {
x x
}; };
// Not okay, since we are borrowing something with interior mutability.
const INTERIOR_MUT_VARIANT: &Option<UnsafeCell<bool>> = &{
//~^ERROR: cannot refer to interior mutable data
let mut x = None;
assert!(x.is_none());
x = Some(UnsafeCell::new(false));
x
};
fn main() {} fn main() {}

View File

@ -12,6 +12,19 @@ error[E0492]: constants cannot refer to interior mutable data
LL | const RAW_SYNC_C: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) }; LL | const RAW_SYNC_C: SyncPtr<Cell<i32>> = SyncPtr { x: &Cell::new(42) };
| ^^^^^^^^^^^^^^ this borrow of an interior mutable value may end up in the final value | ^^^^^^^^^^^^^^ this borrow of an interior mutable value may end up in the final value
error: aborting due to 2 previous errors error[E0492]: constants cannot refer to interior mutable data
--> $DIR/refs-to-cell-in-final.rs:41:57
|
LL | const INTERIOR_MUT_VARIANT: &Option<UnsafeCell<bool>> = &{
| _________________________________________________________^
LL | |
LL | | let mut x = None;
LL | | assert!(x.is_none());
LL | | x = Some(UnsafeCell::new(false));
LL | | x
LL | | };
| |_^ this borrow of an interior mutable value may end up in the final value
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0492`. For more information about this error, try `rustc --explain E0492`.

View File

@ -1,5 +1,3 @@
#![feature(const_refs_to_cell)]
use std::cell::*; use std::cell::*;
// not ok, because this creates a dangling pointer, just like `let x = Cell::new(42).as_ptr()` would // not ok, because this creates a dangling pointer, just like `let x = Cell::new(42).as_ptr()` would

View File

@ -1,23 +1,23 @@
error: encountered dangling pointer in final value of static error: encountered dangling pointer in final value of static
--> $DIR/cell.rs:6:1 --> $DIR/cell.rs:4:1
| |
LL | static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); LL | static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: encountered dangling pointer in final value of constant error: encountered dangling pointer in final value of constant
--> $DIR/cell.rs:8:1 --> $DIR/cell.rs:6:1
| |
LL | const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); LL | const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: encountered dangling pointer in final value of constant error: encountered dangling pointer in final value of constant
--> $DIR/cell.rs:22:1 --> $DIR/cell.rs:20:1
| |
LL | const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr()); LL | const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: encountered dangling pointer in final value of constant error: encountered dangling pointer in final value of constant
--> $DIR/cell.rs:27:1 --> $DIR/cell.rs:25:1
| |
LL | const FOO2: *mut u32 = Cell::new(42).as_ptr(); LL | const FOO2: *mut u32 = Cell::new(42).as_ptr();
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^

View File

@ -1,16 +0,0 @@
const FOO: () = {
let x = std::cell::Cell::new(42);
let y = &x; //~ERROR: cannot borrow here
};
const FOO2: () = {
let mut x = std::cell::Cell::new(42);
let y = &*&mut x; //~ERROR: cannot borrow here
};
const FOO3: () = unsafe {
let mut x = std::cell::Cell::new(42);
let y = &*(&mut x as *mut _); //~ERROR: cannot borrow here
};
fn main() {}

View File

@ -1,33 +0,0 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/feature-gate-const_refs_to_cell.rs:3:13
|
LL | let y = &x;
| ^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/feature-gate-const_refs_to_cell.rs:8:13
|
LL | let y = &*&mut x;
| ^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/feature-gate-const_refs_to_cell.rs:13:13
|
LL | let y = &*(&mut x as *mut _);
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -2,7 +2,6 @@
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
#![feature(const_trait_impl)] #![feature(const_trait_impl)]
#![feature(const_refs_to_cell)]
use std::marker::Destruct; use std::marker::Destruct;

View File

@ -1,17 +1,17 @@
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/normalize-tait-in-const.rs:27:42 --> $DIR/normalize-tait-in-const.rs:26:42
| |
LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
error: `~const` can only be applied to `#[const_trait]` traits error: `~const` can only be applied to `#[const_trait]` traits
--> $DIR/normalize-tait-in-const.rs:27:69 --> $DIR/normalize-tait-in-const.rs:26:69
| |
LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
| ^^^^^^^^ | ^^^^^^^^
error[E0015]: cannot call non-const closure in constant functions error[E0015]: cannot call non-const closure in constant functions
--> $DIR/normalize-tait-in-const.rs:28:5 --> $DIR/normalize-tait-in-const.rs:27:5
| |
LL | fun(filter_positive()); LL | fun(filter_positive());
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
@ -27,7 +27,7 @@ LL + #![feature(effects)]
| |
error[E0493]: destructor of `F` cannot be evaluated at compile-time error[E0493]: destructor of `F` cannot be evaluated at compile-time
--> $DIR/normalize-tait-in-const.rs:27:79 --> $DIR/normalize-tait-in-const.rs:26:79
| |
LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) { LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
| ^^^ the destructor for this type cannot be evaluated in constant functions | ^^^ the destructor for this type cannot be evaluated in constant functions

View File

@ -11,8 +11,7 @@ impl Foo {
//~^ ERROR: `R` cannot be used as the type of `self` //~^ ERROR: `R` cannot be used as the type of `self`
//~| ERROR destructor of `R` cannot be evaluated at compile-time //~| ERROR destructor of `R` cannot be evaluated at compile-time
self.0 self.0
//~^ ERROR cannot borrow here, since the borrowed element may contain interior mutability //~^ ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
//~| ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
} }
} }

View File

@ -1,13 +1,3 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
|
LL | self.0
| ^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0015]: cannot call non-const fn `<R as Deref>::deref` in constant functions error[E0015]: cannot call non-const fn `<R as Deref>::deref` in constant functions
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9 --> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
| |
@ -40,7 +30,7 @@ LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`) = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: aborting due to 4 previous errors error: aborting due to 3 previous errors
Some errors have detailed explanations: E0015, E0493, E0658. Some errors have detailed explanations: E0015, E0493, E0658.
For more information about an error, try `rustc --explain E0015`. For more information about an error, try `rustc --explain E0015`.

View File

@ -4,7 +4,7 @@
//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" //@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
#![feature(const_refs_to_static, const_refs_to_cell)] #![feature(const_refs_to_static)]
use std::cell::UnsafeCell; use std::cell::UnsafeCell;

View File

@ -1,6 +1,5 @@
// Check that we forbid nested statics in `thread_local` statics. // Check that we forbid nested statics in `thread_local` statics.
#![feature(const_refs_to_cell)]
#![feature(thread_local)] #![feature(thread_local)]
#[thread_local] #[thread_local]

View File

@ -1,5 +1,5 @@
error: #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead error: #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead
--> $DIR/nested_thread_local.rs:7:1 --> $DIR/nested_thread_local.rs:6:1
| |
LL | static mut FOO: &u32 = { LL | static mut FOO: &u32 = {
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^

View File

@ -9,13 +9,13 @@ fn main() {}
const fn foo() -> NonZero<Cell<u32>> { const fn foo() -> NonZero<Cell<u32>> {
let mut x = unsafe { NonZero(Cell::new(1)) }; let mut x = unsafe { NonZero(Cell::new(1)) };
let y = &x.0; //~ ERROR the borrowed element may contain interior mutability let y = &x.0;
//~^ ERROR borrow of layout constrained field with interior mutability //~^ ERROR borrow of layout constrained field with interior mutability
unsafe { NonZero(Cell::new(1)) } unsafe { NonZero(Cell::new(1)) }
} }
const fn bar() -> NonZero<Cell<u32>> { const fn bar() -> NonZero<Cell<u32>> {
let mut x = unsafe { NonZero(Cell::new(1)) }; let mut x = unsafe { NonZero(Cell::new(1)) };
let y = unsafe { &x.0 }; //~ ERROR the borrowed element may contain interior mutability let y = unsafe { &x.0 };
unsafe { NonZero(Cell::new(1)) } unsafe { NonZero(Cell::new(1)) }
} }

View File

@ -6,27 +6,6 @@ LL | let y = &x.0;
| |
= note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability error: aborting due to 1 previous error
--> $DIR/ranged_ints3_const.rs:12:13
|
LL | let y = &x.0;
| ^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability For more information about this error, try `rustc --explain E0133`.
--> $DIR/ranged_ints3_const.rs:19:22
|
LL | let y = unsafe { &x.0 };
| ^^^^
|
= note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
= help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0133, E0658.
For more information about an error, try `rustc --explain E0133`.