Rollup merge of #129195 - RalfJung:const-mut-refs, r=fee1-dead

Stabilize `&mut` (and `*mut`) as well as `&Cell` (and `*const Cell`) in const

This stabilizes `const_mut_refs` and `const_refs_to_cell`. That allows a bunch of new things in const contexts:
- Mentioning `&mut` types
- Creating `&mut` and `*mut` values
- Creating `&T` and `*const T` values where `T` contains interior mutability
- Dereferencing `&mut` and `*mut` values (both for reads and writes)

The same rules as at runtime apply: mutating immutable data is UB. This includes mutation through pointers derived from shared references; the following is diagnosed with a hard error:
```rust
#[allow(invalid_reference_casting)]
const _: () = {
    let mut val = 15;
    let ptr = &val as *const i32 as *mut i32;
    unsafe { *ptr = 16; }
};
```

The main limitation that is enforced is that the final value of a const (or non-`mut` static) may not contain `&mut` values nor interior mutable `&` values. This is necessary because the memory those references point to becomes *read-only* when the constant is done computing, so (interior) mutable references to such memory would be pretty dangerous. We take a multi-layered approach here to ensuring no mutable references escape the initializer expression:
- A static analysis rejects (interior) mutable references when the referee looks like it may outlive the current MIR body.
- To be extra sure, this static check is complemented by a "safety net" of dynamic checks. ("Dynamic" in the sense of "running during/after const-evaluation, e.g. at runtime of this code" -- in contrast to "static" which works entirely by looking at the MIR without evaluating it.)
  - After the final value is computed, we do a type-driven traversal of the entire value, and if we find any `&mut` or interior-mutable `&` we error out.
  - However, the type-driven traversal cannot traverse `union` or raw pointers, so there is a second dynamic check where if the final value of the const contains any pointer that was not derived from a shared reference, we complain. This is currently a future-compat lint, but will become an ICE in #128543. On the off-chance that it's actually possible to trigger this lint on stable, I'd prefer if we could make it an ICE before stabilizing const_mut_refs, but it's not a hard blocker. This part of the "safety net" is only active for mutable references since with shared references, it has false positives.

Altogether this should prevent people from leaking (interior) mutable references out of the const initializer.

While updating the tests I learned that surprisingly, this code gets rejected:
```rust
const _: Vec<i32> = {
    let mut x = Vec::<i32>::new(); //~ ERROR destructor of `Vec<i32>` cannot be evaluated at compile-time
    let r = &mut x;
    let y = x;
    y
};
```
The analysis that rejects destructors in `const` is very conservative when it sees an `&mut` being created to `x`, and then considers `x` to be always live. See [here](https://github.com/rust-lang/rust/issues/65394#issuecomment-541499219) for a longer explanation. `const_precise_live_drops` will solve this, so I consider this problem to be tracked by https://github.com/rust-lang/rust/issues/73255.

Cc `@rust-lang/wg-const-eval` `@rust-lang/lang`
Cc https://github.com/rust-lang/rust/issues/57349
Cc https://github.com/rust-lang/rust/issues/80384
This commit is contained in:
Matthias Krüger 2024-09-15 11:55:45 +02:00 committed by GitHub
commit 011289c9d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
175 changed files with 382 additions and 1693 deletions

View File

@ -134,9 +134,6 @@ const_eval_incompatible_return_types =
const_eval_incompatible_types =
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_const_context}s cannot refer to interior mutable data
.label = this borrow of an interior mutable value may end up in the final value
@ -230,9 +227,6 @@ const_eval_memory_exhausted =
const_eval_modified_global =
modifying a static's initial value from another static's initializer
const_eval_mut_deref =
mutation through a reference is not allowed in {const_eval_const_context}s
const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind}
const_eval_nested_static_in_thread_local = #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead
@ -363,10 +357,6 @@ const_eval_too_generic =
const_eval_too_many_caller_args =
calling a function with more arguments than it expected
const_eval_transient_mut_borrow = mutable references are not allowed in {const_eval_const_context}s
const_eval_transient_mut_raw = raw mutable pointers are not allowed in {const_eval_const_context}s
const_eval_try_block_from_output_non_const =
`try` block cannot convert `{$ty}` to the result in {const_eval_const_context}s
const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {const_eval_const_context}s

View File

