Skip to content

Commit

Permalink
fix(40222): fix crash on using destructuring in a catch clause (#40240)
Browse files Browse the repository at this point in the history
  • Loading branch information
a-tarasyuk authored Sep 8, 2020
1 parent fa89ce6 commit 1508446
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 6 deletions.
13 changes: 8 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34237,12 +34237,15 @@ namespace ts {
if (catchClause) {
// Grammar checking
if (catchClause.variableDeclaration) {
if (catchClause.variableDeclaration.type && getTypeOfNode(catchClause.variableDeclaration) === errorType) {
grammarErrorOnFirstToken(catchClause.variableDeclaration.type,
Diagnostics.Catch_clause_variable_type_annotation_must_be_any_or_unknown_if_specified);
const declaration = catchClause.variableDeclaration;
if (declaration.type) {
const type = getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ false);
if (type && !(type.flags & TypeFlags.AnyOrUnknown)) {
grammarErrorOnFirstToken(declaration.type, Diagnostics.Catch_clause_variable_type_annotation_must_be_any_or_unknown_if_specified);
}
}
else if (catchClause.variableDeclaration.initializer) {
grammarErrorOnFirstToken(catchClause.variableDeclaration.initializer, Diagnostics.Catch_clause_variable_cannot_have_an_initializer);
else if (declaration.initializer) {
grammarErrorOnFirstToken(declaration.initializer, Diagnostics.Catch_clause_variable_cannot_have_an_initializer);
}
else {
const blockLocals = catchClause.block.locals;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.t
tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.ts(20,23): error TS1196: Catch clause variable type annotation must be 'any' or 'unknown' if specified.
tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.ts(29,29): error TS2492: Cannot redeclare identifier 'x' in catch clause.
tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.ts(30,29): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'boolean', but here has type 'string'.
tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.ts(38,27): error TS1196: Catch clause variable type annotation must be 'any' or 'unknown' if specified.
tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.ts(39,27): error TS1196: Catch clause variable type annotation must be 'any' or 'unknown' if specified.


==== tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.ts (6 errors) ====
==== tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.ts (8 errors) ====
type any1 = any;
type unknown1 = unknown;

Expand Down Expand Up @@ -52,5 +54,16 @@ tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.t
!!! related TS6203 tests/cases/conformance/statements/tryStatements/catchClauseWithTypeAnnotation.ts:4:13: 'x' was also declared here.
try { } catch (x) { var x: boolean; }

try { } catch ({ x }) { } // should be OK
try { } catch ({ x }: any) { x.foo; } // should be OK
try { } catch ({ x }: any1) { x.foo;} // should be OK
try { } catch ({ x }: unknown) { console.log(x); } // should be OK
try { } catch ({ x }: unknown1) { console.log(x); } // should be OK
try { } catch ({ x }: object) { } // error in the type
~~~~~~
!!! error TS1196: Catch clause variable type annotation must be 'any' or 'unknown' if specified.
try { } catch ({ x }: Error) { } // error in the type
~~~~~
!!! error TS1196: Catch clause variable type annotation must be 'any' or 'unknown' if specified.
}

39 changes: 39 additions & 0 deletions tests/baselines/reference/catchClauseWithTypeAnnotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ function fn(x: boolean) {
try { } catch (x) { var x: string; }
try { } catch (x) { var x: boolean; }

try { } catch ({ x }) { } // should be OK
try { } catch ({ x }: any) { x.foo; } // should be OK
try { } catch ({ x }: any1) { x.foo;} // should be OK
try { } catch ({ x }: unknown) { console.log(x); } // should be OK
try { } catch ({ x }: unknown1) { console.log(x); } // should be OK
try { } catch ({ x }: object) { } // error in the type
try { } catch ({ x }: Error) { } // error in the type
}


Expand Down Expand Up @@ -99,4 +106,36 @@ function fn(x) {
catch (x) {
var x;
}
try { }
catch (_a) {
var x_2 = _a.x;
} // should be OK
try { }
catch (_b) {
var x_3 = _b.x;
x_3.foo;
} // should be OK
try { }
catch (_c) {
var x_4 = _c.x;
x_4.foo;
} // should be OK
try { }
catch (_d) {
var x_5 = _d.x;
console.log(x_5);
} // should be OK
try { }
catch (_e) {
var x_6 = _e.x;
console.log(x_6);
} // should be OK
try { }
catch (_f) {
var x_7 = _f.x;
} // error in the type
try { }
catch (_g) {
var x_8 = _g.x;
} // error in the type
}
33 changes: 33 additions & 0 deletions tests/baselines/reference/catchClauseWithTypeAnnotation.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,38 @@ function fn(x: boolean) {
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 30, 19))
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 3, 12), Decl(catchClauseWithTypeAnnotation.ts, 29, 27), Decl(catchClauseWithTypeAnnotation.ts, 30, 27))

try { } catch ({ x }) { } // should be OK
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 32, 20))

try { } catch ({ x }: any) { x.foo; } // should be OK
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 33, 20))
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 33, 20))

try { } catch ({ x }: any1) { x.foo;} // should be OK
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 34, 20))
>any1 : Symbol(any1, Decl(catchClauseWithTypeAnnotation.ts, 0, 0))
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 34, 20))

try { } catch ({ x }: unknown) { console.log(x); } // should be OK
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 35, 20))
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 35, 20))

try { } catch ({ x }: unknown1) { console.log(x); } // should be OK
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 36, 20))
>unknown1 : Symbol(unknown1, Decl(catchClauseWithTypeAnnotation.ts, 0, 16))
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 36, 20))

try { } catch ({ x }: object) { } // error in the type
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 37, 20))

try { } catch ({ x }: Error) { } // error in the type
>x : Symbol(x, Decl(catchClauseWithTypeAnnotation.ts, 38, 20))
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}

36 changes: 36 additions & 0 deletions tests/baselines/reference/catchClauseWithTypeAnnotation.types
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,41 @@ function fn(x: boolean) {
>x : any
>x : boolean

try { } catch ({ x }) { } // should be OK
>x : any

try { } catch ({ x }: any) { x.foo; } // should be OK
>x : any
>x.foo : any
>x : any
>foo : any

try { } catch ({ x }: any1) { x.foo;} // should be OK
>x : any
>x.foo : any
>x : any
>foo : any

try { } catch ({ x }: unknown) { console.log(x); } // should be OK
>x : any
>console.log(x) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>x : any

try { } catch ({ x }: unknown1) { console.log(x); } // should be OK
>x : any
>console.log(x) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>x : any

try { } catch ({ x }: object) { } // error in the type
>x : any

try { } catch ({ x }: Error) { } // error in the type
>x : any
}

Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,11 @@ function fn(x: boolean) {
try { } catch (x) { var x: string; }
try { } catch (x) { var x: boolean; }

try { } catch ({ x }) { } // should be OK
try { } catch ({ x }: any) { x.foo; } // should be OK
try { } catch ({ x }: any1) { x.foo;} // should be OK
try { } catch ({ x }: unknown) { console.log(x); } // should be OK
try { } catch ({ x }: unknown1) { console.log(x); } // should be OK
try { } catch ({ x }: object) { } // error in the type
try { } catch ({ x }: Error) { } // error in the type
}

0 comments on commit 1508446

Please sign in to comment.