Skip to content

Commit

Permalink
Don't promote references to statics that occur in non-static locations
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron1011 committed Sep 9, 2017
1 parent 07becc5 commit 813b323
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
46 changes: 31 additions & 15 deletions src/librustc_passes/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ use std::cmp::Ordering;
struct CheckCrateVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
in_fn: bool,
in_static: bool,
promotable: bool,
mut_rvalue_borrows: NodeSet,
param_env: ty::ParamEnv<'tcx>,
Expand Down Expand Up @@ -128,10 +129,16 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
let outer_param_env = self.param_env;
let outer_identity_substs = self.identity_substs;

self.in_fn = match MirSource::from_node(self.tcx, item_id) {
MirSource::Fn(_) => true,
_ => false
self.in_fn = false;
self.in_static = false;

match MirSource::from_node(self.tcx, item_id) {
MirSource::Fn(_) => self.in_fn = true,
MirSource::Static(_, _) => self.in_static = true,
_ => {}
};


self.tables = self.tcx.typeck_tables_of(item_def_id);
self.param_env = self.tcx.param_env(item_def_id);
self.identity_substs = Substs::identity_for_item(self.tcx, item_def_id);
Expand Down Expand Up @@ -333,20 +340,28 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
// with the exception of "#[thread_loca]" statics.
// The latter may not outlive the current function
Def::Static(did, _) => {
let mut thread_local = false;

for attr in &v.tcx.get_attrs(did)[..] {
if attr.check_name("thread_local") {
debug!("Static(id={:?}) is unpromotable \
due to a #[thread_local] attribute", did);
v.promotable = false;
thread_local = true;
break;

if v.in_static {
let mut thread_local = false;

for attr in &v.tcx.get_attrs(did)[..] {
if attr.check_name("thread_local") {
debug!("Reference to Static(id={:?}) is unpromotable \
due to a #[thread_local] attribute", did);
v.promotable = false;
thread_local = true;
break;
}
}
}

if !thread_local {
debug!("Allowing promotion of reference to Static(id={:?})", did);
if !thread_local {
debug!("Allowing promotion of reference to Static(id={:?})", did);
}
} else {
debug!("Reference to Static(id={:?}) is unpromotable as it is not \
referenced from a static", did);
v.promotable = false;

}
}

Expand Down Expand Up @@ -502,6 +517,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx,
tables: &ty::TypeckTables::empty(None),
in_fn: false,
in_static: false,
promotable: false,
mut_rvalue_borrows: NodeSet(),
param_env: ty::ParamEnv::empty(Reveal::UserFacing),
Expand Down
16 changes: 16 additions & 0 deletions src/test/compile-fail/issue-44373.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.


static FOO: u32 = 50;

fn main() {
let _val: &'static [&'static u32] = &[&FOO]; //~ ERROR borrowed value does not live long enough
}

0 comments on commit 813b323

Please sign in to comment.