Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,8 +823,16 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
}

if let Some(Res::Def(DefKind::Struct, def_id)) = res {
self.update_err_for_private_tuple_struct_fields(err, &source, def_id);
err.note("constructor is not visible here due to private fields");
let private_fields = self.has_private_fields(def_id);
let adjust_error_message =
private_fields && self.is_struct_with_fn_ctor(def_id);
if adjust_error_message {
self.update_err_for_private_tuple_struct_fields(err, &source, def_id);
}

if private_fields {
err.note("constructor is not visible here due to private fields");
}
} else {
err.span_suggestion(
call_span,
Expand Down Expand Up @@ -1642,6 +1650,19 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
}
}

fn is_struct_with_fn_ctor(&mut self, def_id: DefId) -> bool {
def_id
.as_local()
.and_then(|local_id| self.r.struct_constructors.get(&local_id))
.map(|struct_ctor| {
matches!(
struct_ctor.0,
def::Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), _)
)
})
.unwrap_or(false)
}

fn update_err_for_private_tuple_struct_fields(
&mut self,
err: &mut Diag<'_>,
Expand Down Expand Up @@ -1674,7 +1695,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
*call_span,
&args[..],
);
// Use spans of the tuple struct definition.

self.r
.field_idents(def_id)
.map(|fields| fields.iter().map(|f| f.span).collect::<Vec<_>>())
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/resolve/regression-struct-called-as-function-148919.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
struct Bar {}

impl Bar {
fn into_self(self) -> Bar {
Bar(self)
//~^ ERROR expected function, tuple struct or tuple variant, found struct `Bar` [E0423]
}
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0423]: expected function, tuple struct or tuple variant, found struct `Bar`
--> $DIR/regression-struct-called-as-function-148919.rs:5:9
|
LL | Bar(self)
| ^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0423`.
Loading