From eafdc7135b79d2e51da740b67946512d949632a1 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 25 Feb 2015 22:37:12 +1100 Subject: [PATCH] Record the publicity of struct fields and enum variants. The stability check checks the `PublicItems` map when giving errors if there is a #[stable] item with a public contents that doesn't not have its own stability. Without recording this, struct fields and enum variants will not get errors for e.g. stable modules with unmarked functions internally. This is just improving the compiler's precision to give the standard library developers more information earlier. E.g. #![staged_api] #![feature(staged_api)] #![crate_type = "lib"] #[stable(feature = "rust1", since = "1.0.0")] pub struct Foo { pub x: i32 } #[stable(feature = "rust1", since = "1.0.0")] pub mod bar { pub fn baz() {} } Without the patch it gives: test.rs:12:5: 12:20 error: This node does not have a stability attribute test.rs:12 pub fn baz() {} ^~~~~~~~~~~~~~~ error: aborting due to previous error With the patch it gives: test.rs:7:9: 7:15 error: This node does not have a stability attribute test.rs:7 pub x: i32 ^~~~~~ test.rs:12:5: 12:20 error: This node does not have a stability attribute test.rs:12 pub fn baz() {} ^~~~~~~~~~~~~~~ error: aborting due to 2 previous errors --- src/librustc_privacy/lib.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 436a826687e1..46729988bb6b 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -233,6 +233,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { ast::ItemEnum(ref def, _) if public_first => { for variant in &def.variants { self.exported_items.insert(variant.node.id); + self.public_items.insert(variant.node.id); } } @@ -321,6 +322,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> { Some(id) => { self.exported_items.insert(id); } None => {} } + // fields can be public or private, so lets check + for field in &def.fields { + let vis = match field.node.kind { + ast::NamedField(_, vis) | ast::UnnamedField(vis) => vis + }; + if vis == ast::Public { + self.public_items.insert(field.node.id); + } + } } ast::ItemTy(ref ty, _) if public_first => {