about summary refs log tree commit diff
path: root/compiler/rustc_resolve/src/lib.rs
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2025-01-21 21:07:20 +0000
committerEsteban Küber <esteban@kuber.com.ar>2025-08-10 19:15:18 +0000
commit464a6b1b4af28f7b2d1adf051bad3f182e23b88e (patch)
tree33f8b9d8e302ee705b99b74923c63c20bc96b97e /compiler/rustc_resolve/src/lib.rs
parent18eeac04fc5c2a4c4a8020dbdf1c652077ad0e4e (diff)
downloadrust-464a6b1b4af28f7b2d1adf051bad3f182e23b88e.tar.gz
rust-464a6b1b4af28f7b2d1adf051bad3f182e23b88e.zip
Detect struct construction with private field in field with default
When trying to construct a struct that has a public field of a private type, suggest using `..` if that field has a default value.

```
error[E0603]: struct `Priv1` is private
  --> $DIR/non-exhaustive-ctor.rs:25:39
   |
LL |     let _ = S { field: (), field1: m::Priv1 {} };
   |                            ------     ^^^^^ private struct
   |                            |
   |                            while setting this field
   |
note: the struct `Priv1` is defined here
  --> $DIR/non-exhaustive-ctor.rs:14:4
   |
LL |    struct Priv1 {}
   |    ^^^^^^^^^^^^
help: the field `field1` you're trying to set has a default value, you can use `..` to use it
   |
LL |     let _ = S { field: (), .. };
   |                            ~~
```
Diffstat (limited to 'compiler/rustc_resolve/src/lib.rs')
-rw-r--r--compiler/rustc_resolve/src/lib.rs18
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 23f44ff1658..b43f71913d9 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -822,6 +822,7 @@ struct PrivacyError<'ra> {
     parent_scope: ParentScope<'ra>,
     /// Is the format `use a::{b,c}`?
     single_nested: bool,
+    source: Option<ast::Expr>,
 }
 
 #[derive(Debug)]
@@ -1064,6 +1065,7 @@ pub struct Resolver<'ra, 'tcx> {
 
     /// N.B., this is used only for better diagnostics, not name resolution itself.
     field_names: LocalDefIdMap<Vec<Ident>>,
+    field_defaults: LocalDefIdMap<Vec<Symbol>>,
 
     /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax.
     /// Used for hints during error reporting.
@@ -1538,6 +1540,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             extern_prelude,
 
             field_names: Default::default(),
+            field_defaults: Default::default(),
             field_visibility_spans: FxHashMap::default(),
 
             determined_imports: Vec::new(),
@@ -2318,6 +2321,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         }
     }
 
+    fn field_defaults(&self, def_id: DefId) -> Option<Vec<Symbol>> {
+        match def_id.as_local() {
+            Some(def_id) => self.field_defaults.get(&def_id).cloned(),
+            None => Some(
+                self.tcx
+                    .associated_item_def_ids(def_id)
+                    .iter()
+                    .filter_map(|&def_id| {
+                        self.tcx.default_field(def_id).map(|_| self.tcx.item_name(def_id))
+                    })
+                    .collect(),
+            ),
+        }
+    }
+
     /// Checks if an expression refers to a function marked with
     /// `#[rustc_legacy_const_generics]` and returns the argument index list
     /// from the attribute.