Skip to content

Commit 5237fd4

Browse files
authored
Cache undefined widening properties per symbol, not per name (#64728)
1 parent 2e9fb00 commit 5237fd4

8 files changed

Lines changed: 125 additions & 39 deletions

‎tsc/internal/checker/checker.go‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ type Checker struct {
639639
subtypeReductionCache map[CacheHashKey][]*Type
640640
cachedTypes map[CachedTypeKey]*Type
641641
cachedSignatures map[CachedSignatureKey]*Signature
642-
undefinedProperties map[string]*ast.Symbol
642+
undefinedProperties map[*ast.Symbol]*ast.Symbol
643643
narrowedTypes map[NarrowedTypeKey]*Type
644644
assignmentReducedTypes map[AssignmentReducedKey]*Type
645645
discriminatedContextualTypes map[DiscriminatedContextualTypeKey]*Type
@@ -977,7 +977,7 @@ func NewChecker(program Program, tracer *Tracer) (*Checker, *sync.Mutex) {
977977
c.subtypeReductionCache = make(map[CacheHashKey][]*Type)
978978
c.cachedTypes = make(map[CachedTypeKey]*Type)
979979
c.cachedSignatures = make(map[CachedSignatureKey]*Signature)
980-
c.undefinedProperties = make(map[string]*ast.Symbol)
980+
c.undefinedProperties = make(map[*ast.Symbol]*ast.Symbol)
981981
c.narrowedTypes = make(map[NarrowedTypeKey]*Type)
982982
c.assignmentReducedTypes = make(map[AssignmentReducedKey]*Type)
983983
c.discriminatedContextualTypes = make(map[DiscriminatedContextualTypeKey]*Type)
@@ -18927,12 +18927,12 @@ func (c *Checker) getSiblingsOfContext(context *WideningContext) []*Type {
1892718927
}
1892818928

1892918929
func (c *Checker) getUndefinedProperty(prop *ast.Symbol) *ast.Symbol {
18930-
if cached := c.undefinedProperties[prop.Name()]; cached != nil {
18930+
if cached := c.undefinedProperties[prop]; cached != nil {
1893118931
return cached
1893218932
}
1893318933
result := c.createSymbolWithType(prop, c.undefinedOrMissingType)
1893418934
result.SetFlags(result.Flags() | ast.SymbolFlagsOptional)
18935-
c.undefinedProperties[prop.Name()] = result
18935+
c.undefinedProperties[prop] = result
1893618936
return result
1893718937
}
1893818938

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//// [tests/cases/compiler/undefinedPropertyDeclarationOrder.ts] ////
2+
3+
//// [undefinedPropertyDeclarationOrder.ts]
4+
export const a = Math.random() > 0.5 ? { user: 1 } : { status: "a" };
5+
export const b = Math.random() > 0.5 ? { status: "no" } : { status: "ok", user: 2 };
6+
7+
8+
9+
10+
//// [undefinedPropertyDeclarationOrder.d.ts]
11+
export declare const a: {
12+
user: number;
13+
status?: undefined;
14+
} | {
15+
user?: undefined;
16+
status: string;
17+
};
18+
export declare const b: {
19+
status: string;
20+
user?: undefined;
21+
} | {
22+
status: string;
23+
user: number;
24+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//// [tests/cases/compiler/undefinedPropertyDeclarationOrder.ts] ////
2+
3+
=== undefinedPropertyDeclarationOrder.ts ===
4+
export const a = Math.random() > 0.5 ? { user: 1 } : { status: "a" };
5+
>a : Symbol(a, Decl(undefinedPropertyDeclarationOrder.ts, 0, 12))
6+
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
7+
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2025.float16.d.ts, --, --) ... and 1 more)
8+
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
9+
>user : Symbol(user, Decl(undefinedPropertyDeclarationOrder.ts, 0, 40))
10+
>status : Symbol(status, Decl(undefinedPropertyDeclarationOrder.ts, 0, 54))
11+
12+
export const b = Math.random() > 0.5 ? { status: "no" } : { status: "ok", user: 2 };
13+
>b : Symbol(b, Decl(undefinedPropertyDeclarationOrder.ts, 1, 12))
14+
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
15+
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2025.float16.d.ts, --, --) ... and 1 more)
16+
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
17+
>status : Symbol(status, Decl(undefinedPropertyDeclarationOrder.ts, 1, 40))
18+
>status : Symbol(status, Decl(undefinedPropertyDeclarationOrder.ts, 1, 59))
19+
>user : Symbol(user, Decl(undefinedPropertyDeclarationOrder.ts, 1, 73))
20+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//// [tests/cases/compiler/undefinedPropertyDeclarationOrder.ts] ////
2+
3+
=== undefinedPropertyDeclarationOrder.ts ===
4+
export const a = Math.random() > 0.5 ? { user: 1 } : { status: "a" };
5+
>a : { user: number; status?: undefined; } | { user?: undefined; status: string; }
6+
>Math.random() > 0.5 ? { user: 1 } : { status: "a" } : { user: number; } | { status: string; }
7+
>Math.random() > 0.5 : boolean
8+
>Math.random() : number
9+
>Math.random : () => number
10+
>Math : Math
11+
>random : () => number
12+
>0.5 : 0.5
13+
>{ user: 1 } : { user: number; }
14+
>user : number
15+
>1 : 1
16+
>{ status: "a" } : { status: string; }
17+
>status : string
18+
>"a" : "a"
19+
20+
export const b = Math.random() > 0.5 ? { status: "no" } : { status: "ok", user: 2 };
21+
>b : { status: string; user?: undefined; } | { status: string; user: number; }
22+
>Math.random() > 0.5 ? { status: "no" } : { status: "ok", user: 2 } : { status: string; } | { status: string; user: number; }
23+
>Math.random() > 0.5 : boolean
24+
>Math.random() : number
25+
>Math.random : () => number
26+
>Math : Math
27+
>random : () => number
28+
>0.5 : 0.5
29+
>{ status: "no" } : { status: string; }
30+
>status : string
31+
>"no" : "no"
32+
>{ status: "ok", user: 2 } : { status: string; user: number; }
33+
>status : string
34+
>"ok" : "ok"
35+
>user : number
36+
>2 : 2
37+

‎tsc/testdata/baselines/reference/conformance/objectLiteralNormalization.js‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,35 +160,35 @@ declare let c3: {
160160
a: number;
161161
b: number;
162162
} | {
163-
b?: undefined;
164163
a?: undefined;
164+
b?: undefined;
165165
};
166166
declare let c4: {
167-
b?: undefined;
168167
a?: undefined;
168+
b?: undefined;
169169
} | {
170170
a: number;
171171
b: number;
172172
};
173173
declare let d1: {
174174
kind: string;
175175
pos: {
176-
b?: undefined;
177-
a?: undefined;
178176
x: number;
179177
y: number;
178+
a?: undefined;
179+
b?: undefined;
180180
};
181181
} | {
182182
kind: string;
183183
pos: {
184-
b?: undefined;
185184
x?: undefined;
186185
y?: undefined;
187186
a: string;
187+
b?: undefined;
188188
} | {
189-
a?: undefined;
190189
x?: undefined;
191190
y?: undefined;
191+
a?: undefined;
192192
b: number;
193193
};
194194
};
@@ -209,11 +209,11 @@ declare let e1: {
209209
a?: undefined;
210210
};
211211
declare let e2: {
212-
b?: undefined;
213212
a?: undefined;
214-
} | {
215213
b?: undefined;
214+
} | {
216215
a: string;
216+
b?: undefined;
217217
} | {
218218
a: number;
219219
b: number;

‎tsc/testdata/baselines/reference/conformance/objectLiteralNormalization.symbols‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ a2.a; // string | number | undefined
5555
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27))
5656

