diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index b812073c3a82a..3a329164e512b 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 3ec91bf984052..2a8aa791c61a6 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 c8ed926d6fe48..f0ec5beec4607 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 { + 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 ac7f83cb385c2..44f6f5f547093 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 { }) } +pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec { + 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> diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index d27a0d27c7b62..f8cf7887924ba 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 875a79373a69d..94c6c7bc757d1 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>>>, } 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(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 { - let mut acc = Vec::new(); +pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc> { + 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 efc75de7142b8..8963185192a8b 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -508,7 +508,7 @@ fn int_type_of_word(s: &str) -> Option { } } -#[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)