@@ -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,22 @@ 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 ( )
399400 {
400- removal_span =
401- expr. span . shrink_to_hi ( ) . to ( call_expr. span . shrink_to_hi ( ) ) ;
401+ let descr = match kind {
402+ def:: CtorOf :: Struct => "struct" ,
403+ def:: CtorOf :: Variant => "enum variant" ,
404+ } ;
405+ let removal_span =
406+ callee_expr. span . shrink_to_hi ( ) . to ( call_expr. span . shrink_to_hi ( ) ) ;
402407 unit_variant =
403- self . tcx . sess . source_map ( ) . span_to_snippet ( expr . span ) . ok ( ) ;
408+ Some ( ( removal_span , descr , rustc_hir_pretty :: qpath_to_string ( qpath ) ) ) ;
404409 }
405410
406411 let callee_ty = self . resolve_vars_if_possible ( callee_ty) ;
@@ -410,8 +415,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
410415 callee_ty,
411416 E0618 ,
412417 "expected function, found {}" ,
413- match unit_variant {
414- Some ( ref path) => format!( "enum variant `{path}`" ) ,
418+ match & unit_variant {
419+ Some ( ( _ , kind , path) ) => format!( "{kind} `{path}`" ) ,
415420 None => format!( "`{callee_ty}`" ) ,
416421 }
417422 ) ;
@@ -423,11 +428,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
423428 callee_expr. span ,
424429 ) ;
425430
426- if let Some ( ref path) = unit_variant {
431+ if let Some ( ( removal_span , kind , path) ) = & unit_variant {
427432 err. span_suggestion_verbose (
428- removal_span,
433+ * removal_span,
429434 & format ! (
430- "`{path}` is a unit variant, you need to write it without the parentheses " ,
435+ "`{path}` is a unit {kind}, and does not take parentheses to be constructed " ,
431436 ) ,
432437 "" ,
433438 Applicability :: MachineApplicable ,
@@ -470,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
470475 if let Some ( span) = self . tcx . hir ( ) . res_span ( def) {
471476 let callee_ty = callee_ty. to_string ( ) ;
472477 let label = match ( unit_variant, inner_callee_path) {
473- ( Some ( path) , _) => Some ( format ! ( "`{path}` defined here" ) ) ,
478+ ( Some ( ( _ , kind , path) ) , _) => Some ( format ! ( "{kind} `{path}` defined here" ) ) ,
474479 ( _, Some ( hir:: QPath :: Resolved ( _, path) ) ) => self
475480 . tcx
476481 . sess
0 commit comments