about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs13
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs18
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs21
-rw-r--r--src/test/ui/issues/auxiliary/issue-75907.rs12
-rw-r--r--src/test/ui/issues/issue-75907_b.rs5
-rw-r--r--src/test/ui/issues/issue-75907_b.stderr26
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/struct.stderr2
7 files changed, 83 insertions, 14 deletions
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index e2e523fad66..de5279c4a8d 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -27,7 +27,7 @@ use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_middle::mir::{self, Body, Promoted};
 use rustc_middle::ty::codec::TyDecoder;
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
 use rustc_serialize::{opaque, Decodable, Decoder};
 use rustc_session::Session;
 use rustc_span::hygiene::ExpnDataDecodeMode;
@@ -1312,6 +1312,17 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .collect()
     }
 
+    fn get_struct_field_visibilities(&self, id: DefIndex) -> Vec<Visibility> {
+        self.root
+            .tables
+            .children
+            .get(self, id)
+            .unwrap_or_else(Lazy::empty)
+            .decode(self)
+            .map(|field_index| self.get_visibility(field_index))
+            .collect()
+    }
+
     fn get_inherent_implementations_for_type(
         &self,
         tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index cda57f48cae..82ca634f282 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -8,7 +8,7 @@ use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_data_structures::stable_map::FxHashMap;
 use rustc_data_structures::svh::Svh;
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
 use rustc_middle::hir::exports::Export;
@@ -17,7 +17,7 @@ use rustc_middle::middle::cstore::{CrateSource, CrateStore, EncodedMetadata};
 use rustc_middle::middle::exported_symbols::ExportedSymbol;
 use rustc_middle::middle::stability::DeprecationEntry;
 use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt, Visibility};
 use rustc_session::utils::NativeLibKind;
 use rustc_session::{CrateDisambiguator, Session};
 use rustc_span::source_map::{Span, Spanned};
@@ -392,6 +392,20 @@ impl CStore {
         self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
     }
 
+    pub fn struct_field_visibilities_untracked(&self, def: DefId) -> Vec<Visibility> {
+        self.get_crate_data(def.krate).get_struct_field_visibilities(def.index)
+    }
+
+    pub fn ctor_def_id_and_kind_untracked(&self, def: DefId) -> Option<(DefId, CtorKind)> {
+        self.get_crate_data(def.krate).get_ctor_def_id(def.index).map(|ctor_def_id| {
+            (ctor_def_id, self.get_crate_data(def.krate).get_ctor_kind(def.index))
+        })
+    }
+
+    pub fn visibility_untracked(&self, def: DefId) -> Visibility {
+        self.get_crate_data(def.krate).get_visibility(def.index)
+    }
+
     pub fn item_children_untracked(
         &self,
         def_id: DefId,
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index b5c95cfcb29..e10314a11fc 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -995,7 +995,20 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         // Record some extra data for better diagnostics.
         let cstore = self.r.cstore();
         match res {
-            Res::Def(DefKind::Struct | DefKind::Union, def_id) => {
+            Res::Def(DefKind::Struct, def_id) => {
+                let field_names = cstore.struct_field_names_untracked(def_id, self.r.session);
+                let ctor = cstore.ctor_def_id_and_kind_untracked(def_id);
+                if let Some((ctor_def_id, ctor_kind)) = ctor {
+                    let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
+                    let ctor_vis = cstore.visibility_untracked(ctor_def_id);
+                    let field_visibilities = cstore.struct_field_visibilities_untracked(def_id);
+                    self.r
+                        .struct_constructors
+                        .insert(def_id, (ctor_res, ctor_vis, field_visibilities));
+                }
+                self.insert_field_names(def_id, field_names);
+            }
+            Res::Def(DefKind::Union, def_id) => {
                 let field_names = cstore.struct_field_names_untracked(def_id, self.r.session);
                 self.insert_field_names(def_id, field_names);
             }
@@ -1007,12 +1020,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                     self.r.has_self.insert(def_id);
                 }
             }
-            Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => {
-                let parent = cstore.def_key(def_id).parent;
-                if let Some(struct_def_id) = parent.map(|index| DefId { index, ..def_id }) {
-                    self.r.struct_constructors.insert(struct_def_id, (res, vis, vec![]));
-                }
-            }
             _ => {}
         }
     }
diff --git a/src/test/ui/issues/auxiliary/issue-75907.rs b/src/test/ui/issues/auxiliary/issue-75907.rs
index 0b70452a24d..389c9c35101 100644
--- a/src/test/ui/issues/auxiliary/issue-75907.rs
+++ b/src/test/ui/issues/auxiliary/issue-75907.rs
@@ -3,3 +3,15 @@ pub struct Bar(pub u8, u8, u8);
 pub fn make_bar() -> Bar {
     Bar(1, 12, 10)
 }
+
+mod inner {
+    pub struct Foo(u8, pub u8, u8);
+
+    impl Foo {
+        pub fn new() -> Foo {
+            Foo(1, 12, 10)
+        }
+    }
+}
+
+pub use inner::Foo;
diff --git a/src/test/ui/issues/issue-75907_b.rs b/src/test/ui/issues/issue-75907_b.rs
index a775845279e..e3074778233 100644
--- a/src/test/ui/issues/issue-75907_b.rs
+++ b/src/test/ui/issues/issue-75907_b.rs
@@ -3,9 +3,12 @@
 
 extern crate issue_75907 as a;
 
-use a::{make_bar, Bar};
+use a::{make_bar, Bar, Foo};
 
 fn main() {
     let Bar(x, y, z) = make_bar();
     //~^ ERROR cannot match against a tuple struct which contains private fields
+
+    let Foo(x, y, z) = Foo::new();
+    //~^ ERROR cannot match against a tuple struct which contains private fields
 }
diff --git a/src/test/ui/issues/issue-75907_b.stderr b/src/test/ui/issues/issue-75907_b.stderr
index 8884484e18d..b82d08473c8 100644
--- a/src/test/ui/issues/issue-75907_b.stderr
+++ b/src/test/ui/issues/issue-75907_b.stderr
@@ -2,8 +2,30 @@ error[E0532]: cannot match against a tuple struct which contains private fields
   --> $DIR/issue-75907_b.rs:9:9
    |
 LL |     let Bar(x, y, z) = make_bar();
-   |         ^^^ constructor is not visible here due to private fields
+   |         ^^^
+   |
+note: constructor is not visible here due to private fields
+  --> $DIR/issue-75907_b.rs:9:16
+   |
+LL |     let Bar(x, y, z) = make_bar();
+   |                ^  ^ private field
+   |                |
+   |                private field
+
+error[E0532]: cannot match against a tuple struct which contains private fields
+  --> $DIR/issue-75907_b.rs:12:9
+   |
+LL |     let Foo(x, y, z) = Foo::new();
+   |         ^^^
+   |
+note: constructor is not visible here due to private fields
+  --> $DIR/issue-75907_b.rs:12:13
+   |
+LL |     let Foo(x, y, z) = Foo::new();
+   |             ^     ^ private field
+   |             |
+   |             private field
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0532`.
diff --git a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr
index e2ee8d6a6fe..d023ba3096e 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr
@@ -2,7 +2,7 @@ error[E0423]: cannot initialize a tuple struct which contains private fields
   --> $DIR/struct.rs:20:14
    |
 LL |     let ts = TupleStruct(640, 480);
-   |              ^^^^^^^^^^^ constructor is not visible here due to private fields
+   |              ^^^^^^^^^^^
 
 error[E0423]: expected value, found struct `UnitStruct`
   --> $DIR/struct.rs:29:14