@@ -66,7 +66,7 @@ use hir::map as hir_map;
6666use hir:: def_id:: DefId ;
6767use middle:: region;
6868use traits:: { ObligationCause , ObligationCauseCode } ;
69- use ty:: { self , Region , Ty , TyCtxt , TypeFoldable } ;
69+ use ty:: { self , Region , Ty , TyCtxt , TypeFoldable , TypeVariants } ;
7070use ty:: error:: TypeError ;
7171use syntax:: ast:: DUMMY_NODE_ID ;
7272use syntax_pos:: { Pos , Span } ;
@@ -673,14 +673,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
673673 values : Option < ValuePairs < ' tcx > > ,
674674 terr : & TypeError < ' tcx > )
675675 {
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 ) ,
678678 Some ( values) => {
679- let is_simple_error = match values {
679+ let ( is_simple_error, exp_found ) = match values {
680680 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) )
682685 }
683- _ => false ,
686+ _ => ( false , None ) ,
684687 } ;
685688 let vals = match self . values_str ( & values) {
686689 Some ( ( expected, found) ) => Some ( ( expected, found) ) ,
@@ -690,12 +693,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
690693 return
691694 }
692695 } ;
693- ( vals, is_simple_error)
696+ ( vals, exp_found , is_simple_error)
694697 }
695698 } ;
696699
697700 let span = cause. span ;
698701
702+ diag. span_label ( span, terr. to_string ( ) ) ;
703+ if let Some ( ( sp, msg) ) = secondary_span {
704+ diag. span_label ( sp, msg) ;
705+ }
706+
699707 if let Some ( ( expected, found) ) = expected_found {
700708 match ( terr, is_simple_error, expected == found) {
701709 ( & TypeError :: Sorts ( ref values) , false , true ) => {
@@ -704,18 +712,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
704712 & format ! ( " ({})" , values. expected. sort_string( self . tcx) ) ,
705713 & format ! ( " ({})" , values. found. sort_string( self . tcx) ) ) ;
706714 }
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+
708740 diag. note_expected_found ( & "type" , expected, found) ;
709741 }
710742 _ => ( ) ,
711743 }
712744 }
713745
714- diag. span_label ( span, terr. to_string ( ) ) ;
715- if let Some ( ( sp, msg) ) = secondary_span {
716- diag. span_label ( sp, msg) ;
717- }
718-
719746 self . note_error_origin ( diag, & cause) ;
720747 self . check_and_note_conflicting_crates ( diag, terr, span) ;
721748 self . tcx . note_and_explain_type_err ( diag, terr, span) ;
0 commit comments