@@ -340,25 +340,11 @@ impl<'a> InferenceContext<'a> {
340
340
None => ( Vec :: new ( ) , self . err_ty ( ) ) ,
341
341
} ;
342
342
self . register_obligations_for_call ( & callee_ty) ;
343
-
344
- let expected_inputs = self . expected_inputs_for_expected_output (
345
- expected,
346
- ret_ty. clone ( ) ,
347
- param_tys. clone ( ) ,
348
- ) ;
349
-
350
- self . check_call_arguments ( args, & expected_inputs, & param_tys) ;
343
+ self . check_call_arguments ( args, & param_tys) ;
351
344
self . normalize_associated_types_in ( ret_ty)
352
345
}
353
346
Expr :: MethodCall { receiver, args, method_name, generic_args } => self
354
- . infer_method_call (
355
- tgt_expr,
356
- * receiver,
357
- args,
358
- method_name,
359
- generic_args. as_deref ( ) ,
360
- expected,
361
- ) ,
347
+ . infer_method_call ( tgt_expr, * receiver, args, method_name, generic_args. as_deref ( ) ) ,
362
348
Expr :: Match { expr, arms } => {
363
349
let input_ty = self . infer_expr ( * expr, & Expectation :: none ( ) ) ;
364
350
@@ -589,7 +575,7 @@ impl<'a> InferenceContext<'a> {
589
575
// FIXME: record type error - expected reference but found ptr,
590
576
// which cannot be coerced
591
577
}
592
- Expectation :: rvalue_hint ( & mut self . table , Ty :: clone ( exp_inner) )
578
+ Expectation :: rvalue_hint ( Ty :: clone ( exp_inner) )
593
579
} else {
594
580
Expectation :: none ( )
595
581
} ;
@@ -916,7 +902,6 @@ impl<'a> InferenceContext<'a> {
916
902
args : & [ ExprId ] ,
917
903
method_name : & Name ,
918
904
generic_args : Option < & GenericArgs > ,
919
- expected : & Expectation ,
920
905
) -> Ty {
921
906
let receiver_ty = self . infer_expr ( receiver, & Expectation :: none ( ) ) ;
922
907
let canonicalized_receiver = self . canonicalize ( receiver_ty. clone ( ) ) ;
@@ -950,7 +935,7 @@ impl<'a> InferenceContext<'a> {
950
935
} ;
951
936
let method_ty = method_ty. substitute ( & Interner , & substs) ;
952
937
self . register_obligations_for_call ( & method_ty) ;
953
- let ( formal_receiver_ty , param_tys, ret_ty) = match method_ty. callable_sig ( self . db ) {
938
+ let ( expected_receiver_ty , param_tys, ret_ty) = match method_ty. callable_sig ( self . db ) {
954
939
Some ( sig) => {
955
940
if !sig. params ( ) . is_empty ( ) {
956
941
( sig. params ( ) [ 0 ] . clone ( ) , sig. params ( ) [ 1 ..] . to_vec ( ) , sig. ret ( ) . clone ( ) )
@@ -960,87 +945,28 @@ impl<'a> InferenceContext<'a> {
960
945
}
961
946
None => ( self . err_ty ( ) , Vec :: new ( ) , self . err_ty ( ) ) ,
962
947
} ;
963
- self . unify ( & formal_receiver_ty, & receiver_ty) ;
964
-
965
- let expected_inputs =
966
- self . expected_inputs_for_expected_output ( expected, ret_ty. clone ( ) , param_tys. clone ( ) ) ;
948
+ self . unify ( & expected_receiver_ty, & receiver_ty) ;
967
949
968
- self . check_call_arguments ( args, & expected_inputs , & param_tys) ;
950
+ self . check_call_arguments ( args, & param_tys) ;
969
951
self . normalize_associated_types_in ( ret_ty)
970
952
}
971
953
972
- fn expected_inputs_for_expected_output (
973
- & mut self ,
974
- expected_output : & Expectation ,
975
- output : Ty ,
976
- inputs : Vec < Ty > ,
977
- ) -> Vec < Ty > {
978
- // rustc does a snapshot here and rolls back the unification, but since
979
- // we actually want to keep unbound variables in the result it then
980
- // needs to do 'fudging' to recreate them. So I'm not sure rustc's
981
- // approach is cleaner than ours, which is to create independent copies
982
- // of the variables before unifying. It might be more performant though,
983
- // so we might want to benchmark when we can actually do
984
- // snapshot/rollback.
985
- if let Some ( expected_ty) = expected_output. to_option ( & mut self . table ) {
986
- let ( expected_ret_ty, expected_params) = self . table . reinstantiate ( ( output, inputs) ) ;
987
- if self . table . try_unify ( & expected_ty, & expected_ret_ty) . is_ok ( ) {
988
- expected_params
989
- } else {
990
- Vec :: new ( )
991
- }
992
- } else {
993
- Vec :: new ( )
994
- }
995
- }
996
-
997
- fn check_call_arguments ( & mut self , args : & [ ExprId ] , expected_inputs : & [ Ty ] , param_tys : & [ Ty ] ) {
954
+ fn check_call_arguments ( & mut self , args : & [ ExprId ] , param_tys : & [ Ty ] ) {
998
955
// Quoting https://github.com/rust-lang/rust/blob/6ef275e6c3cb1384ec78128eceeb4963ff788dca/src/librustc_typeck/check/mod.rs#L3325 --
999
956
// We do this in a pretty awful way: first we type-check any arguments
1000
957
// that are not closures, then we type-check the closures. This is so
1001
958
// that we have more information about the types of arguments when we
1002
959
// type-check the functions. This isn't really the right way to do this.
1003
960
for & check_closures in & [ false , true ] {
1004
961
let param_iter = param_tys. iter ( ) . cloned ( ) . chain ( repeat ( self . err_ty ( ) ) ) ;
1005
- let expected_iter = expected_inputs
1006
- . iter ( )
1007
- . cloned ( )
1008
- . chain ( param_iter. clone ( ) . skip ( expected_inputs. len ( ) ) ) ;
1009
- for ( ( & arg, param_ty) , expected_ty) in args. iter ( ) . zip ( param_iter) . zip ( expected_iter) {
962
+ for ( & arg, param_ty) in args. iter ( ) . zip ( param_iter) {
1010
963
let is_closure = matches ! ( & self . body[ arg] , Expr :: Lambda { .. } ) ;
1011
964
if is_closure != check_closures {
1012
965
continue ;
1013
966
}
1014
967
1015
- // the difference between param_ty and expected here is that
1016
- // expected is the parameter when the expected *return* type is
1017
- // taken into account. So in `let _: &[i32] = identity(&[1, 2])`
1018
- // the expected type is already `&[i32]`, whereas param_ty is
1019
- // still an unbound type variable. We don't always want to force
1020
- // the parameter to coerce to the expected type (for example in
1021
- // `coerce_unsize_expected_type_4`).
1022
968
let param_ty = self . normalize_associated_types_in ( param_ty) ;
1023
- let expected = Expectation :: rvalue_hint ( & mut self . table , expected_ty) ;
1024
- // infer with the expected type we have...
1025
- let ty = self . infer_expr_inner ( arg, & expected) ;
1026
-
1027
- // then coerce to either the expected type or just the formal parameter type
1028
- let coercion_target = if let Some ( ty) = expected. only_has_type ( & mut self . table ) {
1029
- // if we are coercing to the expectation, unify with the
1030
- // formal parameter type to connect everything
1031
- self . unify ( & ty, & param_ty) ;
1032
- ty
1033
- } else {
1034
- param_ty
1035
- } ;
1036
- if !coercion_target. is_unknown ( ) {
1037
- if self . coerce ( Some ( arg) , & ty, & coercion_target) . is_err ( ) {
1038
- self . result . type_mismatches . insert (
1039
- arg. into ( ) ,
1040
- TypeMismatch { expected : coercion_target, actual : ty. clone ( ) } ,
1041
- ) ;
1042
- }
1043
- }
969
+ self . infer_expr_coerce ( arg, & Expectation :: has_type ( param_ty. clone ( ) ) ) ;
1044
970
}
1045
971
}
1046
972
}
0 commit comments