Skip to content

Commit ed6a78c

Browse files
committed
Fix error message for calling a non-tuple struct
1 parent 140044c commit ed6a78c

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -823,8 +823,10 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
823823
}
824824

825825
if let Some(Res::Def(DefKind::Struct, def_id)) = res {
826-
self.update_err_for_private_tuple_struct_fields(err, &source, def_id);
827-
err.note("constructor is not visible here due to private fields");
826+
if self.has_private_fields(def_id) {
827+
self.update_err_for_private_tuple_struct_fields(err, &source, def_id);
828+
err.note("constructor is not visible here due to private fields");
829+
}
828830
} else {
829831
err.span_suggestion(
830832
call_span,
@@ -1642,6 +1644,17 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
16421644
}
16431645
}
16441646

1647+
fn has_tuple_fields(&mut self, def_id: DefId) -> bool {
1648+
// As we cannot name a field "0", this is an indictation
1649+
// that we are looking at a tuple struct
1650+
if let Some(fields) = self.r.field_idents(def_id) {
1651+
if let Some(first_field) = fields.get(0) {
1652+
return first_field.name.as_str() == "0";
1653+
}
1654+
}
1655+
false
1656+
}
1657+
16451658
fn update_err_for_private_tuple_struct_fields(
16461659
&mut self,
16471660
err: &mut Diag<'_>,
@@ -1664,17 +1677,18 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
16641677
span: call_span,
16651678
..
16661679
})) => {
1667-
err.primary_message(
1668-
"cannot initialize a tuple struct which contains private fields",
1669-
);
1670-
self.suggest_alternative_construction_methods(
1671-
def_id,
1672-
err,
1673-
path.span,
1674-
*call_span,
1675-
&args[..],
1676-
);
1677-
// Use spans of the tuple struct definition.
1680+
if self.has_tuple_fields(def_id) {
1681+
err.primary_message(
1682+
"cannot initialize a tuple struct which contains private fields",
1683+
);
1684+
self.suggest_alternative_construction_methods(
1685+
def_id,
1686+
err,
1687+
path.span,
1688+
*call_span,
1689+
&args[..],
1690+
);
1691+
}
16781692
self.r
16791693
.field_idents(def_id)
16801694
.map(|fields| fields.iter().map(|f| f.span).collect::<Vec<_>>())
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
struct Bar {}
2+
3+
impl Bar {
4+
fn into_self(self) -> Bar {
5+
Bar(self)
6+
//~^ ERROR expected function, tuple struct or tuple variant, found struct `Bar` [E0423]
7+
}
8+
}
9+
10+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0423]: expected function, tuple struct or tuple variant, found struct `Bar`
2+
--> $DIR/regression-struct-called-as-function-148919.rs:5:9
3+
|
4+
LL | Bar(self)
5+
| ^^^
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0423`.

0 commit comments

Comments
 (0)