Skip to content

Commit 87dc85d

Browse files
committed
Suggest assoc fn new when trying to build tuple struct with private fields
Fix #22488.
1 parent 93e62a2 commit 87dc85d

File tree

4 files changed

+70
-1
lines changed

4 files changed

+70
-1
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -1570,7 +1570,26 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
15701570
err.set_primary_message(
15711571
"cannot initialize a tuple struct which contains private fields",
15721572
);
1573-
1573+
if !def_id.is_local()
1574+
&& self
1575+
.r
1576+
.tcx
1577+
.inherent_impls(def_id)
1578+
.iter()
1579+
.flat_map(|impl_def_id| {
1580+
self.r.tcx.provided_trait_methods(*impl_def_id)
1581+
})
1582+
.any(|assoc| !assoc.fn_has_self_parameter && assoc.name == sym::new)
1583+
{
1584+
// FIXME: look for associated functions with Self return type,
1585+
// instead of relying only on the name and lack of self receiver.
1586+
err.span_suggestion_verbose(
1587+
span.shrink_to_hi(),
1588+
"you might have meant to use the `new` associated function",
1589+
"::new".to_string(),
1590+
Applicability::MaybeIncorrect,
1591+
);
1592+
}
15741593
// Use spans of the tuple struct definition.
15751594
self.r.field_def_ids(def_id).map(|field_ids| {
15761595
field_ids
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
struct U <T> {
4+
wtf: Option<Box<U<T>>>,
5+
x: T,
6+
}
7+
fn main() {
8+
U {
9+
wtf: Some(Box::new(U { //~ ERROR cannot initialize a tuple struct which contains private fields
10+
wtf: None,
11+
x: (),
12+
})),
13+
x: ()
14+
};
15+
}

tests/ui/privacy/suggest-box-new.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// run-rustfix
2+
#![allow(dead_code)]
3+
struct U <T> {
4+
wtf: Option<Box<U<T>>>,
5+
x: T,
6+
}
7+
fn main() {
8+
U {
9+
wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields
10+
wtf: None,
11+
x: (),
12+
})),
13+
x: ()
14+
};
15+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0423]: cannot initialize a tuple struct which contains private fields
2+
--> $DIR/suggest-box-new.rs:9:19
3+
|
4+
LL | wtf: Some(Box(U {
5+
| ^^^
6+
|
7+
note: constructor is not visible here due to private fields
8+
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
9+
|
10+
= note: private field
11+
|
12+
= note: private field
13+
help: you might have meant to use the `new` associated function
14+
|
15+
LL | wtf: Some(Box::new(U {
16+
| +++++
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0423`.

0 commit comments

Comments
 (0)