@@ -66,7 +66,7 @@ use crate::expr::inference::{ImplVarTraitItemMappings, InferenceId};
66
66
use crate :: items:: constant:: { ConstValue , resolve_const_expr_and_evaluate, validate_const_expr} ;
67
67
use crate :: items:: enm:: SemanticEnumEx ;
68
68
use crate :: items:: feature_kind:: extract_item_feature_config;
69
- use crate :: items:: functions:: function_signature_params;
69
+ use crate :: items:: functions:: { concrete_function_closure_params , function_signature_params} ;
70
70
use crate :: items:: imp:: { ImplLookupContext , filter_candidate_traits, infer_impl_by_self} ;
71
71
use crate :: items:: modifiers:: compute_mutability;
72
72
use crate :: items:: us:: get_use_path_segments;
@@ -424,7 +424,7 @@ pub fn maybe_compute_expr_semantic(
424
424
ast:: Expr :: Indexed ( expr) => compute_expr_indexed_semantic ( ctx, expr) ,
425
425
ast:: Expr :: FixedSizeArray ( expr) => compute_expr_fixed_size_array_semantic ( ctx, expr) ,
426
426
ast:: Expr :: For ( expr) => compute_expr_for_semantic ( ctx, expr) ,
427
- ast:: Expr :: Closure ( expr) => compute_expr_closure_semantic ( ctx, expr) ,
427
+ ast:: Expr :: Closure ( expr) => compute_expr_closure_semantic ( ctx, expr, None ) ,
428
428
}
429
429
}
430
430
@@ -882,7 +882,7 @@ fn compute_expr_function_call_semantic(
882
882
let mut arg_types = vec ! [ ] ;
883
883
for arg_syntax in args_iter {
884
884
let stable_ptr = arg_syntax. stable_ptr ( ) ;
885
- let arg = compute_named_argument_clause ( ctx, arg_syntax) ;
885
+ let arg = compute_named_argument_clause ( ctx, arg_syntax, None ) ;
886
886
if arg. 2 != Mutability :: Immutable {
887
887
return Err ( ctx. diagnostics . report ( stable_ptr, RefClosureArgument ) ) ;
888
888
}
@@ -930,7 +930,7 @@ fn compute_expr_function_call_semantic(
930
930
let named_args: Vec < _ > = args_syntax
931
931
. elements ( syntax_db)
932
932
. into_iter ( )
933
- . map ( |arg_syntax| compute_named_argument_clause ( ctx, arg_syntax) )
933
+ . map ( |arg_syntax| compute_named_argument_clause ( ctx, arg_syntax, None ) )
934
934
. collect ( ) ;
935
935
if named_args. len ( ) != 1 {
936
936
return Err ( ctx. diagnostics . report ( syntax, WrongNumberOfArguments {
@@ -979,16 +979,21 @@ fn compute_expr_function_call_semantic(
979
979
let mut args_iter = args_syntax. elements ( syntax_db) . into_iter ( ) ;
980
980
// Normal parameters
981
981
let mut named_args = vec ! [ ] ;
982
- for _ in function_parameter_types ( ctx, function) ? {
982
+ let closure_params = concrete_function_closure_params ( db, function) ?;
983
+ for ty in function_parameter_types ( ctx, function) ? {
983
984
let Some ( arg_syntax) = args_iter. next ( ) else {
984
985
continue ;
985
986
} ;
986
- named_args. push ( compute_named_argument_clause ( ctx, arg_syntax) ) ;
987
+ named_args. push ( compute_named_argument_clause (
988
+ ctx,
989
+ arg_syntax,
990
+ closure_params. get ( & ty) . cloned ( ) ,
991
+ ) ) ;
987
992
}
988
993
989
994
// Maybe coupon
990
995
if let Some ( arg_syntax) = args_iter. next ( ) {
991
- named_args. push ( compute_named_argument_clause ( ctx, arg_syntax) ) ;
996
+ named_args. push ( compute_named_argument_clause ( ctx, arg_syntax, None ) ) ;
992
997
}
993
998
994
999
expr_function_call ( ctx, function, named_args, syntax, syntax. stable_ptr ( ) . into ( ) )
@@ -1006,6 +1011,7 @@ fn compute_expr_function_call_semantic(
1006
1011
pub fn compute_named_argument_clause (
1007
1012
ctx : & mut ComputationContext < ' _ > ,
1008
1013
arg_syntax : ast:: Arg ,
1014
+ closure_param_types : Option < TypeId > ,
1009
1015
) -> NamedArg {
1010
1016
let syntax_db = ctx. db . upcast ( ) ;
1011
1017
@@ -1018,12 +1024,24 @@ pub fn compute_named_argument_clause(
1018
1024
let arg_clause = arg_syntax. arg_clause ( syntax_db) ;
1019
1025
let ( expr, arg_name_identifier) = match arg_clause {
1020
1026
ast:: ArgClause :: Unnamed ( arg_unnamed) => {
1021
- ( compute_expr_semantic ( ctx, & arg_unnamed. value ( syntax_db) ) , None )
1027
+ let arg_expr = arg_unnamed. value ( syntax_db) ;
1028
+ if let ast:: Expr :: Closure ( expr_closure) = arg_expr {
1029
+ ( handle_closure_expr ( ctx, & expr_closure, closure_param_types) , None )
1030
+ } else {
1031
+ ( compute_expr_semantic ( ctx, & arg_unnamed. value ( syntax_db) ) , None )
1032
+ }
1033
+ }
1034
+ ast:: ArgClause :: Named ( arg_named) => {
1035
+ let arg_expr = arg_named. value ( syntax_db) ;
1036
+ if let ast:: Expr :: Closure ( expr_closure) = arg_expr {
1037
+ ( handle_closure_expr ( ctx, & expr_closure, closure_param_types) , None )
1038
+ } else {
1039
+ (
1040
+ compute_expr_semantic ( ctx, & arg_named. value ( syntax_db) ) ,
1041
+ Some ( arg_named. name ( syntax_db) ) ,
1042
+ )
1043
+ }
1022
1044
}
1023
- ast:: ArgClause :: Named ( arg_named) => (
1024
- compute_expr_semantic ( ctx, & arg_named. value ( syntax_db) ) ,
1025
- Some ( arg_named. name ( syntax_db) ) ,
1026
- ) ,
1027
1045
ast:: ArgClause :: FieldInitShorthand ( arg_field_init_shorthand) => {
1028
1046
let name_expr = arg_field_init_shorthand. name ( syntax_db) ;
1029
1047
let stable_ptr: ast:: ExprPtr = name_expr. stable_ptr ( ) . into ( ) ;
@@ -1038,6 +1056,17 @@ pub fn compute_named_argument_clause(
1038
1056
NamedArg ( expr, arg_name_identifier, mutability)
1039
1057
}
1040
1058
1059
+ fn handle_closure_expr (
1060
+ ctx : & mut ComputationContext < ' _ > ,
1061
+ expr_closure : & ast:: ExprClosure ,
1062
+ closure_param_types : Option < TypeId > ,
1063
+ ) -> ExprAndId {
1064
+ let expr = compute_expr_closure_semantic ( ctx, expr_closure, closure_param_types) ;
1065
+ let expr = wrap_maybe_with_missing ( ctx, expr, ast:: ExprPtr :: from ( expr_closure. stable_ptr ( ) ) ) ;
1066
+ let id = ctx. arenas . exprs . alloc ( expr. clone ( ) ) ;
1067
+ ExprAndId { expr, id }
1068
+ }
1069
+
1041
1070
pub fn compute_root_expr (
1042
1071
ctx : & mut ComputationContext < ' _ > ,
1043
1072
syntax : & ast:: ExprBlock ,
@@ -1645,6 +1674,7 @@ fn compute_loop_body_semantic(
1645
1674
fn compute_expr_closure_semantic (
1646
1675
ctx : & mut ComputationContext < ' _ > ,
1647
1676
syntax : & ast:: ExprClosure ,
1677
+ param_types : Option < TypeId > ,
1648
1678
) -> Maybe < Expr > {
1649
1679
ctx. are_closures_in_context = true ;
1650
1680
let syntax_db = ctx. db . upcast ( ) ;
@@ -1663,6 +1693,14 @@ fn compute_expr_closure_semantic(
1663
1693
} else {
1664
1694
vec ! [ ]
1665
1695
} ;
1696
+ let closure_type =
1697
+ TypeLongId :: Tuple ( params. iter ( ) . map ( |param| param. ty ) . collect ( ) ) . intern ( new_ctx. db ) ;
1698
+ if let Some ( param_types) = param_types {
1699
+ if let Err ( err_set) = new_ctx. resolver . inference ( ) . conform_ty ( closure_type, param_types)
1700
+ {
1701
+ new_ctx. resolver . inference ( ) . consume_error_without_reporting ( err_set) ;
1702
+ }
1703
+ }
1666
1704
1667
1705
params. iter ( ) . filter ( |param| param. mutability == Mutability :: Reference ) . for_each ( |param| {
1668
1706
new_ctx. diagnostics . report ( param. stable_ptr ( ctx. db . upcast ( ) ) , RefClosureParam ) ;
@@ -2834,16 +2872,22 @@ fn method_call_expr(
2834
2872
// Self argument.
2835
2873
let mut named_args = vec ! [ NamedArg ( fixed_lexpr, None , mutability) ] ;
2836
2874
// Other arguments.
2837
- for _ in function_parameter_types ( ctx, function_id) ?. skip ( 1 ) {
2875
+ let closure_params: OrderedHashMap < TypeId , TypeId > =
2876
+ concrete_function_closure_params ( ctx. db , function_id) ?;
2877
+ for ty in function_parameter_types ( ctx, function_id) ?. skip ( 1 ) {
2838
2878
let Some ( arg_syntax) = args_iter. next ( ) else {
2839
2879
break ;
2840
2880
} ;
2841
- named_args. push ( compute_named_argument_clause ( ctx, arg_syntax) ) ;
2881
+ named_args. push ( compute_named_argument_clause (
2882
+ ctx,
2883
+ arg_syntax,
2884
+ closure_params. get ( & ty) . cloned ( ) ,
2885
+ ) ) ;
2842
2886
}
2843
2887
2844
2888
// Maybe coupon
2845
2889
if let Some ( arg_syntax) = args_iter. next ( ) {
2846
- named_args. push ( compute_named_argument_clause ( ctx, arg_syntax) ) ;
2890
+ named_args. push ( compute_named_argument_clause ( ctx, arg_syntax, None ) ) ;
2847
2891
}
2848
2892
2849
2893
expr_function_call ( ctx, function_id, named_args, & expr, stable_ptr)
0 commit comments