diff --git a/src/resolver.ts b/src/resolver.ts index 5a19f8e152..6689c88add 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -763,7 +763,14 @@ export class Resolver extends DiagnosticEmitter { } let defaultType = typeParameterNode.defaultType; if (defaultType) { - let resolvedDefaultType = this.resolveType(defaultType, ctxFlow.actualFunction, contextualTypeArguments, reportMode); + // Default parameters are resolved in context of the called function, not the calling function + let defaultTypeContextualTypeArguments: Map | null = null; + if (prototype.parent.kind == ElementKind.CLASS) { + defaultTypeContextualTypeArguments = (prototype.parent).contextualTypeArguments; + } else if (prototype.parent.kind == ElementKind.FUNCTION) { + defaultTypeContextualTypeArguments = (prototype.parent).contextualTypeArguments; + } + let resolvedDefaultType = this.resolveType(defaultType, prototype, defaultTypeContextualTypeArguments, reportMode); if (!resolvedDefaultType) return null; resolvedTypeArguments[i] = resolvedDefaultType; continue; diff --git a/tests/compiler/optional-typeparameters.debug.wat b/tests/compiler/optional-typeparameters.debug.wat index efbf0b9585..cbe085dc33 100644 --- a/tests/compiler/optional-typeparameters.debug.wat +++ b/tests/compiler/optional-typeparameters.debug.wat @@ -26,10 +26,12 @@ (global $~lib/native/ASC_LOW_MEMORY_LIMIT i32 (i32.const 0)) (global $optional-typeparameters/tConcrete (mut i32) (i32.const 0)) (global $optional-typeparameters/tDerived (mut i32) (i32.const 0)) + (global $optional-typeparameters/tMethodDerived (mut i32) (i32.const 0)) + (global $optional-typeparameters/tMethodDerived2 (mut i32) (i32.const 0)) (global $~lib/rt/__rtti_base i32 (i32.const 416)) - (global $~lib/memory/__data_end i32 (i32.const 460)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 16844)) - (global $~lib/memory/__heap_base i32 (i32.const 16844)) + (global $~lib/memory/__data_end i32 (i32.const 484)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 16868)) + (global $~lib/memory/__heap_base i32 (i32.const 16868)) (memory $0 1) (data (i32.const 12) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e\00\00\00\00\00") (data (i32.const 76) "<\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00 \00\00\00~\00l\00i\00b\00/\00r\00t\00/\00i\00t\00c\00m\00s\00.\00t\00s\00\00\00\00\00\00\00\00\00\00\00\00\00") @@ -39,7 +41,7 @@ (data (i32.const 268) ",\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 320) "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00") (data (i32.const 348) "<\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 416) "\05\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") + (data (i32.const 416) "\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 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00\02A\00\00\00\00\00\00 \00\00\00\00\00\00\00") (table $0 1 1 funcref) (elem $0 (i32.const 1)) (export "memory" (memory $0)) @@ -2132,6 +2134,16 @@ local.get $b f64.add ) + (func $optional-typeparameters/TestMethodDerived<~lib/string/String>#test<~lib/array/Array<~lib/string/String>> (param $this i32) + i32.const 6 + i32.const 6 + i32.eq + drop + ) + (func $optional-typeparameters/TestMethodDerived2#foo (param $this i32) (param $v i32) + local.get $v + call $optional-typeparameters/TestMethodDerived<~lib/string/String>#test<~lib/array/Array<~lib/string/String>> + ) (func $~lib/rt/__visit_globals (param $0 i32) (local $1 i32) global.get $optional-typeparameters/tConcrete @@ -2148,6 +2160,20 @@ local.get $0 call $~lib/rt/itcms/__visit end + global.get $optional-typeparameters/tMethodDerived + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end + global.get $optional-typeparameters/tMethodDerived2 + local.tee $1 + if + local.get $1 + local.get $0 + call $~lib/rt/itcms/__visit + end i32.const 224 local.get $0 call $~lib/rt/itcms/__visit @@ -2166,28 +2192,90 @@ call $~lib/rt/itcms/__visit end ) + (func $~lib/array/Array<~lib/string/String>#__visit (param $this i32) (param $cookie i32) + (local $var$2 i32) + (local $var$3 i32) + (local $var$4 i32) + (local $val i32) + i32.const 1 + drop + local.get $this + i32.load offset=4 + local.set $var$2 + local.get $var$2 + local.get $this + i32.load offset=12 + i32.const 2 + i32.shl + i32.add + local.set $var$3 + loop $while-continue|0 + local.get $var$2 + local.get $var$3 + i32.lt_u + local.set $var$4 + local.get $var$4 + if + local.get $var$2 + i32.load + local.set $val + local.get $val + if + local.get $val + local.get $cookie + call $~lib/rt/itcms/__visit + end + local.get $var$2 + i32.const 4 + i32.add + local.set $var$2 + br $while-continue|0 + end + end + local.get $this + i32.load + local.get $cookie + call $~lib/rt/itcms/__visit + ) + (func $~lib/array/Array<~lib/string/String>~visit (param $0 i32) (param $1 i32) + local.get $0 + local.get $1 + call $~lib/array/Array<~lib/string/String>#__visit + ) (func $~lib/rt/__visit_members (param $0 i32) (param $1 i32) block $invalid - block $optional-typeparameters/TestDerived - block $optional-typeparameters/TestConcrete - block $~lib/arraybuffer/ArrayBufferView - block $~lib/string/String - block $~lib/arraybuffer/ArrayBuffer + block $optional-typeparameters/TestMethodDerived2 + block $~lib/array/Array<~lib/string/String> + block $optional-typeparameters/TestMethodDerived<~lib/string/String> + block $optional-typeparameters/TestDerived + block $optional-typeparameters/TestConcrete + 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 $optional-typeparameters/TestConcrete $optional-typeparameters/TestDerived $optional-typeparameters/TestMethodDerived<~lib/string/String> $~lib/array/Array<~lib/string/String> $optional-typeparameters/TestMethodDerived2 $invalid + end + return + end + return + end local.get $0 - i32.const 8 - i32.sub - i32.load - br_table $~lib/arraybuffer/ArrayBuffer $~lib/string/String $~lib/arraybuffer/ArrayBufferView $optional-typeparameters/TestConcrete $optional-typeparameters/TestDerived $invalid + local.get $1 + call $~lib/arraybuffer/ArrayBufferView~visit + return 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/array/Array<~lib/string/String>~visit return end return @@ -2202,8 +2290,8 @@ global.get $~lib/memory/__data_end i32.lt_s if - i32.const 16864 - i32.const 16912 + i32.const 16896 + i32.const 16944 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -2213,13 +2301,13 @@ (func $start:optional-typeparameters (local $0 i32) global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 8 i32.sub global.set $~lib/memory/__stack_pointer call $~stack_check global.get $~lib/memory/__stack_pointer - i32.const 0 - i32.store + i64.const 0 + i64.store i32.const 1 call $optional-typeparameters/testConcrete drop @@ -2269,8 +2357,34 @@ f64.const 2 call $optional-typeparameters/TestDerived#test drop + i32.const 0 + call $optional-typeparameters/TestMethodDerived<~lib/string/String>#constructor + global.set $optional-typeparameters/tMethodDerived + global.get $optional-typeparameters/tMethodDerived + local.set $0 global.get $~lib/memory/__stack_pointer - i32.const 4 + local.get $0 + i32.store + local.get $0 + call $optional-typeparameters/TestMethodDerived<~lib/string/String>#test<~lib/array/Array<~lib/string/String>> + i32.const 0 + call $optional-typeparameters/TestMethodDerived2#constructor + global.set $optional-typeparameters/tMethodDerived2 + global.get $optional-typeparameters/tMethodDerived2 + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store + local.get $0 + global.get $optional-typeparameters/tMethodDerived + local.set $0 + global.get $~lib/memory/__stack_pointer + local.get $0 + i32.store offset=4 + local.get $0 + call $optional-typeparameters/TestMethodDerived2#foo + global.get $~lib/memory/__stack_pointer + i32.const 8 i32.add global.set $~lib/memory/__stack_pointer ) @@ -2330,4 +2444,60 @@ global.set $~lib/memory/__stack_pointer local.get $1 ) + (func $optional-typeparameters/TestMethodDerived<~lib/string/String>#constructor (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 + i32.const 0 + i32.store + local.get $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store + end + local.get $0 + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) + (func $optional-typeparameters/TestMethodDerived2#constructor (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 + i32.const 0 + i32.store + local.get $0 + i32.eqz + if + global.get $~lib/memory/__stack_pointer + i32.const 0 + i32.const 7 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store + end + local.get $0 + local.set $1 + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $1 + ) ) diff --git a/tests/compiler/optional-typeparameters.release.wat b/tests/compiler/optional-typeparameters.release.wat index ddb8d5a540..f8d4bdf5dd 100644 --- a/tests/compiler/optional-typeparameters.release.wat +++ b/tests/compiler/optional-typeparameters.release.wat @@ -19,7 +19,9 @@ (global $~lib/rt/tlsf/ROOT (mut i32) (i32.const 0)) (global $optional-typeparameters/tConcrete (mut i32) (i32.const 0)) (global $optional-typeparameters/tDerived (mut i32) (i32.const 0)) - (global $~lib/memory/__stack_pointer (mut i32) (i32.const 17868)) + (global $optional-typeparameters/tMethodDerived (mut i32) (i32.const 0)) + (global $optional-typeparameters/tMethodDerived2 (mut i32) (i32.const 0)) + (global $~lib/memory/__stack_pointer (mut i32) (i32.const 17892)) (memory $0 1) (data (i32.const 1036) "<") (data (i32.const 1048) "\01\00\00\00(\00\00\00A\00l\00l\00o\00c\00a\00t\00i\00o\00n\00 \00t\00o\00o\00 \00l\00a\00r\00g\00e") @@ -31,8 +33,8 @@ (data (i32.const 1304) "\01\00\00\00\14\00\00\00~\00l\00i\00b\00/\00r\00t\00.\00t\00s") (data (i32.const 1372) "<") (data (i32.const 1384) "\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 1440) "\05\00\00\00 \00\00\00\00\00\00\00 ") - (data (i32.const 1468) " \00\00\00\00\00\00\00 ") + (data (i32.const 1440) "\08\00\00\00 \00\00\00\00\00\00\00 ") + (data (i32.const 1468) " \00\00\00\00\00\00\00 \00\00\00\00\00\00\00 \00\00\00\00\00\00\00\02A\00\00\00\00\00\00 ") (export "memory" (memory $0)) (start $~start) (func $~lib/rt/itcms/visitRoots @@ -50,6 +52,18 @@ local.get $0 call $byn-split-outlined-A$~lib/rt/itcms/__visit end + global.get $optional-typeparameters/tMethodDerived + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + global.get $optional-typeparameters/tMethodDerived2 + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end i32.const 1248 call $byn-split-outlined-A$~lib/rt/itcms/__visit i32.const 1056 @@ -623,10 +637,10 @@ if unreachable end - i32.const 17872 + i32.const 17904 i32.const 0 i32.store - i32.const 19440 + i32.const 19472 i32.const 0 i32.store loop $for-loop|0 @@ -637,7 +651,7 @@ local.get $0 i32.const 2 i32.shl - i32.const 17872 + i32.const 17904 i32.add i32.const 0 i32.store offset=4 @@ -655,7 +669,7 @@ i32.add i32.const 2 i32.shl - i32.const 17872 + i32.const 17904 i32.add i32.const 0 i32.store offset=96 @@ -673,13 +687,13 @@ br $for-loop|0 end end - i32.const 17872 - i32.const 19444 + i32.const 17904 + i32.const 19476 memory.size i32.const 16 i32.shl call $~lib/rt/tlsf/addMemory - i32.const 17872 + i32.const 17904 global.set $~lib/rt/tlsf/ROOT ) (func $~lib/rt/itcms/step (result i32) @@ -764,7 +778,7 @@ local.set $0 loop $while-continue|0 local.get $0 - i32.const 17868 + i32.const 17892 i32.lt_u if local.get $0 @@ -864,7 +878,7 @@ unreachable end local.get $0 - i32.const 17868 + i32.const 17892 i32.lt_u if local.get $0 @@ -887,7 +901,7 @@ i32.const 4 i32.add local.tee $0 - i32.const 17868 + i32.const 17892 i32.ge_u if global.get $~lib/rt/tlsf/ROOT @@ -1240,56 +1254,95 @@ local.get $0 ) (func $~lib/rt/__visit_members (param $0 i32) - block $invalid - block $optional-typeparameters/TestDerived - block $optional-typeparameters/TestConcrete - 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 $optional-typeparameters/TestConcrete $optional-typeparameters/TestDerived $invalid + (local $1 i32) + (local $2 i32) + (local $3 i32) + block $folding-inner0 + block $invalid + block $optional-typeparameters/TestMethodDerived2 + block $~lib/array/Array<~lib/string/String> + block $optional-typeparameters/TestMethodDerived<~lib/string/String> + block $optional-typeparameters/TestDerived + block $optional-typeparameters/TestConcrete + 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 $folding-inner0 $optional-typeparameters/TestConcrete $optional-typeparameters/TestDerived $optional-typeparameters/TestMethodDerived<~lib/string/String> $~lib/array/Array<~lib/string/String> $optional-typeparameters/TestMethodDerived2 $invalid + end + return + end + return + end + return end return end return end local.get $0 - i32.load - local.tee $0 - if - local.get $0 - call $byn-split-outlined-A$~lib/rt/itcms/__visit + i32.load offset=4 + local.tee $1 + local.get $0 + i32.load offset=12 + i32.const 2 + i32.shl + i32.add + local.set $3 + loop $while-continue|0 + local.get $1 + local.get $3 + i32.lt_u + if + local.get $1 + i32.load + local.tee $2 + if + local.get $2 + call $byn-split-outlined-A$~lib/rt/itcms/__visit + end + local.get $1 + i32.const 4 + i32.add + local.set $1 + br $while-continue|0 + end end - return + br $folding-inner0 end return end - return + unreachable + end + local.get $0 + i32.load + local.tee $0 + if + local.get $0 + call $byn-split-outlined-A$~lib/rt/itcms/__visit end - unreachable ) (func $~start (local $0 i32) global.get $~lib/memory/__stack_pointer - i32.const 4 + i32.const 8 i32.sub global.set $~lib/memory/__stack_pointer block $folding-inner0 global.get $~lib/memory/__stack_pointer - i32.const 1484 + i32.const 1508 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer local.tee $0 - i32.const 0 - i32.store + i64.const 0 + i64.store memory.size i32.const 16 i32.shl - i32.const 17868 + i32.const 17892 i32.sub i32.const 1 i32.shr_u @@ -1323,7 +1376,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1484 + i32.const 1508 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1349,7 +1402,7 @@ i32.sub global.set $~lib/memory/__stack_pointer global.get $~lib/memory/__stack_pointer - i32.const 1484 + i32.const 1508 i32.lt_s br_if $folding-inner0 global.get $~lib/memory/__stack_pointer @@ -1372,12 +1425,67 @@ i32.store global.get $~lib/memory/__stack_pointer i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1508 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store + local.get $0 + i32.const 5 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $optional-typeparameters/tMethodDerived + global.get $~lib/memory/__stack_pointer + global.get $optional-typeparameters/tMethodDerived + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.sub + global.set $~lib/memory/__stack_pointer + global.get $~lib/memory/__stack_pointer + i32.const 1508 + i32.lt_s + br_if $folding-inner0 + global.get $~lib/memory/__stack_pointer + local.tee $0 + i32.const 0 + i32.store + local.get $0 + i32.const 7 + call $~lib/rt/itcms/__new + local.tee $0 + i32.store + global.get $~lib/memory/__stack_pointer + i32.const 4 + i32.add + global.set $~lib/memory/__stack_pointer + local.get $0 + global.set $optional-typeparameters/tMethodDerived2 + global.get $~lib/memory/__stack_pointer + global.get $optional-typeparameters/tMethodDerived2 + i32.store + global.get $~lib/memory/__stack_pointer + global.get $optional-typeparameters/tMethodDerived + i32.store offset=4 + global.get $~lib/memory/__stack_pointer + i32.const 8 i32.add global.set $~lib/memory/__stack_pointer return end - i32.const 17888 - i32.const 17936 + i32.const 17920 + i32.const 17968 i32.const 1 i32.const 1 call $~lib/builtins/abort @@ -1426,7 +1534,7 @@ if i32.const 0 local.get $1 - i32.const 17868 + i32.const 17892 i32.lt_u local.get $1 i32.load offset=8 diff --git a/tests/compiler/optional-typeparameters.ts b/tests/compiler/optional-typeparameters.ts index a726b28f4a..7ba1699c0e 100644 --- a/tests/compiler/optional-typeparameters.ts +++ b/tests/compiler/optional-typeparameters.ts @@ -1,21 +1,21 @@ -function testConcrete(a: T): U { +function testConcrete(a: T): U { return a; } -function testDerived(a: T): U { +function testDerived(a: T): U { return a; } testConcrete(1); testDerived(2); -class TestConcrete { +class TestConcrete { test(a: T, b: U): V { return a + b; } } -class TestDerived { +class TestDerived { test(a: T, b: U): V { return a + b; } @@ -25,3 +25,19 @@ var tConcrete = new TestConcrete(); tConcrete.test(1, 2); var tDerived = new TestDerived(); tDerived.test(1, 2); + +class TestMethodDerived { + test(): void { + assert(idof() == idof()); + } +} +class TestMethodDerived2 { + foo(v: TestMethodDerived): void { + v.test(); + } +} + +var tMethodDerived = new TestMethodDerived(); +tMethodDerived.test(); +var tMethodDerived2 = new TestMethodDerived2(); +tMethodDerived2.foo(tMethodDerived);