5757
a2.b; // number | undefined
58-
>a2.b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17), Decl(objectLiteralNormalization.ts, 1, 45))
58+
>a2.b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17))
5959
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
60-
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17), Decl(objectLiteralNormalization.ts, 1, 45))
60+
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17))
6161

6262
a2 = { a: 10, b: 20 };
6363
>a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3))
@@ -160,18 +160,18 @@ d1.pos.y;
160160
>y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35))
161161

162162
d1.pos.a;
163-
>d1.pos.a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 27), Decl(objectLiteralNormalization.ts, 33, 73))
163+
>d1.pos.a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73))
164164
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
165165
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
166166
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
167-
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 27), Decl(objectLiteralNormalization.ts, 33, 73))
167+
>a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73))
168168

169169
d1.pos.b;
170-
>d1.pos.b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 45), Decl(objectLiteralNormalization.ts, 33, 86))
170+
>d1.pos.b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86))
171171
>d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
172172
>d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3))
173173
>pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58))
174-
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 45), Decl(objectLiteralNormalization.ts, 33, 86))
174+
>b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86))
175175

176176
declare function f<T>(...items: T[]): T;
177177
>f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9))

‎tsc/testdata/baselines/reference/conformance/objectLiteralNormalization.types‎

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ let c2 = !true ? opts : {};
175175
>{} : {}
176176

177177
let c3 = !true ? { a: 0, b: 0 } : {};
178-
>c3 : { a: number; b: number; } | { b?: undefined; a?: undefined; }
178+
>c3 : { a: number; b: number; } | { a?: undefined; b?: undefined; }
179179
>!true ? { a: 0, b: 0 } : {} : { a: number; b: number; } | {}
180180
>!true : false
181181
>true : true
@@ -187,7 +187,7 @@ let c3 = !true ? { a: 0, b: 0 } : {};
187187
>{} : {}
188188

