Skip to content

fix: remove the parameter number limit for functionType infer #2434

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions src/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -834,20 +834,21 @@ export class Resolver extends DiagnosticEmitter {
} else if (node.kind == NodeKind.FUNCTIONTYPE) { // foo<T>(bar: (baz: T) => i32))
let functionTypeNode = <FunctionTypeNode>node;
let parameterNodes = functionTypeNode.parameters;
if (parameterNodes && parameterNodes.length > 0) {
let signatureReference = type.signatureReference;
if (signatureReference) {
let parameterTypes = signatureReference.parameterTypes;
let thisType = signatureReference.thisType;
if (parameterTypes.length == parameterNodes.length && !thisType == !functionTypeNode.explicitThisType) {
for (let i = 0, k = parameterTypes.length; i < k; ++i) {
this.propagateInferredGenericTypes(parameterNodes[i].type, parameterTypes[i], ctxElement, ctxTypes, typeParameterNames);
}
this.propagateInferredGenericTypes(functionTypeNode.returnType, signatureReference.returnType, ctxElement, ctxTypes, typeParameterNames);
if (thisType) this.propagateInferredGenericTypes(functionTypeNode.explicitThisType!, thisType, ctxElement, ctxTypes, typeParameterNames);
return;
}
let signatureReference = type.signatureReference;
if (signatureReference) {
let parameterTypes = signatureReference.parameterTypes;
for (let i = 0, k = min(parameterTypes.length, parameterNodes.length) ; i < k; ++i) {
this.propagateInferredGenericTypes(parameterNodes[i].type, parameterTypes[i], ctxElement, ctxTypes, typeParameterNames);
}
if (signatureReference.returnType != Type.void) {
this.propagateInferredGenericTypes(functionTypeNode.returnType, signatureReference.returnType, ctxElement, ctxTypes, typeParameterNames);
}
let thisType = signatureReference.thisType;
let explicitThisType = functionTypeNode.explicitThisType;
if (thisType && explicitThisType) {
this.propagateInferredGenericTypes(explicitThisType, thisType, ctxElement, ctxTypes, typeParameterNames);
}
return;
}
}
}
Expand Down
96 changes: 70 additions & 26 deletions tests/compiler/infer-generic.debug.wat
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
(global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0))
(global $~lib/native/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0))
(global $~lib/rt/__rtti_base i32 (i32.const 592))
(global $~lib/memory/__data_end i32 (i32.const 660))
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 17044))
(global $~lib/memory/__heap_base i32 (i32.const 17044))
(global $~lib/memory/__data_end i32 (i32.const 668))
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 17052))
(global $~lib/memory/__heap_base i32 (i32.const 17052))
(memory $0 1)
(data (i32.const 12) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00 \00\00\00i\00n\00f\00e\00r\00-\00g\00e\00n\00e\00r\00i\00c\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00")
(data (i32.const 76) "\1c\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0c\00\00\00\00\00\80?\00\00\00@\00\00@@")
Expand All @@ -45,14 +45,15 @@
(data (i32.const 444) ",\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s\00\00\00\00\00\00\00\00\00")
(data (i32.const 496) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")
(data (i32.const 524) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")
(data (i32.const 592) "\08\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\02\19\00\00\00\00\00\00\00\00\00\00\00\00\00\00 \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")
(data (i32.const 592) "\t\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\02\19\00\00\00\00\00\00\00\00\00\00\00\00\00\00 \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00")
(table $0 2 2 funcref)
(elem $0 (i32.const 1) $start:infer-generic~anonymous|0)
(export "test1" (func $infer-generic/test1))
(export "memory" (memory $0))
(export "test2" (func $export:infer-generic/test2))
(export "test3" (func $export:infer-generic/test3))
(export "test4" (func $export:infer-generic/test4))
(export "test5" (func $export:infer-generic/test5))
(export "inferAssert" (func $export:infer-generic/inferAssert))
(start $~start)
(func $infer-generic/inferCompatible<f64> (param $a f64) (param $b f64) (result i32)
Expand Down Expand Up @@ -2220,17 +2221,24 @@
local.get $arr
call $infer-generic/inferEncapsulatedClass<f32>
)
(func $infer-generic/inferEncapsulatedFunction<f32,f64> (param $fn i32) (result i32)
(func $infer-generic/inferEncapsulatedFunctionNull<f64> (param $fn i32) (result i32)
local.get $fn
)
(func $infer-generic/test3 (param $fn i32) (result i32)
local.get $fn
call $infer-generic/inferEncapsulatedFunctionNull<f64>
)
(func $infer-generic/inferEncapsulatedFunction<f32,f64> (param $fn i32) (result i32)
local.get $fn
)
(func $infer-generic/test4 (param $fn i32) (result i32)
local.get $fn
call $infer-generic/inferEncapsulatedFunction<f32,f64>
)
(func $infer-generic/inferEncapsulatedFunctionMixed<f32,f64> (param $fn i32) (result i32)
local.get $fn
)
(func $infer-generic/test4 (param $fn i32) (result i32)
(func $infer-generic/test5 (param $fn i32) (result i32)
local.get $fn
call $infer-generic/inferEncapsulatedFunctionMixed<f32,f64>
)
Expand All @@ -2242,7 +2250,7 @@
if (result i32)
i32.const 0
i32.const 32
i32.const 67
i32.const 75
i32.const 3
call $~lib/builtins/abort
unreachable
Expand Down Expand Up @@ -2303,6 +2311,17 @@
local.get $1
call $~lib/function/Function<%28bool%2Cf32%2Ci32%2C~lib/array/Array<f32>%29=>bool>#__visit
)
(func $~lib/function/Function<%28%29=>f64>#__visit (param $this i32) (param $cookie i32)
local.get $this
i32.load offset=4
local.get $cookie
call $~lib/rt/itcms/__visit
)
(func $~lib/function/Function<%28%29=>f64>~visit (param $0 i32) (param $1 i32)
local.get $0
local.get $1
call $~lib/function/Function<%28%29=>f64>#__visit
)
(func $~lib/function/Function<%28f32%29=>f64>#__visit (param $this i32) (param $cookie i32)
local.get $this
i32.load offset=4
Expand All @@ -2329,37 +2348,43 @@
block $invalid
block $~lib/function/Function<%28f32%2Ci32%29=>f64>
block $~lib/function/Function<%28f32%29=>f64>
block $infer-generic/Ref
block $~lib/function/Function<%28bool%2Cf32%2Ci32%2C~lib/array/Array<f32>%29=>bool>
block $~lib/array/Array<f32>
block $~lib/arraybuffer/ArrayBufferView
block $~lib/string/String
block $~lib/arraybuffer/ArrayBuffer
local.get $0
i32.const 8
i32.sub
i32.load
br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $~lib/array/Array<f32> $~lib/function/Function<%28bool%2Cf32%2Ci32%2C~lib/array/Array<f32>%29=>bool> $infer-generic/Ref $~lib/function/Function<%28f32%29=>f64> $~lib/function/Function<%28f32%2Ci32%29=>f64> $invalid
block $~lib/function/Function<%28%29=>f64>
block $infer-generic/Ref
block $~lib/function/Function<%28bool%2Cf32%2Ci32%2C~lib/array/Array<f32>%29=>bool>
block $~lib/array/Array<f32>
block $~lib/arraybuffer/ArrayBufferView
block $~lib/string/String
block $~lib/arraybuffer/ArrayBuffer
local.get $0
i32.const 8
i32.sub
i32.load
br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $~lib/array/Array<f32> $~lib/function/Function<%28bool%2Cf32%2Ci32%2C~lib/array/Array<f32>%29=>bool> $infer-generic/Ref $~lib/function/Function<%28%29=>f64> $~lib/function/Function<%28f32%29=>f64> $~lib/function/Function<%28f32%2Ci32%29=>f64> $invalid
end
return
end
return
end
local.get $0
local.get $1
call $~lib/arraybuffer/ArrayBufferView~visit
return
end
local.get $0
local.get $1
call $~lib/arraybuffer/ArrayBufferView~visit
call $~lib/array/Array<f32>~visit
return
end
local.get $0
local.get $1
call $~lib/array/Array<f32>~visit
call $~lib/function/Function<%28bool%2Cf32%2Ci32%2C~lib/array/Array<f32>%29=>bool>~visit
return
end
local.get $0
local.get $1
call $~lib/function/Function<%28bool%2Cf32%2Ci32%2C~lib/array/Array<f32>%29=>bool>~visit
return
end
local.get $0
local.get $1
call $~lib/function/Function<%28%29=>f64>~visit
return
end
local.get $0
Expand Down Expand Up @@ -2412,7 +2437,7 @@
if
i32.const 0
i32.const 32
i32.const 46
i32.const 54
i32.const 1
call $~lib/builtins/abort
unreachable
Expand Down Expand Up @@ -2440,7 +2465,7 @@
if
i32.const 0
i32.const 32
i32.const 62
i32.const 70
i32.const 1
call $~lib/builtins/abort
unreachable
Expand Down Expand Up @@ -2483,7 +2508,7 @@
if
i32.const 0
i32.const 32
i32.const 63
i32.const 71
i32.const 1
call $~lib/builtins/abort
unreachable
Expand Down Expand Up @@ -2581,6 +2606,25 @@
global.set $~lib/memory/__stack_pointer
local.get $1
)
(func $export:infer-generic/test5 (param $0 i32) (result i32)
(local $1 i32)
global.get $~lib/memory/__stack_pointer
i32.const 4
i32.sub
global.set $~lib/memory/__stack_pointer
call $~stack_check
global.get $~lib/memory/__stack_pointer
local.get $0
i32.store
local.get $0
call $infer-generic/test5
local.set $1
global.get $~lib/memory/__stack_pointer
i32.const 4
i32.add
global.set $~lib/memory/__stack_pointer
local.get $1
)
(func $export:infer-generic/inferAssert (param $0 i32)
global.get $~lib/memory/__stack_pointer
i32.const 4
Expand Down
27 changes: 14 additions & 13 deletions tests/compiler/infer-generic.release.wat
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
(global $~lib/rt/itcms/white (mut i32) (i32.const 0))
(global $~lib/rt/itcms/fromSpace (mut i32) (i32.const 0))
(global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0))
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 18068))
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 18076))
(memory $0 1)
(data (i32.const 1036) "<")
(data (i32.const 1048) "\01\00\00\00 \00\00\00i\00n\00f\00e\00r\00-\00g\00e\00n\00e\00r\00i\00c\00.\00t\00s")
Expand All @@ -39,7 +39,7 @@
(data (i32.const 1480) "\01\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s")
(data (i32.const 1548) "<")
(data (i32.const 1560) "\01\00\00\00\1e\00\00\00~\00l\00i\00b\00/\00r\00t\00/\00t\00l\00s\00f\00.\00t\00s")
(data (i32.const 1616) "\08\00\00\00 \00\00\00\00\00\00\00 ")
(data (i32.const 1616) "\t\00\00\00 \00\00\00\00\00\00\00 ")
(data (i32.const 1644) "\02\19")
(data (i32.const 1660) " ")
(table $0 2 2 funcref)
Expand All @@ -49,6 +49,7 @@
(export "test2" (func $export:infer-generic/test2))
(export "test3" (func $export:infer-generic/test2))
(export "test4" (func $export:infer-generic/test2))
(export "test5" (func $export:infer-generic/test2))
(export "inferAssert" (func $export:infer-generic/inferAssert))
(start $~start)
(func $start:infer-generic~anonymous|0 (param $0 i32) (param $1 f32) (param $2 i32) (param $3 i32) (result i32)
Expand Down Expand Up @@ -778,7 +779,7 @@
local.set $0
loop $while-continue|0
local.get $0
i32.const 18068
i32.const 18076
i32.lt_u
if
local.get $0
Expand Down Expand Up @@ -878,7 +879,7 @@
unreachable
end
local.get $0
i32.const 18068
i32.const 18076
i32.lt_u
if
local.get $0
Expand All @@ -901,7 +902,7 @@
i32.const 4
i32.add
local.tee $0
i32.const 18068
i32.const 18076
i32.ge_u
if
global.get $~lib/rt/tlsf/ROOT
Expand Down Expand Up @@ -1266,7 +1267,7 @@
i32.const 8
i32.sub
i32.load
br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $folding-inner1 $folding-inner1 $folding-inner0 $infer-generic/Ref $folding-inner0 $folding-inner0 $invalid
br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $folding-inner1 $folding-inner1 $folding-inner0 $infer-generic/Ref $folding-inner0 $folding-inner0 $folding-inner0 $invalid
end
return
end
Expand Down Expand Up @@ -1304,7 +1305,7 @@
global.set $~lib/memory/__stack_pointer
block $folding-inner0
global.get $~lib/memory/__stack_pointer
i32.const 1684
i32.const 1692
i32.lt_s
br_if $folding-inner0
global.get $~lib/memory/__stack_pointer
Expand Down Expand Up @@ -1359,7 +1360,7 @@
memory.size
i32.const 16
i32.shl
i32.const 18068
i32.const 18076
i32.sub
i32.const 1
i32.shr_u
Expand Down Expand Up @@ -1394,7 +1395,7 @@
i32.sub
global.set $~lib/memory/__stack_pointer
global.get $~lib/memory/__stack_pointer
i32.const 1684
i32.const 1692
i32.lt_s
br_if $folding-inner0
global.get $~lib/memory/__stack_pointer
Expand Down Expand Up @@ -1441,7 +1442,7 @@
i32.sub
global.set $~lib/memory/__stack_pointer
global.get $~lib/memory/__stack_pointer
i32.const 1684
i32.const 1692
i32.lt_s
if
i32.const 18096
Expand All @@ -1467,7 +1468,7 @@
i32.sub
global.set $~lib/memory/__stack_pointer
global.get $~lib/memory/__stack_pointer
i32.const 1684
i32.const 1692
i32.lt_s
if
i32.const 18096
Expand All @@ -1485,7 +1486,7 @@
if
i32.const 0
i32.const 1056
i32.const 67
i32.const 75
i32.const 3
call $~lib/builtins/abort
unreachable
Expand Down Expand Up @@ -1541,7 +1542,7 @@
if
i32.const 0
local.get $1
i32.const 18068
i32.const 18076
i32.lt_u
local.get $1
i32.load offset=8
Expand Down
12 changes: 10 additions & 2 deletions tests/compiler/infer-generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,21 @@ export function test2(arr: f32[]): f32[] {
return inferEncapsulatedClass(arr);
}

// () => R should infer R
function inferEncapsulatedFunctionNull<R>(fn: () => R): () => R {
return fn;
}
export function test3(fn: () => f64): () => f64 {
return inferEncapsulatedFunctionNull(fn);
}

// (a: T) => R should infer T,R

function inferEncapsulatedFunction<T, R>(fn: (a: T) => R): (a: T) => R {
return fn;
}

export function test3(fn: (a: f32) => f64): (a: f32) => f64 {
export function test4(fn: (a: f32) => f64): (a: f32) => f64 {
return inferEncapsulatedFunction(fn);
}

Expand All @@ -34,7 +42,7 @@ function inferEncapsulatedFunctionMixed<T, R>(fn: (a: T, b: i32) => R): (a: T, b
return fn;
}

export function test4(fn: (a: f32, b: i32) => f64): (a: f32, b: i32) => f64 {
export function test5(fn: (a: f32, b: i32) => f64): (a: f32, b: i32) => f64 {
return inferEncapsulatedFunctionMixed(fn);
}

Expand Down