@ -11,18 +11,17 @@ use rustc_hir::{self as hir, LangItem};
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::*;
use rustc_middle::span_bug;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt};
use rustc_mir_dataflow::impls::MaybeStorageLive;
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_mir_dataflow::Analysis;
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor};
use tracing::{debug, instrument, trace};
use super::ops::{self, NonConstOp, Status};
@ -166,24 +165,6 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
}
}
struct LocalReturnTyVisitor<'a, 'mir, 'tcx> {
kind: LocalKind,
checker: &'a mut Checker<'mir, 'tcx>,
}
impl<'a, 'mir, 'tcx> TypeVisitor<TyCtxt<'tcx>> for LocalReturnTyVisitor<'a, 'mir, 'tcx> {
fn visit_ty(&mut self, t: Ty<'tcx>) {
match t.kind() {
ty::FnPtr(..) => {}
ty::Ref(_, _, hir::Mutability::Mut) => {
self.checker.check_op(ops::mut_ref::MutRef(self.kind));
t.super_visit_with(self)
}
_ => t.super_visit_with(self),
}
}
}
pub struct Checker<'mir, 'tcx> {
ccx: &'mir ConstCx<'mir, 'tcx>,
qualifs: Qualifs<'mir, 'tcx>,
@ -230,25 +211,6 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
return;
}
// The local type and predicate checks are not free and only relevant for `const fn`s.
if self.const_kind() == hir::ConstContext::ConstFn {
for (idx, local) in body.local_decls.iter_enumerated() {
// Handle the return place below.
if idx == RETURN_PLACE {
continue;
}
self.span = local.source_info.span;
self.check_local_or_return_ty(local.ty, idx);
}
// impl trait is gone in MIR, so check the return type of a const fn by its signature
// instead of the type of the return place.
self.span = body.local_decls[RETURN_PLACE].source_info.span;
let return_ty = self.ccx.fn_sig().output();
self.check_local_or_return_ty(return_ty.skip_binder(), RETURN_PLACE);
}
if !tcx.has_attr(def_id, sym::rustc_do_not_const_check) {
self.visit_body(body);
}
@ -358,16 +320,11 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
self.check_op_spanned(ops::StaticAccess, span)
}
fn check_local_or_return_ty(&mut self, ty: Ty<'tcx>, local: Local) {
let kind = self.body.local_kind(local);
let mut visitor = LocalReturnTyVisitor { kind, checker: self };
visitor.visit_ty(ty);
}
fn check_mut_borrow(&mut self, place: &Place<'_>, kind: hir::BorrowKind) {
match self.const_kind() {
/// 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() {
// 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
// TransientMutBorrow/MutBorrow as appropriate).
@ -375,7 +332,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
// 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 mutable memory.
hir::ConstContext::ConstFn => self.check_op(ops::TransientMutBorrow(kind)),
hir::ConstContext::ConstFn => true,
_ => {
// For indirect places, we are not creating a new permanent borrow, it's just as
// transient as the already existing one. For reborrowing references this is handled
@ -387,15 +344,16 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
// value of the constant.
// 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.
// The good news is that interning will detect if any unexpected mutable
// pointer slips through.
if place.is_indirect() || self.local_is_transient(place.local) {
self.check_op(ops::TransientMutBorrow(kind));
} else {
self.check_op(ops::MutBorrow(kind));
}
// 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. (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)
}
}
};
// Transient places cannot possibly escape because the place doesn't exist any more at the
// end of evaluation.
!is_transient
}
}
@ -420,47 +378,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
trace!("visit_rvalue: rvalue={:?} location={:?}", rvalue, location);
// Special-case reborrows to be more like a copy of a reference.
// FIXME: this does not actually handle all reborrows. It only detects cases where `*` is the outermost
// projection of the borrowed place, it skips deref'ing raw pointers and it skips `static`.
// All those cases are handled below with shared/mutable borrows.
// Once `const_mut_refs` is stable, we should be able to entirely remove this special case.
// (`const_refs_to_cell` is not needed, we already allow all borrows of indirect places anyway.)
match *rvalue {
Rvalue::Ref(_, kind, place) => {
if let Some(reborrowed_place_ref) = place_as_reborrow(self.tcx, self.body, place) {
let ctx = match kind {
BorrowKind::Shared => {
PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
}
BorrowKind::Fake(_) => {
PlaceContext::NonMutatingUse(NonMutatingUseContext::FakeBorrow)
}
BorrowKind::Mut { .. } => {
PlaceContext::MutatingUse(MutatingUseContext::Borrow)
}
};
self.visit_local(reborrowed_place_ref.local, ctx, location);
self.visit_projection(reborrowed_place_ref, ctx, location);
return;
}
}
Rvalue::RawPtr(mutbl, place) => {
if let Some(reborrowed_place_ref) = place_as_reborrow(self.tcx, self.body, place) {
let ctx = match mutbl {
Mutability::Not => {
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow)
}
Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::RawBorrow),
};
self.visit_local(reborrowed_place_ref.local, ctx, location);
self.visit_projection(reborrowed_place_ref, ctx, location);
return;
}
}
_ => {}
}
self.super_rvalue(rvalue, location);
match rvalue {
@ -494,15 +411,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let is_allowed =
self.const_kind() == hir::ConstContext::Static(hir::Mutability::Mut);
if !is_allowed {
self.check_mut_borrow(
place,
if matches!(rvalue, Rvalue::Ref(..)) {
hir::BorrowKind::Ref
} else {
hir::BorrowKind::Raw
},
);
if !is_allowed && self.place_may_escape(place) {
self.check_op(ops::EscapingMutBorrow(if matches!(rvalue, Rvalue::Ref(..)) {
hir::BorrowKind::Ref
} else {
hir::BorrowKind::Raw
}));
}
}
@ -514,40 +428,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
place.as_ref(),
);
// If the place is indirect, this is basically a reborrow. We have a reborrow
// special case above, but for raw pointers and pointers/references to `static` and
// 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.
if borrowed_place_has_mut_interior && !place.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);
}
}
}
if borrowed_place_has_mut_interior && self.place_may_escape(place) {
self.check_op(ops::EscapingCellBorrow);
}
}
@ -636,58 +518,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
}
}
fn visit_projection_elem(
&mut self,
place_ref: PlaceRef<'tcx>,
elem: PlaceElem<'tcx>,
context: PlaceContext,
location: Location,
) {
trace!(
"visit_projection_elem: place_ref={:?} elem={:?} \
context={:?} location={:?}",
place_ref, elem, context, location,
);
self.super_projection_elem(place_ref, elem, context, location);
match elem {
ProjectionElem::Deref => {
let base_ty = place_ref.ty(self.body, self.tcx).ty;
if base_ty.is_unsafe_ptr() {
if place_ref.projection.is_empty() {
let decl = &self.body.local_decls[place_ref.local];
// If this is a static, then this is not really dereferencing a pointer,
// just directly accessing a static. That is not subject to any feature
// gates (except for the one about whether statics can even be used, but
// that is checked already by `visit_operand`).
if let LocalInfo::StaticRef { .. } = *decl.local_info() {
return;
}
}
// `*const T` is stable, `*mut T` is not
if !base_ty.is_mutable_ptr() {
return;
}
self.check_op(ops::RawMutPtrDeref);
}
if context.is_mutating_use() {
self.check_op(ops::MutDeref);
}
}
ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Downcast(..)
| ProjectionElem::OpaqueCast(..)
| ProjectionElem::Subslice { .. }
| ProjectionElem::Subtype(..)
| ProjectionElem::Field(..)
| ProjectionElem::Index(_) => {}
}
}
fn visit_source_info(&mut self, source_info: &SourceInfo) {
trace!("visit_source_info: source_info={:?}", source_info);
@ -984,40 +814,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
}
fn place_as_reborrow<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
place: Place<'tcx>,
) -> Option<PlaceRef<'tcx>> {
match place.as_ref().last_projection() {
Some((place_base, ProjectionElem::Deref)) => {
// FIXME: why do statics and raw pointers get excluded here? This makes
// some code involving mutable pointers unstable, but it is unclear
// why that code is treated differently from mutable references.
// Once TransientMutBorrow and TransientCellBorrow are stable,
// this can probably be cleaned up without any behavioral changes.
// A borrow of a `static` also looks like `&(*_1)` in the MIR, but `_1` is a `const`
// that points to the allocation for the static. Don't treat these as reborrows.
if body.local_decls[place_base.local].is_ref_to_static() {
None
} else {
// Ensure the type being derefed is a reference and not a raw pointer.
// This is sufficient to prevent an access to a `static mut` from being marked as a
// reborrow, even if the check above were to disappear.
let inner_ty = place_base.ty(body, tcx).ty;
if let ty::Ref(..) = inner_ty.kind() {
return Some(place_base);
} else {
return None;
}
}
}
_ => None,
}
}
fn is_int_bool_float_or_char(ty: Ty<'_>) -> bool {
ty.is_bool() || ty.is_integral() || ty.is_char() || ty.is_floating_point()
}

View File

@ -8,7 +8,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
use rustc_middle::mir::{self, CallSource};
use rustc_middle::mir::CallSource;
use rustc_middle::span_bug;
use rustc_middle::ty::print::{with_no_trimmed_paths, PrintTraitRefExt as _};
use rustc_middle::ty::{
@ -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)]
/// 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
/// it in the future for static items.
pub(crate) struct CellBorrow;
impl<'tcx> NonConstOp<'tcx> for CellBorrow {
pub(crate) struct EscapingCellBorrow;
impl<'tcx> NonConstOp<'tcx> for EscapingCellBorrow {
fn importance(&self) -> DiagImportance {
// 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.
@ -431,9 +416,9 @@ impl<'tcx> NonConstOp<'tcx> for CellBorrow {
/// This op is for `&mut` borrows in the trailing expression of a constant
/// which uses the "enclosing scopes rule" to leak its locals into anonymous
/// static or const items.
pub(crate) struct MutBorrow(pub hir::BorrowKind);
pub(crate) struct EscapingMutBorrow(pub hir::BorrowKind);
impl<'tcx> NonConstOp<'tcx> for MutBorrow {
impl<'tcx> NonConstOp<'tcx> for EscapingMutBorrow {
fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
Status::Forbidden
}
@ -460,49 +445,6 @@ impl<'tcx> NonConstOp<'tcx> for MutBorrow {
}
}
#[derive(Debug)]
pub(crate) struct TransientMutBorrow(pub hir::BorrowKind);
impl<'tcx> NonConstOp<'tcx> for TransientMutBorrow {
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_mut_refs)
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
let kind = ccx.const_kind();
match self.0 {
hir::BorrowKind::Raw => ccx
.tcx
.sess
.create_feature_err(errors::TransientMutRawErr { span, kind }, sym::const_mut_refs),
hir::BorrowKind::Ref => ccx.tcx.sess.create_feature_err(
errors::TransientMutBorrowErr { span, kind },
sym::const_mut_refs,
),
}
}
}
#[derive(Debug)]
pub(crate) struct MutDeref;
impl<'tcx> NonConstOp<'tcx> for MutDeref {
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_mut_refs)
}
fn importance(&self) -> DiagImportance {
// Usually a side-effect of a `TransientMutBorrow` somewhere.
DiagImportance::Secondary
}
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
ccx.tcx.sess.create_feature_err(
errors::MutDerefErr { span, kind: ccx.const_kind() },
sym::const_mut_refs,
)
}
}
/// A call to a `panic()` lang item where the first argument is _not_ a `&str`.
#[derive(Debug)]
pub(crate) struct PanicNonStr;
@ -524,24 +466,6 @@ impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
}
}
#[derive(Debug)]
pub(crate) struct RawMutPtrDeref;
impl<'tcx> NonConstOp<'tcx> for RawMutPtrDeref {
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
Status::Unstable(sym::const_mut_refs)
}
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
feature_err(
&ccx.tcx.sess,
sym::const_mut_refs,
span,
format!("dereferencing raw mutable pointers in {}s is unstable", ccx.const_kind(),),
)
}
}
/// Casting raw pointer or function pointer to an integer.
/// Not currently intended to ever be allowed, even behind a feature gate: operation depends on
/// allocation base addresses that are not known at compile-time.
@ -588,33 +512,3 @@ impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess {
ccx.dcx().create_err(errors::ThreadLocalAccessErr { span })
}
}
/// Types that cannot appear in the signature or locals of a `const fn`.
pub(crate) mod mut_ref {
use super::*;
#[derive(Debug)]
pub(crate) struct MutRef(pub mir::LocalKind);
impl<'tcx> NonConstOp<'tcx> for MutRef {
fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
Status::Unstable(sym::const_mut_refs)
}
fn importance(&self) -> DiagImportance {
match self.0 {
mir::LocalKind::Temp => DiagImportance::Secondary,
mir::LocalKind::ReturnPointer | mir::LocalKind::Arg => DiagImportance::Primary,
}
}
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
feature_err(
&ccx.tcx.sess,
sym::const_mut_refs,
span,
format!("mutable references are not allowed in {}s", ccx.const_kind()),
)
}
}
}

