about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-27 12:16:01 +0000
committerbors <bors@rust-lang.org>2023-10-27 12:16:01 +0000
commit688892938e825312fcf808236af95cadb4f088e9 (patch)
tree3754bf5b15b52b22b3ee22cb3a8df0c199dcf6eb
parent95f6a01e8f8fb121ded7d0eaa86906437cb08652 (diff)
parent87dc85d3222743aeb82848537ad77c2ece746ef6 (diff)
downloadrust-688892938e825312fcf808236af95cadb4f088e9.tar.gz
rust-688892938e825312fcf808236af95cadb4f088e9.zip
Auto merge of #116858 - estebank:issue-22488, r=petrochenkov
Suggest assoc fn `new` when trying to build tuple struct with private fields

Fix #22488.
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs21
-rw-r--r--tests/ui/privacy/suggest-box-new.fixed15
-rw-r--r--tests/ui/privacy/suggest-box-new.rs15
-rw-r--r--tests/ui/privacy/suggest-box-new.stderr20
4 files changed, 70 insertions, 1 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index a5f8f61f3db..fd5d6fabf02 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1570,7 +1570,26 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                         err.set_primary_message(
                             "cannot initialize a tuple struct which contains private fields",
                         );
-
+                        if !def_id.is_local()
+                            && self
+                                .r
+                                .tcx
+                                .inherent_impls(def_id)
+                                .iter()
+                                .flat_map(|impl_def_id| {
+                                    self.r.tcx.provided_trait_methods(*impl_def_id)
+                                })
+                                .any(|assoc| !assoc.fn_has_self_parameter && assoc.name == sym::new)
+                        {
+                            // FIXME: look for associated functions with Self return type,
+                            // instead of relying only on the name and lack of self receiver.
+                            err.span_suggestion_verbose(
+                                span.shrink_to_hi(),
+                                "you might have meant to use the `new` associated function",
+                                "::new".to_string(),
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
                         // Use spans of the tuple struct definition.
                         self.r.field_def_ids(def_id).map(|field_ids| {
                             field_ids
diff --git a/tests/ui/privacy/suggest-box-new.fixed b/tests/ui/privacy/suggest-box-new.fixed
new file mode 100644
index 00000000000..f5ae5c2abfd
--- /dev/null
+++ b/tests/ui/privacy/suggest-box-new.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(dead_code)]
+struct U <T> {
+    wtf: Option<Box<U<T>>>,
+    x: T,
+}
+fn main() {
+    U {
+        wtf: Some(Box::new(U { //~ ERROR cannot initialize a tuple struct which contains private fields
+            wtf: None,
+            x: (),
+        })),
+        x: ()
+    };
+}
diff --git a/tests/ui/privacy/suggest-box-new.rs b/tests/ui/privacy/suggest-box-new.rs
new file mode 100644
index 00000000000..2e18dba8b9f
--- /dev/null
+++ b/tests/ui/privacy/suggest-box-new.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+#![allow(dead_code)]
+struct U <T> {
+    wtf: Option<Box<U<T>>>,
+    x: T,
+}
+fn main() {
+    U {
+        wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields
+            wtf: None,
+            x: (),
+        })),
+        x: ()
+    };
+}
diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr
new file mode 100644
index 00000000000..ed7fa036408
--- /dev/null
+++ b/tests/ui/privacy/suggest-box-new.stderr
@@ -0,0 +1,20 @@
+error[E0423]: cannot initialize a tuple struct which contains private fields
+  --> $DIR/suggest-box-new.rs:9:19
+   |
+LL |         wtf: Some(Box(U {
+   |                   ^^^
+   |
+note: constructor is not visible here due to private fields
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+   |
+   = note: private field
+   |
+   = note: private field
+help: you might have meant to use the `new` associated function
+   |
+LL |         wtf: Some(Box::new(U {
+   |                      +++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0423`.