Skip to content

Commit 813b323

Browse files
committed
Don't promote references to statics that occur in non-static locations
1 parent 07becc5 commit 813b323

File tree

2 files changed

+47
-15
lines changed

2 files changed

+47
-15
lines changed

src/librustc_passes/consts.rs

+31-15
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use std::cmp::Ordering;
5656
struct CheckCrateVisitor<'a, 'tcx: 'a> {
5757
tcx: TyCtxt<'a, 'tcx, 'tcx>,
5858
in_fn: bool,
59+
in_static: bool,
5960
promotable: bool,
6061
mut_rvalue_borrows: NodeSet,
6162
param_env: ty::ParamEnv<'tcx>,
@@ -128,10 +129,16 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
128129
let outer_param_env = self.param_env;
129130
let outer_identity_substs = self.identity_substs;
130131

131-
self.in_fn = match MirSource::from_node(self.tcx, item_id) {
132-
MirSource::Fn(_) => true,
133-
_ => false
132+
self.in_fn = false;
133+
self.in_static = false;
134+
135+
match MirSource::from_node(self.tcx, item_id) {
136+
MirSource::Fn(_) => self.in_fn = true,
137+
MirSource::Static(_, _) => self.in_static = true,
138+
_ => {}
134139
};
140+
141+
135142
self.tables = self.tcx.typeck_tables_of(item_def_id);
136143
self.param_env = self.tcx.param_env(item_def_id);
137144
self.identity_substs = Substs::identity_for_item(self.tcx, item_def_id);
@@ -333,20 +340,28 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
333340
// with the exception of "#[thread_loca]" statics.
334341
// The latter may not outlive the current function
335342
Def::Static(did, _) => {
336-
let mut thread_local = false;
337-
338-
for attr in &v.tcx.get_attrs(did)[..] {
339-
if attr.check_name("thread_local") {
340-
debug!("Static(id={:?}) is unpromotable \
341-
due to a #[thread_local] attribute", did);
342-
v.promotable = false;
343-
thread_local = true;
344-
break;
343+
344+
if v.in_static {
345+
let mut thread_local = false;
346+
347+
for attr in &v.tcx.get_attrs(did)[..] {
348+
if attr.check_name("thread_local") {
349+
debug!("Reference to Static(id={:?}) is unpromotable \
350+
due to a #[thread_local] attribute", did);
351+
v.promotable = false;
352+
thread_local = true;
353+
break;
354+
}
345355
}
346-
}
347356

348-
if !thread_local {
349-
debug!("Allowing promotion of reference to Static(id={:?})", did);
357+
if !thread_local {
358+
debug!("Allowing promotion of reference to Static(id={:?})", did);
359+
}
360+
} else {
361+
debug!("Reference to Static(id={:?}) is unpromotable as it is not \
362+
referenced from a static", did);
363+
v.promotable = false;
364+
350365
}
351366
}
352367

@@ -502,6 +517,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
502517
tcx,
503518
tables: &ty::TypeckTables::empty(None),
504519
in_fn: false,
520+
in_static: false,
505521
promotable: false,
506522
mut_rvalue_borrows: NodeSet(),
507523
param_env: ty::ParamEnv::empty(Reveal::UserFacing),

src/test/compile-fail/issue-44373.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
12+
static FOO: u32 = 50;
13+
14+
fn main() {
15+
let _val: &'static [&'static u32] = &[&FOO]; //~ ERROR borrowed value does not live long enough
16+
}

0 commit comments

Comments
 (0)