mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Allow references to interior mutable data behind a feature gate
This commit is contained in:
parent
a609fb45ef
commit
0b841846ba
@ -3,10 +3,11 @@ A borrow of a constant containing interior mutability was attempted.
|
|||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0492
|
```compile_fail,E0492
|
||||||
|
#![feature(const_refs_to_cell)]
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
|
||||||
const A: AtomicUsize = AtomicUsize::new(0);
|
const A: AtomicUsize = AtomicUsize::new(0);
|
||||||
static B: &'static AtomicUsize = &A;
|
const B: &'static AtomicUsize = &A;
|
||||||
// error: cannot borrow a constant which may contain interior mutability,
|
// error: cannot borrow a constant which may contain interior mutability,
|
||||||
// create a static instead
|
// create a static instead
|
||||||
```
|
```
|
||||||
@ -18,7 +19,7 @@ can't be changed via a shared `&` pointer, but interior mutability would allow
|
|||||||
it. That is, a constant value could be mutated. On the other hand, a `static` is
|
it. That is, a constant value could be mutated. On the other hand, a `static` is
|
||||||
explicitly a single memory location, which can be mutated at will.
|
explicitly a single memory location, which can be mutated at will.
|
||||||
|
|
||||||
So, in order to solve this error, either use statics which are `Sync`:
|
So, in order to solve this error, use statics which are `Sync`:
|
||||||
|
|
||||||
```
|
```
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
@ -30,6 +31,7 @@ static B: &'static AtomicUsize = &A; // ok!
|
|||||||
You can also have this error while using a cell type:
|
You can also have this error while using a cell type:
|
||||||
|
|
||||||
```compile_fail,E0492
|
```compile_fail,E0492
|
||||||
|
#![feature(const_refs_to_cell)]
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
const A: Cell<usize> = Cell::new(1);
|
const A: Cell<usize> = Cell::new(1);
|
||||||
|
@ -626,6 +626,9 @@ declare_features! (
|
|||||||
/// Allows const generics to have default values (e.g. `struct Foo<const N: usize = 3>(...);`).
|
/// Allows const generics to have default values (e.g. `struct Foo<const N: usize = 3>(...);`).
|
||||||
(active, const_generics_defaults, "1.51.0", Some(44580), None),
|
(active, const_generics_defaults, "1.51.0", Some(44580), None),
|
||||||
|
|
||||||
|
/// Allows references to types with interior mutability within constants
|
||||||
|
(active, const_refs_to_cell, "1.51.0", Some(80384), None),
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// feature-group-end: actual feature gates
|
// feature-group-end: actual feature gates
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
@ -208,9 +208,29 @@ impl NonConstOp for LiveDrop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CellBorrowBehindRef;
|
||||||
|
impl NonConstOp for CellBorrowBehindRef {
|
||||||
|
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
|
||||||
|
Status::Unstable(sym::const_refs_to_cell)
|
||||||
|
}
|
||||||
|
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||||
|
feature_err(
|
||||||
|
&ccx.tcx.sess.parse_sess,
|
||||||
|
sym::const_refs_to_cell,
|
||||||
|
span,
|
||||||
|
"cannot borrow here, since the borrowed element may contain interior mutability",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CellBorrow;
|
pub struct CellBorrow;
|
||||||
impl NonConstOp for CellBorrow {
|
impl NonConstOp for CellBorrow {
|
||||||
|
fn importance(&self) -> DiagnosticImportance {
|
||||||
|
// The problematic cases will already emit a `CellBorrowBehindRef`
|
||||||
|
DiagnosticImportance::Secondary
|
||||||
|
}
|
||||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
ccx.tcx.sess,
|
ccx.tcx.sess,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorReported};
|
use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorReported};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::{self as hir, HirId, LangItem};
|
use rustc_hir::{self as hir, HirId, LangItem};
|
||||||
|
use rustc_index::bit_set::BitSet;
|
||||||
use rustc_infer::infer::TyCtxtInferExt;
|
use rustc_infer::infer::TyCtxtInferExt;
|
||||||
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
|
||||||
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
|
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
|
||||||
@ -188,6 +189,9 @@ pub struct Validator<'mir, 'tcx> {
|
|||||||
/// The span of the current statement.
|
/// The span of the current statement.
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
||||||
|
/// A set that stores for each local whether it has a `StorageDead` for it somewhere.
|
||||||
|
local_has_storage_dead: Option<BitSet<Local>>,
|
||||||
|
|
||||||
error_emitted: Option<ErrorReported>,
|
error_emitted: Option<ErrorReported>,
|
||||||
secondary_errors: Vec<Diagnostic>,
|
secondary_errors: Vec<Diagnostic>,
|
||||||
}
|
}
|
||||||
@ -206,6 +210,7 @@ impl Validator<'mir, 'tcx> {
|
|||||||
span: ccx.body.span,
|
span: ccx.body.span,
|
||||||
ccx,
|
ccx,
|
||||||
qualifs: Default::default(),
|
qualifs: Default::default(),
|
||||||
|
local_has_storage_dead: None,
|
||||||
error_emitted: None,
|
error_emitted: None,
|
||||||
secondary_errors: Vec::new(),
|
secondary_errors: Vec::new(),
|
||||||
}
|
}
|
||||||
@ -282,6 +287,27 @@ impl Validator<'mir, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn local_has_storage_dead(&mut self, local: Local) -> bool {
|
||||||
|
let ccx = self.ccx;
|
||||||
|
self.local_has_storage_dead
|
||||||
|
.get_or_insert_with(|| {
|
||||||
|
struct StorageDeads {
|
||||||
|
locals: BitSet<Local>,
|
||||||
|
}
|
||||||
|
impl Visitor<'tcx> for StorageDeads {
|
||||||
|
fn visit_statement(&mut self, stmt: &Statement<'tcx>, _: Location) {
|
||||||
|
if let StatementKind::StorageDead(l) = stmt.kind {
|
||||||
|
self.locals.insert(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut v = StorageDeads { locals: BitSet::new_empty(ccx.body.local_decls.len()) };
|
||||||
|
v.visit_body(ccx.body);
|
||||||
|
v.locals
|
||||||
|
})
|
||||||
|
.contains(local)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn qualifs_in_return_place(&mut self) -> ConstQualifs {
|
pub fn qualifs_in_return_place(&mut self) -> ConstQualifs {
|
||||||
self.qualifs.in_return_place(self.ccx, self.error_emitted)
|
self.qualifs.in_return_place(self.ccx, self.error_emitted)
|
||||||
}
|
}
|
||||||
@ -556,7 +582,13 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if borrowed_place_has_mut_interior {
|
if borrowed_place_has_mut_interior {
|
||||||
self.check_op(ops::CellBorrow);
|
// Locals without StorageDead follow the "trailing expression" rule, meaning
|
||||||
|
// they are essentially anonymous static items themselves.
|
||||||
|
if self.local_has_storage_dead(place.local) {
|
||||||
|
self.check_op(ops::CellBorrowBehindRef);
|
||||||
|
} else {
|
||||||
|
self.check_op(ops::CellBorrow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,6 +381,7 @@ symbols! {
|
|||||||
const_ptr,
|
const_ptr,
|
||||||
const_raw_ptr_deref,
|
const_raw_ptr_deref,
|
||||||
const_raw_ptr_to_usize_cast,
|
const_raw_ptr_to_usize_cast,
|
||||||
|
const_refs_to_cell,
|
||||||
const_slice_ptr,
|
const_slice_ptr,
|
||||||
const_trait_bound_opt_out,
|
const_trait_bound_opt_out,
|
||||||
const_trait_impl,
|
const_trait_impl,
|
||||||
|
@ -1,27 +1,39 @@
|
|||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
--> $DIR/const-address-of-interior-mut.rs:5:39
|
--> $DIR/const-address-of-interior-mut.rs:5:39
|
||||||
|
|
|
|
||||||
LL | const A: () = { let x = Cell::new(2); &raw const x; };
|
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
|
||||||
|
|
||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
--> $DIR/const-address-of-interior-mut.rs:7:40
|
--> $DIR/const-address-of-interior-mut.rs:7:40
|
||||||
|
|
|
|
||||||
LL | static B: () = { let x = Cell::new(2); &raw const x; };
|
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
|
||||||
|
|
||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
--> $DIR/const-address-of-interior-mut.rs:9:44
|
--> $DIR/const-address-of-interior-mut.rs:9:44
|
||||||
|
|
|
|
||||||
LL | static mut C: () = { let x = Cell::new(2); &raw const x; };
|
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
|
||||||
|
|
||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
--> $DIR/const-address-of-interior-mut.rs:13:13
|
--> $DIR/const-address-of-interior-mut.rs:13:13
|
||||||
|
|
|
|
||||||
LL | let y = &raw const x;
|
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
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0492`.
|
For more information about this error, try `rustc --explain E0658`.
|
||||||
|
@ -13,7 +13,7 @@ const _: i32 = {
|
|||||||
|
|
||||||
const _: std::cell::Cell<i32> = {
|
const _: std::cell::Cell<i32> = {
|
||||||
let mut a = std::cell::Cell::new(5);
|
let mut a = std::cell::Cell::new(5);
|
||||||
let p = &a; //~ ERROR cannot borrow a constant which may contain interior mutability
|
let p = &a; //~ ERROR borrowed element may contain interior mutability
|
||||||
|
|
||||||
let reborrow = {p};
|
let reborrow = {p};
|
||||||
let pp = &reborrow;
|
let pp = &reborrow;
|
||||||
|
@ -4,13 +4,16 @@ error[E0764]: mutable references are not allowed in constants
|
|||||||
LL | let p = &mut a;
|
LL | let p = &mut a;
|
||||||
| ^^^^^^ `&mut` is only allowed in `const fn`
|
| ^^^^^^ `&mut` is only allowed in `const fn`
|
||||||
|
|
||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
--> $DIR/const-multi-ref.rs:16:13
|
--> $DIR/const-multi-ref.rs:16:13
|
||||||
|
|
|
|
||||||
LL | let p = &a;
|
LL | let p = &a;
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
||||||
|
= 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
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0492, E0764.
|
Some errors have detailed explanations: E0658, E0764.
|
||||||
For more information about an error, try `rustc --explain E0492`.
|
For more information about an error, try `rustc --explain E0658`.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![feature(const_refs_to_cell)]
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
const FOO: &(Cell<usize>, bool) = {
|
const FOO: &(Cell<usize>, bool) = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||||
--> $DIR/partial_qualif.rs:6:5
|
--> $DIR/partial_qualif.rs:8:5
|
||||||
|
|
|
|
||||||
LL | &{a}
|
LL | &{a}
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![feature(const_refs_to_cell)]
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
// this is overly conservative. The reset to `None` should clear `a` of all qualifications
|
// this is overly conservative. The reset to `None` should clear `a` of all qualifications
|
||||||
@ -7,7 +9,7 @@ use std::cell::Cell;
|
|||||||
const FOO: &Option<Cell<usize>> = {
|
const FOO: &Option<Cell<usize>> = {
|
||||||
let mut a = Some(Cell::new(0));
|
let mut a = Some(Cell::new(0));
|
||||||
a = None; // sets `qualif(a)` to `qualif(a) | qualif(None)`
|
a = None; // sets `qualif(a)` to `qualif(a) | qualif(None)`
|
||||||
&{a} //~ ERROR cannot borrow a constant which may contain interior mutability
|
&{a}//~ ERROR cannot borrow a constant which may contain interior mutability
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||||
--> $DIR/qualif_overwrite.rs:10:5
|
--> $DIR/qualif_overwrite.rs:12:5
|
||||||
|
|
|
|
||||||
LL | &{a}
|
LL | &{a}
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![feature(const_refs_to_cell)]
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
|
||||||
// const qualification is not smart enough to know about fields and always assumes that there might
|
// const qualification is not smart enough to know about fields and always assumes that there might
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||||
--> $DIR/qualif_overwrite_2.rs:8:5
|
--> $DIR/qualif_overwrite_2.rs:10:5
|
||||||
|
|
|
|
||||||
LL | &{a.0}
|
LL | &{a.0}
|
||||||
| ^^^^^^
|
| ^^^^^^
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
|
#![feature(const_refs_to_cell)]
|
||||||
|
|
||||||
use std::cell::*;
|
use std::cell::*;
|
||||||
|
|
||||||
// not ok, because this would create a silent constant with interior mutability.
|
// not ok, because this would create a silent constant with interior mutability.
|
||||||
// the rules could be relaxed in the future
|
// the rules could be relaxed in the future
|
||||||
static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
|
static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
|
||||||
//~^ ERROR cannot borrow a constant which may contain interior mutability
|
//~^ ERROR encountered dangling pointer
|
||||||
|
const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
|
||||||
|
//~^ ERROR encountered dangling pointer
|
||||||
|
|
||||||
static FOO3: Wrap<Cell<u32>> = Wrap(Cell::new(42));
|
static FOO3: Wrap<Cell<u32>> = Wrap(Cell::new(42));
|
||||||
|
const FOO3_CONST: Wrap<Cell<u32>> = Wrap(Cell::new(42));
|
||||||
|
|
||||||
// ok
|
// ok
|
||||||
static FOO4: Wrap<*mut u32> = Wrap(FOO3.0.as_ptr());
|
static FOO4: Wrap<*mut u32> = Wrap(FOO3.0.as_ptr());
|
||||||
|
const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr());
|
||||||
|
//~^ ERROR encountered dangling pointer
|
||||||
|
|
||||||
// not ok, because the `as_ptr` call takes a reference to a type with interior mutability
|
// not ok, because the `as_ptr` call takes a reference to a type with interior mutability
|
||||||
// which is not allowed in constants
|
// which is not allowed in constants
|
||||||
const FOO2: *mut u32 = Cell::new(42).as_ptr();
|
const FOO2: *mut u32 = Cell::new(42).as_ptr();
|
||||||
//~^ ERROR cannot borrow a constant which may contain interior mutability
|
//~^ ERROR encountered dangling pointer
|
||||||
|
|
||||||
struct IMSafeTrustMe(UnsafeCell<u32>);
|
struct IMSafeTrustMe(UnsafeCell<u32>);
|
||||||
unsafe impl Send for IMSafeTrustMe {}
|
unsafe impl Send for IMSafeTrustMe {}
|
||||||
@ -21,6 +29,7 @@ unsafe impl Sync for IMSafeTrustMe {}
|
|||||||
static BAR: IMSafeTrustMe = IMSafeTrustMe(UnsafeCell::new(5));
|
static BAR: IMSafeTrustMe = IMSafeTrustMe(UnsafeCell::new(5));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct Wrap<T>(T);
|
struct Wrap<T>(T);
|
||||||
unsafe impl<T> Send for Wrap<T> {}
|
unsafe impl<T> Send for Wrap<T> {}
|
||||||
unsafe impl<T> Sync for Wrap<T> {}
|
unsafe impl<T> Sync for Wrap<T> {}
|
||||||
|
@ -1,15 +1,26 @@
|
|||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error: encountered dangling pointer in final constant
|
||||||
--> $DIR/cell.rs:5:35
|
--> $DIR/cell.rs:7: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[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error: encountered dangling pointer in final constant
|
||||||
--> $DIR/cell.rs:14:24
|
--> $DIR/cell.rs:9:1
|
||||||
|
|
|
||||||
|
LL | const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: encountered dangling pointer in final constant
|
||||||
|
--> $DIR/cell.rs:17:1
|
||||||
|
|
|
||||||
|
LL | const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr());
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: encountered dangling pointer in final constant
|
||||||
|
--> $DIR/cell.rs:22:1
|
||||||
|
|
|
|
||||||
LL | const FOO2: *mut u32 = Cell::new(42).as_ptr();
|
LL | const FOO2: *mut u32 = Cell::new(42).as_ptr();
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0492`.
|
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
|
#![feature(const_refs_to_cell)]
|
||||||
|
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
|
|
||||||
const A: AtomicUsize = AtomicUsize::new(0);
|
const A: AtomicUsize = AtomicUsize::new(0);
|
||||||
static B: &'static AtomicUsize = &A; //~ ERROR E0492
|
const B: &'static AtomicUsize = &A; //~ ERROR E0492
|
||||||
|
static C: &'static AtomicUsize = &A; //~ ERROR E0492
|
||||||
|
|
||||||
|
const NONE: &'static Option<AtomicUsize> = &None;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||||
--> $DIR/E0492.rs:4:34
|
--> $DIR/E0492.rs:6:33
|
||||||
|
|
|
|
||||||
LL | static B: &'static AtomicUsize = &A;
|
LL | const B: &'static AtomicUsize = &A;
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||||
|
--> $DIR/E0492.rs:7:34
|
||||||
|
|
|
||||||
|
LL | static C: &'static AtomicUsize = &A;
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0492`.
|
For more information about this error, try `rustc --explain E0492`.
|
||||||
|
12
src/test/ui/feature-gate/feature-gate-const_refs_to_cell.rs
Normal file
12
src/test/ui/feature-gate/feature-gate-const_refs_to_cell.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(const_refs_to_cell)]
|
||||||
|
|
||||||
|
const FOO: () = {
|
||||||
|
let x = std::cell::Cell::new(42);
|
||||||
|
let y = &x;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
FOO;
|
||||||
|
}
|
@ -1,14 +1,16 @@
|
|||||||
|
#![feature(const_refs_to_cell)]
|
||||||
|
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
|
|
||||||
const A: UnsafeCell<usize> = UnsafeCell::new(1);
|
const A: UnsafeCell<usize> = UnsafeCell::new(1);
|
||||||
const B: &'static UnsafeCell<usize> = &A;
|
const B: &'static UnsafeCell<usize> = &A;
|
||||||
//~^ ERROR: cannot borrow a constant which may contain interior mutability
|
//~^ ERROR: may contain interior mutability
|
||||||
|
|
||||||
struct C { a: UnsafeCell<usize> }
|
struct C { a: UnsafeCell<usize> }
|
||||||
const D: C = C { a: UnsafeCell::new(1) };
|
const D: C = C { a: UnsafeCell::new(1) };
|
||||||
const E: &'static UnsafeCell<usize> = &D.a;
|
const E: &'static UnsafeCell<usize> = &D.a;
|
||||||
//~^ ERROR: cannot borrow a constant which may contain interior mutability
|
//~^ ERROR: may contain interior mutability
|
||||||
const F: &'static C = &D;
|
const F: &'static C = &D;
|
||||||
//~^ ERROR: cannot borrow a constant which may contain interior mutability
|
//~^ ERROR: may contain interior mutability
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||||
--> $DIR/issue-17718-const-borrow.rs:4:39
|
--> $DIR/issue-17718-const-borrow.rs:6:39
|
||||||
|
|
|
|
||||||
LL | const B: &'static UnsafeCell<usize> = &A;
|
LL | const B: &'static UnsafeCell<usize> = &A;
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||||
--> $DIR/issue-17718-const-borrow.rs:9:39
|
--> $DIR/issue-17718-const-borrow.rs:11:39
|
||||||
|
|
|
|
||||||
LL | const E: &'static UnsafeCell<usize> = &D.a;
|
LL | const E: &'static UnsafeCell<usize> = &D.a;
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||||
--> $DIR/issue-17718-const-borrow.rs:11:23
|
--> $DIR/issue-17718-const-borrow.rs:13:23
|
||||||
|
|
|
|
||||||
LL | const F: &'static C = &D;
|
LL | const F: &'static C = &D;
|
||||||
| ^^
|
| ^^
|
||||||
|
@ -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 cannot borrow a constant which may contain interior mutability
|
let y = &x.0; //~ ERROR the borrowed element may contain interior mutability
|
||||||
//~^ 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 cannot borrow a constant which may contain interior mut
|
let y = unsafe { &x.0 }; //~ ERROR the borrowed element may contain interior mutability
|
||||||
unsafe { NonZero(Cell::new(1)) }
|
unsafe { NonZero(Cell::new(1)) }
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
--> $DIR/ranged_ints3_const.rs:12:13
|
--> $DIR/ranged_ints3_const.rs:12:13
|
||||||
|
|
|
|
||||||
LL | let y = &x.0;
|
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
|
||||||
|
|
||||||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
|
||||||
--> $DIR/ranged_ints3_const.rs:19:22
|
--> $DIR/ranged_ints3_const.rs:19:22
|
||||||
|
|
|
|
||||||
LL | let y = unsafe { &x.0 };
|
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
|
||||||
|
|
||||||
error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
|
error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
|
||||||
--> $DIR/ranged_ints3_const.rs:12:13
|
--> $DIR/ranged_ints3_const.rs:12:13
|
||||||
@ -20,5 +26,5 @@ LL | let y = &x.0;
|
|||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0133, E0492.
|
Some errors have detailed explanations: E0133, E0658.
|
||||||
For more information about an error, try `rustc --explain E0133`.
|
For more information about an error, try `rustc --explain E0133`.
|
||||||
|
Loading…
Reference in New Issue
Block a user