@harmoniclabs/pebble 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FuncExpr } from "../../../../ast/nodes/expr/functions/FuncExpr.js";
|
|
1
2
|
import { DiagnosticCode } from "../../../../diagnostics/diagnosticMessages.generated.js";
|
|
2
3
|
import { TirCallExpr } from "../../../tir/expressions/TirCallExpr.js";
|
|
3
4
|
import { TirFuncT } from "../../../tir/types/TirNativeType/native/function.js";
|
|
@@ -48,15 +49,62 @@ export function _compileCallExpr(ctx, expr, typeHint) {
|
|
|
48
49
|
}
|
|
49
50
|
// 2) Compile arguments. We need them anyway, and they're used for
|
|
50
51
|
// inference when no explicit args were given.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
//
|
|
53
|
+
// For inferred-type-args calls, lambda arguments cannot be compiled
|
|
54
|
+
// without an expected function type (their param types would be
|
|
55
|
+
// unannotated). So we compile non-lambda args first, build an
|
|
56
|
+
// inference environment from them, then compile lambda args with
|
|
57
|
+
// the substituted expected type from `funcType.argTypes[i]`.
|
|
58
|
+
const tirArgs = new Array(expr.args.length);
|
|
59
|
+
const usable = Math.min(expr.args.length, funcType.argTypes.length);
|
|
60
|
+
if (explicitArgs) {
|
|
61
|
+
const explicitSubst = new Map(template.typeParams.map((tp, idx) => [tp.symbol, explicitArgs[idx]]));
|
|
62
|
+
for (let i = 0; i < expr.args.length; i++) {
|
|
63
|
+
const expected = i < funcType.argTypes.length
|
|
64
|
+
? substituteTypeParams(funcType.argTypes[i], explicitSubst)
|
|
65
|
+
: undefined;
|
|
66
|
+
const compiled = _compileExpr(ctx, expr.args[i], expected);
|
|
67
|
+
if (!compiled)
|
|
68
|
+
return undefined;
|
|
69
|
+
tirArgs[i] = compiled;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const env = new Map();
|
|
74
|
+
// Pass 1: compile non-FuncExpr args (no type hint needed) and
|
|
75
|
+
// populate `env` from each arg's resolved type.
|
|
76
|
+
for (let i = 0; i < expr.args.length; i++) {
|
|
77
|
+
if (expr.args[i] instanceof FuncExpr)
|
|
78
|
+
continue;
|
|
79
|
+
const compiled = _compileExpr(ctx, expr.args[i], undefined);
|
|
80
|
+
if (!compiled)
|
|
81
|
+
return undefined;
|
|
82
|
+
tirArgs[i] = compiled;
|
|
83
|
+
if (i < usable) {
|
|
84
|
+
if (!inferTypeArgs(funcType.argTypes[i], compiled.type, env))
|
|
85
|
+
return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.args[i].range, compiled.type.toString(), funcType.argTypes[i].toString());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Pass 2: compile FuncExpr args with the substituted expected
|
|
89
|
+
// type so lambda param types can be inferred from context.
|
|
90
|
+
for (let i = 0; i < expr.args.length; i++) {
|
|
91
|
+
if (!(expr.args[i] instanceof FuncExpr))
|
|
92
|
+
continue;
|
|
93
|
+
const expected = i < funcType.argTypes.length
|
|
94
|
+
? substituteTypeParams(funcType.argTypes[i], env)
|
|
95
|
+
: undefined;
|
|
96
|
+
const compiled = _compileExpr(ctx, expr.args[i], expected);
|
|
97
|
+
if (!compiled)
|
|
98
|
+
return undefined;
|
|
99
|
+
tirArgs[i] = compiled;
|
|
100
|
+
if (i < usable) {
|
|
101
|
+
// re-run to capture type params bound only via the
|
|
102
|
+
// lambda's return type (e.g. `map<T, A>(f: (T) -> A, ...)`)
|
|
103
|
+
if (!inferTypeArgs(funcType.argTypes[i], compiled.type, env))
|
|
104
|
+
return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.args[i].range, compiled.type.toString(), funcType.argTypes[i].toString());
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
60
108
|
// 3) Determine final type arguments
|
|
61
109
|
let resolvedArgs;
|
|
62
110
|
if (explicitArgs) {
|
|
@@ -64,7 +112,6 @@ export function _compileCallExpr(ctx, expr, typeHint) {
|
|
|
64
112
|
}
|
|
65
113
|
else {
|
|
66
114
|
const env = new Map();
|
|
67
|
-
const usable = Math.min(tirArgs.length, funcType.argTypes.length);
|
|
68
115
|
for (let i = 0; i < usable; i++) {
|
|
69
116
|
if (!inferTypeArgs(funcType.argTypes[i], tirArgs[i].type, env)) {
|
|
70
117
|
return ctx.error(DiagnosticCode.Type_0_is_not_assignable_to_type_1, expr.args[i].range, tirArgs[i].type.toString(), funcType.argTypes[i].toString());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const COMPILER_VERSION = "0.3.
|
|
1
|
+
export declare const COMPILER_VERSION = "0.3.1";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated by scripts/genVersion.js. Do not edit.
|
|
2
|
-
export const COMPILER_VERSION = "0.3.
|
|
2
|
+
export const COMPILER_VERSION = "0.3.1";
|
package/package.json
CHANGED