Skip to content

Commit fd59466

Browse files
committed
change approach back to structural, and fix async as well
1 parent e2d5c0e commit fd59466

6 files changed

Lines changed: 31 additions & 17 deletions

File tree

compiler/ml/dict_type_helpers.ml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,9 @@
2828
A dict pattern is treated as a record pattern in the compiler and syntax, with an attriubute `@res.dictPattern`
2929
attached to it. This attribute is used to tell the compiler that the pattern is a dict pattern, and is what
3030
triggers the compiler to treat the dict record type differently to regular record types.
31-
Dict expressions are lowered to `Primitive_dict.make`, with an internal attribute attached so typing can
32-
recognize the construct without depending on the exact lowered callee path.
3331
*)
3432
let dict_magic_field_name = "dictValuesType"
3533

36-
let has_dict_literal_attribute attrs =
37-
attrs
38-
|> List.find_opt (fun (({txt}, _) : Parsetree.attribute) ->
39-
txt = "res.$dictLiteral")
40-
|> Option.is_some
41-
4234
let has_dict_pattern_attribute attrs =
4335
attrs
4436
|> List.find_opt (fun (({txt}, _) : Parsetree.attribute) ->
@@ -55,6 +47,3 @@ let dict_attr : Parsetree.attribute =
5547

5648
let dict_magic_field_attr : Parsetree.attribute =
5749
(Location.mknoloc "res.$dictMagicField", Parsetree.PStr [])
58-
59-
let dict_literal_attr : Parsetree.attribute =
60-
(Location.mknoloc "res.$dictLiteral", Parsetree.PStr [])

compiler/ml/typecore.ml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,6 +2259,19 @@ let extract_function_name funct =
22592259
| Texp_ident (path, _, _) -> Some (Longident.parse (Path.name path))
22602260
| _ -> None
22612261
2262+
let should_unify_expected_result_before_typing_lowered_apply funct sargs =
2263+
match (extract_function_name funct, sargs) with
2264+
| ( Some (Longident.Ldot (Longident.Lident "Primitive_dict", "make")),
2265+
[(Asttypes.Nolabel, {Parsetree.pexp_desc = Parsetree.Pexp_array _})] ) ->
2266+
(* Dict literals *)
2267+
true
2268+
| ( Some
2269+
(Longident.Ldot (Longident.Lident "Primitive_promise", "unsafe_async")),
2270+
[(Asttypes.Nolabel, _)] ) ->
2271+
(* Async wrapper *)
2272+
true
2273+
| _ -> false
2274+
22622275
type lazy_args =
22632276
(Asttypes.arg_label * (unit -> Typedtree.expression) option) list
22642277
@@ -2460,9 +2473,11 @@ and type_expect_ ?deprecated_context ~context ?in_function ?(recarg = Rejected)
24602473
let funct =
24612474
type_exp ~deprecated_context:FunctionCall ~context:None env sfunct
24622475
in
2463-
(if Dict_type_helpers.has_dict_literal_attribute sexp.pexp_attributes then
2464-
(* Dict literals lower to a regular application, so thread the expected
2465-
dict value type into the application before typing the tuple values. *)
2476+
(if should_unify_expected_result_before_typing_lowered_apply funct sargs
2477+
then
2478+
(* Lowered syntax like dict literals and async wrappers becomes a regular
2479+
application, so thread the expected result type into the application
2480+
before typing its arguments. *)
24662481
let _, ty_res =
24672482
filter_arrow ~env
24682483
~arity:(Some (List.length sargs))

compiler/syntax/src/res_core.ml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4324,7 +4324,6 @@ and parse_dict_expr ~start_pos p =
43244324
let key_value_pairs = List.filter_map to_key_value_pair rows in
43254325
Parser.expect Rbrace p;
43264326
Ast_helper.Exp.apply ~loc
4327-
~attrs:[Dict_type_helpers.dict_literal_attr]
43284327
(Ast_helper.Exp.ident ~loc
43294328
(Location.mkloc
43304329
(Longident.Ldot (Longident.Lident Primitive_modules.dict, "make"))

compiler/syntax/src/res_parsetree_viewer.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ let filter_parsing_attrs attrs =
250250
Location.txt =
251251
( "res.braces" | "ns.braces" | "res.iflet" | "res.ternary"
252252
| "res.await" | "res.template" | "res.taggedTemplate"
253-
| "res.patVariantSpread" | "res.dictPattern" | "res.$dictLiteral"
253+
| "res.patVariantSpread" | "res.dictPattern"
254254
| "res.inlineRecordDefinition" );
255255
},
256256
_ ) ->
@@ -585,7 +585,7 @@ let is_printable_attribute attr =
585585
Location.txt =
586586
( "res.iflet" | "res.braces" | "ns.braces" | "JSX" | "res.await"
587587
| "res.template" | "res.taggedTemplate" | "res.ternary"
588-
| "res.$dictLiteral" | "res.inlineRecordDefinition" );
588+
| "res.inlineRecordDefinition" );
589589
},
590590
_ ) ->
591591
false

tests/tests/src/DictScopedRecordLiteral.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ let dictValueInference = {
99
}
1010
};
1111

12+
async function asyncValueInference() {
13+
return {
14+
get: 200
15+
};
16+
}
17+
1218
let primitiveMakeValueInference = {
1319
health: {
1420
get: 200
@@ -18,6 +24,7 @@ let primitiveMakeValueInference = {
1824
export {
1925
Hidden,
2026
dictValueInference,
27+
asyncValueInference,
2128
primitiveMakeValueInference,
2229
}
2330
/* No side effect */

tests/tests/src/DictScopedRecordLiteral.res

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ let dictValueInference: Dict.t<Hidden.routeHandlerObject> = dict{
66
"health": {get: 200},
77
}
88

9+
let asyncValueInference: unit => promise<Hidden.routeHandlerObject> = async () => {
10+
get: 200,
11+
}
12+
913
let primitiveMakeValueInference: Dict.t<Hidden.routeHandlerObject> = dict{"health": {get: 200}}

0 commit comments

Comments
 (0)