@@ -4,7 +4,7 @@ use crate::type_error_struct;
44
55use rustc_errors:: { struct_span_err, Applicability , Diagnostic } ;
66use rustc_hir as hir;
7- use rustc_hir:: def:: { Namespace , Res } ;
7+ use rustc_hir:: def:: { self , Namespace , Res } ;
88use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
99use rustc_infer:: {
1010 infer,
@@ -390,17 +390,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
390390 ( fn_sig, Some ( def_id) )
391391 }
392392 ty:: FnPtr ( sig) => ( sig, None ) ,
393- ref t => {
393+ _ => {
394394 let mut unit_variant = None ;
395- let mut removal_span = call_expr. span ;
396- if let ty:: Adt ( adt_def, ..) = t
397- && adt_def. is_enum ( )
398- && let hir:: ExprKind :: Call ( expr, _) = call_expr. kind
395+ if let hir:: ExprKind :: Path ( qpath) = & callee_expr. kind
396+ && let Res :: Def ( def:: DefKind :: Ctor ( kind, def:: CtorKind :: Const ) , _)
397+ = self . typeck_results . borrow ( ) . qpath_res ( qpath, callee_expr. hir_id )
398+ // Only suggest removing parens if there are no arguments
399+ && arg_exprs. is_empty ( )
400+ && let Ok ( path) = self . tcx . sess . source_map ( ) . span_to_snippet ( callee_expr. span )
399401 {
400- removal_span =
401- expr. span . shrink_to_hi ( ) . to ( call_expr. span . shrink_to_hi ( ) ) ;
402+ let descr = match kind {
403+ def:: CtorOf :: Struct => "struct" ,
404+ def:: CtorOf :: Variant => "enum variant" ,
405+ } ;
406+ let removal_span =
407+ callee_expr. span . shrink_to_hi ( ) . to ( call_expr. span . shrink_to_hi ( ) ) ;
402408 unit_variant =
403- self . tcx . sess . source_map ( ) . span_to_snippet ( expr . span ) . ok ( ) ;
409+ Some ( ( removal_span , descr , path ) ) ;
404410 }
405411
406412 let callee_ty = self . resolve_vars_if_possible ( callee_ty) ;
@@ -410,8 +416,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
410416 callee_ty,
411417 E0618 ,
412418 "expected function, found {}" ,
413- match unit_variant {
414- Some ( ref path) => format!( "enum variant `{path}`" ) ,
419+ match & unit_variant {
420+ Some ( ( _ , kind , path) ) => format!( "{kind} `{path}`" ) ,
415421 None => format!( "`{callee_ty}`" ) ,
416422 }
417423 ) ;
@@ -423,11 +429,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
423429 callee_expr. span ,
424430 ) ;
425431
426- if let Some ( ref path) = unit_variant {
432+ if let Some ( ( removal_span , kind , path) ) = & unit_variant {
427433 err. span_suggestion_verbose (
428- removal_span,
434+ * removal_span,
429435 & format ! (
430- "`{path}` is a unit variant, you need to write it without the parentheses " ,
436+ "`{path}` is a unit {kind}, and does not take parentheses to be constructed " ,
431437 ) ,
432438 "" ,
433439 Applicability :: MachineApplicable ,
@@ -470,7 +476,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
470476 if let Some ( span) = self . tcx . hir ( ) . res_span ( def) {
471477 let callee_ty = callee_ty. to_string ( ) ;
472478 let label = match ( unit_variant, inner_callee_path) {
473- ( Some ( path) , _) => Some ( format ! ( "`{path}` defined here" ) ) ,
479+ ( Some ( ( _ , kind , path) ) , _) => Some ( format ! ( "{kind} `{path}` defined here" ) ) ,
474480 ( _, Some ( hir:: QPath :: Resolved ( _, path) ) ) => self
475481 . tcx
476482 . sess
0 commit comments