about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_typeck/Cargo.toml1
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs69
-rw-r--r--src/test/ui/issues/issue-76077.stderr6
-rw-r--r--src/test/ui/privacy/issue-79593.stderr6
-rw-r--r--src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr6
-rw-r--r--src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr10
7 files changed, 33 insertions, 66 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cc0f4cc53e6..df6f46f26cf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4590,7 +4590,6 @@ dependencies = [
 name = "rustc_typeck"
 version = "0.0.0"
 dependencies = [
- "itertools",
  "rustc_arena",
  "rustc_ast",
  "rustc_attr",
diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml
index b3dd6955080..c08023ee6a7 100644
--- a/compiler/rustc_typeck/Cargo.toml
+++ b/compiler/rustc_typeck/Cargo.toml
@@ -10,7 +10,6 @@ doctest = false
 [dependencies]
 rustc_arena = { path = "../rustc_arena" }
 tracing = "0.1"
-itertools = "0.10.1"
 rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_attr = { path = "../rustc_attr" }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 0a017de80f2..e5048fc5132 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -23,13 +23,12 @@ use crate::type_error_struct;
 
 use super::suggest_call_constructor;
 use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
-use itertools::{Either, Itertools};
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::{
     pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticId,
-    EmissionGuarantee, ErrorGuaranteed, MultiSpan,
+    EmissionGuarantee, ErrorGuaranteed,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
@@ -1682,11 +1681,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 })
                 .collect();
 
-            if !private_fields.is_empty()
-                && tcx
-                    .visibility(variant.def_id)
-                    .is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
-            {
+            if !private_fields.is_empty() {
                 self.report_private_fields(adt_ty, span, private_fields, ast_fields);
             } else {
                 self.report_missing_fields(
@@ -1826,12 +1821,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         private_fields: Vec<&ty::FieldDef>,
         used_fields: &'tcx [hir::ExprField<'tcx>],
     ) {
-        let field_names = |fields: Vec<Symbol>, len: usize| match &fields
+        let mut err = self.tcx.sess.struct_span_err(
+            span,
+            &format!(
+                "cannot construct `{adt_ty}` with struct literal syntax due to private fields",
+            ),
+        );
+        let (used_private_fields, remaining_private_fields): (
+            Vec<(Symbol, Span, bool)>,
+            Vec<(Symbol, Span, bool)>,
+        ) = private_fields
+            .iter()
+            .map(|field| {
+                match used_fields.iter().find(|used_field| field.name == used_field.ident.name) {
+                    Some(used_field) => (field.name, used_field.span, true),
+                    None => (field.name, self.tcx.def_span(field.did), false),
+                }
+            })
+            .partition(|field| field.2);
+        let remaining_private_fields_len = remaining_private_fields.len();
+        let names = match &remaining_private_fields
             .iter()
-            .map(|field| field.to_string())
+            .map(|(name, _, _)| name.to_string())
             .collect::<Vec<_>>()[..]
         {
-            _ if len > 6 => String::new(),
+            _ if remaining_private_fields_len > 6 => String::new(),
             [name] => format!("`{name}` "),
             [names @ .., last] => {
                 let names = names.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
@@ -1839,36 +1853,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             [] => unreachable!(),
         };
-
-        let mut err = self.tcx.sess.struct_span_err(
-            span,
-            &format!(
-                "cannot construct `{adt_ty}` with struct literal syntax due to private fields",
-            ),
-        );
-        let (used_private_fields, remaining_private_fields): (
-            Vec<(Symbol, Span)>,
-            Vec<(Symbol, Span)>,
-        ) = private_fields.iter().partition_map(|field| {
-            match used_fields.iter().find(|used_field| field.name == used_field.ident.name) {
-                Some(used_field) => Either::Left((field.name, used_field.span)),
-                None => Either::Right((field.name, self.tcx.def_span(field.did))),
-            }
-        });
-        let remaining_private_fields_len = remaining_private_fields.len();
-        err.span_labels(used_private_fields.iter().map(|(_, span)| *span), "private field");
-        err.span_note(
-            MultiSpan::from_spans(remaining_private_fields.iter().map(|(_, span)| *span).collect()),
-            format!(
-                "missing field{s} {names}{are} private",
-                s = pluralize!(remaining_private_fields_len),
-                are = pluralize!("is", remaining_private_fields_len),
-                names = field_names(
-                    remaining_private_fields.iter().map(|(name, _)| *name).collect(),
-                    remaining_private_fields_len
-                )
-            ),
-        );
+        err.span_labels(used_private_fields.iter().map(|(_, span, _)| *span), "private field");
+        err.note(format!(
+            "... and other private field{s} {names}that were not provided",
+            s = pluralize!(remaining_private_fields_len),
+        ));
         err.emit();
     }
 
diff --git a/src/test/ui/issues/issue-76077.stderr b/src/test/ui/issues/issue-76077.stderr
index c70a928f647..57f7abe3931 100644
--- a/src/test/ui/issues/issue-76077.stderr
+++ b/src/test/ui/issues/issue-76077.stderr
@@ -4,11 +4,7 @@ error: cannot construct `Foo` with struct literal syntax due to private fields
 LL |     foo::Foo {};
    |     ^^^^^^^^
    |
-note: missing field `you_cant_use_this_field` is private
-  --> $DIR/issue-76077.rs:3:9
-   |
-LL |         you_cant_use_this_field: bool,
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ... and other private field `you_cant_use_this_field` that were not provided
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/privacy/issue-79593.stderr b/src/test/ui/privacy/issue-79593.stderr
index 435d4cbf735..d878e1c023f 100644
--- a/src/test/ui/privacy/issue-79593.stderr
+++ b/src/test/ui/privacy/issue-79593.stderr
@@ -16,11 +16,7 @@ error: cannot construct `Pub` with struct literal syntax due to private fields
 LL |     foo::Pub {};
    |     ^^^^^^^^
    |
-note: missing field `private` is private
-  --> $DIR/issue-79593.rs:2:22
-   |
-LL |     pub struct Pub { private: () }
-   |                      ^^^^^^^^^^^
+   = note: ... and other private field `private` that were not provided
 
 error[E0063]: missing field `y` in initializer of `Enum`
   --> $DIR/issue-79593.rs:23:5
diff --git a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr
index 2ade7aea57b..fa1c661ef24 100644
--- a/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr
+++ b/src/test/ui/typeck/issue-87872-missing-inaccessible-field-literal.stderr
@@ -4,11 +4,7 @@ error: cannot construct `Foo` with struct literal syntax due to private fields
 LL |     foo::Foo {};
    |     ^^^^^^^^
    |
-note: missing field `you_cant_use_this_field` is private
-  --> $DIR/issue-87872-missing-inaccessible-field-literal.rs:4:9
-   |
-LL |         you_cant_use_this_field: bool,
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ... and other private field `you_cant_use_this_field` that were not provided
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr b/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr
index eb5f460f868..234110f31f7 100644
--- a/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr
+++ b/src/test/ui/typeck/missing-private-fields-in-struct-literal.stderr
@@ -9,15 +9,7 @@ LL |         a: (),
 LL |         b: (),
    |         ----- private field
    |
-note: missing fields `c`, `d` and `e` are private
-  --> $DIR/missing-private-fields-in-struct-literal.rs:6:9
-   |
-LL |         c: (),
-   |         ^^^^^
-LL |         d: (),
-   |         ^^^^^
-LL |         e: (),
-   |         ^^^^^
+   = note: ... and other private fields `c`, `d` and `e` that were not provided
 
 error: aborting due to previous error