View File

@ -93,30 +93,6 @@ pub(crate) struct PanicNonStrErr {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(const_eval_mut_deref, code = E0658)]
pub(crate) struct MutDerefErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}
#[derive(Diagnostic)]
#[diag(const_eval_transient_mut_borrow, code = E0658)]
pub(crate) struct TransientMutBorrowErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}
#[derive(Diagnostic)]
#[diag(const_eval_transient_mut_raw, code = E0658)]
pub(crate) struct TransientMutRawErr {
#[primary_span]
pub span: Span,
pub kind: ConstContext,
}
#[derive(Diagnostic)]
#[diag(const_eval_max_num_nodes_in_const)]
pub(crate) struct MaxNumNodesInConstErr {
@ -217,13 +193,6 @@ pub(crate) struct InteriorMutableDataRefer {
pub teach: bool,
}
#[derive(Diagnostic)]
#[diag(const_eval_interior_mutability_borrow)]
pub(crate) struct InteriorMutabilityBorrow {
#[primary_span]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[diag(const_eval_long_running)]
#[note]

View File

@ -3,8 +3,6 @@ A mutable reference was used in a constant.
Erroneous code example:
```compile_fail,E0764
#![feature(const_mut_refs)]
fn main() {
const OH_NO: &'static mut usize = &mut 1; // error!
}
@ -26,8 +24,6 @@ Remember: you cannot use a function call inside a constant or static. However,
you can totally use it in constant functions:
```
#![feature(const_mut_refs)]
const fn foo(x: usize) -> usize {
let mut y = 1;
let z = &mut y;

View File

@ -143,10 +143,14 @@ declare_features! (
(accepted, const_let, "1.33.0", Some(48821)),
/// Allows the use of `loop` and `while` in constants.
(accepted, const_loop, "1.46.0", Some(52000)),
/// Allows using `&mut` in constant functions.
(accepted, const_mut_refs, "CURRENT_RUSTC_VERSION", Some(57349)),
/// Allows panicking during const eval (producing compile-time errors).
(accepted, const_panic, "1.57.0", Some(51999)),
/// Allows dereferencing raw pointers during const eval.
(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).
(accepted, copy_closures, "1.26.0", Some(44490)),
/// Allows `crate` in paths.

View File

@ -403,12 +403,8 @@ declare_features! (
(incomplete, const_closures, "1.68.0", Some(106003)),
/// Allows `for _ in _` loops in const contexts.
(unstable, const_for, "1.56.0", Some(87575)),
/// Allows using `&mut` in constant functions.
(unstable, const_mut_refs, "1.41.0", Some(57349)),
/// Be more precise when looking for live drops in a const context.
(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.
(unstable, const_refs_to_static, "1.78.0", Some(119618)),
/// Allows `impl const Trait for T` syntax.

View File

@ -114,7 +114,6 @@
#![feature(const_maybe_uninit_write)]
#![feature(const_option)]
#![feature(const_pin)]
#![feature(const_refs_to_cell)]
#![feature(const_size_of_val)]
#![feature(core_intrinsics)]
#![feature(deprecated_suggestion)]
@ -164,13 +163,14 @@
//
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![cfg_attr(bootstrap, feature(const_refs_to_cell))]
#![cfg_attr(not(test), feature(coroutine_trait))]
#![cfg_attr(test, feature(panic_update_hook))]
#![cfg_attr(test, feature(test))]
#![feature(allocator_internals)]
#![feature(allow_internal_unstable)]
#![feature(cfg_sanitize)]
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
#![feature(const_ptr_write)]
#![feature(const_try)]

View File

@ -6,7 +6,7 @@
#![feature(cow_is_borrowed)]
#![feature(const_cow_is_borrowed)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![feature(const_slice_from_raw_parts_mut)]
#![feature(const_ptr_write)]
#![feature(const_try)]

View File

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

View File

@ -1569,7 +1569,7 @@ impl<T: ?Sized> *mut T {
///
/// ```
/// #![feature(const_pointer_is_aligned)]
/// #![feature(const_mut_refs)]
/// # #![cfg_attr(bootstrap, feature(const_mut_refs))]
///
/// // On some platforms, the alignment of primitives is less than their size.
/// #[repr(align(4))]
@ -1695,7 +1695,7 @@ impl<T: ?Sized> *mut T {
/// ```
/// #![feature(pointer_is_aligned_to)]
/// #![feature(const_pointer_is_aligned)]
/// #![feature(const_mut_refs)]
/// # #![cfg_attr(bootstrap, feature(const_mut_refs))]
///
/// // On some platforms, the alignment of i32 is less than 4.
/// #[repr(align(4))]

View File

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

View File

@ -1,4 +1,5 @@
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
#![cfg_attr(test, feature(cfg_match))]
#![feature(alloc_layout_extra)]
@ -26,7 +27,6 @@
#![feature(const_ipv6)]
#![feature(const_likely)]
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_mut_refs)]
#![feature(const_nonnull_new)]
#![feature(const_option)]
#![feature(const_option_ext)]

View File

@ -272,6 +272,7 @@
//
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(const_mut_refs))]
#![feature(alloc_error_handler)]
#![feature(allocator_internals)]
#![feature(allow_internal_unsafe)]
@ -281,7 +282,6 @@
#![feature(cfg_target_thread_local)]
#![feature(cfi_encoding)]
#![feature(concat_idents)]
#![feature(const_mut_refs)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(doc_cfg)]

View File

@ -1,5 +1,8 @@
//@aux-build:proc_macro_derive.rs
#![feature(f128)]
#![feature(f16)]
#![allow(
clippy::assign_op_pattern,
clippy::erasing_op,
@ -10,9 +13,6 @@
arithmetic_overflow,
unconditional_panic
)]
#![feature(const_mut_refs)]
#![feature(f128)]
#![feature(f16)]
#![warn(clippy::arithmetic_side_effects)]
extern crate proc_macro_derive;

View File

@ -1,7 +1,6 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
#![allow(unsupported_calling_conventions)]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]
use std::mem::transmute;

View File

@ -1,7 +1,6 @@
#![warn(clippy::missing_const_for_fn)]
#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
#![allow(unsupported_calling_conventions)]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]
use std::mem::transmute;

View File

@ -1,5 +1,5 @@
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:15:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:14:5
|
LL | / pub fn new() -> Self {
LL | |
@ -16,7 +16,7 @@ LL | pub const fn new() -> Self {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:21:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:20:5
|
LL | / fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {
LL | |
@ -30,7 +30,7 @@ LL | const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T;
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:28:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:27:1
|
LL | / fn one() -> i32 {
LL | |
@ -44,7 +44,7 @@ LL | const fn one() -> i32 {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:34:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:33:1
|
LL | / fn two() -> i32 {
LL | |
@ -59,7 +59,7 @@ LL | const fn two() -> i32 {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:41:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:40:1
|
LL | / fn string() -> String {
LL | |
@ -73,7 +73,7 @@ LL | const fn string() -> String {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:47:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:46:1
|
LL | / unsafe fn four() -> i32 {
LL | |
@ -87,7 +87,7 @@ LL | const unsafe fn four() -> i32 {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:53:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:52:1
|
LL | / fn generic<T>(t: T) -> T {
LL | |
@ -101,7 +101,7 @@ LL | const fn generic<T>(t: T) -> T {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:62:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:61:1
|
LL | / fn generic_arr<T: Copy>(t: [T; 1]) -> T {
LL | |
@ -115,7 +115,7 @@ LL | const fn generic_arr<T: Copy>(t: [T; 1]) -> T {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:76:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:75:9
|
LL | / pub fn b(self, a: &A) -> B {
LL | |
@ -129,7 +129,7 @@ LL | pub const fn b(self, a: &A) -> B {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:86:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:85:5
|
LL | / fn const_fn_stabilized_before_msrv(byte: u8) {
LL | |
@ -143,7 +143,7 @@ LL | const fn const_fn_stabilized_before_msrv(byte: u8) {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:98:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:97:1
|
LL | / fn msrv_1_46() -> i32 {
LL | |
@ -157,7 +157,7 @@ LL | const fn msrv_1_46() -> i32 {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:118:1
--> tests/ui/missing_const_for_fn/could_be_const.rs:117:1
|
LL | fn d(this: D) {}
| ^^^^^^^^^^^^^^^^
@ -168,7 +168,7 @@ LL | const fn d(this: D) {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:126:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:125:9
|
LL | / fn deref_ptr_can_be_const(self) -> usize {
LL | |
@ -182,7 +182,7 @@ LL | const fn deref_ptr_can_be_const(self) -> usize {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:131:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:130:9
|
LL | / fn deref_copied_val(self) -> usize {
LL | |
@ -196,7 +196,7 @@ LL | const fn deref_copied_val(self) -> usize {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:142:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:141:5
|
LL | / fn union_access_can_be_const() {
LL | |
@ -211,7 +211,7 @@ LL | const fn union_access_can_be_const() {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:150:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:149:9
|
LL | extern "C" fn c() {}
| ^^^^^^^^^^^^^^^^^^^^
@ -222,7 +222,7 @@ LL | const extern "C" fn c() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:154:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:153:9
|
LL | extern fn implicit_c() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@ -233,7 +233,7 @@ LL | const extern fn implicit_c() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:171:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:170:9
|
LL | / pub fn new(strings: Vec<String>) -> Self {
LL | | Self { strings }
@ -246,7 +246,7 @@ LL | pub const fn new(strings: Vec<String>) -> Self {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:176:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:175:9
|
LL | / pub fn empty() -> Self {
LL | | Self { strings: Vec::new() }
@ -259,7 +259,7 @@ LL | pub const fn empty() -> Self {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:187:9
--> tests/ui/missing_const_for_fn/could_be_const.rs:186:9
|
LL | / pub fn new(text: String) -> Self {
LL | | let vec = Vec::new();
@ -273,7 +273,7 @@ LL | pub const fn new(text: String) -> Self {
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:206:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:205:5
|
LL | fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -284,7 +284,7 @@ LL | const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:210:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:209:5
|
LL | extern "C-unwind" fn c_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -295,7 +295,7 @@ LL | const extern "C-unwind" fn c_unwind() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:212:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:211:5
|
LL | extern "system" fn system() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -306,7 +306,7 @@ LL | const extern "system" fn system() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:214:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:213:5
|
LL | extern "system-unwind" fn system_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -317,7 +317,7 @@ LL | const extern "system-unwind" fn system_unwind() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:216:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:215:5
|
LL | pub extern "stdcall" fn std_call() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -328,7 +328,7 @@ LL | pub const extern "stdcall" fn std_call() {}
| +++++
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:218:5
--> tests/ui/missing_const_for_fn/could_be_const.rs:217:5
|
LL | pub extern "stdcall-unwind" fn std_call_unwind() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -675,8 +675,6 @@ ui/consts/auxiliary/issue-17718-aux.rs
ui/consts/auxiliary/issue-63226.rs
ui/consts/const-eval/issue-100878.rs
ui/consts/const-eval/issue-104390.rs
ui/consts/const-eval/issue-114994-fail.rs
ui/consts/const-eval/issue-114994.rs
ui/consts/const-eval/issue-43197.rs
ui/consts/const-eval/issue-44578.rs
ui/consts/const-eval/issue-47971.rs

View File

@ -1,5 +1,4 @@
#![allow(incomplete_features)]
#![feature(const_mut_refs)]
#![feature(adt_const_params, unsized_const_params)]
struct T<const B: &'static bool>;

View File

@ -1,16 +1,16 @@
error[E0080]: evaluation of constant value failed
--> $DIR/issue-100313.rs:10:13
--> $DIR/issue-100313.rs:9:13
|
LL | *(B as *const bool as *mut bool) = false;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ writing to ALLOC0 which is read-only
|
note: inside `T::<&true>::set_false`
--> $DIR/issue-100313.rs:10:13
--> $DIR/issue-100313.rs:9:13
|
LL | *(B as *const bool as *mut bool) = false;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `_`
--> $DIR/issue-100313.rs:18:5
--> $DIR/issue-100313.rs:17:5
|
LL | x.set_false();
| ^^^^^^^^^^^^^

View File

@ -10,8 +10,6 @@
// See also ../const-mut-refs-crate.rs for more details
// about this test.
#![feature(const_mut_refs)]
// if we used immutable references here, then promotion would
// turn the `&42` into a promoted, which gets duplicated arbitrarily.
pub static mut FOO: &'static mut i32 = &mut 42;

View File

@ -1,14 +1,15 @@
//@check-pass
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() {
let x = Cell::new(0);
let y = &raw const x; //~ ERROR interior mutability
let y = &raw const x;
}
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,10 +1,12 @@
const A: () = { let mut x = 2; &raw mut x; }; //~ mutable pointer
//@check-pass
static B: () = { let mut x = 2; &raw mut x; }; //~ mutable pointer
const A: () = { let mut x = 2; &raw mut x; };
static B: () = { let mut x = 2; &raw mut x; };
const fn foo() {
let mut x = 0;
let y = &raw mut x; //~ mutable pointer
let y = &raw mut x;
}
fn main() {}

View File

@ -1,33 +0,0 @@
error[E0658]: raw mutable pointers are not allowed in constants
--> $DIR/const-address-of-mut.rs:1:32
|
LL | const A: () = { let mut x = 2; &raw mut x; };
| ^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: raw mutable pointers are not allowed in statics
--> $DIR/const-address-of-mut.rs:3:33
|
LL | static B: () = { let mut x = 2; &raw mut x; };
| ^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: raw mutable pointers are not allowed in constant functions
--> $DIR/const-address-of-mut.rs:7:13
|
LL | let y = &raw mut x;
| ^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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

@ -1,6 +1,5 @@
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
use std::intrinsics;
const FOO: i32 = foo();

View File

@ -1,16 +1,16 @@
error[E0080]: evaluation of constant value failed
--> $DIR/alloc_intrinsic_errors.rs:9:17
--> $DIR/alloc_intrinsic_errors.rs:8:17
|
LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid align passed to `const_allocate`: 3 is not a power of 2
|
note: inside `foo`
--> $DIR/alloc_intrinsic_errors.rs:9:17
--> $DIR/alloc_intrinsic_errors.rs:8:17
|
LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `FOO`
--> $DIR/alloc_intrinsic_errors.rs:6:18
--> $DIR/alloc_intrinsic_errors.rs:5:18
|
LL | const FOO: i32 = foo();
| ^^^^^

View File

@ -1,7 +1,6 @@
//@ run-pass
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
use std::intrinsics;
const FOO: &i32 = foo();

View File

@ -1,7 +1,6 @@
//@ run-pass
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
use std::intrinsics;
const FOO: i32 = foo();

View File

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/alloc_intrinsic_uninit.rs:8:1
--> $DIR/alloc_intrinsic_uninit.rs:7:1
|
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
| ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer

View File

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/alloc_intrinsic_uninit.rs:8:1
--> $DIR/alloc_intrinsic_uninit.rs:7:1
|
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
| ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer

View File

@ -2,7 +2,6 @@
// compile-test
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
use std::intrinsics;
const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };

View File

@ -1,9 +1,8 @@
// We unleash Miri here since this test demonstrates code that bypasses the checks against interning
// mutable pointers, which currently ICEs. Unleashing Miri silence the ICE.
// mutable pointers, which currently ICEs. Unleashing Miri silences the ICE.
//@ compile-flags: -Zunleash-the-miri-inside-of-you
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
use std::intrinsics;
const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };

View File

@ -1,5 +1,5 @@
error: encountered mutable pointer in final value of constant
--> $DIR/alloc_intrinsic_untyped.rs:9:1
--> $DIR/alloc_intrinsic_untyped.rs:8:1
|
LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32 };
| ^^^^^^^^^^^^^^^^^^^

View File

@ -1,7 +1,6 @@
//@ run-pass
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
use std::intrinsics;

View File

@ -1,6 +1,5 @@
#![feature(core_intrinsics)]
#![feature(const_heap)]
#![feature(const_mut_refs)]
// Strip out raw byte dumps to make comparison platform-independent:
//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"

View File

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/dealloc_intrinsic_dangling.rs:12:1
--> $DIR/dealloc_intrinsic_dangling.rs:11:1
|
LL | const _X: &'static u8 = unsafe {
| ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free)
@ -10,7 +10,7 @@ LL | const _X: &'static u8 = unsafe {
}
error[E0080]: evaluation of constant value failed
--> $DIR/dealloc_intrinsic_dangling.rs:23:5
--> $DIR/dealloc_intrinsic_dangling.rs:22:5
|
LL | *reference
| ^^^^^^^^^^ memory access failed: ALLOC1 has been freed, so this pointer is dangling

View File

@ -1,14 +0,0 @@
// This checks that function pointer signatures that are referenced mutably
// but contain a &mut T parameter still fail in a constant context: see issue #114994.
//
//@ check-fail
const fn use_mut_const_fn(_f: &mut fn(&mut String)) { //~ ERROR mutable references are not allowed in constant functions
()
}
const fn use_mut_const_tuple_fn(_f: (fn(), &mut u32)) { //~ ERROR mutable references are not allowed in constant functions
}
fn main() {}

View File

@ -1,23 +0,0 @@
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/issue-114994-fail.rs:6:27
|
LL | const fn use_mut_const_fn(_f: &mut fn(&mut String)) {
| ^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/issue-114994-fail.rs:10:33
|
LL | const fn use_mut_const_tuple_fn(_f: (fn(), &mut u32)) {
| ^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,18 +0,0 @@
// This checks that function pointer signatures containing &mut T types
// work in a constant context: see issue #114994.
//
//@ check-pass
const fn use_const_fn(_f: fn(&mut String)) {
()
}
const fn get_some_fn() -> fn(&mut String) {
String::clear
}
const fn some_const_fn() {
let _f: fn(&mut String) = String::clear;
}
fn main() {}

View File

@ -1,11 +1,16 @@
//@ revisions: stock precise_drops
//@[precise_drops] check-pass
// This test originated from #65394. We conservatively assume that `x` is still `LiveDrop` even
// after it has been moved because a mutable reference to it exists at some point in the const body.
//
// We will likely have to change this behavior before we allow `&mut` in a `const`.
// With `&mut` in `const` being stable, this surprising behavior is now observable.
// `const_precise_live_drops` fixes that.
#![cfg_attr(precise_drops, feature(const_precise_live_drops))]
const _: Vec<i32> = {
let mut x = Vec::<i32>::new(); //~ ERROR destructor of
let r = &mut x; //~ ERROR mutable references are not allowed in constants
let mut x = Vec::<i32>::new(); //[stock]~ ERROR destructor of
let r = &mut x;
let y = x;
y
};

View File

@ -1,23 +0,0 @@
error[E0658]: mutable references are not allowed in constants
--> $DIR/issue-65394.rs:8:13
|
LL | let r = &mut x;
| ^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 `Vec<i32>` cannot be evaluated at compile-time
--> $DIR/issue-65394.rs:7:9
|
LL | let mut x = Vec::<i32>::new();
| ^^^^^ the destructor for this type cannot be evaluated in constants
...
LL | };
| - value is dropped here
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0493, E0658.
For more information about an error, try `rustc --explain E0493`.

View File

@ -0,0 +1,12 @@
error[E0493]: destructor of `Vec<i32>` cannot be evaluated at compile-time
--> $DIR/issue-65394.rs:12:9
|
LL | let mut x = Vec::<i32>::new();
| ^^^^^ the destructor for this type cannot be evaluated in constants
...
LL | };
| - value is dropped here
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0493`.

View File

@ -1,8 +1,6 @@
// New test for #53818: modifying static memory at compile-time is not allowed.
// The test should never compile successfully
#![feature(const_mut_refs)]
use std::cell::UnsafeCell;
struct Foo(UnsafeCell<u32>);

View File

@ -1,5 +1,5 @@
error[E0080]: could not evaluate static initializer
--> $DIR/mod-static-with-const-fn.rs:16:5
--> $DIR/mod-static-with-const-fn.rs:14:5
|
LL | *FOO.0.get() = 5;
| ^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer

View File

@ -4,8 +4,6 @@
// its address may be taken and it may be written to indirectly. Ensure that the const-eval
// interpreter can handle this.
#![feature(const_mut_refs)]
#[inline(never)] // Try to ensure that MIR optimizations don't optimize this away.
const fn init(buf: &mut [u8; 1024]) {
buf[33] = 3;

View File

@ -1,5 +1,4 @@
// Test for the behavior described in <https://github.com/rust-lang/rust/issues/87184>.
#![feature(const_mut_refs)]
const PARTIAL_OVERWRITE: () = {
let mut p = &42;

View File

@ -1,5 +1,5 @@
error[E0080]: evaluation of constant value failed
--> $DIR/partial_ptr_overwrite.rs:8:9
--> $DIR/partial_ptr_overwrite.rs:7:9
|
LL | *(ptr as *mut u8) = 123;
| ^^^^^^^^^^^^^^^^^^^^^^^ unable to overwrite parts of a pointer in memory at ALLOC0

View File

@ -1,4 +1,4 @@
#![feature(const_mut_refs, const_intrinsic_copy)]
#![feature(const_intrinsic_copy)]
const MISALIGNED_LOAD: () = unsafe {

View File

@ -1,5 +1,3 @@
#![feature(const_mut_refs)]
enum E {
A(u8),
B,

View File

@ -1,5 +1,5 @@
error[E0080]: evaluation of constant value failed
--> $DIR/ub-enum-overwrite.rs:13:14
--> $DIR/ub-enum-overwrite.rs:11:14
|
LL | unsafe { *p }
| ^^ using uninitialized data, but this operation requires initialized memory

View File

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

View File

@ -1,11 +1,11 @@
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;
| ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference
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;
| ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference

View File

@ -5,7 +5,6 @@ const fn f(x: usize) -> usize {
for i in 0..x {
//~^ ERROR cannot convert
//~| ERROR `for` is not allowed in a `const fn`
//~| ERROR mutable references are not allowed in constant functions
//~| ERROR cannot call non-const fn
sum += i;
}

View File

@ -5,7 +5,6 @@ LL | / for i in 0..x {
LL | |
LL | |
LL | |
LL | |
LL | | sum += i;
LL | | }
| |_____^
@ -28,16 +27,6 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
LL + #![feature(const_trait_impl)]
|
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/const-fn-error.rs:5:14
|
LL | for i in 0..x {
| ^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 `<std::ops::Range<usize> as Iterator>::next` in constant functions
--> $DIR/const-fn-error.rs:5:14
|
@ -50,7 +39,7 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
LL + #![feature(const_trait_impl)]
|
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0015, E0658.
For more information about an error, try `rustc --explain E0015`.

View File

@ -5,7 +5,6 @@ const _: () = {
//~^ error: `for` is not allowed in a `const`
//~| ERROR: cannot convert
//~| ERROR: cannot call
//~| ERROR: mutable references
};
fn main() {}

View File

@ -22,16 +22,6 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
LL + #![feature(const_trait_impl)]
|
error[E0658]: mutable references are not allowed in constants
--> $DIR/const-for-feature-gate.rs:4:14
|
LL | for _ in 0..5 {}
| ^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 `<std::ops::Range<i32> as Iterator>::next` in constants
--> $DIR/const-for-feature-gate.rs:4:14
|
@ -44,7 +34,7 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
LL + #![feature(const_trait_impl)]
|
error: aborting due to 4 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0015, E0658.
For more information about an error, try `rustc --explain E0015`.

View File

@ -1,5 +1,4 @@
#![feature(const_for)]
#![feature(const_mut_refs)]
const _: () = {
for _ in 0..5 {}

View File

@ -1,5 +1,5 @@
error[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants
--> $DIR/const-for.rs:5:14
--> $DIR/const-for.rs:4:14
|
LL | for _ in 0..5 {}
| ^^^^
@ -13,7 +13,7 @@ LL + #![feature(const_trait_impl)]
|
error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
--> $DIR/const-for.rs:5:14
--> $DIR/const-for.rs:4:14
|
LL | for _ in 0..5 {}
| ^^^^

View File

@ -1,24 +0,0 @@
// Ensure that we point the user to the erroneous borrow but not to any subsequent borrows of that
// initial one.
const _: i32 = {
let mut a = 5;
let p = &mut a; //~ ERROR mutable references are not allowed in constants
let reborrow = {p};
let pp = &reborrow;
let ppp = &pp;
***ppp
};
const _: std::cell::Cell<i32> = {
let mut a = std::cell::Cell::new(5);
let p = &a; //~ ERROR borrowed element may contain interior mutability
let reborrow = {p};
let pp = &reborrow;
let ppp = &pp;
a
};
fn main() {}

View File

@ -1,23 +0,0 @@
error[E0658]: mutable references are not allowed in constants
--> $DIR/const-multi-ref.rs:6:13
|
LL | let p = &mut a;
| ^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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-multi-ref.rs:16:13
|
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
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,8 +1,6 @@
//@ run-pass
//@ aux-build:const_mut_refs_crate.rs
#![feature(const_mut_refs)]
//! Regression test for https://github.com/rust-lang/rust/issues/79738
//! Show how we are not duplicating allocations anymore. Statics that
//! copy their value from another static used to also duplicate

View File

@ -1,5 +1,4 @@
//@ check-pass
#![feature(const_mut_refs)]
struct Foo {
x: usize

View File

@ -1,5 +1,4 @@
//@ check-pass
#![feature(const_mut_refs)]
use std::sync::Mutex;

View File

@ -1,8 +0,0 @@
fn main() {
foo(&mut 5);
}
const fn foo(x: &mut i32) -> i32 { //~ ERROR mutable references
*x + 1
}

View File

@ -1,13 +0,0 @@
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/feature-gate-const_mut_refs.rs:5:14
|
LL | const fn foo(x: &mut i32) -> i32 {
| ^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 1 previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -2,7 +2,6 @@ use std::mem::{transmute, ManuallyDrop};
const S: &'static mut str = &mut " hello ";
//~^ ERROR: mutable references are not allowed in the final value of constants
//~| ERROR: mutation through a reference is not allowed in constants
const fn trigger() -> [(); unsafe {
let s = transmute::<(*const u8, usize), &ManuallyDrop<str>>((S.as_ptr(), 3));

View File

@ -4,17 +4,6 @@ error[E0764]: mutable references are not allowed in the final value of constants
LL | const S: &'static mut str = &mut " hello ";
| ^^^^^^^^^^^^^^
error[E0658]: mutation through a reference is not allowed in constants
--> $DIR/issue-76510.rs:3:29
|
LL | const S: &'static mut str = &mut " hello ";
| ^^^^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 1 previous error
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0658, E0764.
For more information about an error, try `rustc --explain E0658`.
For more information about this error, try `rustc --explain E0764`.

View File

@ -1,4 +1,4 @@
#![feature(const_mut_refs)]
use std::cell::UnsafeCell;
const NULL: *mut i32 = std::ptr::null_mut();
const A: *const i32 = &4;
@ -25,7 +25,14 @@ const C: *const i32 = &{
x
};
use std::cell::UnsafeCell;
// Still ok, since `x` will be moved before the final pointer is crated,
// so `_ref` doesn't actually point to the memory that escapes.
const C_NO: *const i32 = &{
let mut x = 42;
let _ref = &mut x;
x
};
struct NotAMutex<T>(UnsafeCell<T>);
unsafe impl<T> Sync for NotAMutex<T> {}

View File

@ -25,7 +25,7 @@ LL | const B4: Option<&mut i32> = helper(&mut 42);
| using this value as a constant requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
--> $DIR/mut_ref_in_final.rs:33:65
--> $DIR/mut_ref_in_final.rs:40:65
|
LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| -------------------------------^^--
@ -35,7 +35,7 @@ LL | const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| using this value as a constant requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
--> $DIR/mut_ref_in_final.rs:36:67
--> $DIR/mut_ref_in_final.rs:43:67
|
LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| -------------------------------^^--
@ -45,7 +45,7 @@ LL | static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| using this value as a static requires that borrow lasts for `'static`
error[E0716]: temporary value dropped while borrowed
--> $DIR/mut_ref_in_final.rs:39:71
--> $DIR/mut_ref_in_final.rs:46:71
|
LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| -------------------------------^^--
@ -55,25 +55,25 @@ LL | static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
| using this value as a static requires that borrow lasts for `'static`
error[E0764]: mutable references are not allowed in the final value of statics
--> $DIR/mut_ref_in_final.rs:52:53
--> $DIR/mut_ref_in_final.rs:59:53
|
LL | static RAW_MUT_CAST_S: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
| ^^^^^^^
error[E0764]: mutable references are not allowed in the final value of statics
--> $DIR/mut_ref_in_final.rs:54:54
--> $DIR/mut_ref_in_final.rs:61:54
|
LL | static RAW_MUT_COERCE_S: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^
error[E0764]: mutable references are not allowed in the final value of constants
--> $DIR/mut_ref_in_final.rs:56:52
--> $DIR/mut_ref_in_final.rs:63:52
|
LL | const RAW_MUT_CAST_C: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
| ^^^^^^^
error[E0764]: mutable references are not allowed in the final value of constants
--> $DIR/mut_ref_in_final.rs:58:53
--> $DIR/mut_ref_in_final.rs:65:53
|
LL | const RAW_MUT_COERCE_C: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^

View File

@ -1,7 +1,7 @@
//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
//@ normalize-stderr-test: "( 0x[0-9a-f][0-9a-f] │)? ([0-9a-f][0-9a-f] |__ |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> " HEX_DUMP"
//@ normalize-stderr-test: "HEX_DUMP\s*\n\s*HEX_DUMP" -> "HEX_DUMP"
#![feature(const_mut_refs, const_refs_to_static)]
#![feature(const_refs_to_static)]
use std::sync::Mutex;

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
--> $DIR/const-promoted-opaque.rs:28:26
|
LL | let _: &'static _ = &FOO;
| ^^^ the destructor for this type cannot be evaluated in constants
...
LL |
LL | };
| - value is dropped here
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;
| ^^^^ this borrow of an interior mutable value may end up in the final value
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;
| ---------- ^^^ creates a temporary value which is freed while still in use
@ -34,7 +24,7 @@ LL |
LL | }
| - 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`.

View File

@ -27,7 +27,6 @@ use helper::*;
const BAR: () = {
let _: &'static _ = &FOO;
//[string,atomic]~^ ERROR: destructor of `helper::Foo` cannot be evaluated at compile-time
//[atomic]~| ERROR: cannot borrow here
};
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;
| ^^^ the destructor for this type cannot be evaluated in constants
...
LL |
LL | };
| - value is dropped here
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;
| ---------- ^^^ creates a temporary value which is freed while still in use

View File

@ -1,6 +1,6 @@
//@check-pass
//! This is the reduced version of the "Linux kernel vtable" use-case.
#![feature(const_mut_refs, const_refs_to_static)]
#![feature(const_refs_to_static)]
use std::ptr::addr_of_mut;
#[repr(C)]

View File

@ -1,7 +1,10 @@
//@compile-flags: --edition 2018
use std::cell::Cell;
const WRITE: () = unsafe {
*std::ptr::null_mut() = 0;
//~^ ERROR dereferencing raw mutable pointers in constants is unstable
//~| HELP add `#![feature(const_mut_refs)]` to the crate attributes to enable
let x = async { 13 };
//~^ ERROR `async` blocks
//~| HELP add `#![feature(const_async_blocks)]` to the crate attributes to enable
};
fn main() {}

View File

@ -1,11 +1,11 @@
error[E0658]: dereferencing raw mutable pointers in constants is unstable
--> $DIR/const-suggest-feature.rs:2:5
error[E0658]: `async` blocks are not allowed in constants
--> $DIR/const-suggest-feature.rs:5:13
|
LL | *std::ptr::null_mut() = 0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | let x = async { 13 };
| ^^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
= note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
= 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
error: aborting due to 1 previous error

View File

@ -1,23 +1,24 @@
//@ check-pass
struct S {
state: u32,
}
impl S {
const fn foo(&mut self, x: u32) {
//~^ ERROR mutable reference
self.state = x;
}
}
const FOO: S = {
let mut s = S { state: 42 };
s.foo(3); //~ ERROR mutable reference
s.foo(3);
s
};
type Array = [u32; {
let mut x = 2;
let y = &mut x; //~ ERROR mutable reference
let y = &mut x;
*y = 42;
*y
}];

View File

@ -1,33 +0,0 @@
error[E0658]: mutable references are not allowed in constants
--> $DIR/const_let_assign3.rs:14:5
|
LL | s.foo(3);
| ^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/const_let_assign3.rs:6:18
|
LL | const fn foo(&mut self, x: u32) {
| ^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constants
--> $DIR/const_let_assign3.rs:20:13
|
LL | let y = &mut x;
| ^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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

@ -1,6 +1,6 @@
//@ 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] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP"
#![feature(const_refs_to_static, const_mut_refs, sync_unsafe_cell)]
#![feature(const_refs_to_static, sync_unsafe_cell)]
use std::cell::SyncUnsafeCell;
static S: SyncUnsafeCell<i32> = SyncUnsafeCell::new(0);

View File

@ -52,14 +52,12 @@ const _: i32 = {
for i in 0..4 { //~ ERROR `for` is not allowed in a `const`
//~^ ERROR: cannot call
//~| ERROR: mutable references
//~| ERROR: cannot convert
x += i;
}
for i in 0..4 { //~ ERROR `for` is not allowed in a `const`
//~^ ERROR: cannot call
//~| ERROR: mutable references
//~| ERROR: cannot convert
x += i;
}

View File

@ -4,7 +4,6 @@ error[E0658]: `for` is not allowed in a `const`
LL | / for i in 0..4 {
LL | |
LL | |
LL | |
LL | | x += i;
LL | | }
| |_____^
@ -14,12 +13,11 @@ LL | | }
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error[E0658]: `for` is not allowed in a `const`
--> $DIR/loop.rs:60:5
--> $DIR/loop.rs:59:5
|
LL | / for i in 0..4 {
LL | |
LL | |
LL | |
LL | | x += i;
LL | | }
| |_____^
@ -42,16 +40,6 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
LL + #![feature(const_trait_impl)]
|
error[E0658]: mutable references are not allowed in constants
--> $DIR/loop.rs:53:14
|
LL | for i in 0..4 {
| ^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 `<std::ops::Range<i32> as Iterator>::next` in constants
--> $DIR/loop.rs:53:14
|
@ -65,7 +53,7 @@ LL + #![feature(const_trait_impl)]
|
error[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants
--> $DIR/loop.rs:60:14
--> $DIR/loop.rs:59:14
|
LL | for i in 0..4 {
| ^^^^
@ -78,18 +66,8 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
LL + #![feature(const_trait_impl)]
|
error[E0658]: mutable references are not allowed in constants
--> $DIR/loop.rs:60:14
|
LL | for i in 0..4 {
| ^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 `<std::ops::Range<i32> as Iterator>::next` in constants
--> $DIR/loop.rs:60:14
--> $DIR/loop.rs:59:14
|
LL | for i in 0..4 {
| ^^^^
@ -100,7 +78,7 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
LL + #![feature(const_trait_impl)]
|
error: aborting due to 8 previous errors
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0015, E0658.
For more information about an error, try `rustc --explain E0015`.

View File

@ -2,7 +2,6 @@
// ignore-tidy-linelength
#![feature(intrinsics, staged_api)]
#![feature(const_mut_refs)]
use std::mem;
extern "rust-intrinsic" {

View File

@ -1,23 +1,23 @@
error[E0080]: evaluation of constant value failed
--> $DIR/copy-intrinsic.rs:29:5
--> $DIR/copy-intrinsic.rs:28:5
|
LL | copy_nonoverlapping(0x100 as *const i32, dangle, 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got 0x100[noalloc] which is a dangling pointer (it has no provenance)
error[E0080]: evaluation of constant value failed
--> $DIR/copy-intrinsic.rs:38:5
--> $DIR/copy-intrinsic.rs:37:5
|
LL | copy_nonoverlapping(dangle, 0x100 as *mut i32, 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: expected a pointer to 4 bytes of memory, but got ALLOC0+0x28 which is at or beyond the end of the allocation of size 4 bytes
error[E0080]: evaluation of constant value failed
--> $DIR/copy-intrinsic.rs:45:5
--> $DIR/copy-intrinsic.rs:44:5
|
LL | copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy`
error[E0080]: evaluation of constant value failed
--> $DIR/copy-intrinsic.rs:51:5
--> $DIR/copy-intrinsic.rs:50:5
|
LL | copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping`

View File

@ -4,9 +4,7 @@
#![feature(fn_traits)]
#![feature(unboxed_closures)]
#![feature(const_trait_impl)]
#![feature(const_mut_refs)]
#![feature(const_cmp)]
#![feature(const_refs_to_cell)]
use std::marker::Destruct;

View File

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

View File

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/interior-mut-const-via-union.rs:35:1
--> $DIR/interior-mut-const-via-union.rs:34:1
|
LL | fn main() {
| ^^^^^^^^^ constructing invalid value at .<deref>.y.<enum-variant(B)>.0: encountered `UnsafeCell` in read-only memory
@ -10,13 +10,13 @@ LL | fn main() {
}
note: erroneous constant encountered
--> $DIR/interior-mut-const-via-union.rs:37:25
--> $DIR/interior-mut-const-via-union.rs:36:25
|
LL | let _: &'static _ = &C;
| ^^
note: erroneous constant encountered
--> $DIR/interior-mut-const-via-union.rs:37:25
--> $DIR/interior-mut-const-via-union.rs:36:25
|
LL | let _: &'static _ = &C;
| ^^

View File

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/interior-mut-const-via-union.rs:35:1
--> $DIR/interior-mut-const-via-union.rs:34:1
|
LL | fn main() {
| ^^^^^^^^^ constructing invalid value at .<deref>.y.<enum-variant(B)>.0: encountered `UnsafeCell` in read-only memory
@ -10,13 +10,13 @@ LL | fn main() {
}
note: erroneous constant encountered
--> $DIR/interior-mut-const-via-union.rs:37:25
--> $DIR/interior-mut-const-via-union.rs:36:25
|
LL | let _: &'static _ = &C;
| ^^
note: erroneous constant encountered
--> $DIR/interior-mut-const-via-union.rs:37:25
--> $DIR/interior-mut-const-via-union.rs:36:25
|
LL | let _: &'static _ = &C;
| ^^

View File

@ -3,7 +3,6 @@
//
//@ build-fail
//@ stderr-per-bitwidth
#![feature(const_mut_refs)]
use std::cell::Cell;
use std::mem::ManuallyDrop;

View File

@ -6,6 +6,5 @@ const C1: &'static mut [usize] = &mut [];
static mut S: usize = 3;
const C2: &'static mut usize = unsafe { &mut S };
//~^ ERROR: referencing statics in constants
//~| ERROR: mutable references are not allowed
fn main() {}

View File

@ -16,17 +16,7 @@ LL | const C2: &'static mut usize = unsafe { &mut S };
= note: `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
= help: to fix this, the value can be extracted to a `const` and then used.
error[E0658]: mutable references are not allowed in constants
--> $DIR/issue-17718-const-bad-values.rs:7:41
|
LL | const C2: &'static mut usize = unsafe { &mut S };
| ^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0658, E0764.
For more information about an error, try `rustc --explain E0658`.

View File

@ -1,7 +1,6 @@
//@ run-pass
#![feature(const_ptr_write)]
#![feature(const_mut_refs)]
// Or, equivalently: `MaybeUninit`.
pub union BagOfBits<T: Copy> {

View File

@ -1,7 +1,6 @@
//@ check-pass
#![feature(const_swap)]
#![feature(const_mut_refs)]
#[repr(C)]
struct Demo(u64, bool, u64, u32, u64, u64, u64);

View File

@ -1,6 +1,6 @@
//@ known-bug: #103507
#![feature(const_trait_impl, const_mut_refs)]
#![feature(const_trait_impl)]
struct Foo<'a> {
bar: &'a mut Vec<usize>,

View File

@ -1,15 +0,0 @@
const fn mutable_address_of_in_const() {
let mut a = 0;
let b = &raw mut a; //~ ERROR mutable pointer
}
struct X;
impl X {
const fn inherent_mutable_address_of_in_const() {
let mut a = 0;
let b = &raw mut a; //~ ERROR mutable pointer
}
}
fn main() {}

View File

@ -1,23 +0,0 @@
error[E0658]: raw mutable pointers are not allowed in constant functions
--> $DIR/address_of.rs:3:13
|
LL | let b = &raw mut a;
| ^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: raw mutable pointers are not allowed in constant functions
--> $DIR/address_of.rs:11:17
|
LL | let b = &raw mut a;
| ^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -37,34 +37,22 @@ impl<T> Foo<T> {
const fn into_inner(self) -> T { self.0 } //~ destructor of
const fn get(&self) -> &T { &self.0 }
const fn get_mut(&mut self) -> &mut T { &mut self.0 }
//~^ mutable references
//~| mutable references
//~| mutable references
}
impl<'a, T> Foo<T> {
const fn new_lt(t: T) -> Self { Foo(t) }
const fn into_inner_lt(self) -> T { self.0 } //~ destructor of
const fn get_lt(&'a self) -> &T { &self.0 } //~ WARNING elided lifetime has a name
const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 } //~ WARNING elided lifetime has a name
//~^ mutable references
//~| mutable references
//~| mutable references
const fn get_lt(&self) -> &T { &self.0 }
const fn get_mut_lt(&mut self) -> &mut T { &mut self.0 }
}
impl<T: Sized> Foo<T> {
const fn new_s(t: T) -> Self { Foo(t) }
const fn into_inner_s(self) -> T { self.0 } //~ ERROR destructor
const fn get_s(&self) -> &T { &self.0 }
const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
//~^ mutable references
//~| mutable references
//~| mutable references
}
impl<T: ?Sized> Foo<T> {
const fn get_sq(&self) -> &T { &self.0 }
const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
//~^ mutable references
//~| mutable references
//~| mutable references
}
@ -98,7 +86,6 @@ const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
//~^ ERROR pointers cannot be cast to integers
const fn foo30_6() -> bool { let x = true; x }
const fn inc(x: &mut i32) { *x += 1 }
//~^ ERROR mutable references
// ok
const fn foo36(a: bool, b: bool) -> bool { a && b }

View File

@ -1,23 +1,3 @@
warning: elided lifetime has a name
--> $DIR/min_const_fn.rs:47:34
|
LL | impl<'a, T> Foo<T> {
| -- lifetime `'a` declared here
...
LL | const fn get_lt(&'a self) -> &T { &self.0 }
| ^ this elided lifetime gets resolved as `'a`
|
= note: `#[warn(elided_named_lifetimes)]` on by default
warning: elided lifetime has a name
--> $DIR/min_const_fn.rs:48:42
|
LL | impl<'a, T> Foo<T> {
| -- lifetime `'a` declared here
...
LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
| ^ this elided lifetime gets resolved as `'a`
error[E0493]: destructor of `Foo<T>` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:37:25
|
@ -26,144 +6,24 @@ LL | const fn into_inner(self) -> T { self.0 }
| |
| the destructor for this type cannot be evaluated in constant functions
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:39:22
|
LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:39:36
|
LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:39:45
|
LL | const fn get_mut(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 `Foo<T>` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:46:28
--> $DIR/min_const_fn.rs:43:28
|
LL | const fn into_inner_lt(self) -> T { self.0 }
| ^^^^ - value is dropped here
| |
| the destructor for this type cannot be evaluated in constant functions
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:48:25
|
LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
| ^^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:48:42
|
LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
| ^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:48:51
|
LL | const fn get_mut_lt(&'a mut self) -> &mut T { &mut self.0 }
| ^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 `Foo<T>` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:55:27
--> $DIR/min_const_fn.rs:49:27
|
LL | const fn into_inner_s(self) -> T { self.0 }
| ^^^^ - value is dropped here
| |
| the destructor for this type cannot be evaluated in constant functions
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:57:24
|
LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:57:38
|
LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:57:47
|
LL | const fn get_mut_s(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:64:25
|
LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:64:39
|
LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:64:48
|
LL | const fn get_mut_sq(&mut self) -> &mut T { &mut self.0 }
| ^^^^^^^^^^^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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]: referencing statics in constant functions is unstable
--> $DIR/min_const_fn.rs:89:27
--> $DIR/min_const_fn.rs:77:27
|
LL | const fn foo25() -> u32 { BAR }
| ^^^
@ -175,7 +35,7 @@ LL | const fn foo25() -> u32 { BAR }
= help: to fix this, the value can be extracted to a `const` and then used.
error[E0658]: referencing statics in constant functions is unstable
--> $DIR/min_const_fn.rs:90:37
--> $DIR/min_const_fn.rs:78:37
|
LL | const fn foo26() -> &'static u32 { &BAR }
| ^^^
@ -187,7 +47,7 @@ LL | const fn foo26() -> &'static u32 { &BAR }
= help: to fix this, the value can be extracted to a `const` and then used.
error: pointers cannot be cast to integers during const eval
--> $DIR/min_const_fn.rs:91:42
--> $DIR/min_const_fn.rs:79:42
|
LL | const fn foo30(x: *const u32) -> usize { x as usize }
| ^^^^^^^^^^
@ -196,7 +56,7 @@ LL | const fn foo30(x: *const u32) -> usize { x as usize }
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error: pointers cannot be cast to integers during const eval
--> $DIR/min_const_fn.rs:93:63
--> $DIR/min_const_fn.rs:81:63
|
LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize } }
| ^^^^^^^^^^
@ -205,7 +65,7 @@ LL | const fn foo30_with_unsafe(x: *const u32) -> usize { unsafe { x as usize }
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error: pointers cannot be cast to integers during const eval
--> $DIR/min_const_fn.rs:95:42
--> $DIR/min_const_fn.rs:83:42
|
LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
| ^^^^^^^^^^
@ -214,7 +74,7 @@ LL | const fn foo30_2(x: *mut u32) -> usize { x as usize }
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error: pointers cannot be cast to integers during const eval
--> $DIR/min_const_fn.rs:97:63
--> $DIR/min_const_fn.rs:85:63
|
LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
| ^^^^^^^^^^
@ -222,18 +82,8 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize }
= note: at compile-time, pointers do not have an integer value
= note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
error[E0658]: mutable references are not allowed in constant functions
--> $DIR/min_const_fn.rs:100:14
|
LL | const fn inc(x: &mut i32) { *x += 1 }
| ^
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
= help: add `#![feature(const_mut_refs)]` 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 `AlanTuring<impl std::fmt::Debug>` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:122:19
--> $DIR/min_const_fn.rs:109:19
|
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
| ^^ - value is dropped here
@ -241,14 +91,14 @@ LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
| the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `impl std::fmt::Debug` cannot be evaluated at compile-time
--> $DIR/min_const_fn.rs:124:18
--> $DIR/min_const_fn.rs:111:18
|
LL | const fn no_apit(_x: impl std::fmt::Debug) {}
| ^^ - value is dropped here
| |
| the destructor for this type cannot be evaluated in constant functions
error: aborting due to 24 previous errors; 2 warnings emitted
error: aborting due to 11 previous errors
Some errors have detailed explanations: E0493, E0658.
For more information about an error, try `rustc --explain E0493`.

View File

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

Some files were not shown because too many files have changed in this diff Show More