Skip to content

Commit ddbe69a

Browse files
Special treatment for dereferencing a borrow to a static definition
1 parent 1799d31 commit ddbe69a

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

src/librustc_mir/transform/promote_consts.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,33 @@ impl<'tcx> Validator<'_, 'tcx> {
502502
fn validate_place(&self, place: PlaceRef<'tcx>) -> Result<(), Unpromotable> {
503503
match place {
504504
PlaceRef { local, projection: [] } => self.validate_local(local),
505-
PlaceRef { local: _, projection: [proj_base @ .., elem] } => {
505+
PlaceRef { local, projection: [proj_base @ .., elem] } => {
506506
match *elem {
507-
ProjectionElem::Deref | ProjectionElem::Downcast(..) => {
507+
ProjectionElem::Deref => {
508+
let mut not_promotable = true;
509+
if let TempState::Defined { location, .. } = self.temps[local] {
510+
let def_stmt =
511+
self.body[location.block].statements.get(location.statement_index);
512+
if let Some(Statement {
513+
kind:
514+
StatementKind::Assign(box (_, Rvalue::Use(Operand::Constant(c)))),
515+
..
516+
}) = def_stmt
517+
{
518+
if let Some(did) = c.check_static_ptr(self.tcx) {
519+
if let Some(hir::ConstContext::Static(..)) = self.const_kind {
520+
if !self.tcx.is_thread_local_static(did) {
521+
not_promotable = false;
522+
}
523+
}
524+
}
525+
}
526+
}
527+
if not_promotable {
528+
return Err(Unpromotable);
529+
}
530+
}
531+
ProjectionElem::Downcast(..) => {
508532
return Err(Unpromotable);
509533
}
510534

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// run-pass
2+
3+
struct A<T: 'static>(&'static T);
4+
struct B<T: 'static + ?Sized> {
5+
x: &'static T,
6+
}
7+
static C: A<B<B<[u8]>>> = {
8+
A(&B {
9+
x: &B { x: b"hi" as &[u8] },
10+
})
11+
};
12+
13+
fn main() {
14+
assert_eq!(b"hi", C.0.x.x);
15+
}

0 commit comments

Comments
 (0)