@@ -24,7 +24,7 @@ use rustc_infer::infer::TypeTrace;
2424use rustc_middle:: ty:: adjustment:: AllowTwoPhase ;
2525use rustc_middle:: ty:: error:: TypeError ;
2626use rustc_middle:: ty:: fold:: TypeFoldable ;
27- use rustc_middle:: ty:: { self , Ty } ;
27+ use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
2828use rustc_session:: Session ;
2929use rustc_span:: symbol:: Ident ;
3030use rustc_span:: { self , Span } ;
@@ -394,6 +394,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
394394 break ' errors;
395395 }
396396
397+ self . set_tainted_by_errors ( ) ;
398+
397399 // The algorithm here is inspired by levenshtein distance and longest common subsequence.
398400 // We'll try to detect 4 different types of mistakes:
399401 // - An extra parameter has been provided that doesn't satisfy *any* of the other inputs
@@ -502,6 +504,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
502504 TupleMatchFound :: Single => {
503505 let expected_ty = expected_input_tys[ 0 ] ;
504506 let provided_ty = final_arg_types[ 0 ] . map ( |ty| ty. 0 ) . unwrap ( ) ;
507+ let expected_ty = self . resolve_vars_if_possible ( expected_ty) ;
508+ let provided_ty = self . resolve_vars_if_possible ( provided_ty) ;
505509 let cause = & self . misc ( provided_args[ 0 ] . span ) ;
506510 let compatibility = demand_compatible ( 0 , & mut final_arg_types) ;
507511 let type_error = match compatibility {
@@ -523,24 +527,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
523527 format ! ( "arguments to this {} are incorrect" , call_name) ,
524528 ) ;
525529 // Call out where the function is defined
526- if let Some ( def_id) = fn_def_id && let Some ( def_span) = tcx. def_ident_span ( def_id) {
527- let mut spans: MultiSpan = def_span. into ( ) ;
528-
529- let params = tcx
530- . hir ( )
531- . get_if_local ( def_id)
532- . and_then ( |node| node. body_id ( ) )
533- . into_iter ( )
534- . map ( |id| tcx. hir ( ) . body ( id) . params )
535- . flatten ( ) ;
536-
537- for param in params {
538- spans. push_span_label ( param. span , String :: new ( ) ) ;
539- }
540-
541- let def_kind = tcx. def_kind ( def_id) ;
542- err. span_note ( spans, & format ! ( "{} defined here" , def_kind. descr( def_id) ) ) ;
543- }
530+ label_fn_like ( tcx, & mut err, fn_def_id) ;
544531 err. emit ( ) ;
545532 break ' errors;
546533 }
@@ -558,24 +545,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
558545 DiagnosticId :: Error ( err_code. to_owned ( ) ) ,
559546 ) ;
560547 // Call out where the function is defined
561- if let Some ( def_id) = fn_def_id && let Some ( def_span) = tcx. def_ident_span ( def_id) {
562- let mut spans: MultiSpan = def_span. into ( ) ;
563-
564- let params = tcx
565- . hir ( )
566- . get_if_local ( def_id)
567- . and_then ( |node| node. body_id ( ) )
568- . into_iter ( )
569- . map ( |id| tcx. hir ( ) . body ( id) . params )
570- . flatten ( ) ;
571-
572- for param in params {
573- spans. push_span_label ( param. span , String :: new ( ) ) ;
574- }
575-
576- let def_kind = tcx. def_kind ( def_id) ;
577- err. span_note ( spans, & format ! ( "{} defined here" , def_kind. descr( def_id) ) ) ;
578- }
548+ label_fn_like ( tcx, & mut err, fn_def_id) ;
579549 err. multipart_suggestion (
580550 "use parentheses to construct a tuple" ,
581551 vec ! [ ( start, '(' . to_string( ) ) , ( end, ')' . to_string( ) ) ] ,
@@ -597,13 +567,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
597567 {
598568 let expected_ty = expected_input_tys[ * input_idx] ;
599569 let provided_ty = final_arg_types[ * input_idx] . map ( |ty| ty. 0 ) . unwrap ( ) ;
570+ let expected_ty = self . resolve_vars_if_possible ( expected_ty) ;
571+ let provided_ty = self . resolve_vars_if_possible ( provided_ty) ;
600572 let cause = & self . misc ( provided_args[ * input_idx] . span ) ;
601573 let trace = TypeTrace :: types ( cause, true , expected_ty, provided_ty) ;
602574 let mut err = self . report_and_explain_type_error ( trace, error) ;
603575 self . emit_coerce_suggestions (
604576 & mut err,
605577 & provided_args[ * input_idx] ,
606- final_arg_types [ * input_idx ] . map ( |ty| ty . 0 ) . unwrap ( ) ,
578+ provided_ty ,
607579 final_arg_types[ * input_idx] . map ( |ty| ty. 1 ) . unwrap ( ) ,
608580 None ,
609581 None ,
@@ -613,24 +585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
613585 format ! ( "arguments to this {} are incorrect" , call_name) ,
614586 ) ;
615587 // Call out where the function is defined
616- if let Some ( def_id) = fn_def_id && let Some ( def_span) = tcx. def_ident_span ( def_id) {
617- let mut spans: MultiSpan = def_span. into ( ) ;
618-
619- let params = tcx
620- . hir ( )
621- . get_if_local ( def_id)
622- . and_then ( |node| node. body_id ( ) )
623- . into_iter ( )
624- . map ( |id| tcx. hir ( ) . body ( id) . params )
625- . flatten ( ) ;
626-
627- for param in params {
628- spans. push_span_label ( param. span , String :: new ( ) ) ;
629- }
630-
631- let def_kind = tcx. def_kind ( def_id) ;
632- err. span_note ( spans, & format ! ( "{} defined here" , def_kind. descr( def_id) ) ) ;
633- }
588+ label_fn_like ( tcx, & mut err, fn_def_id) ;
634589 err. emit ( ) ;
635590 break ' errors;
636591 }
@@ -678,12 +633,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
678633 match error {
679634 Error :: Invalid ( input_idx, compatibility) => {
680635 let expected_ty = expected_input_tys[ input_idx] ;
636+ let provided_ty = final_arg_types
637+ . get ( input_idx)
638+ . and_then ( |x| x. as_ref ( ) )
639+ . map ( |ty| ty. 0 )
640+ . unwrap_or ( tcx. ty_error ( ) ) ;
641+ let expected_ty = self . resolve_vars_if_possible ( expected_ty) ;
642+ let provided_ty = self . resolve_vars_if_possible ( provided_ty) ;
681643 if let Compatibility :: Incompatible ( error) = & compatibility {
682- let provided_ty = final_arg_types
683- . get ( input_idx)
684- . and_then ( |x| x. as_ref ( ) )
685- . map ( |ty| ty. 0 )
686- . unwrap_or ( tcx. ty_error ( ) ) ;
687644 let cause = & self . misc (
688645 provided_args. get ( input_idx) . map ( |i| i. span ) . unwrap_or ( call_span) ,
689646 ) ;
@@ -948,24 +905,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
948905 }
949906
950907 // Call out where the function is defined
951- if let Some ( def_id) = fn_def_id && let Some ( def_span) = tcx. def_ident_span ( def_id) {
952- let mut spans: MultiSpan = def_span. into ( ) ;
953-
954- let params = tcx
955- . hir ( )
956- . get_if_local ( def_id)
957- . and_then ( |node| node. body_id ( ) )
958- . into_iter ( )
959- . flat_map ( |id| tcx. hir ( ) . body ( id) . params )
960- ;
961-
962- for param in params {
963- spans. push_span_label ( param. span , String :: new ( ) ) ;
964- }
965-
966- let def_kind = tcx. def_kind ( def_id) ;
967- err. span_note ( spans, & format ! ( "{} defined here" , def_kind. descr( def_id) ) ) ;
968- }
908+ label_fn_like ( tcx, & mut err, fn_def_id) ;
969909
970910 // And add a suggestion block for all of the parameters
971911 let suggestion_text = match suggestion_text {
@@ -1790,3 +1730,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17901730 }
17911731 }
17921732}
1733+
1734+ fn label_fn_like < ' tcx > (
1735+ tcx : TyCtxt < ' tcx > ,
1736+ err : & mut rustc_errors:: DiagnosticBuilder < ' tcx , rustc_errors:: ErrorGuaranteed > ,
1737+ def_id : Option < DefId > ,
1738+ ) {
1739+ let Some ( def_id) = def_id else {
1740+ return ;
1741+ } ;
1742+
1743+ if let Some ( def_span) = tcx. def_ident_span ( def_id) {
1744+ let mut spans: MultiSpan = def_span. into ( ) ;
1745+
1746+ let params = tcx
1747+ . hir ( )
1748+ . get_if_local ( def_id)
1749+ . and_then ( |node| node. body_id ( ) )
1750+ . into_iter ( )
1751+ . map ( |id| tcx. hir ( ) . body ( id) . params )
1752+ . flatten ( ) ;
1753+
1754+ for param in params {
1755+ spans. push_span_label ( param. span , String :: new ( ) ) ;
1756+ }
1757+
1758+ let def_kind = tcx. def_kind ( def_id) ;
1759+ err. span_note ( spans, & format ! ( "{} defined here" , def_kind. descr( def_id) ) ) ;
1760+ } else {
1761+ match tcx. hir ( ) . get_if_local ( def_id) {
1762+ Some ( hir:: Node :: Expr ( hir:: Expr {
1763+ kind : hir:: ExprKind :: Closure ( _, _, _, span, ..) ,
1764+ ..
1765+ } ) ) => {
1766+ let spans: MultiSpan = ( * span) . into ( ) ;
1767+
1768+ // Note: We don't point to param spans here because they overlap
1769+ // with the closure span itself
1770+
1771+ err. span_note ( spans, "closure defined here" ) ;
1772+ }
1773+ _ => { }
1774+ }
1775+ }
1776+ }
0 commit comments