about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-04-21 13:40:22 +0000
committerbors <bors@rust-lang.org>2019-04-21 13:40:22 +0000
commit31a75a172859d906d8e6a34af4afff9830af495c (patch)
treeebc94a1a8d740f638ea3839716314c7adf41c40c
parent06a271a6eb5521d50cbe20a782a20e7c993e7725 (diff)
parent4eb94b44072697be70fc2a74ed9989e88f9cd70c (diff)
downloadrust-31a75a172859d906d8e6a34af4afff9830af495c.tar.gz
rust-31a75a172859d906d8e6a34af4afff9830af495c.zip
Auto merge of #60124 - petrochenkov:stanomut, r=eddyb
Remove mutability from `Def::Static`

Querify `TyCtxt::is_static`.
Use `Mutability` instead of bool in foreign statics in AST/HIR.

cc https://github.com/rust-lang/rust/pull/60110
r? @eddyb
-rw-r--r--src/librustc/hir/def.rs6
-rw-r--r--src/librustc/hir/lowering.rs2
-rw-r--r--src/librustc/hir/map/mod.rs4
-rw-r--r--src/librustc/hir/mod.rs5
-rw-r--r--src/librustc/hir/print.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs7
-rw-r--r--src/librustc/query/mod.rs3
-rw-r--r--src/librustc/ty/util.rs39
-rw-r--r--src/librustc_codegen_llvm/common.rs2
-rw-r--r--src/librustc_codegen_ssa/mono_item.rs13
-rw-r--r--src/librustc_lint/builtin.rs3
-rw-r--r--src/librustc_metadata/cstore_impl.rs1
-rw-r--r--src/librustc_metadata/decoder.rs14
-rw-r--r--src/librustc_metadata/encoder.rs4
-rw-r--r--src/librustc_mir/borrow_check/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs4
-rw-r--r--src/librustc_mir/borrow_check/place_ext.rs2
-rw-r--r--src/librustc_mir/borrow_check/places_conflict.rs2
-rw-r--r--src/librustc_mir/const_eval.rs11
-rw-r--r--src/librustc_mir/hair/cx/expr.rs2
-rw-r--r--src/librustc_mir/interpret/eval_context.rs2
-rw-r--r--src/librustc_mir/interpret/memory.rs2
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs2
-rw-r--r--src/librustc_mir/util/pretty.rs4
-rw-r--r--src/librustc_passes/rvalue_promotion.rs2
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs11
-rw-r--r--src/librustc_save_analysis/sig.rs2
-rw-r--r--src/librustc_typeck/astconv.rs2
-rw-r--r--src/librustc_typeck/collect.rs17
-rw-r--r--src/librustdoc/clean/inline.rs4
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/libsyntax/ast.rs5
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/libsyntax/print/pprust.rs2
34 files changed, 93 insertions, 96 deletions
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index 7d173af3112..4af79764a60 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -73,7 +73,7 @@ pub enum Def<Id = hir::HirId> {
     Fn(DefId),
     Const(DefId),
     ConstParam(DefId),
-    Static(DefId, bool /* is_mutbl */),
+    Static(DefId),
     /// `DefId` refers to the struct or enum variant's constructor.
     Ctor(DefId, CtorOf, CtorKind),
     SelfCtor(DefId /* impl */),  // `DefId` refers to the impl
@@ -291,7 +291,7 @@ impl<Id> Def<Id> {
     /// Return `Some(..)` with the `DefId` of this `Def` if it has a id, else `None`.
     pub fn opt_def_id(&self) -> Option<DefId> {
         match *self {
-            Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
+            Def::Fn(id) | Def::Mod(id) | Def::Static(id) |
             Def::Variant(id) | Def::Ctor(id, ..) | Def::Enum(id) |
             Def::TyAlias(id) | Def::TraitAlias(id) |
             Def::AssociatedTy(id) | Def::TyParam(id) | Def::ConstParam(id) | Def::Struct(id) |
@@ -379,7 +379,7 @@ impl<Id> Def<Id> {
         match self {
             Def::Fn(id) => Def::Fn(id),
             Def::Mod(id) => Def::Mod(id),
-            Def::Static(id, is_mutbl) => Def::Static(id, is_mutbl),
+            Def::Static(id) => Def::Static(id),
             Def::Enum(id) => Def::Enum(id),
             Def::Variant(id) => Def::Variant(id),
             Def::Ctor(a, b, c) => Def::Ctor(a, b, c),
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 42ad571cf28..99cae00fafc 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -3742,7 +3742,7 @@ impl<'a> LoweringContext<'a> {
                 }
                 ForeignItemKind::Static(ref t, m) => {
                     hir::ForeignItemKind::Static(
-                        self.lower_ty(t, ImplTraitContext::disallowed()), m)
+                        self.lower_ty(t, ImplTraitContext::disallowed()), self.lower_mutability(m))
                 }
                 ForeignItemKind::Ty => hir::ForeignItemKind::Type,
                 ForeignItemKind::Macro(_) => panic!("shouldn't exist here"),
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 4eef2019e26..10a5bd11b2f 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -322,7 +322,7 @@ impl<'hir> Map<'hir> {
                 let def_id = || self.local_def_id_from_hir_id(item.hir_id);
 
                 match item.node {
-                    ItemKind::Static(_, m, _) => Some(Def::Static(def_id(), m == MutMutable)),
+                    ItemKind::Static(..) => Some(Def::Static(def_id())),
                     ItemKind::Const(..) => Some(Def::Const(def_id())),
                     ItemKind::Fn(..) => Some(Def::Fn(def_id())),
                     ItemKind::Mod(..) => Some(Def::Mod(def_id())),
@@ -344,7 +344,7 @@ impl<'hir> Map<'hir> {
                 let def_id = self.local_def_id_from_hir_id(item.hir_id);
                 match item.node {
                     ForeignItemKind::Fn(..) => Some(Def::Fn(def_id)),
-                    ForeignItemKind::Static(_, m) => Some(Def::Static(def_id, m)),
+                    ForeignItemKind::Static(..) => Some(Def::Static(def_id)),
                     ForeignItemKind::Type => Some(Def::ForeignTy(def_id)),
                 }
             }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 7ed8c08c923..630c163bcaf 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2405,9 +2405,8 @@ pub struct ForeignItem {
 pub enum ForeignItemKind {
     /// A foreign function.
     Fn(P<FnDecl>, HirVec<Ident>, Generics),
-    /// A foreign static item (`static ext: u8`), with optional mutability
-    /// (the boolean is true when mutable).
-    Static(P<Ty>, bool),
+    /// A foreign static item (`static ext: u8`).
+    Static(P<Ty>, Mutability),
     /// A foreign type.
     Type,
 }
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index d1020a2d151..dc87e13b739 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -466,7 +466,7 @@ impl<'a> State<'a> {
             }
             hir::ForeignItemKind::Static(ref t, m) => {
                 self.head(visibility_qualified(&item.vis, "static"))?;
-                if m {
+                if m == hir::MutMutable {
                     self.word_space("mut")?;
                 }
                 self.print_ident(item.ident)?;
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 9240cb2a411..a4a54ba1837 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -705,7 +705,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                 Ok(self.cat_rvalue_node(hir_id, span, expr_ty))
             }
 
-            Def::Static(def_id, mutbl) => {
+            Def::Static(def_id) => {
                 // `#[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)[..]
@@ -723,7 +723,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                     hir_id,
                     span,
                     cat,
-                    mutbl: if mutbl { McDeclared } else { McImmutable},
+                    mutbl: match self.tcx.static_mutability(def_id).unwrap() {
+                        hir::MutImmutable => McImmutable,
+                        hir::MutMutable => McDeclared,
+                    },
                     ty:expr_ty,
                     note: NoteNone
                 })
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index bc9aaf870ce..8c1e345cdae 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -238,6 +238,9 @@ rustc_queries! {
         /// True if this is a foreign item (i.e., linked via `extern { ... }`).
         query is_foreign_item(_: DefId) -> bool {}
 
+        /// Returns `Some(mutability)` if the node pointed to by `def_id` is a static item.
+        query static_mutability(_: DefId) -> Option<hir::Mutability> {}
+
         /// Get a map with the variance of every item; use `item_variance`
         /// instead.
         query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap> {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index ccead14e76b..67507f7b5d1 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -1,9 +1,8 @@
 //! Miscellaneous type-system utilities that are too small to deserve their own modules.
 
-use crate::hir::def::Def;
+use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::hir::map::DefPathData;
-use crate::hir::{self, Node};
 use crate::mir::interpret::{sign_extend, truncate};
 use crate::ich::NodeIdHashingMode;
 use crate::traits::{self, ObligationCause};
@@ -613,34 +612,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         })
     }
 
-    /// Returns `true` if the node pointed to by `def_id` is a static item, and its mutability.
-    pub fn is_static(&self, def_id: DefId) -> Option<hir::Mutability> {
-        if let Some(node) = self.hir().get_if_local(def_id) {
-            match node {
-                Node::Item(&hir::Item {
-                    node: hir::ItemKind::Static(_, mutbl, _), ..
-                }) => Some(mutbl),
-                Node::ForeignItem(&hir::ForeignItem {
-                    node: hir::ForeignItemKind::Static(_, is_mutbl), ..
-                }) =>
-                    Some(if is_mutbl {
-                        hir::Mutability::MutMutable
-                    } else {
-                        hir::Mutability::MutImmutable
-                    }),
-                _ => None
-            }
-        } else {
-            match self.describe_def(def_id) {
-                Some(Def::Static(_, is_mutbl)) =>
-                    Some(if is_mutbl {
-                        hir::Mutability::MutMutable
-                    } else {
-                        hir::Mutability::MutImmutable
-                    }),
-                _ => None
-            }
-        }
+    /// Returns `true` if the node pointed to by `def_id` is a `static` item.
+    pub fn is_static(&self, def_id: DefId) -> bool {
+        self.static_mutability(def_id).is_some()
+    }
+
+    /// Returns `true` if the node pointed to by `def_id` is a mutable `static` item.
+    pub fn is_mutable_static(&self, def_id: DefId) -> bool {
+        self.static_mutability(def_id) == Some(hir::MutMutable)
     }
 
     /// Expands the given impl trait type, stopping if the type is recursive.
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index 9554e54e414..b9fd9629e6f 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -322,7 +322,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                         self.get_fn(fn_instance)
                     }
                     Some(AllocKind::Static(def_id)) => {
-                        assert!(self.tcx.is_static(def_id).is_some());
+                        assert!(self.tcx.is_static(def_id));
                         self.get_static(def_id)
                     }
                     None => bug!("missing allocation {:?}", ptr.alloc_id),
diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs
index 48159d79799..60d75480e61 100644
--- a/src/librustc_codegen_ssa/mono_item.rs
+++ b/src/librustc_codegen_ssa/mono_item.rs
@@ -1,5 +1,4 @@
 use rustc::hir;
-use rustc::hir::def::Def;
 use rustc::mir::mono::{Linkage, Visibility};
 use rustc::ty::layout::HasTyCtxt;
 use std::fmt;
@@ -19,17 +18,7 @@ pub trait MonoItemExt<'a, 'tcx: 'a>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
 
         match *self.as_mono_item() {
             MonoItem::Static(def_id) => {
-                let tcx = cx.tcx();
-                let is_mutable = match tcx.describe_def(def_id) {
-                    Some(Def::Static(_, is_mutable)) => is_mutable,
-                    Some(other) => {
-                        bug!("Expected Def::Static, found {:?}", other)
-                    }
-                    None => {
-                        bug!("Expected Def::Static for {:?}, found nothing", def_id)
-                    }
-                };
-                cx.codegen_static(def_id, is_mutable);
+                cx.codegen_static(def_id, cx.tcx().is_mutable_static(def_id));
             }
             MonoItem::GlobalAsm(hir_id) => {
                 let item = cx.tcx().hir().expect_item_by_hir_id(hir_id);
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index f289b0b48fb..5fde4331d47 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1171,8 +1171,7 @@ declare_lint_pass!(
 
 fn check_const(cx: &LateContext<'_, '_>, body_id: hir::BodyId) {
     let def_id = cx.tcx.hir().body_owner_def_id(body_id);
-    let is_static = cx.tcx.is_static(def_id).is_some();
-    let param_env = if is_static {
+    let param_env = if cx.tcx.is_static(def_id) {
         // Use the same param_env as `codegen_static_initializer`, to reuse the cache.
         ty::ParamEnv::reveal_all()
     } else {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 10a99e40c41..1a1b933ccf3 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -137,6 +137,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     inherent_impls => { Lrc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
     is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) }
     is_foreign_item => { cdata.is_foreign_item(def_id.index) }
+    static_mutability => { cdata.static_mutability(def_id.index) }
     describe_def => { cdata.get_def(def_id.index) }
     def_span => { cdata.get_span(def_id.index, &tcx.sess) }
     lookup_stability => {
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 5dade8d9438..0e3d05d29a3 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -404,9 +404,9 @@ impl<'tcx> EntryKind<'tcx> {
             EntryKind::Const(..) => Def::Const(did),
             EntryKind::AssociatedConst(..) => Def::AssociatedConst(did),
             EntryKind::ImmStatic |
-            EntryKind::ForeignImmStatic => Def::Static(did, false),
             EntryKind::MutStatic |
-            EntryKind::ForeignMutStatic => Def::Static(did, true),
+            EntryKind::ForeignImmStatic |
+            EntryKind::ForeignMutStatic => Def::Static(did),
             EntryKind::Struct(_, _) => Def::Struct(did),
             EntryKind::Union(_, _) => Def::Union(did),
             EntryKind::Fn(_) |
@@ -1163,6 +1163,16 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
+    crate fn static_mutability(&self, id: DefIndex) -> Option<hir::Mutability> {
+        match self.entry(id).kind {
+            EntryKind::ImmStatic |
+            EntryKind::ForeignImmStatic => Some(hir::MutImmutable),
+            EntryKind::MutStatic |
+            EntryKind::ForeignMutStatic => Some(hir::MutMutable),
+            _ => None,
+        }
+    }
+
     pub fn fn_sig(&self,
                   id: DefIndex,
                   tcx: TyCtxt<'a, 'tcx, 'tcx>)
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 796d2f6a18b..a0f17a55a87 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1647,8 +1647,8 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                 };
                 EntryKind::ForeignFn(self.lazy(&data))
             }
-            hir::ForeignItemKind::Static(_, true) => EntryKind::ForeignMutStatic,
-            hir::ForeignItemKind::Static(_, false) => EntryKind::ForeignImmStatic,
+            hir::ForeignItemKind::Static(_, hir::MutMutable) => EntryKind::ForeignMutStatic,
+            hir::ForeignItemKind::Static(_, hir::MutImmutable) => EntryKind::ForeignImmStatic,
             hir::ForeignItemKind::Type => EntryKind::ForeignType,
         };
 
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 0b2c90b9160..43ed85d4ac5 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -2117,7 +2117,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     is_local_mutation_allowed,
                 }),
             Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
-                if self.infcx.tcx.is_static(def_id) != Some(hir::Mutability::MutMutable) {
+                if !self.infcx.tcx.is_mutable_static(def_id) {
                     Err(place)
                 } else {
                     Ok(RootPlace {
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index d123f3e4059..ce8f1852551 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1321,7 +1321,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                         ..
                     }) = self.borrowck_context
                     {
-                        if tcx.is_static(*def_id).is_some() {
+                        if tcx.is_static(*def_id) {
                             ConstraintCategory::UseAsStatic
                         } else {
                             ConstraintCategory::UseAsConst
@@ -1626,7 +1626,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                             ..
                         }) = self.borrowck_context
                         {
-                            if tcx.is_static(*def_id).is_some() {
+                            if tcx.is_static(*def_id) {
                                 ConstraintCategory::UseAsStatic
                             } else {
                                 ConstraintCategory::UseAsConst
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
index 8269b7b95f4..913884a8218 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -52,7 +52,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
             Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) =>
                 false,
             Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
-                tcx.is_static(*def_id) == Some(hir::Mutability::MutMutable)
+                tcx.is_mutable_static(*def_id)
             }
             Place::Projection(proj) => match proj.elem {
                 ProjectionElem::Field(..)
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index cebf05ad9b9..1bf606109dc 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -321,7 +321,7 @@ fn place_base_conflict<'a, 'gcx: 'tcx, 'tcx>(
                     if def_id_1 != def_id_2 {
                         debug!("place_element_conflict: DISJOINT-STATIC");
                         Overlap::Disjoint
-                    } else if tcx.is_static(*def_id_1) == Some(hir::Mutability::MutMutable) {
+                    } else if tcx.is_mutable_static(*def_id_1) {
                         // We ignore mutable statics - they can only be unsafe code.
                         debug!("place_element_conflict: IGNORE-STATIC-MUT");
                         Overlap::Disjoint
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 09c50d4f81f..b65f2ba2601 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -6,8 +6,8 @@ use std::borrow::{Borrow, Cow};
 use std::hash::Hash;
 use std::collections::hash_map::Entry;
 
-use rustc::hir::{self, def_id::DefId};
 use rustc::hir::def::Def;
+use rustc::hir::def_id::DefId;
 use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
 use rustc::mir;
 use rustc::ty::{self, TyCtxt, query::TyCtxtAt};
@@ -158,9 +158,8 @@ fn eval_body_using_ecx<'mir, 'tcx>(
     ecx.run()?;
 
     // Intern the result
-    let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span);
-    let is_static = tcx.is_static(cid.instance.def_id());
-    let mutability = if is_static == Some(hir::Mutability::MutMutable) || internally_mutable {
+    let mutability = if tcx.is_mutable_static(cid.instance.def_id()) ||
+                     !layout.ty.is_freeze(tcx, param_env, mir.span) {
         Mutability::Mutable
     } else {
         Mutability::Immutable
@@ -533,7 +532,7 @@ fn validate_and_turn_into_const<'a, 'tcx>(
         }
         // Now that we validated, turn this into a proper constant.
         let def_id = cid.instance.def.def_id();
-        if tcx.is_static(def_id).is_some() || cid.promoted.is_some() {
+        if tcx.is_static(def_id) || cid.promoted.is_some() {
             Ok(mplace_to_const(&ecx, mplace))
         } else {
             Ok(op_to_const(&ecx, mplace.into()))
@@ -628,7 +627,7 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
     }).map_err(|error| {
         let err = error_to_const_error(&ecx, error);
         // errors in statics are always emitted as fatal errors
-        if tcx.is_static(def_id).is_some() {
+        if tcx.is_static(def_id) {
             // Ensure that if the above error was either `TooGeneric` or `Reported`
             // an error must be reported.
             let reported_err = tcx.sess.track_errors(|| {
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index b62afc47dea..7ab33411275 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -960,7 +960,7 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
             }
         }
 
-        Def::Static(node_id, _) => ExprKind::StaticRef { id: node_id },
+        Def::Static(id) => ExprKind::StaticRef { id },
 
         Def::Local(..) | Def::Upvar(..) => convert_var(cx, expr, def),
 
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 32f7ecd97b2..4ae8bfe854d 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -634,7 +634,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
         &self,
         gid: GlobalId<'tcx>,
     ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
-        let param_env = if self.tcx.is_static(gid.instance.def_id()).is_some() {
+        let param_env = if self.tcx.is_static(gid.instance.def_id()) {
             ty::ParamEnv::reveal_all()
         } else {
             self.param_env
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 117bd15399c..9674822b47a 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -342,7 +342,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
         // full query anyway
         tcx.const_eval_raw(ty::ParamEnv::reveal_all().and(gid)).map_err(|err| {
             // no need to report anything, the const_eval call takes care of that for statics
-            assert!(tcx.is_static(def_id).is_some());
+            assert!(tcx.is_static(def_id));
             match err {
                 ErrorHandled::Reported => InterpError::ReferencedConstant.into(),
                 ErrorHandled::TooGeneric => InterpError::TooGeneric.into(),
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index c9cccb2b03a..87c02b7f01d 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -306,7 +306,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
             &Place::Base(
                 PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })
             ) => {
-                if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) {
+                if self.tcx.is_mutable_static(def_id) {
                     self.require_unsafe("use of mutable static",
                         "mutable statics can be mutated by multiple threads: aliasing violations \
                          or data races will cause undefined behavior",
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 5e5e451b75b..efae1e56f4d 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -592,8 +592,8 @@ fn write_mir_sig(
     match (descr, src.promoted) {
         (_, Some(i)) => write!(w, "{:?} in ", i)?,
         (Some(Def::Const(_)), _) | (Some(Def::AssociatedConst(_)), _) => write!(w, "const ")?,
-        (Some(Def::Static(_, /*is_mutbl*/false)), _) => write!(w, "static ")?,
-        (Some(Def::Static(_, /*is_mutbl*/true)), _) => write!(w, "static mut ")?,
+        (Some(Def::Static(def_id)), _) =>
+            write!(w, "static {}", if tcx.is_mutable_static(def_id) { "mut " } else { "" })?,
         (_, _) if is_function => write!(w, "fn ")?,
         (None, _) => {}, // things like anon const, not an item
         _ => bug!("Unexpected def description {:?}", descr),
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index ba60fdc0273..e2c5c4ee374 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -329,7 +329,7 @@ fn check_expr_kind<'a, 'tcx>(
                 // are inherently promotable with the exception
                 //  of "#[thread_local]" statics, which may not
                 // outlive the current function
-                Def::Static(did, _) => {
+                Def::Static(did) => {
 
                     if v.in_static {
                         for attr in &v.tcx.get_attrs(did)[..] {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 72dd043f214..6870e97b53b 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -28,7 +28,7 @@ use syntax::ast::{Name, Ident};
 use syntax::attr;
 
 use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
-use syntax::ast::{MetaItemKind, Mutability, StmtKind, TraitItem, TraitItemKind, Variant};
+use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::base::Determinacy::Undetermined;
 use syntax::ext::hygiene::Mark;
@@ -442,9 +442,8 @@ impl<'a> Resolver<'a> {
             ItemKind::ForeignMod(..) => {}
 
             // These items live in the value namespace.
-            ItemKind::Static(_, m, _) => {
-                let mutbl = m == Mutability::Mutable;
-                let def = Def::Static(self.definitions.local_def_id(item.id), mutbl);
+            ItemKind::Static(..) => {
+                let def = Def::Static(self.definitions.local_def_id(item.id));
                 self.define(parent, ident, ValueNS, (def, vis, sp, expansion));
             }
             ItemKind::Const(..) => {
@@ -616,8 +615,8 @@ impl<'a> Resolver<'a> {
             ForeignItemKind::Fn(..) => {
                 (Def::Fn(self.definitions.local_def_id(item.id)), ValueNS)
             }
-            ForeignItemKind::Static(_, m) => {
-                (Def::Static(self.definitions.local_def_id(item.id), m), ValueNS)
+            ForeignItemKind::Static(..) => {
+                (Def::Static(self.definitions.local_def_id(item.id)), ValueNS)
             }
             ForeignItemKind::Ty => {
                 (Def::ForeignTy(self.definitions.local_def_id(item.id)), TypeNS)
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 76034f32c74..90fe6a60dd7 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -798,7 +798,7 @@ impl Sig for ast::ForeignItem {
             }
             ast::ForeignItemKind::Static(ref ty, m) => {
                 let mut text = "static ".to_owned();
-                if m {
+                if m == ast::Mutability::Mutable {
                     text.push_str("mut ");
                 }
                 let name = self.ident.to_string();
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index be8e5dae1d9..f5111954f8d 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1665,7 +1665,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
             Def::Fn(def_id) |
             Def::Const(def_id) |
             Def::ConstParam(def_id) |
-            Def::Static(def_id, _) => {
+            Def::Static(def_id) => {
                 path_segs.push(PathSeg(def_id, last));
             }
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index d601c962fc6..afb30af054f 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -78,6 +78,7 @@ pub fn provide(providers: &mut Providers<'_>) {
         impl_trait_ref,
         impl_polarity,
         is_foreign_item,
+        static_mutability,
         codegen_fn_attrs,
         collect_mod_item_types,
         ..*providers
@@ -2361,6 +2362,22 @@ fn is_foreign_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool
     }
 }
 
+fn static_mutability<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    def_id: DefId,
+) -> Option<hir::Mutability> {
+    match tcx.hir().get_if_local(def_id) {
+        Some(Node::Item(&hir::Item {
+            node: hir::ItemKind::Static(_, mutbl, _), ..
+        })) |
+        Some(Node::ForeignItem( &hir::ForeignItem {
+            node: hir::ForeignItemKind::Static(_, mutbl), ..
+        })) => Some(mutbl),
+        Some(_) => None,
+        _ => bug!("static_mutability applied to non-local def-id {:?}", def_id),
+    }
+}
+
 fn from_target_feature(
     tcx: TyCtxt<'_, '_, '_>,
     id: DefId,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 8da71cf708a..5da74a588c9 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -93,9 +93,9 @@ pub fn try_inline(
             record_extern_fqn(cx, did, clean::TypeKind::Module);
             clean::ModuleItem(build_module(cx, did, visited))
         }
-        Def::Static(did, mtbl) => {
+        Def::Static(did) => {
             record_extern_fqn(cx, did, clean::TypeKind::Static);
-            clean::StaticItem(build_static(cx, did, mtbl))
+            clean::StaticItem(build_static(cx, did, cx.tcx.is_mutable_static(did)))
         }
         Def::Const(did) => {
             record_extern_fqn(cx, did, clean::TypeKind::Const);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 80e796b0af7..586ae6659bb 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -4055,7 +4055,7 @@ impl Clean<Item> for hir::ForeignItem {
             hir::ForeignItemKind::Static(ref ty, mutbl) => {
                 ForeignStaticItem(Static {
                     type_: ty.clean(cx),
-                    mutability: if mutbl {Mutable} else {Immutable},
+                    mutability: mutbl.clean(cx),
                     expr: String::new(),
                 })
             }
@@ -4204,7 +4204,7 @@ pub fn register_def(cx: &DocContext<'_>, def: Def) -> DefId {
         Def::Mod(i) => (i, TypeKind::Module),
         Def::ForeignTy(i) => (i, TypeKind::Foreign),
         Def::Const(i) => (i, TypeKind::Const),
-        Def::Static(i, _) => (i, TypeKind::Static),
+        Def::Static(i) => (i, TypeKind::Static),
         Def::Variant(i) => (cx.tcx.parent(i).expect("cannot get parent def id"),
                             TypeKind::Enum),
         Def::Macro(i, mac_kind) => match mac_kind {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 0668730b3ef..a5472c622e6 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -2340,9 +2340,8 @@ pub struct ForeignItem {
 pub enum ForeignItemKind {
     /// A foreign function.
     Fn(P<FnDecl>, Generics),
-    /// A foreign static item (`static ext: u8`), with optional mutability.
-    /// (The boolean is `true` for mutable items).
-    Static(P<Ty>, bool),
+    /// A foreign static item (`static ext: u8`).
+    Static(P<Ty>, Mutability),
     /// A foreign type.
     Ty,
     /// A macro invocation.
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8d2beaa69dd..824192f0739 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -7683,7 +7683,7 @@ impl<'a> Parser<'a> {
     /// Assumes that the `static` keyword is already parsed.
     fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>)
                                  -> PResult<'a, ForeignItem> {
-        let mutbl = self.eat_keyword(keywords::Mut);
+        let mutbl = self.parse_mutability();
         let ident = self.parse_ident()?;
         self.expect(&token::Colon)?;
         let ty = self.parse_ty()?;
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index ca05ff71c94..d94e4762e67 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1142,7 +1142,7 @@ impl<'a> State<'a> {
             }
             ast::ForeignItemKind::Static(ref t, m) => {
                 self.head(visibility_qualified(&item.vis, "static"))?;
-                if m {
+                if m == ast::Mutability::Mutable {
                     self.word_space("mut")?;
                 }
                 self.print_ident(item.ident)?;