Special treatment for dereferencing a borrow to a static definition

This commit is contained in:
Ding Xiang Fei 2020-07-30 18:33:34 +08:00
parent 1799d31847
commit ddbe69a5b2
No known key found for this signature in database
GPG Key ID: 3CD748647EEF6359
2 changed files with 41 additions and 2 deletions

View File

@ -502,9 +502,33 @@ impl<'tcx> Validator<'_, 'tcx> {
fn validate_place(&self, place: PlaceRef<'tcx>) -> Result<(), Unpromotable> {
match place {
PlaceRef { local, projection: [] } => self.validate_local(local),
PlaceRef { local: _, projection: [proj_base @ .., elem] } => {
PlaceRef { local, projection: [proj_base @ .., elem] } => {
match *elem {
ProjectionElem::Deref | ProjectionElem::Downcast(..) => {
ProjectionElem::Deref => {
let mut not_promotable = true;
if let TempState::Defined { location, .. } = self.temps[local] {
let def_stmt =
self.body[location.block].statements.get(location.statement_index);
if let Some(Statement {
kind:
StatementKind::Assign(box (_, Rvalue::Use(Operand::Constant(c)))),
..
}) = def_stmt
{
if let Some(did) = c.check_static_ptr(self.tcx) {
if let Some(hir::ConstContext::Static(..)) = self.const_kind {
if !self.tcx.is_thread_local_static(did) {
not_promotable = false;
}
}
}
}
}
if not_promotable {
return Err(Unpromotable);
}
}
ProjectionElem::Downcast(..) => {
return Err(Unpromotable);
}

View File

@ -0,0 +1,15 @@
// run-pass
struct A<T: 'static>(&'static T);
struct B<T: 'static + ?Sized> {
x: &'static T,
}
static C: A<B<B<[u8]>>> = {
A(&B {
x: &B { x: b"hi" as &[u8] },
})
};
fn main() {
assert_eq!(b"hi", C.0.x.x);
}