diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 447a7625d38..c0466e7871a 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -490,8 +490,8 @@ namespace ts { const saveReturnTarget = currentReturnTarget; const saveActiveLabels = activeLabels; const saveHasExplicitReturn = hasExplicitReturn; - const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !!getImmediatelyInvokedFunctionExpression(node); - // An IIFE is considered part of the containing control flow. Return statements behave + const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node); + // A non-async IIFE is considered part of the containing control flow. Return statements behave // similarly to break statements that exit to a label just past the statement body. if (isIIFE) { currentReturnTarget = createBranchLabel(); diff --git a/tests/baselines/reference/asyncIIFE.js b/tests/baselines/reference/asyncIIFE.js new file mode 100644 index 00000000000..79779af62f3 --- /dev/null +++ b/tests/baselines/reference/asyncIIFE.js @@ -0,0 +1,28 @@ +//// [asyncIIFE.ts] + +function f1() { + (async () => { + await 10 + throw new Error(); + })(); + + var x = 1; +} + + +//// [asyncIIFE.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments)).next()); + }); +}; +function f1() { + (() => __awaiter(this, void 0, void 0, function* () { + yield 10; + throw new Error(); + }))(); + var x = 1; +} diff --git a/tests/baselines/reference/asyncIIFE.symbols b/tests/baselines/reference/asyncIIFE.symbols new file mode 100644 index 00000000000..92eb054bff0 --- /dev/null +++ b/tests/baselines/reference/asyncIIFE.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/asyncIIFE.ts === + +function f1() { +>f1 : Symbol(f1, Decl(asyncIIFE.ts, 0, 0)) + + (async () => { + await 10 + throw new Error(); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + })(); + + var x = 1; +>x : Symbol(x, Decl(asyncIIFE.ts, 7, 7)) +} + diff --git a/tests/baselines/reference/asyncIIFE.types b/tests/baselines/reference/asyncIIFE.types new file mode 100644 index 00000000000..e49ab96681f --- /dev/null +++ b/tests/baselines/reference/asyncIIFE.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/asyncIIFE.ts === + +function f1() { +>f1 : () => void + + (async () => { +>(async () => { await 10 throw new Error(); })() : Promise +>(async () => { await 10 throw new Error(); }) : () => Promise +>async () => { await 10 throw new Error(); } : () => Promise + + await 10 +>await 10 : 10 +>10 : 10 + + throw new Error(); +>new Error() : Error +>Error : ErrorConstructor + + })(); + + var x = 1; +>x : number +>1 : 1 +} + diff --git a/tests/cases/compiler/asyncIIFE.ts b/tests/cases/compiler/asyncIIFE.ts new file mode 100644 index 00000000000..904476d855c --- /dev/null +++ b/tests/cases/compiler/asyncIIFE.ts @@ -0,0 +1,10 @@ +// @target: ES6 + +function f1() { + (async () => { + await 10 + throw new Error(); + })(); + + var x = 1; +}