diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 0b4c52d68b6ff..da58c923695dd 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -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, @@ -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<'_>, @@ -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::>()) diff --git a/tests/ui/resolve/regression-struct-called-as-function-148919.rs b/tests/ui/resolve/regression-struct-called-as-function-148919.rs new file mode 100644 index 0000000000000..7358e1716c11a --- /dev/null +++ b/tests/ui/resolve/regression-struct-called-as-function-148919.rs @@ -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() {} diff --git a/tests/ui/resolve/regression-struct-called-as-function-148919.stderr b/tests/ui/resolve/regression-struct-called-as-function-148919.stderr new file mode 100644 index 0000000000000..d3e62b3a5a987 --- /dev/null +++ b/tests/ui/resolve/regression-struct-called-as-function-148919.stderr @@ -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`.