From 9f96fe5da33f9297157b326c37680a964b23d7eb Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 21 Sep 2018 11:04:52 -0700 Subject: [PATCH] Remove the narrow-to-fresh rule added with boolean literals --- src/compiler/checker.ts | 5 +---- ...OperatorWithSecondOperandBooleanType.types | 4 ++-- ...onEmitDestructuringObjectLiteralPattern.js | 6 +++--- ...mitDestructuringObjectLiteralPattern.types | 18 ++++++++--------- ...nEmitDestructuringObjectLiteralPattern2.js | 6 +++--- ...itDestructuringObjectLiteralPattern2.types | 18 ++++++++--------- .../declarationsAndAssignments.types | 16 +++++++-------- .../reference/literalFreshnessNarrowing.js | 14 +++++++++++++ .../literalFreshnessNarrowing.symbols | 19 ++++++++++++++++++ .../reference/literalFreshnessNarrowing.types | 20 +++++++++++++++++++ .../reference/typeGuardOfFormThisMember.types | 2 +- .../compiler/literalFreshnessNarrowing.ts | 6 ++++++ 12 files changed, 95 insertions(+), 39 deletions(-) create mode 100644 tests/baselines/reference/literalFreshnessNarrowing.js create mode 100644 tests/baselines/reference/literalFreshnessNarrowing.symbols create mode 100644 tests/baselines/reference/literalFreshnessNarrowing.types create mode 100644 tests/cases/compiler/literalFreshnessNarrowing.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index dc2faa2e298..87188ad9bbc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14208,10 +14208,7 @@ namespace ts { if (assignedType.flags & TypeFlags.Never) { return assignedType; } - let reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t)); - if (assignedType.flags & (TypeFlags.FreshLiteral | TypeFlags.Literal)) { - reducedType = mapType(reducedType, getFreshTypeOfLiteralType); // Ensure that if the assignment is a fresh type, that we narrow to fresh types - } + const reducedType = filterType(declaredType, t => typeMaybeAssignableTo(assignedType, t)); // Our crude heuristic produces an invalid result in some cases: see GH#26130. // For now, when that happens, we give up and don't narrow at all. (This also // means we'll never narrow for erroneous assignments where the assigned type diff --git a/tests/baselines/reference/commaOperatorWithSecondOperandBooleanType.types b/tests/baselines/reference/commaOperatorWithSecondOperandBooleanType.types index 3880059e5cc..c5820232b0f 100644 --- a/tests/baselines/reference/commaOperatorWithSecondOperandBooleanType.types +++ b/tests/baselines/reference/commaOperatorWithSecondOperandBooleanType.types @@ -122,14 +122,14 @@ OBJECT = [1, 2, 3], BOOLEAN = false; >false : false var resultIsBoolean6 = (null, BOOLEAN); ->resultIsBoolean6 : boolean +>resultIsBoolean6 : false >(null, BOOLEAN) : false >null, BOOLEAN : false >null : null >BOOLEAN : false var resultIsBoolean7 = (ANY = undefined, BOOLEAN); ->resultIsBoolean7 : boolean +>resultIsBoolean7 : false >(ANY = undefined, BOOLEAN) : false >ANY = undefined, BOOLEAN : false >ANY = undefined : undefined diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.js b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.js index 10d7427388a..2353206d9b3 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.js +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.js @@ -55,9 +55,9 @@ declare var x11: number, y11: string, z11: boolean; declare function f15(): { a4: string; b4: number; - c4: boolean; + c4: true; }; -declare var a4: string, b4: number, c4: boolean; +declare var a4: string, b4: number, c4: true; declare module m { - var a4: string, b4: number, c4: boolean; + var a4: string, b4: number, c4: true; } diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.types b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.types index 7e6efdf4264..38ddd8e086c 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.types +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern.types @@ -82,7 +82,7 @@ var { a: x11, b: { a: y11, b: { a: z11 }}} = { a: 1, b: { a: "hello", b: { a: tr >true : true function f15() { ->f15 : () => { a4: string; b4: number; c4: boolean; } +>f15 : () => { a4: string; b4: number; c4: true; } var a4 = "hello"; >a4 : string @@ -97,17 +97,17 @@ function f15() { >true : true return { a4, b4, c4 }; ->{ a4, b4, c4 } : { a4: string; b4: number; c4: boolean; } +>{ a4, b4, c4 } : { a4: string; b4: number; c4: true; } >a4 : string >b4 : number ->c4 : boolean +>c4 : true } var { a4, b4, c4 } = f15(); >a4 : string >b4 : number ->c4 : boolean ->f15() : { a4: string; b4: number; c4: boolean; } ->f15 : () => { a4: string; b4: number; c4: boolean; } +>c4 : true +>f15() : { a4: string; b4: number; c4: true; } +>f15 : () => { a4: string; b4: number; c4: true; } module m { >m : typeof m @@ -115,7 +115,7 @@ module m { export var { a4, b4, c4 } = f15(); >a4 : string >b4 : number ->c4 : boolean ->f15() : { a4: string; b4: number; c4: boolean; } ->f15 : () => { a4: string; b4: number; c4: boolean; } +>c4 : true +>f15() : { a4: string; b4: number; c4: true; } +>f15 : () => { a4: string; b4: number; c4: true; } } diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.js b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.js index 66dfe225e83..914cbbd1537 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.js +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.js @@ -34,9 +34,9 @@ declare var x11: number, y11: string, z11: boolean; declare function f15(): { a4: string; b4: number; - c4: boolean; + c4: true; }; -declare var a4: string, b4: number, c4: boolean; +declare var a4: string, b4: number, c4: true; declare module m { - var a4: string, b4: number, c4: boolean; + var a4: string, b4: number, c4: true; } diff --git a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.types b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.types index c73afd0b9cf..6633a9dafea 100644 --- a/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.types +++ b/tests/baselines/reference/declarationEmitDestructuringObjectLiteralPattern2.types @@ -21,7 +21,7 @@ var { a: x11, b: { a: y11, b: { a: z11 }}} = { a: 1, b: { a: "hello", b: { a: tr >true : true function f15() { ->f15 : () => { a4: string; b4: number; c4: boolean; } +>f15 : () => { a4: string; b4: number; c4: true; } var a4 = "hello"; >a4 : string @@ -36,17 +36,17 @@ function f15() { >true : true return { a4, b4, c4 }; ->{ a4, b4, c4 } : { a4: string; b4: number; c4: boolean; } +>{ a4, b4, c4 } : { a4: string; b4: number; c4: true; } >a4 : string >b4 : number ->c4 : boolean +>c4 : true } var { a4, b4, c4 } = f15(); >a4 : string >b4 : number ->c4 : boolean ->f15() : { a4: string; b4: number; c4: boolean; } ->f15 : () => { a4: string; b4: number; c4: boolean; } +>c4 : true +>f15() : { a4: string; b4: number; c4: true; } +>f15 : () => { a4: string; b4: number; c4: true; } module m { >m : typeof m @@ -54,7 +54,7 @@ module m { export var { a4, b4, c4 } = f15(); >a4 : string >b4 : number ->c4 : boolean ->f15() : { a4: string; b4: number; c4: boolean; } ->f15 : () => { a4: string; b4: number; c4: boolean; } +>c4 : true +>f15() : { a4: string; b4: number; c4: true; } +>f15 : () => { a4: string; b4: number; c4: true; } } diff --git a/tests/baselines/reference/declarationsAndAssignments.types b/tests/baselines/reference/declarationsAndAssignments.types index 602ffbd76eb..5b9da633d2a 100644 --- a/tests/baselines/reference/declarationsAndAssignments.types +++ b/tests/baselines/reference/declarationsAndAssignments.types @@ -483,7 +483,7 @@ module M { } function f15() { ->f15 : () => { a: string; b: number; c: boolean; } +>f15 : () => { a: string; b: number; c: true; } var a = "hello"; >a : string @@ -498,10 +498,10 @@ function f15() { >true : true return { a, b, c }; ->{ a, b, c } : { a: string; b: number; c: boolean; } +>{ a, b, c } : { a: string; b: number; c: true; } >a : string >b : number ->c : boolean +>c : true } function f16() { @@ -510,9 +510,9 @@ function f16() { var { a, b, c } = f15(); >a : string >b : number ->c : boolean ->f15() : { a: string; b: number; c: boolean; } ->f15 : () => { a: string; b: number; c: boolean; } +>c : true +>f15() : { a: string; b: number; c: true; } +>f15 : () => { a: string; b: number; c: true; } } function f17({ a = "", b = 0, c = false }) { @@ -547,8 +547,8 @@ f17({ c: true }); f17(f15()); >f17(f15()) : void >f17 : ({ a, b, c }: { a?: string; b?: number; c?: boolean; }) => void ->f15() : { a: string; b: number; c: boolean; } ->f15 : () => { a: string; b: number; c: boolean; } +>f15() : { a: string; b: number; c: true; } +>f15 : () => { a: string; b: number; c: true; } function f18() { >f18 : () => void diff --git a/tests/baselines/reference/literalFreshnessNarrowing.js b/tests/baselines/reference/literalFreshnessNarrowing.js new file mode 100644 index 00000000000..fd665b8c523 --- /dev/null +++ b/tests/baselines/reference/literalFreshnessNarrowing.js @@ -0,0 +1,14 @@ +//// [literalFreshnessNarrowing.ts] +type XY = 'x' | 'y'; +const x: XY = 'x'; +let x2 = x; // Shouldn't have type string + +const y: boolean = true; +let y2 = y; // Shouldn't type boolean + + +//// [literalFreshnessNarrowing.js] +var x = 'x'; +var x2 = x; // Shouldn't have type string +var y = true; +var y2 = y; // Shouldn't type boolean diff --git a/tests/baselines/reference/literalFreshnessNarrowing.symbols b/tests/baselines/reference/literalFreshnessNarrowing.symbols new file mode 100644 index 00000000000..96ceebf3667 --- /dev/null +++ b/tests/baselines/reference/literalFreshnessNarrowing.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/literalFreshnessNarrowing.ts === +type XY = 'x' | 'y'; +>XY : Symbol(XY, Decl(literalFreshnessNarrowing.ts, 0, 0)) + +const x: XY = 'x'; +>x : Symbol(x, Decl(literalFreshnessNarrowing.ts, 1, 5)) +>XY : Symbol(XY, Decl(literalFreshnessNarrowing.ts, 0, 0)) + +let x2 = x; // Shouldn't have type string +>x2 : Symbol(x2, Decl(literalFreshnessNarrowing.ts, 2, 3)) +>x : Symbol(x, Decl(literalFreshnessNarrowing.ts, 1, 5)) + +const y: boolean = true; +>y : Symbol(y, Decl(literalFreshnessNarrowing.ts, 4, 5)) + +let y2 = y; // Shouldn't type boolean +>y2 : Symbol(y2, Decl(literalFreshnessNarrowing.ts, 5, 3)) +>y : Symbol(y, Decl(literalFreshnessNarrowing.ts, 4, 5)) + diff --git a/tests/baselines/reference/literalFreshnessNarrowing.types b/tests/baselines/reference/literalFreshnessNarrowing.types new file mode 100644 index 00000000000..07bf8cb01ed --- /dev/null +++ b/tests/baselines/reference/literalFreshnessNarrowing.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/literalFreshnessNarrowing.ts === +type XY = 'x' | 'y'; +>XY : XY + +const x: XY = 'x'; +>x : XY +>'x' : "x" + +let x2 = x; // Shouldn't have type string +>x2 : "x" +>x : "x" + +const y: boolean = true; +>y : boolean +>true : true + +let y2 = y; // Shouldn't type boolean +>y2 : true +>y : true + diff --git a/tests/baselines/reference/typeGuardOfFormThisMember.types b/tests/baselines/reference/typeGuardOfFormThisMember.types index d887f434781..ed0499ed849 100644 --- a/tests/baselines/reference/typeGuardOfFormThisMember.types +++ b/tests/baselines/reference/typeGuardOfFormThisMember.types @@ -92,7 +92,7 @@ namespace Test { >true : true let x = file.isFile; ->x : boolean +>x : true >file.isFile : true >file : FileSystemObject >isFile : true diff --git a/tests/cases/compiler/literalFreshnessNarrowing.ts b/tests/cases/compiler/literalFreshnessNarrowing.ts new file mode 100644 index 00000000000..5255631ce56 --- /dev/null +++ b/tests/cases/compiler/literalFreshnessNarrowing.ts @@ -0,0 +1,6 @@ +type XY = 'x' | 'y'; +const x: XY = 'x'; +let x2 = x; // Shouldn't have type string + +const y: boolean = true; +let y2 = y; // Shouldn't type boolean