diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index b812073c3a8..3a329164e51 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -593,6 +593,7 @@ impl LintPass for UnusedAttribute {
             "static_assert",
             "thread_local",
             "no_debug",
+            "unsafe_no_drop_flag",
 
             // used in resolve
             "prelude_import",
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index 3ec91bf9840..2a8aa791c61 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -214,6 +214,8 @@ pub static tag_reachable_extern_fn_id: uint = 0x91;
 
 pub static tag_items_data_item_stability: uint = 0x92;
 
+pub static tag_items_data_item_repr: uint = 0x93;
+
 #[deriving(Clone, Show)]
 pub struct LinkMeta {
     pub crate_name: String,
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index c8ed926d6fe..f0ec5beec46 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -350,6 +350,12 @@ pub fn get_stability(cstore: &cstore::CStore,
     decoder::get_stability(&*cdata, def.node)
 }
 
+pub fn get_repr_attrs(cstore: &cstore::CStore, def: ast::DefId)
+                      -> Vec<attr::ReprAttr> {
+    let cdata = cstore.get_crate_data(def.krate);
+    decoder::get_repr_attrs(&*cdata, def.node)
+}
+
 pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::is_associated_type(&*cdata, def.node)
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index ac7f83cb385..44f6f5f5470 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -384,6 +384,17 @@ pub fn get_stability(cdata: Cmd, id: ast::NodeId) -> Option<attr::Stability> {
     })
 }
 
+pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
+    let item = lookup_item(id, cdata.data());
+    match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| {
+        let mut decoder = reader::Decoder::new(doc);
+        Decodable::decode(&mut decoder).unwrap()
+    }) {
+        Some(attrs) => attrs,
+        None => Vec::new(),
+    }
+}
+
 pub fn get_impl_trait(cdata: Cmd,
                       id: ast::NodeId,
                       tcx: &ty::ctxt) -> Option<Rc<ty::TraitRef>>
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index d27a0d27c7b..f8cf7887924 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -332,6 +332,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
         encode_parent_item(rbml_w, local_def(id));
         encode_visibility(rbml_w, variant.node.vis);
         encode_attributes(rbml_w, variant.node.attrs.as_slice());
+        encode_repr_attrs(rbml_w, ecx, variant.node.attrs.as_slice());
 
         let stab = stability::lookup(ecx.tcx, ast_util::local_def(variant.node.id));
         encode_stability(rbml_w, stab);
@@ -948,6 +949,19 @@ fn encode_method_argument_names(rbml_w: &mut Encoder,
     rbml_w.end_tag();
 }
 
+fn encode_repr_attrs(rbml_w: &mut Encoder,
+                     ecx: &EncodeContext,
+                     attrs: &[Attribute]) {
+    let mut repr_attrs = Vec::new();
+    for attr in attrs.iter() {
+        repr_attrs.extend(attr::find_repr_attrs(ecx.tcx.sess.diagnostic(),
+                                                attr).into_iter());
+    }
+    rbml_w.start_tag(tag_items_data_item_repr);
+    repr_attrs.encode(rbml_w);
+    rbml_w.end_tag();
+}
+
 fn encode_inlined_item(ecx: &EncodeContext,
                        rbml_w: &mut Encoder,
                        ii: InlinedItemRef) {
@@ -1137,6 +1151,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_bounds_and_type(rbml_w, ecx, &lookup_item_type(tcx, def_id));
         encode_name(rbml_w, item.ident.name);
         encode_attributes(rbml_w, item.attrs.as_slice());
+        encode_repr_attrs(rbml_w, ecx, item.attrs.as_slice());
         for v in (*enum_definition).variants.iter() {
             encode_variant_id(rbml_w, local_def(v.node.id));
         }
@@ -1183,6 +1198,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         encode_path(rbml_w, path.clone());
         encode_stability(rbml_w, stab);
         encode_visibility(rbml_w, vis);
+        encode_repr_attrs(rbml_w, ecx, item.attrs.as_slice());
 
         /* Encode def_ids for each field and method
          for methods, write all the stuff get_trait_method
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 875a79373a6..94c6c7bc757 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -583,6 +583,9 @@ pub struct ctxt<'tcx> {
     /// Caches the results of trait selection. This cache is used
     /// for things that do not have to do with the parameters in scope.
     pub selection_cache: traits::SelectionCache,
+
+    /// Caches the representation hints for struct definitions.
+    pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
 }
 
 pub enum tbox_flag {
@@ -1533,6 +1536,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         associated_types: RefCell::new(DefIdMap::new()),
         trait_associated_types: RefCell::new(DefIdMap::new()),
         selection_cache: traits::SelectionCache::new(),
+        repr_hint_cache: RefCell::new(DefIdMap::new()),
    }
 }
 
@@ -4326,7 +4330,7 @@ pub fn ty_dtor(cx: &ctxt, struct_id: DefId) -> DtorKind {
 }
 
 pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
-    ty_dtor(cx, struct_id).is_present()
+    cx.destructor_for_type.borrow().contains_key(&struct_id)
 }
 
 pub fn with_path<T>(cx: &ctxt, id: ast::DefId, f: |ast_map::PathElems| -> T) -> T {
@@ -4513,14 +4517,26 @@ pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool {
 }
 
 /// Obtain the representation annotation for a struct definition.
-pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Vec<attr::ReprAttr> {
-    let mut acc = Vec::new();
+pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
+    match tcx.repr_hint_cache.borrow().find(&did) {
+        None => {}
+        Some(ref hints) => return (*hints).clone(),
+    }
 
-    ty::each_attr(tcx, did, |meta| {
-        acc.extend(attr::find_repr_attrs(tcx.sess.diagnostic(), meta).into_iter());
-        true
-    });
+    let acc = if did.krate == LOCAL_CRATE {
+        let mut acc = Vec::new();
+        ty::each_attr(tcx, did, |meta| {
+            acc.extend(attr::find_repr_attrs(tcx.sess.diagnostic(),
+                                             meta).into_iter());
+            true
+        });
+        acc
+    } else {
+        csearch::get_repr_attrs(&tcx.sess.cstore, did)
+    };
 
+    let acc = Rc::new(acc);
+    tcx.repr_hint_cache.borrow_mut().insert(did, acc.clone());
     acc
 }
 
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index efc75de7142..8963185192a 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -508,7 +508,7 @@ fn int_type_of_word(s: &str) -> Option<IntType> {
     }
 }
 
-#[deriving(PartialEq, Show)]
+#[deriving(PartialEq, Show, Encodable, Decodable)]
 pub enum ReprAttr {
     ReprAny,
     ReprInt(Span, IntType),
@@ -527,7 +527,7 @@ impl ReprAttr {
     }
 }
 
-#[deriving(Eq, Hash, PartialEq, Show)]
+#[deriving(Eq, Hash, PartialEq, Show, Encodable, Decodable)]
 pub enum IntType {
     SignedInt(ast::IntTy),
     UnsignedInt(ast::UintTy)