@@ -4,7 +4,7 @@ use crate::type_error_struct;
4
4
5
5
use rustc_errors:: { struct_span_err, Applicability , Diagnostic } ;
6
6
use rustc_hir as hir;
7
- use rustc_hir:: def:: { Namespace , Res } ;
7
+ use rustc_hir:: def:: { self , Namespace , Res } ;
8
8
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
9
9
use rustc_infer:: {
10
10
infer,
@@ -390,17 +390,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
390
390
( fn_sig, Some ( def_id) )
391
391
}
392
392
ty:: FnPtr ( sig) => ( sig, None ) ,
393
- ref t => {
393
+ _ => {
394
394
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 ( )
399
400
{
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 ( ) ) ;
402
407
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 ) ) ) ;
404
409
}
405
410
406
411
let callee_ty = self . resolve_vars_if_possible ( callee_ty) ;
@@ -410,8 +415,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
410
415
callee_ty,
411
416
E0618 ,
412
417
"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}`" ) ,
415
420
None => format!( "`{callee_ty}`" ) ,
416
421
}
417
422
) ;
@@ -423,11 +428,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
423
428
callee_expr. span ,
424
429
) ;
425
430
426
- if let Some ( ref path) = unit_variant {
431
+ if let Some ( ( removal_span , kind , path) ) = & unit_variant {
427
432
err. span_suggestion_verbose (
428
- removal_span,
433
+ * removal_span,
429
434
& 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 " ,
431
436
) ,
432
437
"" ,
433
438
Applicability :: MachineApplicable ,
@@ -470,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
470
475
if let Some ( span) = self . tcx . hir ( ) . res_span ( def) {
471
476
let callee_ty = callee_ty. to_string ( ) ;
472
477
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" ) ) ,
474
479
( _, Some ( hir:: QPath :: Resolved ( _, path) ) ) => self
475
480
. tcx
476
481
. sess
0 commit comments