diff options
Diffstat (limited to 'src/librustc/middle/mem_categorization.rs')
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 13e6f7a4c74..59ef8fa1448 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -76,6 +76,7 @@ use hir::def::{Def, CtorKind}; use ty::adjustment; use ty::{self, Ty, TyCtxt}; use ty::fold::TypeFoldable; +use ty::layout::VariantIdx; use hir::{MutImmutable, MutMutable, PatKind}; use hir::pat_util::EnumerateAndAdjustIterator; @@ -87,12 +88,14 @@ use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; use rustc_data_structures::sync::Lrc; +use rustc_data_structures::indexed_vec::Idx; use std::rc::Rc; use util::nodemap::ItemLocalSet; #[derive(Clone, Debug, PartialEq)] pub enum Categorization<'tcx> { Rvalue(ty::Region<'tcx>), // temporary val, argument is its scope + ThreadLocal(ty::Region<'tcx>), // value that cannot move, but still restricted in scope StaticItem, Upvar(Upvar), // upvar referenced by closure env Local(ast::NodeId), // local variable @@ -226,7 +229,7 @@ impl<'tcx> cmt_<'tcx> { } _ => { assert_eq!(adt_def.variants.len(), 1); - &adt_def.variants[0] + &adt_def.variants[VariantIdx::new(0)] } }; Some((adt_def, &variant_def.fields[field_index])) @@ -268,6 +271,7 @@ impl<'tcx> cmt_<'tcx> { Categorization::Deref(ref base_cmt, _) => { base_cmt.immutability_blame() } + Categorization::ThreadLocal(..) | Categorization::StaticItem => { // Do we want to do something here? None @@ -715,17 +719,23 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { } Def::Static(def_id, mutbl) => { - // `#[thread_local]` statics may not outlive the current function. - for attr in &self.tcx.get_attrs(def_id)[..] { - if attr.check_name("thread_local") { - return Ok(self.cat_rvalue_node(hir_id, span, expr_ty)); - } - } + // `#[thread_local]` statics may not outlive the current function, but + // they also cannot be moved out of. + let is_thread_local = self.tcx.get_attrs(def_id)[..] + .iter() + .any(|attr| attr.check_name("thread_local")); + + let cat = if is_thread_local { + let re = self.temporary_scope(hir_id.local_id); + Categorization::ThreadLocal(re) + } else { + Categorization::StaticItem + }; Ok(cmt_ { hir_id, - span:span, - cat:Categorization::StaticItem, + span, + cat, mutbl: if mutbl { McDeclared } else { McImmutable}, ty:expr_ty, note: NoteNone @@ -1408,6 +1418,7 @@ impl<'tcx> cmt_<'tcx> { match self.cat { Categorization::Rvalue(..) | Categorization::StaticItem | + Categorization::ThreadLocal(..) | Categorization::Local(..) | Categorization::Deref(_, UnsafePtr(..)) | Categorization::Deref(_, BorrowedPtr(..)) | @@ -1439,6 +1450,7 @@ impl<'tcx> cmt_<'tcx> { } Categorization::Rvalue(..) | + Categorization::ThreadLocal(..) | Categorization::Local(..) | Categorization::Upvar(..) | Categorization::Deref(_, UnsafePtr(..)) => { // yes, it's aliasable, but... @@ -1485,6 +1497,9 @@ impl<'tcx> cmt_<'tcx> { Categorization::StaticItem => { "static item".into() } + Categorization::ThreadLocal(..) => { + "thread-local static item".into() + } Categorization::Rvalue(..) => { "non-place".into() } |
