Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4e5fe9c

Browse files
fix: allow using nullable strings in template literals (#2928)
1 parent e5539ef commit 4e5fe9c

File tree

4 files changed

+350
-104
lines changed

4 files changed

+350
-104
lines changed

‎src/compiler.ts‎

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10154,6 +10154,7 @@ export class Compiler extends DiagnosticEmitter {
1015410154

1015510155
/** Makes a string conversion of the given expression. */
1015610156
makeToString(expr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef {
10157+
let module = this.module;
1015710158
let stringType = this.program.stringInstance.type;
1015810159
if (type == stringType) {
1015910160
return expr;
@@ -10170,15 +10171,30 @@ export class Compiler extends DiagnosticEmitter {
1017010171
reportNode
1017110172
)) {
1017210173
this.currentType = stringType;
10173-
return this.module.unreachable();
10174+
return module.unreachable();
1017410175
}
1017510176
if (!type.isStrictlyAssignableTo(assert(toStringSignature.thisType))) {
10176-
this.errorRelated(
10177-
DiagnosticCode.The_this_types_of_each_signature_are_incompatible,
10178-
reportNode.range, toStringInstance.identifierAndSignatureRange
10177+
if (!type.is(TypeFlags.Nullable)) {
10178+
this.errorRelated(
10179+
DiagnosticCode.The_this_types_of_each_signature_are_incompatible,
10180+
reportNode.range, toStringInstance.identifierAndSignatureRange
10181+
);
10182+
this.currentType = stringType;
10183+
return module.unreachable();
10184+
}
10185+
10186+
// Attempt to retry on the non-nullable form of the type, wrapped in a ternary:
10187+
// `expr ? expr.toString() : "null"`
10188+
const tempLocal = this.currentFlow.getTempLocal(type);
10189+
return module.if(
10190+
module.local_tee(tempLocal.index, expr, type.isManaged),
10191+
this.makeToString(
10192+
module.local_get(tempLocal.index, type.toRef()),
10193+
type.nonNullableType,
10194+
reportNode
10195+
),
10196+
this.ensureStaticString("null")
1017910197
);
10180-
this.currentType = stringType;
10181-
return this.module.unreachable();
1018210198
}
1018310199
let toStringReturnType = toStringSignature.returnType;
1018410200
if (!toStringReturnType.isStrictlyAssignableTo(stringType)) {
@@ -10187,7 +10203,7 @@ export class Compiler extends DiagnosticEmitter {
1018710203
reportNode.range, toStringInstance.identifierAndSignatureRange, toStringReturnType.toString(), stringType.toString()
1018810204
);
1018910205
this.currentType = stringType;
10190-
return this.module.unreachable();
10206+
return module.unreachable();
1019110207
}
1019210208
return this.makeCallDirect(toStringInstance, [ expr ], reportNode);
1019310209
}
@@ -10197,7 +10213,7 @@ export class Compiler extends DiagnosticEmitter {
1019710213
reportNode.range, type.toString(), stringType.toString()
1019810214
);
1019910215
this.currentType = stringType;
10200-
return this.module.unreachable();
10216+
return module.unreachable();
1020110217
}
1020210218

1020310219
/** Makes an allocation suitable to hold the data of an instance of the given class. */

‎tests/compiler/templateliteral.debug.wat‎

Lines changed: 143 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
(global $~lib/util/number/_K (mut i32) (i32.const 0))
4040
(global $~lib/util/number/_frc_pow (mut i64) (i64.const 0))
4141
(global $~lib/util/number/_exp_pow (mut i32) (i32.const 0))
42-
(global $~lib/rt/__rtti_base i32 (i32.const 4640))
43-
(global $~lib/memory/__data_end i32 (i32.const 4672))
44-
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 37440))
45-
(global $~lib/memory/__heap_base i32 (i32.const 37440))
42+
(global $~lib/rt/__rtti_base i32 (i32.const 4848))
43+
(global $~lib/memory/__data_end i32 (i32.const 4880))
44+
(global $~lib/memory/__stack_pointer (mut i32) (i32.const 37648))
45+
(global $~lib/memory/__heap_base i32 (i32.const 37648))
4646
(global $~started (mut i32) (i32.const 0))
4747
(memory 0ドル 1)
4848
(data 0ドル (i32.const 12) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円02円00円00円00円a00円00円00円00円00円00円00円00円00円00円00円")
@@ -98,11 +98,16 @@
9898
(data 50ドル (i32.const 4348) ",00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円14円00円00円00円r00円e00円f00円#00円100円r00円e00円f00円#00円200円00円00円00円00円00円00円00円00円")
9999
(data 51ドル (i32.const 4396) ",00円00円00円03円00円00円00円00円00円00円00円04円00円00円00円14円00円00円00円p02円00円00円00円00円00円00円90円02円00円00円00円00円00円00円\b002円00円00円00円00円00円00円00円00円00円00円")
100100
(data 52ドル (i32.const 4444) "<00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円$00円00円00円(00円A00円=00円r00円e00円f00円#00円100円,00円 00円B00円=00円r00円e00円f00円#00円200円)00円00円00円00円00円00円00円00円00円")
101-
(data 53ドル (i32.const 4508) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円02円00円00円00円c00円00円00円00円00円00円00円00円00円00円00円")
102-
(data 54ドル (i32.const 4540) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円02円00円00円00円:00円00円00円00円00円00円00円00円00円00円00円")
103-
(data 55ドル (i32.const 4572) "1円c00円00円00円03円00円00円00円00円00円00円00円04円00円00円00円0円c00円00円00円00円00円00円00円\d011円00円00円00円00円00円00円")
104-
(data 56ドル (i32.const 4604) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円\n00円00円00円a00円:00円b00円:00円c00円00円00円")
105-
(data 57ドル (i32.const 4640) "07円00円00円00円 00円00円00円 00円00円00円 00円00円00円00円00円00円00円04円A00円00円 00円00円00円00円00円00円00円")
101+
(data 53ドル (i32.const 4508) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円06円00円00円00円c00円:00円 00円00円00円00円00円00円00円")
102+
(data 54ドル (i32.const 4540) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円\n00円00円00円;00円 00円d00円:00円 00円00円00円")
103+
(data 55ドル (i32.const 4572) ",00円00円00円03円00円00円00円00円00円00円00円04円00円00円00円10円00円00円00円\b011円00円00円00円00円00円00円\d011円00円00円00円00円00円00円00円00円00円00円00円00円00円00円00円00円00円00円")
104+
(data 56ドル (i32.const 4620) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円08円00円00円00円n00円u00円l00円l00円00円00円00円00円")
105+
(data 57ドル (i32.const 4652) "<00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円\"00円00円00円c00円:00円 00円r00円e00円f00円#00円300円;00円 00円d00円:00円 00円n00円u00円l00円l00円00円00円00円00円00円00円00円00円00円00円")
106+
(data 58ドル (i32.const 4716) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円02円00円00円00円c00円00円00円00円00円00円00円00円00円00円00円")
107+
(data 59ドル (i32.const 4748) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円02円00円00円00円:00円00円00円00円00円00円00円00円00円00円00円")
108+
(data 60ドル (i32.const 4780) "1円c00円00円00円03円00円00円00円00円00円00円00円04円00円00円00円0円c00円00円00円00円00円00円00円\a012円00円00円00円00円00円00円")
109+
(data 61ドル (i32.const 4812) "1円c00円00円00円00円00円00円00円00円00円00円00円02円00円00円00円\n00円00円00円a00円:00円b00円:00円c00円00円00円")
110+
(data 62ドル (i32.const 4848) "07円00円00円00円 00円00円00円 00円00円00円 00円00円00円00円00円00円00円04円A00円00円 00円00円00円00円00円00円00円")
106111
(table 0ドル 1 1 funcref)
107112
(elem 0ドル (i32.const 1))
108113
(export "memory" (memory 0ドル))
@@ -4365,6 +4370,7 @@
43654370
call $templateliteral/test_float
43664371
call $templateliteral/test_fast_paths_string
43674372
call $templateliteral/test_ref
4373+
call $templateliteral/test_null
43684374
call $templateliteral/test_recursive
43694375
)
43704376
(func $~lib/rt/__visit_globals (param 0ドル i32)
@@ -4519,8 +4525,8 @@
45194525
global.get $~lib/memory/__data_end
45204526
i32.lt_s
45214527
if
4522-
i32.const 37472
4523-
i32.const 37520
4528+
i32.const 37680
4529+
i32.const 37728
45244530
i32.const 1
45254531
i32.const 1
45264532
call $~lib/builtins/abort
@@ -5991,6 +5997,126 @@
59915997
i32.add
59925998
global.set $~lib/memory/__stack_pointer
59935999
)
6000+
(func $templateliteral/test_null
6001+
(local $c i32)
6002+
(local $d i32)
6003+
(local 2ドル i32)
6004+
(local 3ドル i32)
6005+
(local 4ドル i32)
6006+
(local 5ドル i32)
6007+
global.get $~lib/memory/__stack_pointer
6008+
i32.const 32
6009+
i32.sub
6010+
global.set $~lib/memory/__stack_pointer
6011+
call $~stack_check
6012+
global.get $~lib/memory/__stack_pointer
6013+
i32.const 0
6014+
i32.const 32
6015+
memory.fill
6016+
global.get $~lib/memory/__stack_pointer
6017+
i32.const 0
6018+
i32.const 3
6019+
call $templateliteral/Ref#constructor
6020+
local.tee $c
6021+
i32.store
6022+
i32.const 0
6023+
local.set $d
6024+
global.get $~lib/memory/__stack_pointer
6025+
local.get $c
6026+
local.set 5ドル
6027+
global.get $~lib/memory/__stack_pointer
6028+
local.get 5ドル
6029+
i32.store offset=12
6030+
local.get 5ドル
6031+
call $templateliteral/Ref#toString
6032+
local.tee 2ドル
6033+
i32.store offset=16
6034+
global.get $~lib/memory/__stack_pointer
6035+
global.get $~lib/memory/__stack_pointer
6036+
local.get $d
6037+
local.tee 4ドル
6038+
i32.store offset=20
6039+
local.get 4ドル
6040+
if (result i32)
6041+
local.get 4ドル
6042+
local.set 5ドル
6043+
global.get $~lib/memory/__stack_pointer
6044+
local.get 5ドル
6045+
i32.store offset=12
6046+
local.get 5ドル
6047+
call $templateliteral/Ref#toString
6048+
else
6049+
i32.const 4640
6050+
end
6051+
local.tee 3ドル
6052+
i32.store offset=24
6053+
i32.const 4592
6054+
local.set 5ドル
6055+
global.get $~lib/memory/__stack_pointer
6056+
local.get 5ドル
6057+
i32.store offset=12
6058+
local.get 5ドル
6059+
i32.const 1
6060+
local.get 2ドル
6061+
local.set 5ドル
6062+
global.get $~lib/memory/__stack_pointer
6063+
local.get 5ドル
6064+
i32.store offset=28
6065+
local.get 5ドル
6066+
call $~lib/staticarray/StaticArray<~lib/string/String>#__uset
6067+
i32.const 4592
6068+
local.set 5ドル
6069+
global.get $~lib/memory/__stack_pointer
6070+
local.get 5ドル
6071+
i32.store offset=12
6072+
local.get 5ドル
6073+
i32.const 3
6074+
local.get 3ドル
6075+
local.set 5ドル
6076+
global.get $~lib/memory/__stack_pointer
6077+
local.get 5ドル
6078+
i32.store offset=28
6079+
local.get 5ドル
6080+
call $~lib/staticarray/StaticArray<~lib/string/String>#__uset
6081+
i32.const 4592
6082+
local.set 5ドル
6083+
global.get $~lib/memory/__stack_pointer
6084+
local.get 5ドル
6085+
i32.store offset=12
6086+
local.get 5ドル
6087+
i32.const 160
6088+
local.set 5ドル
6089+
global.get $~lib/memory/__stack_pointer
6090+
local.get 5ドル
6091+
i32.store offset=28
6092+
local.get 5ドル
6093+
call $~lib/staticarray/StaticArray<~lib/string/String>#join
6094+
local.set 5ドル
6095+
global.get $~lib/memory/__stack_pointer
6096+
local.get 5ドル
6097+
i32.store offset=4
6098+
local.get 5ドル
6099+
i32.const 4672
6100+
local.set 5ドル
6101+
global.get $~lib/memory/__stack_pointer
6102+
local.get 5ドル
6103+
i32.store offset=8
6104+
local.get 5ドル
6105+
call $~lib/string/String.__eq
6106+
i32.eqz
6107+
if
6108+
i32.const 0
6109+
i32.const 96
6110+
i32.const 60
6111+
i32.const 3
6112+
call $~lib/builtins/abort
6113+
unreachable
6114+
end
6115+
global.get $~lib/memory/__stack_pointer
6116+
i32.const 32
6117+
i32.add
6118+
global.set $~lib/memory/__stack_pointer
6119+
)
59946120
(func $templateliteral/RecursiveObject#constructor (param $this i32) (param $key i32) (param $val i32) (result i32)
59956121
(local 3ドル i32)
59966122
global.get $~lib/memory/__stack_pointer
@@ -6110,7 +6236,7 @@
61106236
call $templateliteral/RecursiveObject#toString
61116237
local.tee 3ドル
61126238
i32.store offset=12
6113-
i32.const 4592
6239+
i32.const 4800
61146240
local.set 4ドル
61156241
global.get $~lib/memory/__stack_pointer
61166242
local.get 4ドル
@@ -6124,7 +6250,7 @@
61246250
i32.store offset=16
61256251
local.get 4ドル
61266252
call $~lib/staticarray/StaticArray<~lib/string/String>#__uset
6127-
i32.const 4592
6253+
i32.const 4800
61286254
local.set 4ドル
61296255
global.get $~lib/memory/__stack_pointer
61306256
local.get 4ドル
@@ -6138,7 +6264,7 @@
61386264
i32.store offset=16
61396265
local.get 4ドル
61406266
call $~lib/staticarray/StaticArray<~lib/string/String>#__uset
6141-
i32.const 4592
6267+
i32.const 4800
61426268
local.set 4ドル
61436269
global.get $~lib/memory/__stack_pointer
61446270
local.get 4ドル
@@ -6175,7 +6301,7 @@
61756301
memory.fill
61766302
global.get $~lib/memory/__stack_pointer
61776303
i32.const 0
6178-
i32.const 4528
6304+
i32.const 4736
61796305
local.set 3ドル
61806306
global.get $~lib/memory/__stack_pointer
61816307
local.get 3ドル
@@ -6231,7 +6357,7 @@
62316357
local.get 3ドル
62326358
i32.store
62336359
local.get 3ドル
6234-
i32.const 4624
6360+
i32.const 4832
62356361
local.set 3ドル
62366362
global.get $~lib/memory/__stack_pointer
62376363
local.get 3ドル
@@ -6242,7 +6368,7 @@
62426368
if
62436369
i32.const 0
62446370
i32.const 96
6245-
i32.const 118
6371+
i32.const 125
62466372
i32.const 3
62476373
call $~lib/builtins/abort
62486374
unreachable

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /