about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-04-29 15:49:07 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-04-29 15:49:07 -0700
commit2edb6438cb83c144f0ce480a47975043bbee2d4b (patch)
tree3b0ebb9195271dbb1310ce6f84794aa08761f8fe /src
parentcc04cd4bb169141c12b1f44ea75f265826dfbda9 (diff)
parent8c58fe17393d01a3b1661cc43ec5ffcf005a0c1d (diff)
downloadrust-2edb6438cb83c144f0ce480a47975043bbee2d4b.tar.gz
rust-2edb6438cb83c144f0ce480a47975043bbee2d4b.zip
rollup merge of #24921: tamird/bitflags-associated-const
Conflicts:
	src/librustc/lib.rs
Diffstat (limited to 'src')
-rw-r--r--src/librustc/lib.rs9
-rw-r--r--src/librustc/middle/check_const.rs94
-rw-r--r--src/librustc/middle/mem_categorization.rs8
-rw-r--r--src/librustc/middle/ty.rs62
-rw-r--r--src/librustc_bitflags/lib.rs132
-rw-r--r--src/librustc_llvm/lib.rs47
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs43
-rw-r--r--src/librustc_resolve/lib.rs25
-rw-r--r--src/librustc_resolve/resolve_imports.rs8
-rw-r--r--src/librustc_trans/trans/attributes.rs61
-rw-r--r--src/librustc_trans/trans/cabi_aarch64.rs9
-rw-r--r--src/librustc_trans/trans/cabi_arm.rs9
-rw-r--r--src/librustc_trans/trans/cabi_mips.rs9
-rw-r--r--src/librustc_trans/trans/cabi_powerpc.rs9
-rw-r--r--src/librustc_trans/trans/cabi_x86.rs8
-rw-r--r--src/librustc_trans/trans/cabi_x86_64.rs7
-rw-r--r--src/librustc_trans/trans/cabi_x86_win64.rs8
-rw-r--r--src/librustc_trans/trans/consts.rs4
-rw-r--r--src/librustc_trans/trans/declare.rs4
-rw-r--r--src/librustc_trans/trans/expr.rs16
-rw-r--r--src/librustc_trans/trans/foreign.rs4
-rw-r--r--src/libstd/lib.rs20
-rw-r--r--src/libsyntax/lib.rs3
-rw-r--r--src/libsyntax/parse/parser.rs37
24 files changed, 341 insertions, 295 deletions
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index b0b1b4df6e3..aeb08464ff5 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -25,22 +25,23 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
+#![feature(associated_consts)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
+#![feature(fs_canonicalize)]
 #![feature(hash)]
+#![feature(into_cow)]
 #![feature(libc)]
+#![feature(path_ext)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
+#![feature(slice_patterns)]
 #![feature(staged_api)]
 #![feature(std_misc)]
-#![feature(path_ext)]
 #![feature(str_char)]
-#![feature(into_cow)]
-#![feature(fs_canonicalize)]
-#![feature(slice_patterns)]
 #![cfg_attr(test, feature(test))]
 
 #![allow(trivial_casts)]
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index 80326229618..5b0eea6bcc5 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -46,33 +46,35 @@ bitflags! {
     #[derive(RustcEncodable, RustcDecodable)]
     flags ConstQualif: u8 {
         // Const rvalue which can be placed behind a reference.
-        const PURE_CONST          = 0b000000,
+        const PURE_CONST         = 0,
         // Inner mutability (can not be placed behind a reference) or behind
         // &mut in a non-global expression. Can be copied from static memory.
-        const MUTABLE_MEM         = 0b000001,
+        const MUTABLE_MEM        = 1 << 0,
         // Constant value with a type that implements Drop. Can be copied
         // from static memory, similar to MUTABLE_MEM.
-        const NEEDS_DROP          = 0b000010,
+        const NEEDS_DROP         = 1 << 1,
         // Even if the value can be placed in static memory, copying it from
         // there is more expensive than in-place instantiation, and/or it may
         // be too large. This applies to [T; N] and everything containing it.
         // N.B.: references need to clear this flag to not end up on the stack.
-        const PREFER_IN_PLACE     = 0b000100,
+        const PREFER_IN_PLACE    = 1 << 2,
         // May use more than 0 bytes of memory, doesn't impact the constness
         // directly, but is not allowed to be borrowed mutably in a constant.
-        const NON_ZERO_SIZED      = 0b001000,
+        const NON_ZERO_SIZED     = 1 << 3,
         // Actually borrowed, has to always be in static memory. Does not
         // propagate, and requires the expression to behave like a 'static
         // lvalue. The set of expressions with this flag is the minimum
         // that have to be promoted.
-        const HAS_STATIC_BORROWS  = 0b010000,
+        const HAS_STATIC_BORROWS = 1 << 4,
         // Invalid const for miscellaneous reasons (e.g. not implemented).
-        const NOT_CONST           = 0b100000,
+        const NOT_CONST          = 1 << 5,
 
         // Borrowing the expression won't produce &'static T if any of these
         // bits are set, though the value could be copied from static memory
         // if `NOT_CONST` isn't set.
-        const NON_STATIC_BORROWS = MUTABLE_MEM.bits | NEEDS_DROP.bits | NOT_CONST.bits
+        const NON_STATIC_BORROWS = ConstQualif::MUTABLE_MEM.bits |
+                                   ConstQualif::NEEDS_DROP.bits |
+                                   ConstQualif::NOT_CONST.bits
     }
 }
 
@@ -102,7 +104,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
     {
         let (old_mode, old_qualif) = (self.mode, self.qualif);
         self.mode = mode;
-        self.qualif = PURE_CONST;
+        self.qualif = ConstQualif::PURE_CONST;
         let r = f(self);
         self.mode = old_mode;
         self.qualif = old_qualif;
@@ -126,7 +128,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
             Entry::Occupied(entry) => return *entry.get(),
             Entry::Vacant(entry) => {
                 // Prevent infinite recursion on re-entry.
-                entry.insert(PURE_CONST);
+                entry.insert(ConstQualif::PURE_CONST);
             }
         }
         self.with_mode(mode, |this| {
@@ -271,7 +273,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
 
     fn visit_expr(&mut self, ex: &ast::Expr) {
         let mut outer = self.qualif;
-        self.qualif = PURE_CONST;
+        self.qualif = ConstQualif::PURE_CONST;
 
         let node_ty = ty::node_id_to_type(self.tcx, ex.id);
         check_expr(self, ex, node_ty);
@@ -287,7 +289,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                 self.visit_expr(&**callee);
                 // The callee's size doesn't count in the call.
                 let added = self.qualif - inner;
-                self.qualif = inner | (added - NON_ZERO_SIZED);
+                self.qualif = inner | (added - ConstQualif::NON_ZERO_SIZED);
             }
             ast::ExprRepeat(ref element, _) => {
                 self.visit_expr(&**element);
@@ -298,7 +300,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                 };
                 // [element; 0] is always zero-sized.
                 if count == 0 {
-                    self.qualif = self.qualif - (NON_ZERO_SIZED | PREFER_IN_PLACE);
+                    self.qualif.remove(ConstQualif::NON_ZERO_SIZED | ConstQualif::PREFER_IN_PLACE);
                 }
             }
             ast::ExprMatch(ref discr, ref arms, _) => {
@@ -325,7 +327,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                 let div_or_rem = op.node == ast::BiDiv || op.node == ast::BiRem;
                 match node_ty.sty {
                     ty::ty_uint(_) | ty::ty_int(_) if div_or_rem => {
-                        if !self.qualif.intersects(NOT_CONST) {
+                        if !self.qualif.intersects(ConstQualif::NOT_CONST) {
                             match const_eval::eval_const_expr_partial(self.tcx, ex, None) {
                                 Ok(_) => {}
                                 Err(msg) => {
@@ -348,11 +350,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                 // Constants cannot be borrowed if they contain interior mutability as
                 // it means that our "silent insertion of statics" could change
                 // initializer values (very bad).
-                // If the type doesn't have interior mutability, then `MUTABLE_MEM` has
+                // If the type doesn't have interior mutability, then `ConstQualif::MUTABLE_MEM` has
                 // propagated from another error, so erroring again would be just noise.
                 let tc = ty::type_contents(self.tcx, node_ty);
-                if self.qualif.intersects(MUTABLE_MEM) && tc.interior_unsafe() {
-                    outer = outer | NOT_CONST;
+                if self.qualif.intersects(ConstQualif::MUTABLE_MEM) && tc.interior_unsafe() {
+                    outer = outer | ConstQualif::NOT_CONST;
                     if self.mode != Mode::Var {
                         self.tcx.sess.span_err(ex.span,
                             "cannot borrow a constant which contains \
@@ -361,32 +363,32 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
                 }
                 // If the reference has to be 'static, avoid in-place initialization
                 // as that will end up pointing to the stack instead.
-                if !self.qualif.intersects(NON_STATIC_BORROWS) {
-                    self.qualif = self.qualif - PREFER_IN_PLACE;
-                    self.add_qualif(HAS_STATIC_BORROWS);
+                if !self.qualif.intersects(ConstQualif::NON_STATIC_BORROWS) {
+                    self.qualif = self.qualif - ConstQualif::PREFER_IN_PLACE;
+                    self.add_qualif(ConstQualif::HAS_STATIC_BORROWS);
                 }
             }
             Some(ast::MutMutable) => {
                 // `&mut expr` means expr could be mutated, unless it's zero-sized.
-                if self.qualif.intersects(NON_ZERO_SIZED) {
+                if self.qualif.intersects(ConstQualif::NON_ZERO_SIZED) {
                     if self.mode == Mode::Var {
-                        outer = outer | NOT_CONST;
-                        self.add_qualif(MUTABLE_MEM);
+                        outer = outer | ConstQualif::NOT_CONST;
+                        self.add_qualif(ConstQualif::MUTABLE_MEM);
                     } else {
                         span_err!(self.tcx.sess, ex.span, E0017,
                             "references in {}s may only refer \
                              to immutable values", self.msg())
                     }
                 }
-                if !self.qualif.intersects(NON_STATIC_BORROWS) {
-                    self.add_qualif(HAS_STATIC_BORROWS);
+                if !self.qualif.intersects(ConstQualif::NON_STATIC_BORROWS) {
+                    self.add_qualif(ConstQualif::HAS_STATIC_BORROWS);
                 }
             }
             None => {}
         }
         self.tcx.const_qualif_map.borrow_mut().insert(ex.id, self.qualif);
         // Don't propagate certain flags.
-        self.qualif = outer | (self.qualif - HAS_STATIC_BORROWS);
+        self.qualif = outer | (self.qualif - ConstQualif::HAS_STATIC_BORROWS);
     }
 }
 
@@ -401,7 +403,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
     match node_ty.sty {
         ty::ty_struct(did, _) |
         ty::ty_enum(did, _) if ty::has_dtor(v.tcx, did) => {
-            v.add_qualif(NEEDS_DROP);
+            v.add_qualif(ConstQualif::NEEDS_DROP);
             if v.mode != Mode::Var {
                 v.tcx.sess.span_err(e.span,
                                     &format!("{}s are not allowed to have destructors",
@@ -416,7 +418,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
         ast::ExprUnary(..) |
         ast::ExprBinary(..) |
         ast::ExprIndex(..) if v.tcx.method_map.borrow().contains_key(&method_call) => {
-            v.add_qualif(NOT_CONST);
+            v.add_qualif(ConstQualif::NOT_CONST);
             if v.mode != Mode::Var {
                 span_err!(v.tcx.sess, e.span, E0011,
                             "user-defined operators are not allowed in {}s", v.msg());
@@ -424,7 +426,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
         }
         ast::ExprBox(..) |
         ast::ExprUnary(ast::UnUniq, _) => {
-            v.add_qualif(NOT_CONST);
+            v.add_qualif(ConstQualif::NOT_CONST);
             if v.mode != Mode::Var {
                 span_err!(v.tcx.sess, e.span, E0010,
                           "allocations are not allowed in {}s", v.msg());
@@ -434,7 +436,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             match ty::node_id_to_type(v.tcx, ptr.id).sty {
                 ty::ty_ptr(_) => {
                     // This shouldn't be allowed in constants at all.
-                    v.add_qualif(NOT_CONST);
+                    v.add_qualif(ConstQualif::NOT_CONST);
                 }
                 _ => {}
             }
@@ -447,7 +449,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 ty::type_is_unsafe_ptr(toty) ||
                 (ty::type_is_bare_fn(toty) && ty::type_is_bare_fn_item(fromty));
             if !is_legal_cast {
-                v.add_qualif(NOT_CONST);
+                v.add_qualif(ConstQualif::NOT_CONST);
                 if v.mode != Mode::Var {
                     span_err!(v.tcx.sess, e.span, E0012,
                               "can not cast to `{}` in {}s",
@@ -455,7 +457,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 }
             }
             if ty::type_is_unsafe_ptr(fromty) && ty::type_is_numeric(toty) {
-                v.add_qualif(NOT_CONST);
+                v.add_qualif(ConstQualif::NOT_CONST);
                 if v.mode != Mode::Var {
                     span_err!(v.tcx.sess, e.span, E0018,
                               "can not cast a pointer to an integer in {}s", v.msg());
@@ -467,17 +469,17 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             match def {
                 Some(def::DefVariant(_, _, _)) => {
                     // Count the discriminator or function pointer.
-                    v.add_qualif(NON_ZERO_SIZED);
+                    v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                 }
                 Some(def::DefStruct(_)) => {
                     if let ty::ty_bare_fn(..) = node_ty.sty {
                         // Count the function pointer.
-                        v.add_qualif(NON_ZERO_SIZED);
+                        v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                     }
                 }
                 Some(def::DefFn(..)) | Some(def::DefMethod(..)) => {
                     // Count the function pointer.
-                    v.add_qualif(NON_ZERO_SIZED);
+                    v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                 }
                 Some(def::DefStatic(..)) => {
                     match v.mode {
@@ -487,7 +489,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                                 "constants cannot refer to other statics, \
                                  insert an intermediate constant instead");
                         }
-                        Mode::Var => v.add_qualif(NOT_CONST)
+                        Mode::Var => v.add_qualif(ConstQualif::NOT_CONST)
                     }
                 }
                 Some(def::DefConst(did)) |
@@ -503,7 +505,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                     }
                 }
                 def => {
-                    v.add_qualif(NOT_CONST);
+                    v.add_qualif(ConstQualif::NOT_CONST);
                     if v.mode != Mode::Var {
                         debug!("(checking const) found bad def: {:?}", def);
                         span_err!(v.tcx.sess, e.span, E0014,
@@ -530,10 +532,10 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
                 Some(def::DefStruct(..)) => {}
                 Some(def::DefVariant(..)) => {
                     // Count the discriminator.
-                    v.add_qualif(NON_ZERO_SIZED);
+                    v.add_qualif(ConstQualif::NON_ZERO_SIZED);
                 }
                 _ => {
-                    v.add_qualif(NOT_CONST);
+                    v.add_qualif(ConstQualif::NOT_CONST);
                     if v.mode != Mode::Var {
                         span_err!(v.tcx.sess, e.span, E0015,
                                   "function calls in {}s are limited to \
@@ -545,7 +547,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
         ast::ExprBlock(ref block) => {
             // Check all statements in the block
             let mut block_span_err = |span| {
-                v.add_qualif(NOT_CONST);
+                v.add_qualif(ConstQualif::NOT_CONST);
                 if v.mode != Mode::Var {
                     span_err!(v.tcx.sess, span, E0016,
                               "blocks in {}s are limited to items and \
@@ -574,17 +576,17 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
         ast::ExprStruct(..) => {
             let did = v.tcx.def_map.borrow().get(&e.id).map(|def| def.def_id());
             if did == v.tcx.lang_items.unsafe_cell_type() {
-                v.add_qualif(MUTABLE_MEM);
+                v.add_qualif(ConstQualif::MUTABLE_MEM);
             }
         }
 
         ast::ExprLit(_) |
         ast::ExprAddrOf(..) => {
-            v.add_qualif(NON_ZERO_SIZED);
+            v.add_qualif(ConstQualif::NON_ZERO_SIZED);
         }
 
         ast::ExprRepeat(..) => {
-            v.add_qualif(PREFER_IN_PLACE);
+            v.add_qualif(ConstQualif::PREFER_IN_PLACE);
         }
 
         ast::ExprClosure(..) => {
@@ -593,7 +595,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             if ty::with_freevars(v.tcx, e.id, |fv| !fv.is_empty()) {
                 assert!(v.mode == Mode::Var,
                         "global closures can't capture anything");
-                v.add_qualif(NOT_CONST);
+                v.add_qualif(ConstQualif::NOT_CONST);
             }
         }
 
@@ -631,7 +633,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
         ast::ExprAssignOp(..) |
         ast::ExprInlineAsm(_) |
         ast::ExprMac(_) => {
-            v.add_qualif(NOT_CONST);
+            v.add_qualif(ConstQualif::NOT_CONST);
             if v.mode != Mode::Var {
                 span_err!(v.tcx.sess, e.span, E0019,
                           "{} contains unimplemented expression type", v.msg());
@@ -644,7 +646,7 @@ pub fn check_crate(tcx: &ty::ctxt) {
     visit::walk_crate(&mut CheckCrateVisitor {
         tcx: tcx,
         mode: Mode::Var,
-        qualif: NOT_CONST,
+        qualif: ConstQualif::NOT_CONST,
         rvalue_borrows: NodeMap()
     }, tcx.map.krate());
 
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 587194bafad..c4ab89e3b4d 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -838,20 +838,20 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
                            expr_ty: Ty<'tcx>)
                            -> cmt<'tcx> {
         let qualif = self.tcx().const_qualif_map.borrow().get(&id).cloned()
-                               .unwrap_or(check_const::NOT_CONST);
+                               .unwrap_or(check_const::ConstQualif::NOT_CONST);
 
         // Only promote `[T; 0]` before an RFC for rvalue promotions
         // is accepted.
         let qualif = match expr_ty.sty {
             ty::ty_vec(_, Some(0)) => qualif,
-            _ => check_const::NOT_CONST
+            _ => check_const::ConstQualif::NOT_CONST
         };
 
         // Compute maximum lifetime of this rvalue. This is 'static if
         // we can promote to a constant, otherwise equal to enclosing temp
         // lifetime.
-        let re = match qualif & check_const::NON_STATIC_BORROWS {
-            check_const::PURE_CONST => ty::ReStatic,
+        let re = match qualif & check_const::ConstQualif::NON_STATIC_BORROWS {
+            check_const::ConstQualif::PURE_CONST => ty::ReStatic,
             _ => self.temporary_scope(id),
         };
         let ret = self.cat_rvalue(id, span, re, expr_ty);
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index f172815a4d1..33ba21bc7b1 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -848,16 +848,18 @@ impl<'tcx> ctxt<'tcx> {
 // recursing over the type itself.
 bitflags! {
     flags TypeFlags: u32 {
-        const NO_TYPE_FLAGS       = 0b0,
-        const HAS_PARAMS          = 0b1,
-        const HAS_SELF            = 0b10,
-        const HAS_TY_INFER        = 0b100,
-        const HAS_RE_INFER        = 0b1000,
-        const HAS_RE_LATE_BOUND   = 0b10000,
-        const HAS_REGIONS         = 0b100000,
-        const HAS_TY_ERR          = 0b1000000,
-        const HAS_PROJECTION      = 0b10000000,
-        const NEEDS_SUBST   = HAS_PARAMS.bits | HAS_SELF.bits | HAS_REGIONS.bits,
+        const NO_TYPE_FLAGS     = 0,
+        const HAS_PARAMS        = 1 << 0,
+        const HAS_SELF          = 1 << 1,
+        const HAS_TY_INFER      = 1 << 2,
+        const HAS_RE_INFER      = 1 << 3,
+        const HAS_RE_LATE_BOUND = 1 << 4,
+        const HAS_REGIONS       = 1 << 5,
+        const HAS_TY_ERR        = 1 << 6,
+        const HAS_PROJECTION    = 1 << 7,
+        const NEEDS_SUBST       = TypeFlags::HAS_PARAMS.bits |
+                                  TypeFlags::HAS_SELF.bits |
+                                  TypeFlags::HAS_REGIONS.bits,
     }
 }
 
@@ -890,8 +892,8 @@ macro_rules! sty_debug_print {
                         ty::ty_err => /* unimportant */ continue,
                         $(ty::$variant(..) => &mut $variant,)*
                     };
-                    let region = t.flags.intersects(ty::HAS_RE_INFER);
-                    let ty = t.flags.intersects(ty::HAS_TY_INFER);
+                    let region = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
+                    let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
 
                     variant.total += 1;
                     total.total += 1;
@@ -993,23 +995,23 @@ impl<'tcx> Borrow<sty<'tcx>> for InternedTy<'tcx> {
 }
 
 pub fn type_has_params(ty: Ty) -> bool {
-    ty.flags.intersects(HAS_PARAMS)
+    ty.flags.intersects(TypeFlags::HAS_PARAMS)
 }
 pub fn type_has_self(ty: Ty) -> bool {
-    ty.flags.intersects(HAS_SELF)
+    ty.flags.intersects(TypeFlags::HAS_SELF)
 }
 pub fn type_has_ty_infer(ty: Ty) -> bool {
-    ty.flags.intersects(HAS_TY_INFER)
+    ty.flags.intersects(TypeFlags::HAS_TY_INFER)
 }
 pub fn type_needs_infer(ty: Ty) -> bool {
-    ty.flags.intersects(HAS_TY_INFER | HAS_RE_INFER)
+    ty.flags.intersects(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER)
 }
 pub fn type_has_projection(ty: Ty) -> bool {
-    ty.flags.intersects(HAS_PROJECTION)
+    ty.flags.intersects(TypeFlags::HAS_PROJECTION)
 }
 
 pub fn type_has_late_bound_regions(ty: Ty) -> bool {
-    ty.flags.intersects(HAS_RE_LATE_BOUND)
+    ty.flags.intersects(TypeFlags::HAS_RE_LATE_BOUND)
 }
 
 /// An "escaping region" is a bound region whose binder is not part of `t`.
@@ -2810,7 +2812,7 @@ struct FlagComputation {
 
 impl FlagComputation {
     fn new() -> FlagComputation {
-        FlagComputation { flags: NO_TYPE_FLAGS, depth: 0 }
+        FlagComputation { flags: TypeFlags::NO_TYPE_FLAGS, depth: 0 }
     }
 
     fn for_sty(st: &sty) -> FlagComputation {
@@ -2855,20 +2857,20 @@ impl FlagComputation {
 
             // You might think that we could just return ty_err for
             // any type containing ty_err as a component, and get
-            // rid of the HAS_TY_ERR flag -- likewise for ty_bot (with
+            // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
             // the exception of function types that return bot).
             // But doing so caused sporadic memory corruption, and
             // neither I (tjc) nor nmatsakis could figure out why,
             // so we're doing it this way.
             &ty_err => {
-                self.add_flags(HAS_TY_ERR)
+                self.add_flags(TypeFlags::HAS_TY_ERR)
             }
 
             &ty_param(ref p) => {
                 if p.space == subst::SelfSpace {
-                    self.add_flags(HAS_SELF);
+                    self.add_flags(TypeFlags::HAS_SELF);
                 } else {
-                    self.add_flags(HAS_PARAMS);
+                    self.add_flags(TypeFlags::HAS_PARAMS);
                 }
             }
 
@@ -2877,7 +2879,7 @@ impl FlagComputation {
             }
 
             &ty_infer(_) => {
-                self.add_flags(HAS_TY_INFER)
+                self.add_flags(TypeFlags::HAS_TY_INFER)
             }
 
             &ty_enum(_, substs) | &ty_struct(_, substs) => {
@@ -2885,7 +2887,7 @@ impl FlagComputation {
             }
 
             &ty_projection(ref data) => {
-                self.add_flags(HAS_PROJECTION);
+                self.add_flags(TypeFlags::HAS_PROJECTION);
                 self.add_projection_ty(data);
             }
 
@@ -2949,11 +2951,11 @@ impl FlagComputation {
     }
 
     fn add_region(&mut self, r: Region) {
-        self.add_flags(HAS_REGIONS);
+        self.add_flags(TypeFlags::HAS_REGIONS);
         match r {
-            ty::ReInfer(_) => { self.add_flags(HAS_RE_INFER); }
+            ty::ReInfer(_) => { self.add_flags(TypeFlags::HAS_RE_INFER); }
             ty::ReLateBound(debruijn, _) => {
-                self.add_flags(HAS_RE_LATE_BOUND);
+                self.add_flags(TypeFlags::HAS_RE_LATE_BOUND);
                 self.add_depth(debruijn.depth);
             }
             _ => { }
@@ -3307,11 +3309,11 @@ pub fn type_is_nil(ty: Ty) -> bool {
 }
 
 pub fn type_is_error(ty: Ty) -> bool {
-    ty.flags.intersects(HAS_TY_ERR)
+    ty.flags.intersects(TypeFlags::HAS_TY_ERR)
 }
 
 pub fn type_needs_subst(ty: Ty) -> bool {
-    ty.flags.intersects(NEEDS_SUBST)
+    ty.flags.intersects(TypeFlags::NEEDS_SUBST)
 }
 
 pub fn trait_ref_contains_error(tref: &ty::TraitRef) -> bool {
diff --git a/src/librustc_bitflags/lib.rs b/src/librustc_bitflags/lib.rs
index 93a2a5d1257..6d23cad26cb 100644
--- a/src/librustc_bitflags/lib.rs
+++ b/src/librustc_bitflags/lib.rs
@@ -12,6 +12,7 @@
 // Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
 #![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "rustc_bitflags"]
+#![feature(associated_consts)]
 #![feature(staged_api)]
 #![staged_api]
 #![crate_type = "rlib"]
@@ -34,6 +35,7 @@
 ///
 /// ```{.rust}
 /// # #![feature(rustc_private)]
+/// # #![feature(associated_consts)]
 /// #[macro_use] extern crate rustc_bitflags;
 ///
 /// bitflags! {
@@ -41,19 +43,19 @@
 ///         const FLAG_A       = 0b00000001,
 ///         const FLAG_B       = 0b00000010,
 ///         const FLAG_C       = 0b00000100,
-///         const FLAG_ABC     = FLAG_A.bits
-///                            | FLAG_B.bits
-///                            | FLAG_C.bits,
+///         const FLAG_ABC     = Flags::FLAG_A.bits
+///                            | Flags::FLAG_B.bits
+///                            | Flags::FLAG_C.bits,
 ///     }
 /// }
 ///
 /// fn main() {
-///     let e1 = FLAG_A | FLAG_C;
-///     let e2 = FLAG_B | FLAG_C;
-///     assert!((e1 | e2) == FLAG_ABC);   // union
-///     assert!((e1 & e2) == FLAG_C);     // intersection
-///     assert!((e1 - e2) == FLAG_A);     // set difference
-///     assert!(!e2 == FLAG_A);           // set complement
+///     let e1 = Flags::FLAG_A | Flags::FLAG_C;
+///     let e2 = Flags::FLAG_B | Flags::FLAG_C;
+///     assert!((e1 | e2) == Flags::FLAG_ABC); // union
+///     assert!((e1 & e2) == Flags::FLAG_C);   // intersection
+///     assert!((e1 - e2) == Flags::FLAG_A);   // set difference
+///     assert!(!e2 == Flags::FLAG_A);         // set complement
 /// }
 /// ```
 ///
@@ -86,7 +88,7 @@
 /// }
 ///
 /// fn main() {
-///     let mut flags = FLAG_A | FLAG_B;
+///     let mut flags = Flags::FLAG_A | Flags::FLAG_B;
 ///     flags.clear();
 ///     assert!(flags.is_empty());
 ///     assert_eq!(format!("{:?}", flags), "hi!");
@@ -144,9 +146,9 @@ macro_rules! bitflags {
             bits: $T,
         }
 
-        $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
-
         impl $BitFlags {
+            $($(#[$Flag_attr])* pub const $Flag: $BitFlags = $BitFlags { bits: $value };)+
+
             /// Returns an empty set of flags.
             #[inline]
             pub fn empty() -> $BitFlags {
@@ -314,9 +316,9 @@ mod tests {
             #[doc = "* cmr bed"]
             #[doc = "* strcat table"]
             #[doc = "<strcat> wait what?"]
-            const FlagABC     = FlagA.bits
-                               | FlagB.bits
-                               | FlagC.bits,
+            const FlagABC     = Flags::FlagA.bits
+                               | Flags::FlagB.bits
+                               | Flags::FlagC.bits,
         }
     }
 
@@ -329,32 +331,32 @@ mod tests {
     #[test]
     fn test_bits(){
         assert_eq!(Flags::empty().bits(), 0b00000000);
-        assert_eq!(FlagA.bits(), 0b00000001);
-        assert_eq!(FlagABC.bits(), 0b00000111);
+        assert_eq!(Flags::FlagA.bits(), 0b00000001);
+        assert_eq!(Flags::FlagABC.bits(), 0b00000111);
 
         assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
-        assert_eq!(AnotherFlag.bits(), !0);
+        assert_eq!(AnotherSetOfFlags::AnotherFlag.bits(), !0);
     }
 
     #[test]
     fn test_from_bits() {
         assert!(Flags::from_bits(0) == Some(Flags::empty()));
-        assert!(Flags::from_bits(0b1) == Some(FlagA));
-        assert!(Flags::from_bits(0b10) == Some(FlagB));
-        assert!(Flags::from_bits(0b11) == Some(FlagA | FlagB));
+        assert!(Flags::from_bits(0b1) == Some(Flags::FlagA));
+        assert!(Flags::from_bits(0b10) == Some(Flags::FlagB));
+        assert!(Flags::from_bits(0b11) == Some(Flags::FlagA | Flags::FlagB));
         assert!(Flags::from_bits(0b1000) == None);
 
-        assert!(AnotherSetOfFlags::from_bits(!0) == Some(AnotherFlag));
+        assert!(AnotherSetOfFlags::from_bits(!0) == Some(AnotherSetOfFlags::AnotherFlag));
     }
 
     #[test]
     fn test_from_bits_truncate() {
         assert!(Flags::from_bits_truncate(0) == Flags::empty());
-        assert!(Flags::from_bits_truncate(0b1) == FlagA);
-        assert!(Flags::from_bits_truncate(0b10) == FlagB);
-        assert!(Flags::from_bits_truncate(0b11) == (FlagA | FlagB));
+        assert!(Flags::from_bits_truncate(0b1) == Flags::FlagA);
+        assert!(Flags::from_bits_truncate(0b10) == Flags::FlagB);
+        assert!(Flags::from_bits_truncate(0b11) == (Flags::FlagA | Flags::FlagB));
         assert!(Flags::from_bits_truncate(0b1000) == Flags::empty());
-        assert!(Flags::from_bits_truncate(0b1001) == FlagA);
+        assert!(Flags::from_bits_truncate(0b1001) == Flags::FlagA);
 
         assert!(AnotherSetOfFlags::from_bits_truncate(0) == AnotherSetOfFlags::empty());
     }
@@ -362,19 +364,19 @@ mod tests {
     #[test]
     fn test_is_empty(){
         assert!(Flags::empty().is_empty());
-        assert!(!FlagA.is_empty());
-        assert!(!FlagABC.is_empty());
+        assert!(!Flags::FlagA.is_empty());
+        assert!(!Flags::FlagABC.is_empty());
 
-        assert!(!AnotherFlag.is_empty());
+        assert!(!AnotherSetOfFlags::AnotherFlag.is_empty());
     }
 
     #[test]
     fn test_is_all() {
         assert!(Flags::all().is_all());
-        assert!(!FlagA.is_all());
-        assert!(FlagABC.is_all());
+        assert!(!Flags::FlagA.is_all());
+        assert!(Flags::FlagABC.is_all());
 
-        assert!(AnotherFlag.is_all());
+        assert!(AnotherSetOfFlags::AnotherFlag.is_all());
     }
 
     #[test]
@@ -383,77 +385,77 @@ mod tests {
         let e2 = Flags::empty();
         assert!(!e1.intersects(e2));
 
-        assert!(AnotherFlag.intersects(AnotherFlag));
+        assert!(AnotherSetOfFlags::AnotherFlag.intersects(AnotherSetOfFlags::AnotherFlag));
     }
 
     #[test]
     fn test_empty_does_not_intersect_with_full() {
         let e1 = Flags::empty();
-        let e2 = FlagABC;
+        let e2 = Flags::FlagABC;
         assert!(!e1.intersects(e2));
     }
 
     #[test]
     fn test_disjoint_intersects() {
-        let e1 = FlagA;
-        let e2 = FlagB;
+        let e1 = Flags::FlagA;
+        let e2 = Flags::FlagB;
         assert!(!e1.intersects(e2));
     }
 
     #[test]
     fn test_overlapping_intersects() {
-        let e1 = FlagA;
-        let e2 = FlagA | FlagB;
+        let e1 = Flags::FlagA;
+        let e2 = Flags::FlagA | Flags::FlagB;
         assert!(e1.intersects(e2));
     }
 
     #[test]
     fn test_contains() {
-        let e1 = FlagA;
-        let e2 = FlagA | FlagB;
+        let e1 = Flags::FlagA;
+        let e2 = Flags::FlagA | Flags::FlagB;
         assert!(!e1.contains(e2));
         assert!(e2.contains(e1));
-        assert!(FlagABC.contains(e2));
+        assert!(Flags::FlagABC.contains(e2));
 
-        assert!(AnotherFlag.contains(AnotherFlag));
+        assert!(AnotherSetOfFlags::AnotherFlag.contains(AnotherSetOfFlags::AnotherFlag));
     }
 
     #[test]
     fn test_insert(){
-        let mut e1 = FlagA;
-        let e2 = FlagA | FlagB;
+        let mut e1 = Flags::FlagA;
+        let e2 = Flags::FlagA | Flags::FlagB;
         e1.insert(e2);
         assert!(e1 == e2);
 
         let mut e3 = AnotherSetOfFlags::empty();
-        e3.insert(AnotherFlag);
-        assert!(e3 == AnotherFlag);
+        e3.insert(AnotherSetOfFlags::AnotherFlag);
+        assert!(e3 == AnotherSetOfFlags::AnotherFlag);
     }
 
     #[test]
     fn test_remove(){
-        let mut e1 = FlagA | FlagB;
-        let e2 = FlagA | FlagC;
+        let mut e1 = Flags::FlagA | Flags::FlagB;
+        let e2 = Flags::FlagA | Flags::FlagC;
         e1.remove(e2);
-        assert!(e1 == FlagB);
+        assert!(e1 == Flags::FlagB);
 
-        let mut e3 = AnotherFlag;
-        e3.remove(AnotherFlag);
+        let mut e3 = AnotherSetOfFlags::AnotherFlag;
+        e3.remove(AnotherSetOfFlags::AnotherFlag);
         assert!(e3 == AnotherSetOfFlags::empty());
     }
 
     #[test]
     fn test_operators() {
-        let e1 = FlagA | FlagC;
-        let e2 = FlagB | FlagC;
-        assert!((e1 | e2) == FlagABC);     // union
-        assert!((e1 & e2) == FlagC);       // intersection
-        assert!((e1 - e2) == FlagA);       // set difference
-        assert!(!e2 == FlagA);             // set complement
-        assert!(e1 ^ e2 == FlagA | FlagB); // toggle
+        let e1 = Flags::FlagA | Flags::FlagC;
+        let e2 = Flags::FlagB | Flags::FlagC;
+        assert!((e1 | e2) == Flags::FlagABC);     // union
+        assert!((e1 & e2) == Flags::FlagC);       // intersection
+        assert!((e1 - e2) == Flags::FlagA);       // set difference
+        assert!(!e2 == Flags::FlagA);             // set complement
+        assert!(e1 ^ e2 == Flags::FlagA | Flags::FlagB); // toggle
         let mut e3 = e1;
         e3.toggle(e2);
-        assert!(e3 == FlagA | FlagB);
+        assert!(e3 == Flags::FlagA | Flags::FlagB);
 
         let mut m4 = AnotherSetOfFlags::empty();
         m4.toggle(AnotherSetOfFlags::empty());
@@ -466,11 +468,11 @@ mod tests {
         let mut b = Flags::empty();
 
         assert!(!(a < b) && !(b < a));
-        b = FlagB;
+        b = Flags::FlagB;
         assert!(a < b);
-        a = FlagC;
+        a = Flags::FlagC;
         assert!(!(a < b) && b < a);
-        b = FlagC | FlagB;
+        b = Flags::FlagC | Flags::FlagB;
         assert!(a < b);
     }
 
@@ -480,10 +482,10 @@ mod tests {
         let mut b = Flags::empty();
 
         assert!(a <= b && a >= b);
-        a = FlagA;
+        a = Flags::FlagA;
         assert!(a > b && a >= b);
         assert!(b < a && b <= a);
-        b = FlagB;
+        b = Flags::FlagB;
         assert!(b > a && b >= a);
         assert!(a < b && a <= b);
     }
@@ -494,7 +496,7 @@ mod tests {
       let mut y = Flags::empty();
       assert!(hash::hash::<Flags, SipHasher>(&x) == hash::hash::<Flags, SipHasher>(&y));
       x = Flags::all();
-      y = FlagABC;
+      y = Flags::FlagABC;
       assert!(hash::hash::<Flags, SipHasher>(&x) == hash::hash::<Flags, SipHasher>(&y));
     }
 }
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 79757320ade..db88072150a 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -25,6 +25,7 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
+#![feature(associated_consts)]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(libc)]
@@ -124,32 +125,32 @@ pub enum DiagnosticSeverity {
 
 bitflags! {
     flags Attribute : u32 {
-        const ZExtAttribute = 1 << 0,
-        const SExtAttribute = 1 << 1,
-        const NoReturnAttribute = 1 << 2,
-        const InRegAttribute = 1 << 3,
-        const StructRetAttribute = 1 << 4,
-        const NoUnwindAttribute = 1 << 5,
-        const NoAliasAttribute = 1 << 6,
-        const ByValAttribute = 1 << 7,
-        const NestAttribute = 1 << 8,
-        const ReadNoneAttribute = 1 << 9,
-        const ReadOnlyAttribute = 1 << 10,
-        const NoInlineAttribute = 1 << 11,
-        const AlwaysInlineAttribute = 1 << 12,
+        const ZExtAttribute            = 1 << 0,
+        const SExtAttribute            = 1 << 1,
+        const NoReturnAttribute        = 1 << 2,
+        const InRegAttribute           = 1 << 3,
+        const StructRetAttribute       = 1 << 4,
+        const NoUnwindAttribute        = 1 << 5,
+        const NoAliasAttribute         = 1 << 6,
+        const ByValAttribute           = 1 << 7,
+        const NestAttribute            = 1 << 8,
+        const ReadNoneAttribute        = 1 << 9,
+        const ReadOnlyAttribute        = 1 << 10,
+        const NoInlineAttribute        = 1 << 11,
+        const AlwaysInlineAttribute    = 1 << 12,
         const OptimizeForSizeAttribute = 1 << 13,
-        const StackProtectAttribute = 1 << 14,
+        const StackProtectAttribute    = 1 << 14,
         const StackProtectReqAttribute = 1 << 15,
-        const AlignmentAttribute = 31 << 16,
-        const NoCaptureAttribute = 1 << 21,
-        const NoRedZoneAttribute = 1 << 22,
+        const AlignmentAttribute       = 1 << 16,
+        const NoCaptureAttribute       = 1 << 21,
+        const NoRedZoneAttribute       = 1 << 22,
         const NoImplicitFloatAttribute = 1 << 23,
-        const NakedAttribute = 1 << 24,
-        const InlineHintAttribute = 1 << 25,
-        const StackAttribute = 7 << 26,
-        const ReturnsTwiceAttribute = 1 << 29,
-        const UWTableAttribute = 1 << 30,
-        const NonLazyBindAttribute = 1 << 31,
+        const NakedAttribute           = 1 << 24,
+        const InlineHintAttribute      = 1 << 25,
+        const StackAttribute           = 7 << 26,
+        const ReturnsTwiceAttribute    = 1 << 29,
+        const UWTableAttribute         = 1 << 30,
+        const NonLazyBindAttribute     = 1 << 31,
     }
 }
 
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 0d25700d2b7..4ea18968d43 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -13,7 +13,7 @@
 //! Here we build the "reduced graph": the graph of the module tree without
 //! any imports resolved.
 
-use {DefModifiers, PUBLIC, IMPORTABLE};
+use DefModifiers;
 use resolve_imports::ImportDirective;
 use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport};
 use resolve_imports::ImportResolution;
@@ -262,7 +262,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
         let name = item.ident.name;
         let sp = item.span;
         let is_public = item.vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let modifiers = if is_public {
+            DefModifiers::PUBLIC
+        } else {
+            DefModifiers::empty()
+        } | DefModifiers::IMPORTABLE;
 
         match item.node {
             ItemUse(ref view_path) => {
@@ -533,20 +537,20 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                         ast::ConstTraitItem(..) => {
                             let def = DefAssociatedConst(local_def(trait_item.id),
                                                          FromTrait(local_def(item.id)));
-                            // NB: not IMPORTABLE
-                            name_bindings.define_value(def, trait_item.span, PUBLIC);
+                            // NB: not DefModifiers::IMPORTABLE
+                            name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
                         }
                         ast::MethodTraitItem(..) => {
                             let def = DefMethod(local_def(trait_item.id),
                                                 FromTrait(local_def(item.id)));
-                            // NB: not IMPORTABLE
-                            name_bindings.define_value(def, trait_item.span, PUBLIC);
+                            // NB: not DefModifiers::IMPORTABLE
+                            name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
                         }
                         ast::TypeTraitItem(..) => {
                             let def = DefAssociatedTy(local_def(item.id),
                                                       local_def(trait_item.id));
-                            // NB: not IMPORTABLE
-                            name_bindings.define_type(def, trait_item.span, PUBLIC);
+                            // NB: not DefModifiers::IMPORTABLE
+                            name_bindings.define_type(def, trait_item.span, DefModifiers::PUBLIC);
                         }
                     }
 
@@ -584,10 +588,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
         // used
         child.define_value(DefVariant(item_id,
                                       local_def(variant.node.id), is_exported),
-                           variant.span, PUBLIC | IMPORTABLE);
+                           variant.span, DefModifiers::PUBLIC | DefModifiers::IMPORTABLE);
         child.define_type(DefVariant(item_id,
                                      local_def(variant.node.id), is_exported),
-                          variant.span, PUBLIC | IMPORTABLE);
+                          variant.span, DefModifiers::PUBLIC | DefModifiers::IMPORTABLE);
     }
 
     /// Constructs the reduced graph for one foreign item.
@@ -596,7 +600,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                             parent: &Rc<Module>) {
         let name = foreign_item.ident.name;
         let is_public = foreign_item.vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let modifiers = if is_public {
+            DefModifiers::PUBLIC
+        } else {
+            DefModifiers::empty()
+        } | DefModifiers::IMPORTABLE;
         let name_bindings =
             self.add_child(name, parent, ForbidDuplicateValues,
                            foreign_item.span);
@@ -644,7 +652,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                 external crate) building external def {}, priv {:?}",
                final_ident, vis);
         let is_public = vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let modifiers = if is_public {
+            DefModifiers::PUBLIC
+        } else {
+            DefModifiers::empty()
+        } | DefModifiers::IMPORTABLE;
         let is_exported = is_public && match new_parent.def_id.get() {
             None => true,
             Some(did) => self.external_exports.contains(&did)
@@ -695,7 +707,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                       final_ident);
               // variants are always treated as importable to allow them to be
               // glob used
-              let modifiers = PUBLIC | IMPORTABLE;
+              let modifiers = DefModifiers::PUBLIC | DefModifiers::IMPORTABLE;
               if is_struct {
                   child_name_bindings.define_type(def, DUMMY_SP, modifiers);
                   // Not adding fields for variants as they are not accessed with a self receiver
@@ -715,11 +727,12 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     crate) building value (fn/static) {}", final_ident);
             // impl methods have already been defined with the correct importability modifier
             let mut modifiers = match *child_name_bindings.value_def.borrow() {
-                Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
+                Some(ref def) => (modifiers & !DefModifiers::IMPORTABLE) |
+                             (def.modifiers &  DefModifiers::IMPORTABLE),
                 None => modifiers
             };
             if new_parent.kind.get() != NormalModuleKind {
-                modifiers = modifiers & !IMPORTABLE;
+                modifiers = modifiers & !DefModifiers::IMPORTABLE;
             }
             child_name_bindings.define_value(def, DUMMY_SP, modifiers);
           }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 61eab4ce9b2..d8495fb989b 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -20,6 +20,7 @@
       html_root_url = "http://doc.rust-lang.org/nightly/")]
 
 #![feature(alloc)]
+#![feature(associated_consts)]
 #![feature(collections)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
@@ -477,8 +478,8 @@ impl fmt::Debug for Module {
 bitflags! {
     #[derive(Debug)]
     flags DefModifiers: u8 {
-        const PUBLIC            = 0b0000_0001,
-        const IMPORTABLE        = 0b0000_0010,
+        const PUBLIC     = 1 << 0,
+        const IMPORTABLE = 1 << 1,
     }
 }
 
@@ -524,7 +525,11 @@ impl NameBindings {
                      is_public: bool,
                      sp: Span) {
         // Merges the module with the existing type def or creates a new one.
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let modifiers = if is_public {
+            DefModifiers::PUBLIC
+        } else {
+            DefModifiers::empty()
+        } | DefModifiers::IMPORTABLE;
         let module_ = Rc::new(Module::new(parent_link,
                                           def_id,
                                           kind,
@@ -559,7 +564,11 @@ impl NameBindings {
                        external: bool,
                        is_public: bool,
                        _sp: Span) {
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+        let modifiers = if is_public {
+            DefModifiers::PUBLIC
+        } else {
+            DefModifiers::empty()
+        } | DefModifiers::IMPORTABLE;
         let type_def = self.type_def.borrow().clone();
         match type_def {
             None => {
@@ -659,7 +668,7 @@ impl NameBindings {
     }
 
     fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
-        self.defined_in_namespace_with(namespace, PUBLIC)
+        self.defined_in_namespace_with(namespace, DefModifiers::PUBLIC)
     }
 
     fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
@@ -730,11 +739,11 @@ impl NameBindings {
         match namespace {
             TypeNS  => {
                 let type_def = self.type_def.borrow();
-                type_def.as_ref().unwrap().modifiers.contains(PUBLIC)
+                type_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC)
             }
             ValueNS => {
                 let value_def = self.value_def.borrow();
-                value_def.as_ref().unwrap().modifiers.contains(PUBLIC)
+                value_def.as_ref().unwrap().modifiers.contains(DefModifiers::PUBLIC)
             }
         }
     }
@@ -921,7 +930,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
         NameBindings {
             type_def: RefCell::new(Some(TypeNsDef {
-                modifiers: IMPORTABLE,
+                modifiers: DefModifiers::IMPORTABLE,
                 module_def: Some(module),
                 type_def: None,
                 type_span: None
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 4b488981bfb..350f69d30c4 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -10,7 +10,7 @@
 
 use self::ImportDirectiveSubclass::*;
 
-use {PUBLIC, IMPORTABLE};
+use DefModifiers;
 use Module;
 use Namespace::{self, TypeNS, ValueNS};
 use NameBindings;
@@ -848,7 +848,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
         // Merge the child item into the import resolution.
         {
             let mut merge_child_item = |namespace| {
-                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
+                let modifier = DefModifiers::IMPORTABLE | DefModifiers::PUBLIC;
+
+                if name_bindings.defined_in_namespace_with(namespace, modifier) {
                     let namespace_name = match namespace {
                         TypeNS => "type",
                         ValueNS => "value",
@@ -914,7 +916,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                                        import_span: Span,
                                        name: Name,
                                        namespace: Namespace) {
-        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
+        if !name_bindings.defined_in_namespace_with(namespace, DefModifiers::IMPORTABLE) {
             let msg = format!("`{}` is not directly importable",
                               token::get_name(name));
             span_err!(self.resolver.session, import_span, E0253, "{}", &msg[..]);
diff --git a/src/librustc_trans/trans/attributes.rs b/src/librustc_trans/trans/attributes.rs
index 2615490a9fb..b44ccec0127 100644
--- a/src/librustc_trans/trans/attributes.rs
+++ b/src/librustc_trans/trans/attributes.rs
@@ -39,13 +39,13 @@ pub fn split_stack(val: ValueRef, set: bool) {
 pub fn inline(val: ValueRef, inline: InlineAttr) {
     use self::InlineAttr::*;
     match inline {
-        Hint   => llvm::SetFunctionAttribute(val, llvm::InlineHintAttribute),
-        Always => llvm::SetFunctionAttribute(val, llvm::AlwaysInlineAttribute),
-        Never  => llvm::SetFunctionAttribute(val, llvm::NoInlineAttribute),
+        Hint   => llvm::SetFunctionAttribute(val, llvm::Attribute::InlineHintAttribute),
+        Always => llvm::SetFunctionAttribute(val, llvm::Attribute::AlwaysInlineAttribute),
+        Never  => llvm::SetFunctionAttribute(val, llvm::Attribute::NoInlineAttribute),
         None   => {
-            let attr = llvm::InlineHintAttribute |
-                       llvm::AlwaysInlineAttribute |
-                       llvm::NoInlineAttribute;
+            let attr = llvm::Attribute::InlineHintAttribute |
+                       llvm::Attribute::AlwaysInlineAttribute |
+                       llvm::Attribute::NoInlineAttribute;
             unsafe {
                 llvm::LLVMRemoveFunctionAttr(val, attr.bits() as c_ulonglong)
             }
@@ -57,10 +57,13 @@ pub fn inline(val: ValueRef, inline: InlineAttr) {
 #[inline]
 pub fn emit_uwtable(val: ValueRef, emit: bool) {
     if emit {
-        llvm::SetFunctionAttribute(val, llvm::UWTableAttribute);
+        llvm::SetFunctionAttribute(val, llvm::Attribute::UWTableAttribute);
     } else {
         unsafe {
-            llvm::LLVMRemoveFunctionAttr(val, llvm::UWTableAttribute.bits() as c_ulonglong);
+            llvm::LLVMRemoveFunctionAttr(
+                val,
+                llvm::Attribute::UWTableAttribute.bits() as c_ulonglong,
+            );
         }
     }
 }
@@ -71,10 +74,13 @@ pub fn emit_uwtable(val: ValueRef, emit: bool) {
 pub fn unwind(val: ValueRef, can_unwind: bool) {
     if can_unwind {
         unsafe {
-            llvm::LLVMRemoveFunctionAttr(val, llvm::NoUnwindAttribute.bits() as c_ulonglong);
+            llvm::LLVMRemoveFunctionAttr(
+                val,
+                llvm::Attribute::NoUnwindAttribute.bits() as c_ulonglong,
+            );
         }
     } else {
-        llvm::SetFunctionAttribute(val, llvm::NoUnwindAttribute);
+        llvm::SetFunctionAttribute(val, llvm::Attribute::NoUnwindAttribute);
     }
 }
 
@@ -83,10 +89,13 @@ pub fn unwind(val: ValueRef, can_unwind: bool) {
 #[allow(dead_code)] // possibly useful function
 pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
     if optimize {
-        llvm::SetFunctionAttribute(val, llvm::OptimizeForSizeAttribute);
+        llvm::SetFunctionAttribute(val, llvm::Attribute::OptimizeForSizeAttribute);
     } else {
         unsafe {
-            llvm::LLVMRemoveFunctionAttr(val, llvm::OptimizeForSizeAttribute.bits() as c_ulonglong);
+            llvm::LLVMRemoveFunctionAttr(
+                val,
+                llvm::Attribute::OptimizeForSizeAttribute.bits() as c_ulonglong,
+            );
         }
     }
 }
@@ -107,7 +116,7 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRe
                                                llvm::ColdAttribute as u64)
             }
         } else if attr.check_name("allocator") {
-            llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
+            llvm::Attribute::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
         }
     }
 }
@@ -176,9 +185,9 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
             // The outptr can be noalias and nocapture because it's entirely
             // invisible to the program. We also know it's nonnull as well
             // as how many bytes we can dereference
-            attrs.arg(1, llvm::StructRetAttribute)
-                 .arg(1, llvm::NoAliasAttribute)
-                 .arg(1, llvm::NoCaptureAttribute)
+            attrs.arg(1, llvm::Attribute::StructRetAttribute)
+                 .arg(1, llvm::Attribute::NoAliasAttribute)
+                 .arg(1, llvm::Attribute::NoCaptureAttribute)
                  .arg(1, llvm::DereferenceableAttribute(llret_sz));
 
             // Add one more since there's an outptr
@@ -190,7 +199,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
                 // `~` pointer return values never alias because ownership
                 // is transferred
                 ty::ty_uniq(it) if common::type_is_sized(ccx.tcx(), it) => {
-                    attrs.ret(llvm::NoAliasAttribute);
+                    attrs.ret(llvm::Attribute::NoAliasAttribute);
                 }
                 _ => {}
             }
@@ -207,7 +216,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
             }
 
             if let ty::ty_bool = ret_ty.sty {
-                attrs.ret(llvm::ZExtAttribute);
+                attrs.ret(llvm::Attribute::ZExtAttribute);
             }
         }
     }
@@ -221,20 +230,20 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
                 // For non-immediate arguments the callee gets its own copy of
                 // the value on the stack, so there are no aliases. It's also
                 // program-invisible so can't possibly capture
-                attrs.arg(idx, llvm::NoAliasAttribute)
-                     .arg(idx, llvm::NoCaptureAttribute)
+                attrs.arg(idx, llvm::Attribute::NoAliasAttribute)
+                     .arg(idx, llvm::Attribute::NoCaptureAttribute)
                      .arg(idx, llvm::DereferenceableAttribute(llarg_sz));
             }
 
             ty::ty_bool => {
-                attrs.arg(idx, llvm::ZExtAttribute);
+                attrs.arg(idx, llvm::Attribute::ZExtAttribute);
             }
 
             // `~` pointer parameters never alias because ownership is transferred
             ty::ty_uniq(inner) => {
                 let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, inner));
 
-                attrs.arg(idx, llvm::NoAliasAttribute)
+                attrs.arg(idx, llvm::Attribute::NoAliasAttribute)
                      .arg(idx, llvm::DereferenceableAttribute(llsz));
             }
 
@@ -247,15 +256,15 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
                                   !ty::type_contents(ccx.tcx(), mt.ty).interior_unsafe() => {
 
                 let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
-                attrs.arg(idx, llvm::NoAliasAttribute)
+                attrs.arg(idx, llvm::Attribute::NoAliasAttribute)
                      .arg(idx, llvm::DereferenceableAttribute(llsz));
 
                 if mt.mutbl == ast::MutImmutable {
-                    attrs.arg(idx, llvm::ReadOnlyAttribute);
+                    attrs.arg(idx, llvm::Attribute::ReadOnlyAttribute);
                 }
 
                 if let ReLateBound(_, BrAnon(_)) = *b {
-                    attrs.arg(idx, llvm::NoCaptureAttribute);
+                    attrs.arg(idx, llvm::Attribute::NoCaptureAttribute);
                 }
             }
 
@@ -263,7 +272,7 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
             // reference to escape this function (returned or stored beyond the call by a closure).
             ty::ty_rptr(&ReLateBound(_, BrAnon(_)), mt) => {
                 let llsz = machine::llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
-                attrs.arg(idx, llvm::NoCaptureAttribute)
+                attrs.arg(idx, llvm::Attribute::NoCaptureAttribute)
                      .arg(idx, llvm::DereferenceableAttribute(llsz));
             }
 
diff --git a/src/librustc_trans/trans/cabi_aarch64.rs b/src/librustc_trans/trans/cabi_aarch64.rs
index 57dd2223388..2eef6786739 100644
--- a/src/librustc_trans/trans/cabi_aarch64.rs
+++ b/src/librustc_trans/trans/cabi_aarch64.rs
@@ -10,8 +10,7 @@
 
 #![allow(non_upper_case_globals)]
 
-use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
-use llvm::{StructRetAttribute, ZExtAttribute};
+use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector, Attribute};
 use trans::cabi::{FnType, ArgType};
 use trans::context::CrateContext;
 use trans::type_::Type;
@@ -164,7 +163,7 @@ fn is_homogenous_aggregate_ty(ty: Type) -> Option<(Type, u64)> {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         return ArgType::direct(ty, None, None, attr);
     }
     if let Some((base_ty, members)) = is_homogenous_aggregate_ty(ty) {
@@ -186,12 +185,12 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
         };
         return ArgType::direct(ty, Some(llty), None, None);
     }
-    ArgType::indirect(ty, Some(StructRetAttribute))
+    ArgType::indirect(ty, Some(Attribute::StructRetAttribute))
 }
 
 fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         return ArgType::direct(ty, None, None, attr);
     }
     if let Some((base_ty, members)) = is_homogenous_aggregate_ty(ty) {
diff --git a/src/librustc_trans/trans/cabi_arm.rs b/src/librustc_trans/trans/cabi_arm.rs
index 941c065e3d5..689b3b3ad37 100644
--- a/src/librustc_trans/trans/cabi_arm.rs
+++ b/src/librustc_trans/trans/cabi_arm.rs
@@ -10,8 +10,7 @@
 
 #![allow(non_upper_case_globals)]
 
-use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
-use llvm::{StructRetAttribute, ZExtAttribute};
+use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector, Attribute};
 use trans::cabi::{FnType, ArgType};
 use trans::context::CrateContext;
 use trans::type_::Type;
@@ -132,7 +131,7 @@ fn ty_size(ty: Type, align_fn: TyAlignFn) -> usize {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type, align_fn: TyAlignFn) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         return ArgType::direct(ty, None, None, attr);
     }
     let size = ty_size(ty, align_fn);
@@ -146,12 +145,12 @@ fn classify_ret_ty(ccx: &CrateContext, ty: Type, align_fn: TyAlignFn) -> ArgType
         };
         return ArgType::direct(ty, Some(llty), None, None);
     }
-    ArgType::indirect(ty, Some(StructRetAttribute))
+    ArgType::indirect(ty, Some(Attribute::StructRetAttribute))
 }
 
 fn classify_arg_ty(ccx: &CrateContext, ty: Type, align_fn: TyAlignFn) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         return ArgType::direct(ty, None, None, attr);
     }
     let align = align_fn(ty);
diff --git a/src/librustc_trans/trans/cabi_mips.rs b/src/librustc_trans/trans/cabi_mips.rs
index 2d7fdd2f2eb..2e899f72979 100644
--- a/src/librustc_trans/trans/cabi_mips.rs
+++ b/src/librustc_trans/trans/cabi_mips.rs
@@ -13,8 +13,7 @@
 use libc::c_uint;
 use std::cmp;
 use llvm;
-use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
-use llvm::{StructRetAttribute, ZExtAttribute};
+use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector, Attribute};
 use trans::cabi::{ArgType, FnType};
 use trans::context::CrateContext;
 use trans::type_::Type;
@@ -89,10 +88,10 @@ fn ty_size(ty: Type) -> usize {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         ArgType::direct(ty, None, None, attr)
     } else {
-        ArgType::indirect(ty, Some(StructRetAttribute))
+        ArgType::indirect(ty, Some(Attribute::StructRetAttribute))
     }
 }
 
@@ -106,7 +105,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut usize) -> ArgType
     *offset += align_up_to(size, align * 8) / 8;
 
     if is_reg_ty(ty) {
-        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         ArgType::direct(ty, None, None, attr)
     } else {
         ArgType::direct(
diff --git a/src/librustc_trans/trans/cabi_powerpc.rs b/src/librustc_trans/trans/cabi_powerpc.rs
index 8c30d4fcc2b..eae2378a2c5 100644
--- a/src/librustc_trans/trans/cabi_powerpc.rs
+++ b/src/librustc_trans/trans/cabi_powerpc.rs
@@ -10,8 +10,7 @@
 
 use libc::c_uint;
 use llvm;
-use llvm::{Integer, Pointer, Float, Double, Struct, Array};
-use llvm::{StructRetAttribute, ZExtAttribute};
+use llvm::{Integer, Pointer, Float, Double, Struct, Array, Attribute};
 use trans::cabi::{FnType, ArgType};
 use trans::context::CrateContext;
 use trans::type_::Type;
@@ -85,10 +84,10 @@ fn ty_size(ty: Type) -> usize {
 
 fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
     if is_reg_ty(ty) {
-        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         ArgType::direct(ty, None, None, attr)
     } else {
-        ArgType::indirect(ty, Some(StructRetAttribute))
+        ArgType::indirect(ty, Some(Attribute::StructRetAttribute))
     }
 }
 
@@ -102,7 +101,7 @@ fn classify_arg_ty(ccx: &CrateContext, ty: Type, offset: &mut usize) -> ArgType
     *offset += align_up_to(size, align * 8) / 8;
 
     if is_reg_ty(ty) {
-        let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         ArgType::direct(ty, None, None, attr)
     } else {
         ArgType::direct(
diff --git a/src/librustc_trans/trans/cabi_x86.rs b/src/librustc_trans/trans/cabi_x86.rs
index 028d20f3084..d9c265d94a7 100644
--- a/src/librustc_trans/trans/cabi_x86.rs
+++ b/src/librustc_trans/trans/cabi_x86.rs
@@ -52,11 +52,11 @@ pub fn compute_abi_info(ccx: &CrateContext,
                 ret_ty = ArgType::direct(rty, Some(t), None, None);
             }
             RetPointer => {
-                ret_ty = ArgType::indirect(rty, Some(StructRetAttribute));
+                ret_ty = ArgType::indirect(rty, Some(Attribute::StructRetAttribute));
             }
         }
     } else {
-        let attr = if rty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if rty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         ret_ty = ArgType::direct(rty, None, None, attr);
     }
 
@@ -67,11 +67,11 @@ pub fn compute_abi_info(ccx: &CrateContext,
                 if size == 0 {
                     ArgType::ignore(t)
                 } else {
-                    ArgType::indirect(t, Some(ByValAttribute))
+                    ArgType::indirect(t, Some(Attribute::ByValAttribute))
                 }
             }
             _ => {
-                let attr = if t == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+                let attr = if t == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
                 ArgType::direct(t, None, None, attr)
             }
         };
diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs
index 8d946e2743b..d954a861a72 100644
--- a/src/librustc_trans/trans/cabi_x86_64.rs
+++ b/src/librustc_trans/trans/cabi_x86_64.rs
@@ -16,7 +16,6 @@ use self::RegClass::*;
 
 use llvm::{Integer, Pointer, Float, Double};
 use llvm::{Struct, Array, Attribute, Vector};
-use llvm::{StructRetAttribute, ByValAttribute, ZExtAttribute};
 use trans::cabi::{ArgType, FnType};
 use trans::context::CrateContext;
 use trans::type_::Type;
@@ -407,19 +406,19 @@ pub fn compute_abi_info(ccx: &CrateContext,
                                 None)
             }
         } else {
-            let attr = if ty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+            let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
             ArgType::direct(ty, None, None, attr)
         }
     }
 
     let mut arg_tys = Vec::new();
     for t in atys {
-        let ty = x86_64_ty(ccx, *t, |cls| cls.is_pass_byval(), ByValAttribute);
+        let ty = x86_64_ty(ccx, *t, |cls| cls.is_pass_byval(), Attribute::ByValAttribute);
         arg_tys.push(ty);
     }
 
     let ret_ty = if ret_def {
-        x86_64_ty(ccx, rty, |cls| cls.is_ret_bysret(), StructRetAttribute)
+        x86_64_ty(ccx, rty, |cls| cls.is_ret_bysret(), Attribute::StructRetAttribute)
     } else {
         ArgType::direct(Type::void(ccx), None, None, None)
     };
diff --git a/src/librustc_trans/trans/cabi_x86_win64.rs b/src/librustc_trans/trans/cabi_x86_win64.rs
index 9b34c3bf262..7808b9d27fe 100644
--- a/src/librustc_trans/trans/cabi_x86_win64.rs
+++ b/src/librustc_trans/trans/cabi_x86_win64.rs
@@ -31,10 +31,10 @@ pub fn compute_abi_info(ccx: &CrateContext,
             2 => ArgType::direct(rty, Some(Type::i16(ccx)), None, None),
             4 => ArgType::direct(rty, Some(Type::i32(ccx)), None, None),
             8 => ArgType::direct(rty, Some(Type::i64(ccx)), None, None),
-            _ => ArgType::indirect(rty, Some(StructRetAttribute))
+            _ => ArgType::indirect(rty, Some(Attribute::StructRetAttribute))
         };
     } else {
-        let attr = if rty == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+        let attr = if rty == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
         ret_ty = ArgType::direct(rty, None, None, attr);
     }
 
@@ -46,11 +46,11 @@ pub fn compute_abi_info(ccx: &CrateContext,
                     2 => ArgType::direct(rty, Some(Type::i16(ccx)), None, None),
                     4 => ArgType::direct(rty, Some(Type::i32(ccx)), None, None),
                     8 => ArgType::direct(rty, Some(Type::i64(ccx)), None, None),
-                    _ => ArgType::indirect(t, Some(ByValAttribute))
+                    _ => ArgType::indirect(t, Some(Attribute::ByValAttribute))
                 }
             }
             _ => {
-                let attr = if t == Type::i1(ccx) { Some(ZExtAttribute) } else { None };
+                let attr = if t == Type::i1(ccx) { Some(Attribute::ZExtAttribute) } else { None };
                 ArgType::direct(t, None, None, attr)
             }
         };
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index 9932899ed8f..3aaf4addd89 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -186,7 +186,7 @@ fn get_const_val(ccx: &CrateContext,
                  ref_expr: &ast::Expr) -> ValueRef {
     let expr = get_const_expr(ccx, def_id, ref_expr);
     let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
-    get_const_expr_as_global(ccx, expr, check_const::PURE_CONST, empty_substs)
+    get_const_expr_as_global(ccx, expr, check_const::ConstQualif::PURE_CONST, empty_substs)
 }
 
 pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
@@ -215,7 +215,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         Some(&val) => return val,
         None => {}
     }
-    let val = if qualif.intersects(check_const::NON_STATIC_BORROWS) {
+    let val = if qualif.intersects(check_const::ConstQualif::NON_STATIC_BORROWS) {
         // Avoid autorefs as they would create global instead of stack
         // references, even when only the latter are correct.
         let ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs,
diff --git a/src/librustc_trans/trans/declare.rs b/src/librustc_trans/trans/declare.rs
index 9e7449f670f..35946491ba1 100644
--- a/src/librustc_trans/trans/declare.rs
+++ b/src/librustc_trans/trans/declare.rs
@@ -71,12 +71,12 @@ pub fn declare_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty:
     llvm::SetUnnamedAddr(llfn, true);
 
     if output == ty::FnDiverging {
-        llvm::SetFunctionAttribute(llfn, llvm::NoReturnAttribute);
+        llvm::SetFunctionAttribute(llfn, llvm::Attribute::NoReturnAttribute);
     }
 
     if ccx.tcx().sess.opts.cg.no_redzone
         .unwrap_or(ccx.tcx().sess.target.target.options.disable_redzone) {
-        llvm::SetFunctionAttribute(llfn, llvm::NoRedZoneAttribute)
+        llvm::SetFunctionAttribute(llfn, llvm::Attribute::NoRedZoneAttribute)
     }
 
     if ccx.is_split_stack_supported() && !ccx.sess().opts.cg.no_stack_check {
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index 27919d645b6..f5ee44d69cc 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -126,8 +126,11 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 
     let qualif = *bcx.tcx().const_qualif_map.borrow().get(&expr.id).unwrap();
-    if !qualif.intersects(check_const::NOT_CONST | check_const::NEEDS_DROP) {
-        if !qualif.intersects(check_const::PREFER_IN_PLACE) {
+    if !qualif.intersects(
+        check_const::ConstQualif::NOT_CONST |
+        check_const::ConstQualif::NEEDS_DROP
+    ) {
+        if !qualif.intersects(check_const::ConstQualif::PREFER_IN_PLACE) {
             if let SaveIn(lldest) = dest {
                 let global = consts::get_const_expr_as_global(bcx.ccx(), expr, qualif,
                                                             bcx.fcx.param_substs);
@@ -209,12 +212,15 @@ pub fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let mut bcx = bcx;
     let fcx = bcx.fcx;
     let qualif = *bcx.tcx().const_qualif_map.borrow().get(&expr.id).unwrap();
-    let adjusted_global = !qualif.intersects(check_const::NON_STATIC_BORROWS);
-    let global = if !qualif.intersects(check_const::NOT_CONST | check_const::NEEDS_DROP) {
+    let adjusted_global = !qualif.intersects(check_const::ConstQualif::NON_STATIC_BORROWS);
+    let global = if !qualif.intersects(
+        check_const::ConstQualif::NOT_CONST |
+        check_const::ConstQualif::NEEDS_DROP
+    ) {
         let global = consts::get_const_expr_as_global(bcx.ccx(), expr, qualif,
                                                       bcx.fcx.param_substs);
 
-        if qualif.intersects(check_const::HAS_STATIC_BORROWS) {
+        if qualif.intersects(check_const::ConstQualif::HAS_STATIC_BORROWS) {
             // Is borrowed as 'static, must return lvalue.
 
             // Cast pointer to global, because constants have different types.
diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs
index c025be2ee98..d760b2c52ca 100644
--- a/src/librustc_trans/trans/foreign.rs
+++ b/src/librustc_trans/trans/foreign.rs
@@ -349,8 +349,8 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         // The outptr can be noalias and nocapture because it's entirely
         // invisible to the program. We also know it's nonnull as well
         // as how many bytes we can dereference
-        attrs.arg(1, llvm::NoAliasAttribute)
-             .arg(1, llvm::NoCaptureAttribute)
+        attrs.arg(1, llvm::Attribute::NoAliasAttribute)
+             .arg(1, llvm::Attribute::NoCaptureAttribute)
              .arg(1, llvm::DereferenceableAttribute(llret_sz));
     };
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 8473b24172e..6a84c6ace47 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -107,26 +107,27 @@
 #![doc(test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
 
 #![feature(alloc)]
+#![feature(allow_internal_unstable)]
+#![feature(associated_consts)]
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(core)]
+#![feature(debug_builders)]
+#![feature(into_cow)]
 #![feature(lang_items)]
 #![feature(libc)]
 #![feature(linkage, thread_local, asm)]
+#![feature(macro_reexport)]
 #![feature(optin_builtin_traits)]
 #![feature(rand)]
+#![feature(slice_patterns)]
 #![feature(staged_api)]
+#![feature(std_misc)]
+#![feature(str_char)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
-#![feature(unsafe_no_drop_flag, filling_drop)]
-#![feature(macro_reexport)]
 #![feature(unique)]
-#![feature(allow_internal_unstable)]
-#![feature(str_char)]
-#![feature(into_cow)]
-#![feature(std_misc)]
-#![feature(slice_patterns)]
-#![feature(debug_builders)]
+#![feature(unsafe_no_drop_flag, filling_drop)]
 #![feature(zero_one)]
 #![cfg_attr(test, feature(float_from_str_radix))]
 #![cfg_attr(test, feature(test, rustc_private, std_misc))]
@@ -307,13 +308,12 @@ mod std {
     pub use sync; // used for select!()
     pub use error; // used for try!()
     pub use fmt; // used for any formatting strings
-    pub use option; // used for bitflags!{}
+    pub use option; // used for thread_local!{}
     pub use rt; // used for panic!()
     pub use vec; // used for vec![]
     pub use cell; // used for tls!
     pub use thread; // used for thread_local!
     pub use marker;  // used for tls!
-    pub use ops; // used for bitflags!
 
     // The test runner calls ::std::env::args() but really wants realstd
     #[cfg(test)] pub use realstd::env as env;
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index d8beeb6a550..c22fba65837 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -25,13 +25,14 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
+#![feature(associated_consts)]
 #![feature(collections)]
 #![feature(core)]
 #![feature(libc)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(unicode)]
 #![feature(str_char)]
+#![feature(unicode)]
 
 extern crate arena;
 extern crate fmt_macros;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f76de1f04ce..5f76c214927 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -88,9 +88,9 @@ use std::slice;
 
 bitflags! {
     flags Restrictions: u8 {
-        const UNRESTRICTED                  = 0b0000,
-        const RESTRICTION_STMT_EXPR         = 0b0001,
-        const RESTRICTION_NO_STRUCT_LITERAL = 0b0010,
+        const UNRESTRICTED                  = 0,
+        const RESTRICTION_STMT_EXPR         = 1 << 0,
+        const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1,
     }
 }
 
@@ -339,7 +339,7 @@ impl<'a> Parser<'a> {
             buffer_start: 0,
             buffer_end: 0,
             tokens_consumed: 0,
-            restrictions: UNRESTRICTED,
+            restrictions: Restrictions::UNRESTRICTED,
             quote_depth: 0,
             obsolete_set: HashSet::new(),
             mod_path_stack: Vec::new(),
@@ -2198,7 +2198,10 @@ impl<'a> Parser<'a> {
                     if self.check(&token::OpenDelim(token::Brace)) {
                         // This is a struct literal, unless we're prohibited
                         // from parsing struct literals here.
-                        if !self.restrictions.contains(RESTRICTION_NO_STRUCT_LITERAL) {
+                        let prohibited = self.restrictions.contains(
+                            Restrictions::RESTRICTION_NO_STRUCT_LITERAL
+                        );
+                        if !prohibited {
                             // It's a struct literal.
                             try!(self.bump());
                             let mut fields = Vec::new();
@@ -2759,7 +2762,7 @@ impl<'a> Parser<'a> {
     }
 
     pub fn parse_assign_expr_with(&mut self, lhs: P<Expr>) -> PResult<P<Expr>> {
-        let restrictions = self.restrictions & RESTRICTION_NO_STRUCT_LITERAL;
+        let restrictions = self.restrictions & Restrictions::RESTRICTION_NO_STRUCT_LITERAL;
         let op_span = self.span;
         match self.token {
           token::Eq => {
@@ -2814,7 +2817,7 @@ impl<'a> Parser<'a> {
         if self.token.can_begin_expr() {
             // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
             if self.token == token::OpenDelim(token::Brace) {
-                return !self.restrictions.contains(RESTRICTION_NO_STRUCT_LITERAL);
+                return !self.restrictions.contains(Restrictions::RESTRICTION_NO_STRUCT_LITERAL);
             }
             true
         } else {
@@ -2828,7 +2831,7 @@ impl<'a> Parser<'a> {
             return self.parse_if_let_expr();
         }
         let lo = self.last_span.lo;
-        let cond = try!(self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL));
+        let cond = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
         let thn = try!(self.parse_block());
         let mut els: Option<P<Expr>> = None;
         let mut hi = thn.span.hi;
@@ -2846,7 +2849,7 @@ impl<'a> Parser<'a> {
         try!(self.expect_keyword(keywords::Let));
         let pat = try!(self.parse_pat_nopanic());
         try!(self.expect(&token::Eq));
-        let expr = try!(self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL));
+        let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
         let thn = try!(self.parse_block());
         let (hi, els) = if try!(self.eat_keyword(keywords::Else) ){
             let expr = try!(self.parse_else_expr());
@@ -2905,7 +2908,7 @@ impl<'a> Parser<'a> {
         let lo = self.last_span.lo;
         let pat = try!(self.parse_pat_nopanic());
         try!(self.expect_keyword(keywords::In));
-        let expr = try!(self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL));
+        let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
         let loop_block = try!(self.parse_block());
         let hi = self.last_span.hi;
 
@@ -2918,7 +2921,7 @@ impl<'a> Parser<'a> {
             return self.parse_while_let_expr(opt_ident);
         }
         let lo = self.last_span.lo;
-        let cond = try!(self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL));
+        let cond = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
         let body = try!(self.parse_block());
         let hi = body.span.hi;
         return Ok(self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident)));
@@ -2930,7 +2933,7 @@ impl<'a> Parser<'a> {
         try!(self.expect_keyword(keywords::Let));
         let pat = try!(self.parse_pat_nopanic());
         try!(self.expect(&token::Eq));
-        let expr = try!(self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL));
+        let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
         let body = try!(self.parse_block());
         let hi = body.span.hi;
         return Ok(self.mk_expr(lo, hi, ExprWhileLet(pat, expr, body, opt_ident)));
@@ -2945,7 +2948,7 @@ impl<'a> Parser<'a> {
 
     fn parse_match_expr(&mut self) -> PResult<P<Expr>> {
         let lo = self.last_span.lo;
-        let discriminant = try!(self.parse_expr_res(RESTRICTION_NO_STRUCT_LITERAL));
+        let discriminant = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL));
         try!(self.commit_expr_expecting(&*discriminant, token::OpenDelim(token::Brace)));
         let mut arms: Vec<Arm> = Vec::new();
         while self.token != token::CloseDelim(token::Brace) {
@@ -2966,7 +2969,7 @@ impl<'a> Parser<'a> {
             guard = Some(try!(self.parse_expr_nopanic()));
         }
         try!(self.expect(&token::FatArrow));
-        let expr = try!(self.parse_expr_res(RESTRICTION_STMT_EXPR));
+        let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_STMT_EXPR));
 
         let require_comma =
             !classify::expr_is_simple_block(&*expr)
@@ -2988,7 +2991,7 @@ impl<'a> Parser<'a> {
 
     /// Parse an expression
     pub fn parse_expr_nopanic(&mut self) -> PResult<P<Expr>> {
-        return self.parse_expr_res(UNRESTRICTED);
+        return self.parse_expr_res(Restrictions::UNRESTRICTED);
     }
 
     /// Parse an expression, subject to the given restrictions
@@ -3564,7 +3567,7 @@ impl<'a> Parser<'a> {
                     }
 
                     // Remainder are line-expr stmts.
-                    let e = try!(self.parse_expr_res(RESTRICTION_STMT_EXPR));
+                    let e = try!(self.parse_expr_res(Restrictions::RESTRICTION_STMT_EXPR));
                     spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID))
                 }
             }
@@ -3573,7 +3576,7 @@ impl<'a> Parser<'a> {
 
     /// Is this expression a successfully-parsed statement?
     fn expr_is_complete(&mut self, e: &Expr) -> bool {
-        self.restrictions.contains(RESTRICTION_STMT_EXPR) &&
+        self.restrictions.contains(Restrictions::RESTRICTION_STMT_EXPR) &&
             !classify::expr_requires_semi_to_be_stmt(e)
     }