@@ -37,7 +37,7 @@ use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL;
37
37
use std:: fmt;
38
38
use syntax:: ast;
39
39
use ty:: { self , AdtKind , ToPredicate , ToPolyTraitRef , Ty , TyCtxt , TypeFoldable } ;
40
- use ty:: error:: { ExpectedFound , TypeError } ;
40
+ use ty:: error:: ExpectedFound ;
41
41
use ty:: fast_reject;
42
42
use ty:: fold:: TypeFolder ;
43
43
use ty:: subst:: Subst ;
@@ -711,7 +711,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
711
711
}
712
712
}
713
713
714
- OutputTypeParameterMismatch ( ref expected_trait_ref, ref actual_trait_ref, ref e ) => {
714
+ OutputTypeParameterMismatch ( ref expected_trait_ref, ref actual_trait_ref, _ ) => {
715
715
let expected_trait_ref = self . resolve_type_vars_if_possible ( & * expected_trait_ref) ;
716
716
let actual_trait_ref = self . resolve_type_vars_if_possible ( & * actual_trait_ref) ;
717
717
if actual_trait_ref. self_ty ( ) . references_error ( ) {
@@ -722,48 +722,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
722
722
self . tcx . hir . span_if_local ( did)
723
723
} ) ;
724
724
725
- if let & TypeError :: TupleSize ( ref expected_found) = e {
726
- // Expected `|x| { }`, found `|x, y| { }`
727
- self . report_arg_count_mismatch ( span,
728
- found_span,
729
- expected_found. expected ,
730
- expected_found. found ,
731
- expected_trait_ty. is_closure ( ) )
732
- } else if let & TypeError :: Sorts ( ref expected_found) = e {
733
- let expected = if let ty:: TyTuple ( tys, _) = expected_found. expected . sty {
734
- tys. len ( )
735
- } else {
736
- 1
725
+ let self_ty_count =
726
+ match expected_trait_ref. skip_binder ( ) . substs . type_at ( 1 ) . sty {
727
+ ty:: TyTuple ( ref tys, _) => tys. len ( ) ,
728
+ _ => 1 ,
737
729
} ;
738
- let found = if let ty :: TyTuple ( tys , _ ) = expected_found . found . sty {
739
- tys . len ( )
740
- } else {
741
- 1
730
+ let arg_ty_count =
731
+ match actual_trait_ref . skip_binder ( ) . substs . type_at ( 1 ) . sty {
732
+ ty :: TyTuple ( ref tys , _ ) => tys . len ( ) ,
733
+ _ => 1 ,
742
734
} ;
743
-
744
- if expected != found {
745
- // Expected `|| { }`, found `|x, y| { }`
746
- // Expected `fn(x) -> ()`, found `|| { }`
747
- self . report_arg_count_mismatch ( span,
748
- found_span,
749
- expected,
750
- found,
751
- expected_trait_ty. is_closure ( ) )
752
- } else {
753
- self . report_type_argument_mismatch ( span,
754
- found_span,
755
- expected_trait_ty,
756
- expected_trait_ref,
757
- actual_trait_ref,
758
- e)
759
- }
735
+ if self_ty_count == arg_ty_count {
736
+ self . report_closure_arg_mismatch ( span,
737
+ found_span,
738
+ expected_trait_ref,
739
+ actual_trait_ref)
760
740
} else {
761
- self . report_type_argument_mismatch ( span,
762
- found_span,
763
- expected_trait_ty,
764
- expected_trait_ref,
765
- actual_trait_ref,
766
- e)
741
+ // Expected `|| { }`, found `|x, y| { }`
742
+ // Expected `fn(x) -> ()`, found `|| { }`
743
+ self . report_arg_count_mismatch (
744
+ span,
745
+ found_span,
746
+ arg_ty_count,
747
+ self_ty_count,
748
+ expected_trait_ty. is_closure ( )
749
+ )
767
750
}
768
751
}
769
752
@@ -784,31 +767,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
784
767
err. emit ( ) ;
785
768
}
786
769
787
- fn report_type_argument_mismatch ( & self ,
788
- span : Span ,
789
- found_span : Option < Span > ,
790
- expected_ty : Ty < ' tcx > ,
791
- expected_ref : ty:: PolyTraitRef < ' tcx > ,
792
- found_ref : ty:: PolyTraitRef < ' tcx > ,
793
- type_error : & TypeError < ' tcx > )
794
- -> DiagnosticBuilder < ' tcx >
795
- {
796
- let mut err = struct_span_err ! ( self . tcx. sess, span, E0281 ,
797
- "type mismatch: `{}` implements the trait `{}`, but the trait `{}` is required" ,
798
- expected_ty,
799
- expected_ref,
800
- found_ref) ;
801
-
802
- err. span_label ( span, format ! ( "{}" , type_error) ) ;
803
-
804
- if let Some ( sp) = found_span {
805
- err. span_label ( span, format ! ( "requires `{}`" , found_ref) ) ;
806
- err. span_label ( sp, format ! ( "implements `{}`" , expected_ref) ) ;
807
- }
808
-
809
- err
810
- }
811
-
812
770
fn report_arg_count_mismatch ( & self ,
813
771
span : Span ,
814
772
found_span : Option < Span > ,
@@ -837,6 +795,57 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
837
795
}
838
796
err
839
797
}
798
+
799
+ fn report_closure_arg_mismatch ( & self ,
800
+ span : Span ,
801
+ found_span : Option < Span > ,
802
+ expected_ref : ty:: PolyTraitRef < ' tcx > ,
803
+ found : ty:: PolyTraitRef < ' tcx > )
804
+ -> DiagnosticBuilder < ' tcx >
805
+ {
806
+ fn build_fn_sig_string < ' a , ' gcx , ' tcx > ( tcx : ty:: TyCtxt < ' a , ' gcx , ' tcx > ,
807
+ trait_ref : & ty:: TraitRef < ' tcx > ) -> String {
808
+ let inputs = trait_ref. substs . type_at ( 1 ) ;
809
+ let sig = if let ty:: TyTuple ( inputs, _) = inputs. sty {
810
+ tcx. mk_fn_sig (
811
+ inputs. iter ( ) . map ( |& x| x) ,
812
+ tcx. mk_infer ( ty:: TyVar ( ty:: TyVid { index : 0 } ) ) ,
813
+ false ,
814
+ hir:: Unsafety :: Normal ,
815
+ :: syntax:: abi:: Abi :: Rust
816
+ )
817
+ } else {
818
+ tcx. mk_fn_sig (
819
+ :: std:: iter:: once ( inputs) ,
820
+ tcx. mk_infer ( ty:: TyVar ( ty:: TyVid { index : 0 } ) ) ,
821
+ false ,
822
+ hir:: Unsafety :: Normal ,
823
+ :: syntax:: abi:: Abi :: Rust
824
+ )
825
+ } ;
826
+ format ! ( "{}" , ty:: Binder ( sig) )
827
+ }
828
+
829
+ let argument_is_closure = expected_ref. skip_binder ( ) . substs . type_at ( 0 ) . is_closure ( ) ;
830
+ let mut err = struct_span_err ! ( self . tcx. sess, span, E0631 ,
831
+ "type mismatch in {} arguments" ,
832
+ if argument_is_closure { "closure" } else { "function" } ) ;
833
+
834
+ let found_str = format ! (
835
+ "expected signature of `{}`" ,
836
+ build_fn_sig_string( self . tcx, found. skip_binder( ) )
837
+ ) ;
838
+ err. span_label ( span, found_str) ;
839
+
840
+ let found_span = found_span. unwrap_or ( span) ;
841
+ let expected_str = format ! (
842
+ "found signature of `{}`" ,
843
+ build_fn_sig_string( self . tcx, expected_ref. skip_binder( ) )
844
+ ) ;
845
+ err. span_label ( found_span, expected_str) ;
846
+
847
+ err
848
+ }
840
849
}
841
850
842
851
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
0 commit comments