Rollup merge of #127679 - RalfJung:raw_ref_op, r=jieyouxu

Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](https://github.com/rust-lang/rust/issues/64490#issuecomment-1163802912) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: https://github.com/rust-lang/unsafe-code-guidelines/issues/257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: https://github.com/rust-lang/rust/issues/127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of https://github.com/rust-lang/rust/pull/127679#issuecomment-2264073752 for rationale
  - Implementation: https://github.com/rust-lang/rust/pull/128782
- [ ] Update the Reference.
  - https://github.com/rust-lang/reference/pull/1567

Fixes https://github.com/rust-lang/rust/issues/64490

cc `@rust-lang/lang` `@rust-lang/opsem`

try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
This commit is contained in:
Trevor Gross 2024-08-18 23:41:46 -05:00 committed by GitHub
commit f27a9b15d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
115 changed files with 204 additions and 338 deletions

View File

@ -539,7 +539,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
}
}
gate_all!(gen_blocks, "gen blocks are experimental");
gate_all!(raw_ref_op, "raw address of syntax is experimental");
gate_all!(const_trait_impl, "const trait impls are experimental");
gate_all!(
half_open_range_patterns_in_slices,

View File

@ -55,8 +55,8 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention) |
PlaceContext::NonUse(NonUseContext::AscribeUserTy(_)) |
PlaceContext::MutatingUse(MutatingUseContext::AddressOf) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) |
PlaceContext::MutatingUse(MutatingUseContext::RawBorrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) |

View File

@ -1242,7 +1242,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
);
}
&Rvalue::AddressOf(mutability, place) => {
&Rvalue::RawPtr(mutability, place) => {
let access_kind = match mutability {
Mutability::Mut => (
Deep,

View File

@ -269,7 +269,7 @@ impl<'cx, 'tcx> LoanInvalidationsGenerator<'cx, 'tcx> {
self.access_place(location, place, access_kind, LocalMutationIsAllowed::No);
}
&Rvalue::AddressOf(mutability, place) => {
&Rvalue::RawPtr(mutability, place) => {
let access_kind = match mutability {
Mutability::Mut => (
Deep,

View File

@ -756,7 +756,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
PlaceContext::MutatingUse(_) => ty::Invariant,
PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant,
PlaceContext::NonMutatingUse(
Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | AddressOf
Inspect | Copy | Move | PlaceMention | SharedBorrow | FakeBorrow | RawBorrow
| Projection,
) => ty::Covariant,
PlaceContext::NonUse(AscribeUserTy(variance)) => variance,
@ -2468,7 +2468,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
self.check_operand(right, location);
}
Rvalue::AddressOf(..)
Rvalue::RawPtr(..)
| Rvalue::ThreadLocalRef(..)
| Rvalue::Len(..)
| Rvalue::Discriminant(..)
@ -2485,7 +2485,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
| Rvalue::ThreadLocalRef(_)
| Rvalue::Repeat(..)
| Rvalue::Ref(..)
| Rvalue::AddressOf(..)
| Rvalue::RawPtr(..)
| Rvalue::Len(..)
| Rvalue::Cast(..)
| Rvalue::ShallowInitBox(..)

View File

@ -6,8 +6,7 @@
extern_types,
naked_functions,
thread_local,
repr_simd,
raw_ref_op
repr_simd
)]
#![no_core]
#![allow(dead_code, non_camel_case_types, internal_features)]

View File

@ -25,7 +25,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec<Local, SsaKind> {
for stmt in bb.statements.iter() {
match &stmt.kind {
Assign(place_and_rval) => match &place_and_rval.1 {
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
flag_map[place.local] = SsaKind::NotSsa;
}
_ => {}

View File

@ -595,7 +595,7 @@ fn codegen_stmt<'tcx>(
let val = cplace.to_cvalue(fx);
lval.write_cvalue(fx, val)
}
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
let place = codegen_place(fx, place);
let ref_ = place.place_ref(fx, lval.layout());
lval.write_cvalue(fx, ref_);

View File

@ -2,7 +2,7 @@
#![feature(
no_core, unboxed_closures, start, lang_items, never_type, linkage,
extern_types, thread_local, raw_ref_op
extern_types, thread_local
)]
#![no_core]
#![allow(dead_code, internal_features, non_camel_case_types)]

View File

@ -220,14 +220,14 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
| MutatingUseContext::SetDiscriminant
| MutatingUseContext::AsmOutput
| MutatingUseContext::Borrow
| MutatingUseContext::AddressOf
| MutatingUseContext::RawBorrow
| MutatingUseContext::Projection,
)
| PlaceContext::NonMutatingUse(
NonMutatingUseContext::Inspect
| NonMutatingUseContext::SharedBorrow
| NonMutatingUseContext::FakeBorrow
| NonMutatingUseContext::AddressOf
| NonMutatingUseContext::RawBorrow
| NonMutatingUseContext::Projection,
) => {
self.locals[local] = LocalKind::Memory;

View File

@ -584,7 +584,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::Rvalue::CopyForDeref(place) => {
self.codegen_operand(bx, &mir::Operand::Copy(place))
}
mir::Rvalue::AddressOf(mutability, place) => {
mir::Rvalue::RawPtr(mutability, place) => {
let mk_ptr =
move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| Ty::new_ptr(tcx, ty, mutability);
self.codegen_place_to_pointer(bx, place, mk_ptr)
@ -813,7 +813,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
cg_value.len(bx.cx())
}
/// Codegen an `Rvalue::AddressOf` or `Rvalue::Ref`
/// Codegen an `Rvalue::RawPtr` or `Rvalue::Ref`
fn codegen_place_to_pointer(
&mut self,
bx: &mut Bx,
@ -1085,7 +1085,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
mir::Rvalue::Ref(..) |
mir::Rvalue::CopyForDeref(..) |
mir::Rvalue::AddressOf(..) |
mir::Rvalue::RawPtr(..) |
mir::Rvalue::Len(..) |
mir::Rvalue::Cast(..) | // (*)
mir::Rvalue::ShallowInitBox(..) | // (*)

View File

@ -431,13 +431,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
return;
}
}
Rvalue::AddressOf(mutbl, place) => {
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::AddressOf)
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow)
}
Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::AddressOf),
Mutability::Mut => PlaceContext::MutatingUse(MutatingUseContext::RawBorrow),
};
self.visit_local(reborrowed_place_ref.local, ctx, location);
self.visit_projection(reborrowed_place_ref, ctx, location);
@ -472,7 +472,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
Rvalue::Ref(_, BorrowKind::Mut { .. }, place)
| Rvalue::AddressOf(Mutability::Mut, place) => {
| Rvalue::RawPtr(Mutability::Mut, place) => {
// Inside mutable statics, we allow arbitrary mutable references.
// We've allowed `static mut FOO = &mut [elements];` for a long time (the exact
// reasons why are lost to history), and there is no reason to restrict that to
@ -493,7 +493,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
Rvalue::Ref(_, BorrowKind::Shared | BorrowKind::Fake(_), place)
| Rvalue::AddressOf(Mutability::Not, place) => {
| Rvalue::RawPtr(Mutability::Not, place) => {
let borrowed_place_has_mut_interior = qualifs::in_place::<HasMutInterior, _>(
self.ccx,
&mut |local| self.qualifs.has_mut_interior(self.ccx, local, location),

View File

@ -291,7 +291,7 @@ where
in_operand::<Q, _>(cx, in_local, lhs) || in_operand::<Q, _>(cx, in_local, rhs)
}
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
// Special-case reborrows to be more like a copy of the reference.
if let Some((place_base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
let base_ty = place_base.ty(cx.body, cx.tcx).ty;

View File

@ -96,7 +96,7 @@ where
}
fn address_of_allows_mutation(&self) -> bool {
// Exact set of permissions granted by AddressOf is undecided. Conservatively assume that
// Exact set of permissions granted by RawPtr is undecided. Conservatively assume that
// it might allow mutation until resolution of #56604.
true
}
@ -170,7 +170,7 @@ where
self.super_rvalue(rvalue, location);
match rvalue {
mir::Rvalue::AddressOf(_mt, borrowed_place) => {
mir::Rvalue::RawPtr(_mt, borrowed_place) => {
if !borrowed_place.is_indirect() && self.address_of_allows_mutation() {
let place_ty = borrowed_place.ty(self.ccx.body, self.ccx.tcx).ty;
if Q::in_any_value_of_ty(self.ccx, place_ty) {

View File

@ -234,7 +234,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
self.write_immediate(*val, &dest)?;
}
AddressOf(_, place) => {
RawPtr(_, place) => {
// Figure out whether this is an addr_of of an already raw place.
let place_base_raw = if place.is_indirect_first_projection() {
let ty = self.frame().body.local_decls[place.local].ty;

View File

@ -3,7 +3,6 @@ The address of temporary value was taken.
Erroneous code example:
```compile_fail,E0745
# #![feature(raw_ref_op)]
fn temp_address() {
let ptr = &raw const 2; // error!
}
@ -15,7 +14,6 @@ In this example, `2` is destroyed right after the assignment, which means that
To avoid this error, first bind the temporary to a named local variable:
```
# #![feature(raw_ref_op)]
fn temp_address() {
let val = 2;
let ptr = &raw const val; // ok!

View File

@ -321,6 +321,8 @@ declare_features! (
(accepted, raw_dylib, "1.71.0", Some(58713)),
/// Allows keywords to be escaped for use as identifiers.
(accepted, raw_identifiers, "1.30.0", Some(48589)),
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
(accepted, raw_ref_op, "CURRENT_RUSTC_VERSION", Some(64490)),
/// Allows relaxing the coherence rules such that
/// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
(accepted, re_rebalance_coherence, "1.41.0", Some(55437)),

View File

@ -565,8 +565,6 @@ declare_features! (
(unstable, precise_capturing, "1.79.0", Some(123432)),
/// Allows macro attributes on expressions, statements and non-inline modules.
(unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
/// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
(unstable, raw_ref_op, "1.41.0", Some(64490)),
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
(incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
/// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant

View File

@ -967,7 +967,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
// need to special-case obtaining a raw pointer
// from a region pointer to a vector.
// Coerce to a raw pointer so that we generate AddressOf in MIR.
// Coerce to a raw pointer so that we generate RawPtr in MIR.
let array_ptr_type = Ty::new_ptr(fcx.tcx, m_expr.ty, m_expr.mutbl);
fcx.coerce(self.expr, self.expr_ty, array_ptr_type, AllowTwoPhase::No, None)
.unwrap_or_else(|_| {

View File

@ -1038,7 +1038,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
CopyForDeref(ref place) => write!(fmt, "deref_copy {place:#?}"),
AddressOf(mutability, ref place) => {
RawPtr(mutability, ref place) => {
write!(fmt, "&raw {mut_str} {place:?}", mut_str = mutability.ptr_str())
}

View File

@ -423,7 +423,7 @@ impl<'tcx> Rvalue<'tcx> {
| Rvalue::Repeat(_, _)
| Rvalue::Ref(_, _, _)
| Rvalue::ThreadLocalRef(_)
| Rvalue::AddressOf(_, _)
| Rvalue::RawPtr(_, _)
| Rvalue::Len(_)
| Rvalue::Cast(
CastKind::IntToInt

View File

@ -1293,14 +1293,14 @@ pub enum Rvalue<'tcx> {
/// nature of this operation?
ThreadLocalRef(DefId),
/// Creates a pointer with the indicated mutability to the place.
/// Creates a raw pointer with the indicated mutability to the place.
///
/// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
/// `&raw v` or `addr_of!(v)`.
/// This is generated by pointer casts like `&v as *const _` or raw borrow expressions like
/// `&raw const v`.
///
/// Like with references, the semantics of this operation are heavily dependent on the aliasing
/// model.
AddressOf(Mutability, Place<'tcx>),
RawPtr(Mutability, Place<'tcx>),
/// Yields the length of the place, as a `usize`.
///

View File

@ -170,7 +170,7 @@ impl<'tcx> Rvalue<'tcx> {
let place_ty = place.ty(local_decls, tcx).ty;
Ty::new_ref(tcx, reg, place_ty, bk.to_mutbl_lossy())
}
Rvalue::AddressOf(mutability, ref place) => {
Rvalue::RawPtr(mutability, ref place) => {
let place_ty = place.ty(local_decls, tcx).ty;
Ty::new_ptr(tcx, place_ty, mutability)
}

View File

@ -682,13 +682,13 @@ macro_rules! make_mir_visitor {
);
}
Rvalue::AddressOf(m, path) => {
Rvalue::RawPtr(m, path) => {
let ctx = match m {
Mutability::Mut => PlaceContext::MutatingUse(
MutatingUseContext::AddressOf
MutatingUseContext::RawBorrow
),
Mutability::Not => PlaceContext::NonMutatingUse(
NonMutatingUseContext::AddressOf
NonMutatingUseContext::RawBorrow
),
};
self.visit_place(path, ctx, location);
@ -1299,8 +1299,8 @@ pub enum NonMutatingUseContext {
/// FIXME: do we need to distinguish shallow and deep fake borrows? In fact, do we need to
/// distinguish fake and normal deep borrows?
FakeBorrow,
/// AddressOf for *const pointer.
AddressOf,
/// `&raw const`.
RawBorrow,
/// PlaceMention statement.
///
/// This statement is executed as a check that the `Place` is live without reading from it,
@ -1333,8 +1333,8 @@ pub enum MutatingUseContext {
Drop,
/// Mutable borrow.
Borrow,
/// AddressOf for *mut pointer.
AddressOf,
/// `&raw mut`.
RawBorrow,
/// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
/// For example, the projection `x.y` is marked as a mutation in these cases:
/// ```ignore (illustrative)
@ -1386,8 +1386,8 @@ impl PlaceContext {
pub fn is_address_of(&self) -> bool {
matches!(
self,
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
| PlaceContext::MutatingUse(MutatingUseContext::AddressOf)
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow)
| PlaceContext::MutatingUse(MutatingUseContext::RawBorrow)
)
}

View File

@ -407,7 +407,7 @@ pub enum ExprKind<'tcx> {
arg: ExprId,
},
/// A `&raw [const|mut] $place_expr` raw borrow resulting in type `*[const|mut] T`.
AddressOf {
RawBorrow {
mutability: hir::Mutability,
arg: ExprId,
},

View File

@ -92,7 +92,7 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
}
VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]),
AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
RawBorrow { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
Break { value, label: _ } => {
if let Some(value) = value {
visitor.visit_expr(&visitor.thir()[value])

View File

@ -244,8 +244,8 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
ExprKind::Borrow { borrow_kind, arg } => Ok(
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
),
ExprKind::AddressOf { mutability, arg } => Ok(
Rvalue::AddressOf(*mutability, self.parse_place(*arg)?)
ExprKind::RawBorrow { mutability, arg } => Ok(
Rvalue::RawPtr(*mutability, self.parse_place(*arg)?)
),
ExprKind::Binary { op, lhs, rhs } => Ok(
Rvalue::BinaryOp(*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?)))

View File

@ -542,7 +542,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| ExprKind::PointerCoercion { .. }
| ExprKind::Repeat { .. }
| ExprKind::Borrow { .. }
| ExprKind::AddressOf { .. }
| ExprKind::RawBorrow { .. }
| ExprKind::Match { .. }
| ExprKind::If { .. }
| ExprKind::Loop { .. }

View File

@ -512,7 +512,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
| ExprKind::NeverToAny { .. }
| ExprKind::Use { .. }
| ExprKind::Borrow { .. }
| ExprKind::AddressOf { .. }
| ExprKind::RawBorrow { .. }
| ExprKind::Adt { .. }
| ExprKind::Loop { .. }
| ExprKind::LogicalOp { .. }

View File

@ -51,7 +51,7 @@ impl Category {
| ExprKind::Use { .. }
| ExprKind::Adt { .. }
| ExprKind::Borrow { .. }
| ExprKind::AddressOf { .. }
| ExprKind::RawBorrow { .. }
| ExprKind::Yield { .. }
| ExprKind::Call { .. }
| ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::Into)),

View File

@ -303,12 +303,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
this.cfg.push_assign(block, source_info, destination, borrow);
block.unit()
}
ExprKind::AddressOf { mutability, arg } => {
ExprKind::RawBorrow { mutability, arg } => {
let place = match mutability {
hir::Mutability::Not => this.as_read_only_place(block, arg),
hir::Mutability::Mut => this.as_place(block, arg),
};
let address_of = Rvalue::AddressOf(mutability, unpack!(block = place));
let address_of = Rvalue::RawPtr(mutability, unpack!(block = place));
this.cfg.push_assign(block, source_info, destination, address_of);
block.unit()
}

View File

@ -397,7 +397,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
| ExprKind::Scope { .. }
| ExprKind::Cast { .. } => {}
ExprKind::AddressOf { .. }
ExprKind::RawBorrow { .. }
| ExprKind::Adt { .. }
| ExprKind::Array { .. }
| ExprKind::Binary { .. }
@ -498,7 +498,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
}
}
}
ExprKind::AddressOf { arg, .. } => {
ExprKind::RawBorrow { arg, .. } => {
if let ExprKind::Scope { value: arg, .. } = self.thir[arg].kind
// THIR desugars UNSAFE_STATIC into *UNSAFE_STATIC_REF, where
// UNSAFE_STATIC_REF holds the addr of the UNSAFE_STATIC, so: take two steps

View File

@ -143,7 +143,7 @@ impl<'tcx> Cx<'tcx> {
arg: self.thir.exprs.push(expr),
},
Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
ExprKind::AddressOf { mutability, arg: self.thir.exprs.push(expr) }
ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
}
Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) },
};
@ -396,7 +396,7 @@ impl<'tcx> Cx<'tcx> {
}
hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutability, arg) => {
ExprKind::AddressOf { mutability, arg: self.mirror_expr(arg) }
ExprKind::RawBorrow { mutability, arg: self.mirror_expr(arg) }
}
hir::ExprKind::Block(blk, _) => ExprKind::Block { block: self.mirror_block(blk) },

View File

@ -325,7 +325,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
Assign { .. } | AssignOp { .. } | InlineAsm { .. } | Let { .. } => true,
// These evaluate to a value.
AddressOf { .. }
RawBorrow { .. }
| Adt { .. }
| Array { .. }
| Binary { .. }

View File

@ -379,8 +379,8 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
self.print_expr(*arg, depth_lvl + 2);
print_indented!(self, ")", depth_lvl);
}
AddressOf { mutability, arg } => {
print_indented!(self, "AddressOf {", depth_lvl);
RawBorrow { mutability, arg } => {
print_indented!(self, "RawBorrow {", depth_lvl);
print_indented!(self, format!("mutability: {:?}", mutability), depth_lvl + 1);
print_indented!(self, "arg:", depth_lvl + 1);
self.print_expr(*arg, depth_lvl + 2);

View File

@ -703,7 +703,7 @@ where
statements: vec![
self.assign(
ptr,
Rvalue::AddressOf(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
Rvalue::RawPtr(Mutability::Mut, tcx.mk_place_index(self.place, cur)),
),
self.assign(
cur.into(),

View File

@ -94,7 +94,7 @@ where
match rvalue {
// We ignore fake borrows as these get removed after analysis and shouldn't effect
// the layout of generators.
Rvalue::AddressOf(_, borrowed_place)
Rvalue::RawPtr(_, borrowed_place)
| Rvalue::Ref(_, BorrowKind::Mut { .. } | BorrowKind::Shared, borrowed_place) => {
if !borrowed_place.is_indirect() {
self.trans.gen_(borrowed_place.local);

View File

@ -351,7 +351,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
&& let Some((_, rvalue)) = statement.kind.as_assign()
&& let mir::Rvalue::Ref(_, mir::BorrowKind::Mut { .. }, place)
// FIXME: Does `&raw const foo` allow mutation? See #90413.
| mir::Rvalue::AddressOf(_, place) = rvalue
| mir::Rvalue::RawPtr(_, place) = rvalue
&& let LookupResult::Exact(mpi) = self.move_data().rev_lookup.find(place.as_ref())
{
on_all_children_bits(self.move_data(), mpi, |child| {

View File

@ -189,13 +189,13 @@ impl DefUse {
// All other contexts are uses...
PlaceContext::MutatingUse(
MutatingUseContext::AddressOf
MutatingUseContext::RawBorrow
| MutatingUseContext::Borrow
| MutatingUseContext::Drop
| MutatingUseContext::Retag,
)
| PlaceContext::NonMutatingUse(
NonMutatingUseContext::AddressOf
NonMutatingUseContext::RawBorrow
| NonMutatingUseContext::Copy
| NonMutatingUseContext::Inspect
| NonMutatingUseContext::Move

View File

@ -432,7 +432,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
}
Rvalue::CopyForDeref(..) => unreachable!(),
Rvalue::Ref(..)
| Rvalue::AddressOf(..)
| Rvalue::RawPtr(..)
| Rvalue::Discriminant(..)
| Rvalue::Len(..)
| Rvalue::NullaryOp(

View File

@ -177,7 +177,7 @@ pub trait ValueAnalysis<'tcx> {
match rvalue {
Rvalue::Use(operand) => self.handle_operand(operand, state),
Rvalue::CopyForDeref(place) => self.handle_operand(&Operand::Copy(*place), state),
Rvalue::Ref(..) | Rvalue::AddressOf(..) => {
Rvalue::Ref(..) | Rvalue::RawPtr(..) => {
// We don't track such places.
ValueOrPlace::TOP
}

View File

@ -131,9 +131,9 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
// Ptr-creating operations already do their own internal retagging, no
// need to also add a retag statement.
// *Except* if we are deref'ing a Box, because those get desugared to directly working
// with the inner raw pointer! That's relevant for `AddressOf` as Miri otherwise makes it
// with the inner raw pointer! That's relevant for `RawPtr` as Miri otherwise makes it
// a NOP when the original pointer is already raw.
Rvalue::AddressOf(_mutbl, place) => {
Rvalue::RawPtr(_mutbl, place) => {
// Using `is_box_global` here is a bit sketchy: if this code is
// generic over the allocator, we'll not add a retag! This is a hack
// to make Stacked Borrows compatible with custom allocator code.

View File

@ -71,7 +71,7 @@ struct PointerFinder<'tcx, 'a> {
impl<'tcx, 'a> Visitor<'tcx> for PointerFinder<'tcx, 'a> {
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
// We want to only check reads and writes to Places, so we specifically exclude
// Borrows and AddressOf.
// Borrow and RawBorrow.
match context {
PlaceContext::MutatingUse(
MutatingUseContext::Store

View File

@ -40,7 +40,7 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
// This is a mutation, so mark it as such.
true
}
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) => {
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) => {
// Whether mutating though a `&raw const` is allowed is still undecided, so we
// disable any sketchy `readonly` optimizations for now.
// But we only need to do this if the pointer would point into the argument.

View File

@ -576,7 +576,7 @@ impl WriteInfo {
Rvalue::ThreadLocalRef(_)
| Rvalue::NullaryOp(_, _)
| Rvalue::Ref(_, _, _)
| Rvalue::AddressOf(_, _)
| Rvalue::RawPtr(_, _)
| Rvalue::Len(_)
| Rvalue::Discriminant(_)
| Rvalue::CopyForDeref(_) => (),

View File

@ -45,7 +45,7 @@
//!
//! # Handling of references
//!
//! We handle references by assigning a different "provenance" index to each Ref/AddressOf rvalue.
//! We handle references by assigning a different "provenance" index to each Ref/RawPtr rvalue.
//! This ensure that we do not spuriously merge borrows that should not be merged. Meanwhile, we
//! consider all the derefs of an immutable reference to a freeze type to give the same value:
//! ```ignore (MIR)
@ -832,7 +832,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
self.simplify_place_projection(place, location);
return self.new_pointer(*place, AddressKind::Ref(borrow_kind));
}
Rvalue::AddressOf(mutbl, ref mut place) => {
Rvalue::RawPtr(mutbl, ref mut place) => {
self.simplify_place_projection(place, location);
return self.new_pointer(*place, AddressKind::Address(mutbl));
}

View File

@ -141,7 +141,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
/// Transform `&(*a)` ==> `a`.
fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
if let Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) = rvalue {
if let Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) = rvalue {
if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
if rvalue.ty(self.local_decls, self.tcx) != base.ty(self.local_decls, self.tcx).ty {
return;

View File

@ -419,8 +419,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}
// Do not try creating references (#67862)
Rvalue::AddressOf(_, place) | Rvalue::Ref(_, _, place) => {
trace!("skipping AddressOf | Ref for {:?}", place);
Rvalue::RawPtr(_, place) | Rvalue::Ref(_, _, place) => {
trace!("skipping RawPtr | Ref for {:?}", place);
// This may be creating mutable references or immutable references to cells.
// If that happens, the pointed to value could be mutated via that reference.
@ -616,7 +616,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into()
}
Ref(..) | AddressOf(..) => return None,
Ref(..) | RawPtr(..) => return None,
NullaryOp(ref null_op, ty) => {
let op_layout = self.use_ecx(|this| this.ecx.layout_of(ty))?;
@ -969,9 +969,9 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
// mutation.
| NonMutatingUse(NonMutatingUseContext::SharedBorrow)
| NonMutatingUse(NonMutatingUseContext::FakeBorrow)
| NonMutatingUse(NonMutatingUseContext::AddressOf)
| NonMutatingUse(NonMutatingUseContext::RawBorrow)
| MutatingUse(MutatingUseContext::Borrow)
| MutatingUse(MutatingUseContext::AddressOf) => {
| MutatingUse(MutatingUseContext::RawBorrow) => {
trace!("local {:?} can't be propagated because it's used: {:?}", local, context);
self.can_const_prop[local] = ConstPropMode::NoPropagation;
}

View File

@ -214,7 +214,7 @@ impl EnumSizeOpt {
source_info,
kind: StatementKind::Assign(Box::new((
dst,
Rvalue::AddressOf(Mutability::Mut, *lhs),
Rvalue::RawPtr(Mutability::Mut, *lhs),
))),
};
@ -238,7 +238,7 @@ impl EnumSizeOpt {
source_info,
kind: StatementKind::Assign(Box::new((
src,
Rvalue::AddressOf(Mutability::Not, *rhs),
Rvalue::RawPtr(Mutability::Not, *rhs),
))),
};

View File

@ -551,7 +551,7 @@ impl<'tcx> Validator<'_, 'tcx> {
self.validate_operand(rhs)?;
}
Rvalue::AddressOf(_, place) => {
Rvalue::RawPtr(_, place) => {
// We accept `&raw *`, i.e., raw reborrows -- creating a raw pointer is
// no problem, only using it is.
if let Some((place_base, ProjectionElem::Deref)) = place.as_ref().last_projection()

View File

@ -227,7 +227,7 @@ fn compute_replacement<'tcx>(
}
}
}
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
let mut place = *place;
// Try to see through `place` in order to collapse reborrow chains.
if place.projection.first() == Some(&PlaceElem::Deref)

View File

@ -343,7 +343,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
.tcx
.mk_place_elems(&[PlaceElem::Deref, PlaceElem::Field(field, field_ty)]),
};
self.put_temp_rvalue(Rvalue::AddressOf(Mutability::Mut, place))
self.put_temp_rvalue(Rvalue::RawPtr(Mutability::Mut, place))
}
/// If given Self is an enum puts `to_drop: *mut FieldTy` on top of
@ -363,7 +363,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
PlaceElem::Field(field, field_ty),
]),
};
self.put_temp_rvalue(Rvalue::AddressOf(Mutability::Mut, place))
self.put_temp_rvalue(Rvalue::RawPtr(Mutability::Mut, place))
}
/// If given Self is an enum puts `to_drop: *mut FieldTy` on top of

View File

@ -2,9 +2,9 @@
//! 1/ They are only assigned-to once, either as a function parameter, or in an assign statement;
//! 2/ This single assignment dominates all uses;
//!
//! As we do not track indirect assignments, a local that has its address taken (either by
//! AddressOf or by borrowing) is considered non-SSA. However, it is UB to modify through an
//! immutable borrow of a `Freeze` local. Those can still be considered to be SSA.
//! As we do not track indirect assignments, a local that has its address taken (via a borrow or raw
//! borrow operator) is considered non-SSA. However, it is UB to modify through an immutable borrow
//! of a `Freeze` local. Those can still be considered to be SSA.
use rustc_data_structures::graph::dominators::Dominators;
use rustc_index::bit_set::BitSet;
@ -262,7 +262,7 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'tcx, '_> {
PlaceContext::MutatingUse(MutatingUseContext::Projection)
| PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection) => bug!(),
// Anything can happen with raw pointers, so remove them.
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow)
| PlaceContext::MutatingUse(_) => {
self.assignments[local] = Set1::Many;
}

View File

@ -1345,7 +1345,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
Rvalue::Repeat(_, _)
| Rvalue::ThreadLocalRef(_)
| Rvalue::AddressOf(_, _)
| Rvalue::RawPtr(_, _)
| Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::UbChecks, _)
| Rvalue::Discriminant(_) => {}
}

View File

@ -851,7 +851,7 @@ impl<'a> Parser<'a> {
self.expect_and()?;
let has_lifetime = self.token.is_lifetime() && self.look_ahead(1, |t| t != &token::Colon);
let lifetime = has_lifetime.then(|| self.expect_lifetime()); // For recovery, see below.
let (borrow_kind, mutbl) = self.parse_borrow_modifiers(lo);
let (borrow_kind, mutbl) = self.parse_borrow_modifiers();
let attrs = self.parse_outer_attributes()?;
let expr = if self.token.is_range_separator() {
self.parse_expr_prefix_range(attrs)
@ -871,13 +871,12 @@ impl<'a> Parser<'a> {
}
/// Parse `mut?` or `raw [ const | mut ]`.
fn parse_borrow_modifiers(&mut self, lo: Span) -> (ast::BorrowKind, ast::Mutability) {
fn parse_borrow_modifiers(&mut self) -> (ast::BorrowKind, ast::Mutability) {
if self.check_keyword(kw::Raw) && self.look_ahead(1, Token::is_mutability) {
// `raw [ const | mut ]`.
let found_raw = self.eat_keyword(kw::Raw);
assert!(found_raw);
let mutability = self.parse_const_or_mut().unwrap();
self.psess.gated_spans.gate(sym::raw_ref_op, lo.to(self.prev_token.span));
(ast::BorrowKind::Raw, mutability)
} else {
// `mut?`

View File

@ -174,7 +174,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
ThreadLocalRef(def_id) => {
stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
}
AddressOf(mutability, place) => {
RawPtr(mutability, place) => {
stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
}
Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),

View File

@ -192,7 +192,7 @@ fn recurse_build<'tcx>(
ExprKind::Borrow { arg, .. } => {
let arg_node = &body.exprs[*arg];
// Skip reborrows for now until we allow Deref/Borrow/AddressOf
// Skip reborrows for now until we allow Deref/Borrow/RawBorrow
// expressions.
// FIXME(generic_const_exprs): Verify/explain why this is sound
if let ExprKind::Deref { arg } = arg_node.kind {
@ -202,7 +202,7 @@ fn recurse_build<'tcx>(
}
}
// FIXME(generic_const_exprs): We may want to support these.
ExprKind::AddressOf { .. } | ExprKind::Deref { .. } => maybe_supported_error(
ExprKind::RawBorrow { .. } | ExprKind::Deref { .. } => maybe_supported_error(
GenericConstantTooComplexSub::AddressAndDerefNotSupported(node.span),
)?,
ExprKind::Repeat { .. } | ExprKind::Array { .. } => {
@ -343,7 +343,7 @@ impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> {
| thir::ExprKind::VarRef { .. }
| thir::ExprKind::UpvarRef { .. }
| thir::ExprKind::Borrow { .. }
| thir::ExprKind::AddressOf { .. }
| thir::ExprKind::RawBorrow { .. }
| thir::ExprKind::Break { .. }
| thir::ExprKind::Continue { .. }
| thir::ExprKind::Return { .. }

View File

@ -2209,6 +2209,9 @@ impl<F: FnPtr> fmt::Debug for F {
/// Creates a `const` raw pointer to a place, without creating an intermediate reference.
///
/// `addr_of!(expr)` is equivalent to `&raw const expr`. The macro is *soft-deprecated*;
/// use `&raw const` instead.
///
/// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
/// and points to initialized data. For cases where those requirements do not hold,
/// raw pointers should be used instead. However, `&expr as *const _` creates a reference
@ -2283,6 +2286,9 @@ pub macro addr_of($place:expr) {
/// Creates a `mut` raw pointer to a place, without creating an intermediate reference.
///
/// `addr_of_mut!(expr)` is equivalent to `&raw mut expr`. The macro is *soft-deprecated*;
/// use `&raw mut` instead.
///
/// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
/// and points to initialized data. For cases where those requirements do not hold,
/// raw pointers should be used instead. However, `&mut expr as *mut _` creates a reference

View File

@ -110,7 +110,7 @@ fn check_rvalue<'tcx>(
) -> McfResult {
match rvalue {
Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::RawPtr(_, place) => {
check_place(tcx, *place, span, body, msrv)
},
Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),

View File

@ -1,4 +1,3 @@
#![feature(raw_ref_op)]
#![feature(strict_provenance)]
use std::ptr;

View File

@ -1,7 +1,6 @@
//@revisions: stack tree none
//@[tree]compile-flags: -Zmiri-tree-borrows
//@[none]compile-flags: -Zmiri-disable-stacked-borrows
#![feature(raw_ref_op)]
#![feature(core_intrinsics)]
#![feature(custom_mir)]

View File

@ -1,7 +1,6 @@
// This does need an aliasing model and protectors.
//@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows
#![feature(raw_ref_op)]
#![feature(core_intrinsics)]
#![feature(custom_mir)]

View File

@ -1,7 +1,6 @@
// This does need an aliasing model and protectors.
//@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows
#![feature(raw_ref_op)]
#![feature(core_intrinsics)]
#![feature(custom_mir)]
#![feature(explicit_tail_calls)]

View File

@ -1,6 +1,5 @@
// Doesn't need an aliasing model.
//@compile-flags: -Zmiri-disable-stacked-borrows
#![feature(raw_ref_op)]
#![feature(core_intrinsics)]
#![feature(custom_mir)]

View File

@ -1,4 +1,3 @@
#![feature(raw_ref_op)]
#![feature(core_intrinsics)]
#![feature(custom_mir)]

View File

@ -1,6 +1,5 @@
//@ test-mir-pass: GVN
// Check that we do not propagate past an indirect mutation.
#![feature(raw_ref_op)]
// EMIT_MIR indirect_mutation.foo.GVN.diff
fn foo() {

View File

@ -3,8 +3,6 @@
// Check that CopyProp considers reborrows as not mutating the pointer.
//@ test-mir-pass: CopyProp
#![feature(raw_ref_op)]
#[inline(never)]
fn opaque(_: impl Sized) {}

View File

@ -8,10 +8,10 @@
let mut _3: fn(u8) -> u8;
let _5: ();
let mut _6: fn(u8) -> u8;
let mut _9: {closure@$DIR/gvn.rs:615:19: 615:21};
let mut _9: {closure@$DIR/gvn.rs:614:19: 614:21};
let _10: ();
let mut _11: fn();
let mut _13: {closure@$DIR/gvn.rs:615:19: 615:21};
let mut _13: {closure@$DIR/gvn.rs:614:19: 614:21};
let _14: ();
let mut _15: fn();
scope 1 {
@ -19,7 +19,7 @@
let _4: fn(u8) -> u8;
scope 2 {
debug g => _4;
let _7: {closure@$DIR/gvn.rs:615:19: 615:21};
let _7: {closure@$DIR/gvn.rs:614:19: 614:21};
scope 3 {
debug closure => _7;
let _8: fn();
@ -62,16 +62,16 @@
StorageDead(_6);
StorageDead(_5);
- StorageLive(_7);
- _7 = {closure@$DIR/gvn.rs:615:19: 615:21};
- _7 = {closure@$DIR/gvn.rs:614:19: 614:21};
- StorageLive(_8);
+ nop;
+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ nop;
StorageLive(_9);
- _9 = _7;
- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
StorageDead(_9);
StorageLive(_10);
StorageLive(_11);
@ -88,8 +88,8 @@
StorageLive(_13);
- _13 = _7;
- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
StorageDead(_13);
StorageLive(_14);
StorageLive(_15);

View File

@ -8,10 +8,10 @@
let mut _3: fn(u8) -> u8;
let _5: ();
let mut _6: fn(u8) -> u8;
let mut _9: {closure@$DIR/gvn.rs:615:19: 615:21};
let mut _9: {closure@$DIR/gvn.rs:614:19: 614:21};
let _10: ();
let mut _11: fn();
let mut _13: {closure@$DIR/gvn.rs:615:19: 615:21};
let mut _13: {closure@$DIR/gvn.rs:614:19: 614:21};
let _14: ();
let mut _15: fn();
scope 1 {
@ -19,7 +19,7 @@
let _4: fn(u8) -> u8;
scope 2 {
debug g => _4;
let _7: {closure@$DIR/gvn.rs:615:19: 615:21};
let _7: {closure@$DIR/gvn.rs:614:19: 614:21};
scope 3 {
debug closure => _7;
let _8: fn();
@ -62,16 +62,16 @@
StorageDead(_6);
StorageDead(_5);
- StorageLive(_7);
- _7 = {closure@$DIR/gvn.rs:615:19: 615:21};
- _7 = {closure@$DIR/gvn.rs:614:19: 614:21};
- StorageLive(_8);
+ nop;
+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
+ _7 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ nop;
StorageLive(_9);
- _9 = _7;
- _8 = move _9 as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _9 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ _8 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
StorageDead(_9);
StorageLive(_10);
StorageLive(_11);
@ -88,8 +88,8 @@
StorageLive(_13);
- _13 = _7;
- _12 = move _13 as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21};
+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:615:19: 615:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
+ _13 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21};
+ _12 = const ZeroSized: {closure@$DIR/gvn.rs:614:19: 614:21} as fn() (PointerCoercion(ClosureFnPointer(Safe)));
StorageDead(_13);
StorageLive(_14);
StorageLive(_15);

View File

@ -3,7 +3,6 @@
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
//@ only-64bit
#![feature(raw_ref_op)]
#![feature(rustc_attrs)]
#![feature(custom_mir)]
#![feature(core_intrinsics)]

View File

@ -1,6 +1,5 @@
//@ test-mir-pass: InstSimplify-after-simplifycfg
#![crate_type = "lib"]
#![feature(raw_ref_op)]
// For each of these, only 2 of the 6 should simplify,
// as the others have the wrong types.

View File

@ -2,7 +2,6 @@
//@ test-mir-pass: ReferencePropagation
//@ needs-unwind
#![feature(raw_ref_op)]
#![feature(core_intrinsics, custom_mir)]
#[inline(never)]

View File

@ -1,5 +1,4 @@
//@ pp-exact
#![feature(raw_ref_op)]
const C_PTR: () = { let a = 1; &raw const a; };
static S_PTR: () = { let b = false; &raw const b; };

View File

@ -1,5 +1,3 @@
#![feature(raw_ref_op)]
fn address_of_shared() {
let mut x = 0;
let y = &x;

View File

@ -1,5 +1,5 @@
error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable
--> $DIR/borrow-raw-address-of-borrowed.rs:7:13
--> $DIR/borrow-raw-address-of-borrowed.rs:5:13
|
LL | let y = &x;
| -- immutable borrow occurs here
@ -11,7 +11,7 @@ LL | drop(y);
| - immutable borrow later used here
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> $DIR/borrow-raw-address-of-borrowed.rs:16:13
--> $DIR/borrow-raw-address-of-borrowed.rs:14:13
|
LL | let y = &mut x;
| ------ mutable borrow occurs here
@ -23,7 +23,7 @@ LL | drop(y);
| - mutable borrow later used here
error[E0499]: cannot borrow `x` as mutable more than once at a time
--> $DIR/borrow-raw-address-of-borrowed.rs:17:13
--> $DIR/borrow-raw-address-of-borrowed.rs:15:13
|
LL | let y = &mut x;
| ------ first mutable borrow occurs here

View File

@ -1,7 +1,5 @@
//@ check-pass
#![feature(raw_ref_op)]
fn raw_reborrow() {
let x = &0;
let y = &mut 0;

View File

@ -1,7 +1,5 @@
// Check that `&raw mut` cannot be used to turn a `&T` into a `*mut T`.
#![feature(raw_ref_op)]
fn raw_reborrow() {
let x = &0;

View File

@ -1,5 +1,5 @@
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrow-raw-address-of-deref-mutability.rs:8:13
--> $DIR/borrow-raw-address-of-deref-mutability.rs:6:13
|
LL | let q = &raw mut *x;
| ^^^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
@ -10,7 +10,7 @@ LL | let x = &mut 0;
| +++
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrow-raw-address-of-deref-mutability.rs:14:13
--> $DIR/borrow-raw-address-of-deref-mutability.rs:12:13
|
LL | let q = &raw mut *x;
| ^^^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable

View File

@ -1,7 +1,5 @@
//@ check-pass
#![feature(raw_ref_op)]
fn mutable_address_of() {
let mut x = 0;
let y = &raw mut x;

View File

@ -1,5 +1,3 @@
#![feature(raw_ref_op)]
fn mutable_address_of() {
let x = 0;
let y = &raw mut x; //~ ERROR cannot borrow

View File

@ -1,5 +1,5 @@
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrow-raw-address-of-mutability.rs:5:13
--> $DIR/borrow-raw-address-of-mutability.rs:3:13
|
LL | let y = &raw mut x;
| ^^^^^^^^^^ cannot borrow as mutable
@ -10,7 +10,7 @@ LL | let mut x = 0;
| +++
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrow-raw-address-of-mutability.rs:11:17
--> $DIR/borrow-raw-address-of-mutability.rs:9:17
|
LL | let y = &raw mut x;
| ^^^^^^^^^^ cannot borrow as mutable
@ -21,7 +21,7 @@ LL | let mut x = 0;
| +++
error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
--> $DIR/borrow-raw-address-of-mutability.rs:21:5
--> $DIR/borrow-raw-address-of-mutability.rs:19:5
|
LL | let y = &raw mut x;
| - calling `f` requires mutable binding due to mutable borrow of `x`
@ -35,7 +35,7 @@ LL | let mut f = || {
| +++
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-raw-address-of-mutability.rs:29:17
--> $DIR/borrow-raw-address-of-mutability.rs:27:17
|
LL | fn make_fn<F: Fn()>(f: F) -> F { f }
| - change this to accept `FnMut` instead of `Fn`
@ -48,7 +48,7 @@ LL | let y = &raw mut x;
| ^^^^^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
--> $DIR/borrow-raw-address-of-mutability.rs:37:17
--> $DIR/borrow-raw-address-of-mutability.rs:35:17
|
LL | fn make_fn<F: Fn()>(f: F) -> F { f }
| - change this to accept `FnMut` instead of `Fn`

View File

@ -1,5 +1,3 @@
#![feature(raw_ref_op)]
use std::cell::Cell;
const A: () = { let x = Cell::new(2); &raw const x; }; //~ ERROR interior mutability

View File

@ -1,5 +1,5 @@
error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
--> $DIR/const-address-of-interior-mut.rs:5:39
--> $DIR/const-address-of-interior-mut.rs:3:39
|
LL | const A: () = { let x = Cell::new(2); &raw const x; };
| ^^^^^^^^^^^^
@ -9,7 +9,7 @@ LL | const A: () = { let x = Cell::new(2); &raw const x; };
= 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:40
--> $DIR/const-address-of-interior-mut.rs:5:40
|
LL | static B: () = { let x = Cell::new(2); &raw const x; };
| ^^^^^^^^^^^^
@ -19,7 +19,7 @@ LL | static B: () = { let x = Cell::new(2); &raw const x; };
= 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:9:44
--> $DIR/const-address-of-interior-mut.rs:7:44
|
LL | static mut C: () = { let x = Cell::new(2); &raw const x; };
| ^^^^^^^^^^^^
@ -29,7 +29,7 @@ LL | static mut C: () = { let x = Cell::new(2); &raw const x; };
= 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:13:13
--> $DIR/const-address-of-interior-mut.rs:11:13
|
LL | let y = &raw const x;
| ^^^^^^^^^^^^

View File

@ -1,5 +1,3 @@
#![feature(raw_ref_op)]
const A: () = { let mut x = 2; &raw mut x; }; //~ mutable pointer
static B: () = { let mut x = 2; &raw mut x; }; //~ mutable pointer

View File

@ -1,5 +1,5 @@
error[E0658]: raw mutable pointers are not allowed in constants
--> $DIR/const-address-of-mut.rs:3:32
--> $DIR/const-address-of-mut.rs:1:32
|
LL | const A: () = { let mut x = 2; &raw mut x; };
| ^^^^^^^^^^
@ -9,7 +9,7 @@ LL | const A: () = { let mut x = 2; &raw mut x; };
= 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:5:33
--> $DIR/const-address-of-mut.rs:3:33
|
LL | static B: () = { let mut x = 2; &raw mut x; };
| ^^^^^^^^^^
@ -19,7 +19,7 @@ LL | static B: () = { let mut x = 2; &raw mut x; };
= 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:9:13
--> $DIR/const-address-of-mut.rs:7:13
|
LL | let y = &raw mut x;
| ^^^^^^^^^^

View File

@ -1,7 +1,5 @@
//@ check-pass
#![feature(raw_ref_op)]
const A: *const i32 = &raw const *&2;
static B: () = { &raw const *&2; };
static mut C: *const i32 = &raw const *&2;

View File

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

View File

@ -1,5 +1,4 @@
#![feature(const_mut_refs)]
#![feature(raw_ref_op)]
const NULL: *mut i32 = std::ptr::null_mut();
const A: *const i32 = &4;

View File

@ -1,11 +1,11 @@
error[E0764]: mutable references are not allowed in the final value of constants
--> $DIR/mut_ref_in_final.rs:10:21
--> $DIR/mut_ref_in_final.rs:9:21
|
LL | const B: *mut i32 = &mut 4;
| ^^^^^^
error[E0716]: temporary value dropped while borrowed
--> $DIR/mut_ref_in_final.rs:16:40
--> $DIR/mut_ref_in_final.rs:15:40
|
LL | const B3: Option<&mut i32> = Some(&mut 42);
| ----------^^-
@ -15,7 +15,7 @@ LL | const B3: Option<&mut i32> = Some(&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:19:42
--> $DIR/mut_ref_in_final.rs:18:42
|
LL | const B4: Option<&mut i32> = helper(&mut 42);
| ------------^^-
@ -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:34:65
--> $DIR/mut_ref_in_final.rs:33: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:37:67
--> $DIR/mut_ref_in_final.rs:36: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:40:71
--> $DIR/mut_ref_in_final.rs:39: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:53:53
--> $DIR/mut_ref_in_final.rs:52: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:55:54
--> $DIR/mut_ref_in_final.rs:54: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:57:52
--> $DIR/mut_ref_in_final.rs:56: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:59:53
--> $DIR/mut_ref_in_final.rs:58:53
|
LL | const RAW_MUT_COERCE_C: SyncPtr<i32> = SyncPtr { x: &mut 0 };
| ^^^^^^

View File

@ -2,7 +2,6 @@
//@ 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(raw_ref_op)]
use std::sync::Mutex;

View File

@ -1,5 +1,5 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/mut_ref_in_final_dynamic_check.rs:20:1
--> $DIR/mut_ref_in_final_dynamic_check.rs:19:1
|
LL | const MUT: Option<&mut i32> = helper();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered reference to mutable memory in `const`
@ -10,7 +10,7 @@ LL | const MUT: Option<&mut i32> = helper();
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mut_ref_in_final_dynamic_check.rs:27:1
--> $DIR/mut_ref_in_final_dynamic_check.rs:26:1
|
LL | const INT2PTR: Option<&mut i32> = helper_int2ptr();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (0x2a[noalloc] has no provenance)
@ -21,7 +21,7 @@ LL | const INT2PTR: Option<&mut i32> = helper_int2ptr();
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mut_ref_in_final_dynamic_check.rs:29:1
--> $DIR/mut_ref_in_final_dynamic_check.rs:28:1
|
LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (0x2a[noalloc] has no provenance)
@ -32,7 +32,7 @@ LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr();
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mut_ref_in_final_dynamic_check.rs:36:1
--> $DIR/mut_ref_in_final_dynamic_check.rs:35:1
|
LL | const DANGLING: Option<&mut i32> = helper_dangling();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (use-after-free)
@ -43,7 +43,7 @@ LL | const DANGLING: Option<&mut i32> = helper_dangling();
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/mut_ref_in_final_dynamic_check.rs:37:1
--> $DIR/mut_ref_in_final_dynamic_check.rs:36:1
|
LL | static DANGLING_STATIC: Option<&mut i32> = helper_dangling();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0: encountered a dangling reference (use-after-free)

View File

@ -1,5 +1,3 @@
#![feature(raw_ref_op)]
const fn mutable_address_of_in_const() {
let mut a = 0;
let b = &raw mut a; //~ ERROR mutable pointer

View File

@ -1,5 +1,5 @@
error[E0658]: raw mutable pointers are not allowed in constant functions
--> $DIR/address_of.rs:5:13
--> $DIR/address_of.rs:3:13
|
LL | let b = &raw mut a;
| ^^^^^^^^^^
@ -9,7 +9,7 @@ LL | let b = &raw mut a;
= 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:13:17
--> $DIR/address_of.rs:11:17
|
LL | let b = &raw mut a;
| ^^^^^^^^^^

View File

@ -1,7 +1,5 @@
//@ check-pass
#![feature(raw_ref_op)]
const fn const_address_of_in_const() {
let mut a = 0;
let b = &raw const a;

View File

@ -2,7 +2,6 @@
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
#![feature(const_swap)]
#![feature(raw_ref_op)]
// Mutable borrow of a field with drop impl.
pub const fn f() {

View File

@ -1,5 +1,5 @@
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:15:9
--> $DIR/qualif-indirect-mutation-fail.rs:14:9
|
LL | let mut x = None;
| ^^^^^ the destructor for this type cannot be evaluated in constants
@ -16,13 +16,13 @@ note: inside `std::ptr::drop_in_place::<String> - shim(Some(String))`
note: inside `std::ptr::drop_in_place::<Option<String>> - shim(Some(Option<String>))`
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
note: inside `A1`
--> $DIR/qualif-indirect-mutation-fail.rs:21:1
--> $DIR/qualif-indirect-mutation-fail.rs:20:1
|
LL | };
| ^
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:31:9
--> $DIR/qualif-indirect-mutation-fail.rs:30:9
|
LL | let _z = x;
| ^^ the destructor for this type cannot be evaluated in constants
@ -39,49 +39,49 @@ note: inside `std::ptr::drop_in_place::<String> - shim(Some(String))`
note: inside `std::ptr::drop_in_place::<Option<String>> - shim(Some(Option<String>))`
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
note: inside `A2`
--> $DIR/qualif-indirect-mutation-fail.rs:32:1
--> $DIR/qualif-indirect-mutation-fail.rs:31:1
|
LL | };
| ^
error[E0493]: destructor of `(u32, Option<String>)` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:9:9
--> $DIR/qualif-indirect-mutation-fail.rs:8:9
|
LL | let mut a: (u32, Option<String>) = (0, None);
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:36:9
--> $DIR/qualif-indirect-mutation-fail.rs:35:9
|
LL | let x: Option<T> = None;
| ^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `Option<T>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:44:9
--> $DIR/qualif-indirect-mutation-fail.rs:43:9
|
LL | let _y = x;
| ^^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:52:9
--> $DIR/qualif-indirect-mutation-fail.rs:51:9
|
LL | let mut y: Option<String> = None;
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:49:9
--> $DIR/qualif-indirect-mutation-fail.rs:48:9
|
LL | let mut x: Option<String> = None;
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:62:9
--> $DIR/qualif-indirect-mutation-fail.rs:61:9
|
LL | let y: Option<String> = None;
| ^ the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `Option<String>` cannot be evaluated at compile-time
--> $DIR/qualif-indirect-mutation-fail.rs:59:9
--> $DIR/qualif-indirect-mutation-fail.rs:58:9
|
LL | let x: Option<String> = None;
| ^ the destructor for this type cannot be evaluated in constant functions

View File

@ -1,7 +1,6 @@
//@ run-rustfix
#![deny(unused_parens)]
#![feature(raw_ref_op)]
#![allow(while_true)] // for rustfix
#[derive(Eq, PartialEq)]

View File

@ -1,7 +1,6 @@
//@ run-rustfix
#![deny(unused_parens)]
#![feature(raw_ref_op)]
#![allow(while_true)] // for rustfix
#[derive(Eq, PartialEq)]

View File

@ -1,5 +1,5 @@
error: unnecessary parentheses around `return` value
--> $DIR/lint-unnecessary-parens.rs:14:12
--> $DIR/lint-unnecessary-parens.rs:13:12
|
LL | return (1);
| ^ ^
@ -16,7 +16,7 @@ LL + return 1;
|
error: unnecessary parentheses around `return` value
--> $DIR/lint-unnecessary-parens.rs:17:12
--> $DIR/lint-unnecessary-parens.rs:16:12
|
LL | return (X { y });
| ^ ^
@ -28,7 +28,7 @@ LL + return X { y };
|
error: unnecessary parentheses around type
--> $DIR/lint-unnecessary-parens.rs:20:46
--> $DIR/lint-unnecessary-parens.rs:19:46
|
LL | pub fn unused_parens_around_return_type() -> (u32) {
| ^ ^
@ -40,7 +40,7 @@ LL + pub fn unused_parens_around_return_type() -> u32 {
|
error: unnecessary parentheses around block return value
--> $DIR/lint-unnecessary-parens.rs:26:9
--> $DIR/lint-unnecessary-parens.rs:25:9
|
LL | (5)
| ^ ^
@ -52,7 +52,7 @@ LL + 5
|
error: unnecessary parentheses around block return value
--> $DIR/lint-unnecessary-parens.rs:28:5
--> $DIR/lint-unnecessary-parens.rs:27:5
|
LL | (5)
| ^ ^
@ -64,7 +64,7 @@ LL + 5
|
error: unnecessary parentheses around `if` condition
--> $DIR/lint-unnecessary-parens.rs:40:7
--> $DIR/lint-unnecessary-parens.rs:39:7
|
LL | if(true) {}
| ^ ^
@ -76,7 +76,7 @@ LL + if true {}
|
error: unnecessary parentheses around `while` condition
--> $DIR/lint-unnecessary-parens.rs:41:10
--> $DIR/lint-unnecessary-parens.rs:40:10
|
LL | while(true) {}
| ^ ^
@ -88,7 +88,7 @@ LL + while true {}
|
error: unnecessary parentheses around `for` iterator expression
--> $DIR/lint-unnecessary-parens.rs:42:13
--> $DIR/lint-unnecessary-parens.rs:41:13
|
LL | for _ in(e) {}
| ^ ^
@ -100,7 +100,7 @@ LL + for _ in e {}
|
error: unnecessary parentheses around `match` scrutinee expression
--> $DIR/lint-unnecessary-parens.rs:43:10
--> $DIR/lint-unnecessary-parens.rs:42:10
|
LL | match(1) { _ => ()}
| ^ ^
@ -112,7 +112,7 @@ LL + match 1 { _ => ()}
|
error: unnecessary parentheses around `return` value
--> $DIR/lint-unnecessary-parens.rs:44:11
--> $DIR/lint-unnecessary-parens.rs:43:11
|
LL | return(1);
| ^ ^
@ -124,7 +124,7 @@ LL + return 1;
|
error: unnecessary parentheses around assigned value
--> $DIR/lint-unnecessary-parens.rs:75:31
--> $DIR/lint-unnecessary-parens.rs:74:31
|
LL | pub const CONST_ITEM: usize = (10);
| ^ ^
@ -136,7 +136,7 @@ LL + pub const CONST_ITEM: usize = 10;
|
error: unnecessary parentheses around assigned value
--> $DIR/lint-unnecessary-parens.rs:76:33
--> $DIR/lint-unnecessary-parens.rs:75:33
|
LL | pub static STATIC_ITEM: usize = (10);
| ^ ^
@ -148,7 +148,7 @@ LL + pub static STATIC_ITEM: usize = 10;
|
error: unnecessary parentheses around function argument
--> $DIR/lint-unnecessary-parens.rs:80:9
--> $DIR/lint-unnecessary-parens.rs:79:9
|
LL | bar((true));
| ^ ^
@ -160,7 +160,7 @@ LL + bar(true);
|
error: unnecessary parentheses around `if` condition
--> $DIR/lint-unnecessary-parens.rs:82:8
--> $DIR/lint-unnecessary-parens.rs:81:8
|
LL | if (true) {}
| ^ ^
@ -172,7 +172,7 @@ LL + if true {}
|
error: unnecessary parentheses around `while` condition
--> $DIR/lint-unnecessary-parens.rs:83:11
--> $DIR/lint-unnecessary-parens.rs:82:11
|
LL | while (true) {}
| ^ ^
@ -184,7 +184,7 @@ LL + while true {}
|
error: unnecessary parentheses around `match` scrutinee expression
--> $DIR/lint-unnecessary-parens.rs:84:11
--> $DIR/lint-unnecessary-parens.rs:83:11
|
LL | match (true) {
| ^ ^
@ -196,7 +196,7 @@ LL + match true {
|
error: unnecessary parentheses around `let` scrutinee expression
--> $DIR/lint-unnecessary-parens.rs:87:16
--> $DIR/lint-unnecessary-parens.rs:86:16
|
LL | if let 1 = (1) {}
| ^ ^
@ -208,7 +208,7 @@ LL + if let 1 = 1 {}
|
error: unnecessary parentheses around `let` scrutinee expression
--> $DIR/lint-unnecessary-parens.rs:88:19
--> $DIR/lint-unnecessary-parens.rs:87:19
|
LL | while let 1 = (2) {}
| ^ ^
@ -220,7 +220,7 @@ LL + while let 1 = 2 {}
|
error: unnecessary parentheses around method argument
--> $DIR/lint-unnecessary-parens.rs:104:24
--> $DIR/lint-unnecessary-parens.rs:103:24
|
LL | X { y: false }.foo((true));
| ^ ^
@ -232,7 +232,7 @@ LL + X { y: false }.foo(true);
|
error: unnecessary parentheses around assigned value
--> $DIR/lint-unnecessary-parens.rs:106:18
--> $DIR/lint-unnecessary-parens.rs:105:18
|
LL | let mut _a = (0);
| ^ ^
@ -244,7 +244,7 @@ LL + let mut _a = 0;
|
error: unnecessary parentheses around assigned value
--> $DIR/lint-unnecessary-parens.rs:107:10
--> $DIR/lint-unnecessary-parens.rs:106:10
|
LL | _a = (0);
| ^ ^
@ -256,7 +256,7 @@ LL + _a = 0;
|
error: unnecessary parentheses around assigned value
--> $DIR/lint-unnecessary-parens.rs:108:11
--> $DIR/lint-unnecessary-parens.rs:107:11
|
LL | _a += (1);
| ^ ^
@ -268,7 +268,7 @@ LL + _a += 1;
|
error: unnecessary parentheses around pattern
--> $DIR/lint-unnecessary-parens.rs:110:8
--> $DIR/lint-unnecessary-parens.rs:109:8
|
LL | let(mut _a) = 3;
| ^ ^
@ -280,7 +280,7 @@ LL + let mut _a = 3;
|
error: unnecessary parentheses around pattern
--> $DIR/lint-unnecessary-parens.rs:111:9
--> $DIR/lint-unnecessary-parens.rs:110:9
|
LL | let (mut _a) = 3;
| ^ ^
@ -292,7 +292,7 @@ LL + let mut _a = 3;
|
error: unnecessary parentheses around pattern
--> $DIR/lint-unnecessary-parens.rs:112:8
--> $DIR/lint-unnecessary-parens.rs:111:8
|
LL | let( mut _a) = 3;
| ^^ ^
@ -304,7 +304,7 @@ LL + let mut _a = 3;
|
error: unnecessary parentheses around pattern
--> $DIR/lint-unnecessary-parens.rs:114:8
--> $DIR/lint-unnecessary-parens.rs:113:8
|
LL | let(_a) = 3;
| ^ ^
@ -316,7 +316,7 @@ LL + let _a = 3;
|
error: unnecessary parentheses around pattern
--> $DIR/lint-unnecessary-parens.rs:115:9
--> $DIR/lint-unnecessary-parens.rs:114:9
|
LL | let (_a) = 3;
| ^ ^
@ -328,7 +328,7 @@ LL + let _a = 3;
|
error: unnecessary parentheses around pattern
--> $DIR/lint-unnecessary-parens.rs:116:8
--> $DIR/lint-unnecessary-parens.rs:115:8
|
LL | let( _a) = 3;
| ^^ ^
@ -340,7 +340,7 @@ LL + let _a = 3;
|
error: unnecessary parentheses around block return value
--> $DIR/lint-unnecessary-parens.rs:122:9
--> $DIR/lint-unnecessary-parens.rs:121:9
|
LL | (unit!() - One)
| ^ ^
@ -352,7 +352,7 @@ LL + unit!() - One
|
error: unnecessary parentheses around block return value
--> $DIR/lint-unnecessary-parens.rs:124:9
--> $DIR/lint-unnecessary-parens.rs:123:9
|
LL | (unit![] - One)
| ^ ^
@ -364,7 +364,7 @@ LL + unit![] - One
|
error: unnecessary parentheses around block return value
--> $DIR/lint-unnecessary-parens.rs:127:9
--> $DIR/lint-unnecessary-parens.rs:126:9
|
LL | (unit! {} - One)
| ^ ^
@ -376,7 +376,7 @@ LL + unit! {} - One
|
error: unnecessary parentheses around assigned value
--> $DIR/lint-unnecessary-parens.rs:132:14
--> $DIR/lint-unnecessary-parens.rs:131:14
|
LL | let _r = (&x);
| ^ ^
@ -388,7 +388,7 @@ LL + let _r = &x;
|
error: unnecessary parentheses around assigned value
--> $DIR/lint-unnecessary-parens.rs:133:14
--> $DIR/lint-unnecessary-parens.rs:132:14
|
LL | let _r = (&mut x);
| ^ ^

View File

@ -3,7 +3,7 @@
// Exercise the unused_mut attribute in some positive and negative cases
#![warn(unused_mut)]
#![feature(async_closure, raw_ref_op)]
#![feature(async_closure)]
async fn baz_async(
mut a: i32,

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