diff options
| author | Aaron Hill <aa1ronham@gmail.com> | 2017-09-08 20:22:50 -0400 |
|---|---|---|
| committer | Aaron Hill <aa1ronham@gmail.com> | 2017-09-08 20:22:50 -0400 |
| commit | 07becc5f2438a2f628e8cb5d5a6128dd9ed2cc31 (patch) | |
| tree | 9cdfcf01e197a5d611a7f4959be7e0ba6eec88de /src | |
| parent | dead08cb331343b84564628b139b657f93548320 (diff) | |
Fix regression in promotion of rvalues referencing a static
This commit makes librustc_passes::consts::CheckCrateVisitor properly mark expressions as promotable if they reference a static, as it's perfectly fine for one static to reference another. It fixes a regression that prevented a temporary rvalue from referencing a static if it was itself declared within a static. Prior to commit https://github.com/rust-lang/rust/commit/b8c05fe90bc, `region::ScopeTree` would only register a 'terminating scope' for function bodies. Thus, while rvalues in a static that referenced a static would be marked unpromotable, the lack of enclosing scope would cause mem_categorization::MemCategorizationContext::cat_rvalue_node to compute a 'temporary scope' of `ReStatic`. Since this had the same effect as explicitly selecting a scope of `ReStatic` due to the rvalue being marked by CheckCrateVisitor as promotable, no issue occurred. However, commit https://github.com/rust-lang/rust/commit/b8c05fe90bc made ScopeTree unconditionally register a 'terminating scope' Since mem_categorization would now compute a non-static 'temporary scope', the aforementioned rvalues would be erroneously marked as living for too short a time. By fixing the behavior of CheckCrateVisitor, this commit avoids changing mem_categorization's behavior, while ensuring that temporary values in statics are still allowed to reference other statics. Fixes issue #44373
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_passes/consts.rs | 23 | ||||
| -rw-r--r-- | src/test/run-pass/issue-44373.rs | 18 |
2 files changed, 40 insertions, 1 deletions
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 6f2c448ceb6..f7581bb604f 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -327,7 +327,28 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node let def = v.tables.qpath_def(qpath, e.hir_id); match def { Def::VariantCtor(..) | Def::StructCtor(..) | - Def::Fn(..) | Def::Method(..) => {} + Def::Fn(..) | Def::Method(..) => {} + + // References to a static are inherently promotable, + // 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 !thread_local { + debug!("Allowing promotion of reference to Static(id={:?})", did); + } + } Def::Const(did) | Def::AssociatedConst(did) => { diff --git a/src/test/run-pass/issue-44373.rs b/src/test/run-pass/issue-44373.rs new file mode 100644 index 00000000000..06627e2ad93 --- /dev/null +++ b/src/test/run-pass/issue-44373.rs @@ -0,0 +1,18 @@ +// 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. + +struct Foo(bool); + +struct Container(&'static [&'static Foo]); + +static FOO: Foo = Foo(true); +static CONTAINER: Container = Container(&[&FOO]); + +fn main() {} |
