Skip to content

Decide the precise rules for operand of &raw [const|mut] #66708

Open
@matthewjasper

Description

@matthewjasper

#66671 implements a check on the operand of &raw [const|mut] to ensure that it's not a temporary. It's similar to the check used for the left-hand operand of =, but it only allows field and index projections when they are based on a place expression, or it there is at least one deref adjustment involved.

It's possible that we want to restrict this to "at least one deref adjustment from a reference" or some other variant that limits the use of this with overloaded deref coercions.

// The following are all currently OK
Struct A { f: (i32, u32) }
let x: A = ...;
&raw const x;
&raw const x.f;
&raw const x.f.0;
let y = &x;
&raw const y;
&raw const *y;
&raw const (*y).f;
&raw const y.f;          // Same as above
&raw const (*y).f.0;
&raw const y.f.0;        // Same as above

// There's no distinction between `&T` and `Rc<T>`
use std::rc::Rc;
use std::ops::Deref;

let z = std::rc::Rc::new(x);
&raw const z;
&raw const *(z.deref());
&raw const *z;           // Same as above
&raw const (*z).f;
&raw const z.f;          // Same as above
&raw const (*z).f.0;
&raw const z.f.0;        // Same as above

// The following are not allowed:
&raw const A { ... };
&raw const A { ... }.f;
&raw const A { ... }.f.0;

// These are allowed:
const X: &A = ...;
&raw const *X;
&raw const X.f;
&raw const X.f.0;

// These are allowed, because they can't easily be distinguished from the above. They all result in immediately dangling pointers.
&raw const *(&A { ... });
&raw const (&A { ... }).f;
&raw const (&A { ... }).f.0;

// These are also allowed, and seem even more dubious.
&raw const *Rc::new(A { ... });
&raw const Rc::new(A { ... }).f;
&raw const Rc::new(A { ... }).f.0;

cc #64490
cc @Centril @RalfJung @oli-obk

Metadata

Metadata

Assignees

No one assigned

    Labels

    F-raw_ref_op`#![feature(raw_ref_op)]`T-langRelevant to the language team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions