Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions compiler/rustc_mir_build/src/thir/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,20 @@ impl<'tcx> ThirBuildCx<'tcx> {
Res::Def(DefKind::Static { .. }, id) => {
// this is &raw for extern static or static mut, and & for other statics
let ty = self.tcx.static_ptr_ty(id, self.typing_env);

// If this is behind a `&raw`, set `ty` as a raw ptr to discern it from normal ref
let ty = if let hir::Node::Expr(&hir::Expr {
kind: hir::ExprKind::AddrOf(hir::BorrowKind::Raw, mutbl, _),
..
}) = self.tcx.parent_hir_node(expr.hir_id)
&& let ty::Ref(_, ty, mutbl_) = ty.kind()
&& mutbl == *mutbl_
{
Ty::new_ptr(self.tcx, *ty, mutbl)
} else {
ty
};

let kind = if self.tcx.is_thread_local_static(id) {
ExprKind::ThreadLocalRef(id)
} else {
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_mir_transform/src/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -760,10 +760,12 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
}

let num_stmts = self.source[loc.block].statements.len();
let new_temp = self.promoted.local_decls.push(LocalDecl::new(
self.source.local_decls[temp].ty,
self.source.local_decls[temp].source_info.span,
));
let new_local_decl = {
let temp = &self.source.local_decls[temp];
let local_decl = LocalDecl::new(temp.ty, temp.source_info.span);
if temp.mutability == Mutability::Not { local_decl.immutable() } else { local_decl }
};
let new_temp = self.promoted.local_decls.push(new_local_decl);
Copy link
Member Author

@ShoyuVanilla ShoyuVanilla Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn’t discussed in
#149973 (comment),
but I think it would be better to syntactically track promoted consts.

For example, the promoted const in the following code:

static FOO: () = {
    let _ = &&FOO;
};

is currently lowered to:

const FOO::promoted[0]: &&() = {
    let mut _0: &&();
    let mut _1: &();
    let mut _2: &();

    bb0: {
        _2 = const {alloc1: &()};
        _1 = &(*_2);
        _0 = &_1;
        return;
    }
}

I think it would make more sense for _2 to be immutable. This would also make it clearer when detecting &STATIC from:

_2 = const {alloc1: &()};
_1 = &(*_2);

It seems very unlikely that _2 would ever be truly mutable (for example, being reassigned with a different value), but anyway _2 being immutable gives some more assurance.


debug!("promote({:?} @ {:?}/{:?}, {:?})", temp, loc, num_stmts, self.keep_original);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

const BAR::promoted[0]: &[&i32; 1] = {
let mut _0: &[&i32; 1];
let mut _1: [&i32; 1];
let _1: [&i32; 1];
let mut _2: &i32;
let mut _3: &i32;
let _3: &i32;

bb0: {
_3 = const {ALLOC0: &i32};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

const FOO::promoted[0]: &[&i32; 1] = {
let mut _0: &[&i32; 1];
let mut _1: [&i32; 1];
let _1: [&i32; 1];
let mut _2: &i32;
let mut _3: *const i32;
let _3: *const i32;

bb0: {
_3 = const {ALLOC0: *const i32};
Expand Down
Loading