189189
let c4 = !true ? {} : { a: 0, b: 0 };
190-
>c4 : { b?: undefined; a?: undefined; } | { a: number; b: number; }
190+
>c4 : { a?: undefined; b?: undefined; } | { a: number; b: number; }
191191
>!true ? {} : { a: 0, b: 0 } : {} | { a: number; b: number; }
192192
>!true : false
193193
>true : true
@@ -200,7 +200,7 @@ let c4 = !true ? {} : { a: 0, b: 0 };
200200

201201
// Normalization applies to nested properties
202202
let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0];
203-
>d1 : { kind: string; pos: { b?: undefined; a?: undefined; x: number; y: number; }; } | { kind: string; pos: { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }; }
203+
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }; }
204204
>[{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }][0] : { kind: string; pos: { x: number; y: number; }; } | { kind: string; pos: { a: string; } | { b: number; }; }
205205
>[{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x" } : { b: 0 } }] : ({ kind: string; pos: { x: number; y: number; }; } | { kind: string; pos: { a: string; } | { b: number; }; })[]
206206
>{ kind: 'a', pos: { x: 0, y: 0 } } : { kind: string; pos: { x: number; y: number; }; }
@@ -229,40 +229,40 @@ let d1 = [{ kind: 'a', pos: { x: 0, y: 0 } }, { kind: 'b', pos: !true ? { a: "x"
229229

230230
d1.kind;
231231
>d1.kind : string
232-
>d1 : { kind: string; pos: { b?: undefined; a?: undefined; x: number; y: number; }; } | { kind: string; pos: { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }; }
232+
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }; }
233233
>kind : string
234234

235235
d1.pos;
236-
>d1.pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
237-
>d1 : { kind: string; pos: { b?: undefined; a?: undefined; x: number; y: number; }; } | { kind: string; pos: { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }; }
238-
>pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
236+
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
237+
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }; }
238+
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
239239

240240
d1.pos.x;
241241
>d1.pos.x : number | undefined
242-
>d1.pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
243-
>d1 : { kind: string; pos: { b?: undefined; a?: undefined; x: number; y: number; }; } | { kind: string; pos: { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }; }
244-
>pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
242+
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
243+
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }; }
244+
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
245245
>x : number | undefined
246246

247247
d1.pos.y;
248248
>d1.pos.y : number | undefined
249-
>d1.pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
250-
>d1 : { kind: string; pos: { b?: undefined; a?: undefined; x: number; y: number; }; } | { kind: string; pos: { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }; }
251-
>pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
249+
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
250+
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }; }
251+
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
252252
>y : number | undefined
253253

254254
d1.pos.a;
255255
>d1.pos.a : string | undefined
256-
>d1.pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
257-
>d1 : { kind: string; pos: { b?: undefined; a?: undefined; x: number; y: number; }; } | { kind: string; pos: { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }; }
258-
>pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
256+
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
257+
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }; }
258+
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
259259
>a : string | undefined
260260

261261
d1.pos.b;
262262
>d1.pos.b : number | undefined
263-
>d1.pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
264-
>d1 : { kind: string; pos: { b?: undefined; a?: undefined; x: number; y: number; }; } | { kind: string; pos: { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }; }
265-
>pos : { b?: undefined; a?: undefined; x: number; y: number; } | { b?: undefined; x?: undefined; y?: undefined; a: string; } | { a?: undefined; x?: undefined; y?: undefined; b: number; }
263+
>d1.pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
264+
>d1 : { kind: string; pos: { x: number; y: number; a?: undefined; b?: undefined; }; } | { kind: string; pos: { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }; }
265+
>pos : { x: number; y: number; a?: undefined; b?: undefined; } | { x?: undefined; y?: undefined; a: string; b?: undefined; } | { x?: undefined; y?: undefined; a?: undefined; b: number; }
266266
>b : number | undefined
267267

268268
declare function f<T>(...items: T[]): T;
@@ -292,8 +292,8 @@ let e1 = f({ a: 1, b: 2 }, { a: "abc" }, {});
292292
>{} : {}
293293

294294
let e2 = f({}, { a: "abc" }, { a: 1, b: 2 });
295-
>e2 : { b?: undefined; a?: undefined; } | { b?: undefined; a: string; } | { a: number; b: number; }
296-
>f({}, { a: "abc" }, { a: 1, b: 2 }) : { b?: undefined; a?: undefined; } | { b?: undefined; a: string; } | { a: number; b: number; }
295+
>e2 : { a?: undefined; b?: undefined; } | { a: string; b?: undefined; } | { a: number; b: number; }
296+
>f({}, { a: "abc" }, { a: 1, b: 2 }) : { a?: undefined; b?: undefined; } | { a: string; b?: undefined; } | { a: number; b: number; }
297297
>f : <T>(...items: T[]) => T
298298
>{} : {}
299299
>{ a: "abc" } : { a: string; }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// @strict: true
2+
// @declaration: true
3+
// @emitDeclarationOnly: true
4+
export const a = Math.random() > 0.5 ? { user: 1 } : { status: "a" };
5+
export const b = Math.random() > 0.5 ? { status: "no" } : { status: "ok", user: 2 };

0 commit comments

Comments
 (0)