From bc8983a3fa44f0c35c7fe669913ca7ea82758125 Mon Sep 17 00:00:00 2001 From: David Manescu Date: Thu, 30 Jan 2014 23:36:05 +1100 Subject: [PATCH] Handle attributes on cross-crate tuple-structs correctly Fixes #11741 --- src/librustc/metadata/common.rs | 2 ++ src/librustc/metadata/decoder.rs | 17 ++++++++++++ src/librustc/metadata/encoder.rs | 6 +++++ src/test/auxiliary/lint_stability.rs | 14 ++++++++++ src/test/compile-fail/lint-stability.rs | 30 ++++++++++++++++++++++ src/test/compile-fail/simd-experimental.rs | 2 -- 6 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index e8cfa97c0e1..35bfb02f2aa 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -35,6 +35,8 @@ pub static tag_items_data_item_variant: uint = 0x0eu; pub static tag_items_data_parent_item: uint = 0x0fu; +pub static tag_items_data_item_is_tuple_struct_ctor: uint = 0x10u; + pub static tag_index: uint = 0x11u; pub static tag_index_buckets: uint = 0x12u; diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 11fab9cced7..6496d1c842e 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -980,9 +980,26 @@ pub fn get_static_methods_if_impl(intr: @IdentInterner, return Some(static_impl_methods); } +/// If node_id is the constructor of a tuple struct, retrieve the NodeId of +/// the actual type definition, otherwise, return None +pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, + node_id: ast::NodeId) -> Option { + let item = lookup_item(node_id, cdata.data()); + let mut ret = None; + reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor, |_| { + ret = Some(item_reqd_and_translated_parent_item(cdata.cnum, item)); + false + }); + ret.map(|x| x.node) +} + pub fn get_item_attrs(cdata: Cmd, node_id: ast::NodeId, f: |~[@ast::MetaItem]|) { + // The attributes for a tuple struct are attached to the definition, not the ctor; + // we assume that someone passing in a tuple struct ctor is actually wanting to + // look at the definition + let node_id = get_tuple_struct_definition_if_ctor(cdata, node_id).unwrap_or(node_id); let item = lookup_item(node_id, cdata.data()); reader::tagged_docs(item, tag_attributes, |attributes| { reader::tagged_docs(attributes, tag_attribute, |attribute| { diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index ac3ee78fb86..e35f8d85ca9 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -778,6 +778,12 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext, encode_symbol(ecx, ebml_w, ctor_id); } + // indicate that this is a tuple struct ctor, because downstream users will normally want + // the tuple struct definition, but without this there is no way for them to tell that + // they actually have a ctor rather than a normal function + ebml_w.start_tag(tag_items_data_item_is_tuple_struct_ctor); + ebml_w.end_tag(); + ebml_w.end_tag(); } diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs index 108b715c0fb..4e71f3c0c2a 100644 --- a/src/test/auxiliary/lint_stability.rs +++ b/src/test/auxiliary/lint_stability.rs @@ -159,3 +159,17 @@ pub enum Enum { #[locked] LockedVariant, } + +#[deprecated] +pub struct DeprecatedTupleStruct(int); +#[experimental] +pub struct ExperimentalTupleStruct(int); +#[unstable] +pub struct UnstableTupleStruct(int); +pub struct UnmarkedTupleStruct(int); +#[stable] +pub struct StableTupleStruct(int); +#[frozen] +pub struct FrozenTupleStruct(int); +#[locked] +pub struct LockedTupleStruct(int); diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs index ee683d4de46..1164028ca1a 100644 --- a/src/test/compile-fail/lint-stability.rs +++ b/src/test/compile-fail/lint-stability.rs @@ -101,6 +101,14 @@ mod cross_crate { let _ = StableVariant; let _ = FrozenVariant; let _ = LockedVariant; + + let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item + let _ = ExperimentalTupleStruct (1); //~ ERROR use of experimental item + let _ = UnstableTupleStruct (1); //~ ERROR use of unstable item + let _ = UnmarkedTupleStruct (1); //~ ERROR use of unmarked item + let _ = StableTupleStruct (1); + let _ = FrozenTupleStruct (1); + let _ = LockedTupleStruct (1); } fn test_method_param(foo: F) { @@ -277,6 +285,20 @@ mod this_crate { LockedVariant, } + #[deprecated] + pub struct DeprecatedTupleStruct(int); + #[experimental] + pub struct ExperimentalTupleStruct(int); + #[unstable] + pub struct UnstableTupleStruct(int); + pub struct UnmarkedTupleStruct(int); + #[stable] + pub struct StableTupleStruct(int); + #[frozen] + pub struct FrozenTupleStruct(int); + #[locked] + pub struct LockedTupleStruct(int); + fn test() { let foo = MethodTester; @@ -356,6 +378,14 @@ mod this_crate { let _ = StableVariant; let _ = FrozenVariant; let _ = LockedVariant; + + let _ = DeprecatedTupleStruct (1); //~ ERROR use of deprecated item + let _ = ExperimentalTupleStruct (1); //~ ERROR use of experimental item + let _ = UnstableTupleStruct (1); //~ ERROR use of unstable item + let _ = UnmarkedTupleStruct (1); //~ ERROR use of unmarked item + let _ = StableTupleStruct (1); + let _ = FrozenTupleStruct (1); + let _ = LockedTupleStruct (1); } fn test_method_param(foo: F) { diff --git a/src/test/compile-fail/simd-experimental.rs b/src/test/compile-fail/simd-experimental.rs index 2ed4317d52d..64c045366e1 100644 --- a/src/test/compile-fail/simd-experimental.rs +++ b/src/test/compile-fail/simd-experimental.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-test FIXME #11741 tuple structs ignore stability attributes - #[deny(experimental)]; use std::unstable::simd;