@@ -66,7 +66,7 @@ use hir::map as hir_map;
66
66
use hir:: def_id:: DefId ;
67
67
use middle:: region;
68
68
use traits:: { ObligationCause , ObligationCauseCode } ;
69
- use ty:: { self , Region , Ty , TyCtxt , TypeFoldable } ;
69
+ use ty:: { self , Region , Ty , TyCtxt , TypeFoldable , TypeVariants } ;
70
70
use ty:: error:: TypeError ;
71
71
use syntax:: ast:: DUMMY_NODE_ID ;
72
72
use syntax_pos:: { Pos , Span } ;
@@ -673,14 +673,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
673
673
values : Option < ValuePairs < ' tcx > > ,
674
674
terr : & TypeError < ' tcx > )
675
675
{
676
- let ( expected_found, is_simple_error) = match values {
677
- None => ( None , false ) ,
676
+ let ( expected_found, exp_found , is_simple_error) = match values {
677
+ None => ( None , None , false ) ,
678
678
Some ( values) => {
679
- let is_simple_error = match values {
679
+ let ( is_simple_error, exp_found ) = match values {
680
680
ValuePairs :: Types ( exp_found) => {
681
- exp_found. expected . is_primitive ( ) && exp_found. found . is_primitive ( )
681
+ let is_simple_err = exp_found. expected . is_primitive ( )
682
+ && exp_found. found . is_primitive ( ) ;
683
+
684
+ ( is_simple_err, Some ( exp_found) )
682
685
}
683
- _ => false ,
686
+ _ => ( false , None ) ,
684
687
} ;
685
688
let vals = match self . values_str ( & values) {
686
689
Some ( ( expected, found) ) => Some ( ( expected, found) ) ,
@@ -690,12 +693,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
690
693
return
691
694
}
692
695
} ;
693
- ( vals, is_simple_error)
696
+ ( vals, exp_found , is_simple_error)
694
697
}
695
698
} ;
696
699
697
700
let span = cause. span ;
698
701
702
+ diag. span_label ( span, terr. to_string ( ) ) ;
703
+ if let Some ( ( sp, msg) ) = secondary_span {
704
+ diag. span_label ( sp, msg) ;
705
+ }
706
+
699
707
if let Some ( ( expected, found) ) = expected_found {
700
708
match ( terr, is_simple_error, expected == found) {
701
709
( & TypeError :: Sorts ( ref values) , false , true ) => {
@@ -704,18 +712,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
704
712
& format ! ( " ({})" , values. expected. sort_string( self . tcx) ) ,
705
713
& format ! ( " ({})" , values. found. sort_string( self . tcx) ) ) ;
706
714
}
707
- ( _, false , _) => {
715
+ ( _, false , _) => {
716
+ if let Some ( exp_found) = exp_found {
717
+ let ( def_id, ret_ty) = match exp_found. found . sty {
718
+ TypeVariants :: TyFnDef ( def, _) => {
719
+ ( Some ( def) , Some ( self . tcx . fn_sig ( def) . output ( ) ) )
720
+ }
721
+ _ => ( None , None )
722
+ } ;
723
+
724
+ let exp_is_struct = match exp_found. expected . sty {
725
+ TypeVariants :: TyAdt ( def, _) => def. is_struct ( ) ,
726
+ _ => false
727
+ } ;
728
+
729
+ if let ( Some ( def_id) , Some ( ret_ty) ) = ( def_id, ret_ty) {
730
+ if exp_is_struct && exp_found. expected == ret_ty. 0 {
731
+ let message = format ! (
732
+ "did you mean `{}(/* fields */)`?" ,
733
+ self . tcx. item_path_str( def_id)
734
+ ) ;
735
+ diag. span_label ( cause. span , message) ;
736
+ }
737
+ }
738
+ }
739
+
708
740
diag. note_expected_found ( & "type" , expected, found) ;
709
741
}
710
742
_ => ( ) ,
711
743
}
712
744
}
713
745
714
- diag. span_label ( span, terr. to_string ( ) ) ;
715
- if let Some ( ( sp, msg) ) = secondary_span {
716
- diag. span_label ( sp, msg) ;
717
- }
718
-
719
746
self . note_error_origin ( diag, & cause) ;
720
747
self . check_and_note_conflicting_crates ( diag, terr, span) ;
721
748
self . tcx . note_and_explain_type_err ( diag, terr, span) ;
0 commit comments