Skip to content

Revert restrictions on custom Promise in async function return type #6967

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12623,7 +12623,7 @@ namespace ts {
* callable `then` signature.
*/
function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type {
if (languageVersion >= ScriptTarget.ES6) {
if (compilerOptions.noCustomAsyncPromise && languageVersion >= ScriptTarget.ES6) {
const returnType = getTypeFromTypeNode(node.type);
return checkCorrectPromiseType(returnType, node.type);
}
Expand Down Expand Up @@ -13029,6 +13029,10 @@ namespace ts {
}

function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void {
if (!compilerOptions.noCustomAsyncPromise) {
return;
}

if (!needCollisionCheckForIdentifier(node, name, "Promise")) {
return;
}
Expand Down
5 changes: 5 additions & 0 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,11 @@ namespace ts {
name: "noImplicitUseStrict",
type: "boolean",
description: Diagnostics.Do_not_emit_use_strict_directives_in_module_output
},
{
name: "noCustomAsyncPromise",
type: "boolean",
experimental: true
}
];

Expand Down
16 changes: 8 additions & 8 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,21 +296,21 @@ namespace ts {
* If loop contains block scoped binding captured in some function then loop body is converted to a function.
* Lexical bindings declared in loop initializer will be passed into the loop body function as parameters,
* however if this binding is modified inside the body - this new value should be propagated back to the original binding.
* This is done by declaring new variable (out parameter holder) outside of the loop for every binding that is reassigned inside the body.
* This is done by declaring new variable (out parameter holder) outside of the loop for every binding that is reassigned inside the body.
* On every iteration this variable is initialized with value of corresponding binding.
* At every point where control flow leaves the loop either explicitly (break/continue) or implicitly (at the end of loop body)
* we copy the value inside the loop to the out parameter holder.
*
*
* for (let x;;) {
* let a = 1;
* let b = () => a;
* x++
* if (...) break;
* ...
* }
*
*
* will be converted to
*
*
* var out_x;
* var loop = function(x) {
* var a = 1;
Expand All @@ -326,7 +326,7 @@ namespace ts {
* x = out_x;
* if (state === "break") break;
* }
*
*
* NOTE: values to out parameters are not copies if loop is abrupted with 'return' - in this case this will end the entire enclosing function
* so nobody can observe this new value.
*/
Expand Down Expand Up @@ -3049,7 +3049,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
}

writeLine();
// end of loop body -> copy out parameter
// end of loop body -> copy out parameter
copyLoopOutParameters(convertedLoopState, CopyDirection.ToOutParameter, /*emitAsStatements*/true);

decreaseIndent();
Expand Down Expand Up @@ -4685,7 +4685,7 @@ const _super = (function (geti, seti) {
write(", void 0, ");
}

if (languageVersion >= ScriptTarget.ES6 || !promiseConstructor) {
if (!promiseConstructor || (compilerOptions.noCustomAsyncPromise && languageVersion >= ScriptTarget.ES6)) {
write("void 0");
}
else {
Expand Down Expand Up @@ -7245,7 +7245,7 @@ const _super = (function (geti, seti) {
}

// text should be quoted string
// for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same
// for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same
const key = text.substr(1, text.length - 2);

if (hasProperty(groupIndices, key)) {
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2442,6 +2442,8 @@ namespace ts {
/* @internal */ skipDefaultLibCheck?: boolean;
// Do not perform validation of output file name in transpile scenarios
/* @internal */ suppressOutputPathCheck?: boolean;
// Disallow custom promise return types in async functions.
/* @internal */ noCustomAsyncPromise?: boolean;

[option: string]: string | number | boolean;
}
Expand Down
10 changes: 10 additions & 0 deletions tests/baselines/reference/asyncAliasReturnType_es6.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
tests/cases/conformance/async/es6/asyncAliasReturnType_es6.ts(3,16): error TS1055: Type 'PromiseAlias' is not a valid async function return type.


==== tests/cases/conformance/async/es6/asyncAliasReturnType_es6.ts (1 errors) ====
type PromiseAlias<T> = Promise<T>;

async function f(): PromiseAlias<void> {
~
!!! error TS1055: Type 'PromiseAlias' is not a valid async function return type.
}
2 changes: 1 addition & 1 deletion tests/baselines/reference/asyncAliasReturnType_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ async function f(): PromiseAlias<void> {

//// [asyncAliasReturnType_es6.js]
function f() {
return __awaiter(this, void 0, void 0, function* () {
return __awaiter(this, void 0, PromiseAlias, function* () {
});
}
11 changes: 0 additions & 11 deletions tests/baselines/reference/asyncAliasReturnType_es6.symbols

This file was deleted.

11 changes: 0 additions & 11 deletions tests/baselines/reference/asyncAliasReturnType_es6.types

This file was deleted.

2 changes: 1 addition & 1 deletion tests/baselines/reference/asyncArrowFunction1_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ var foo = async (): Promise<void> => {
};

//// [asyncArrowFunction1_es6.js]
var foo = () => __awaiter(this, void 0, void 0, function* () {
var foo = () => __awaiter(this, void 0, Promise, function* () {
});
2 changes: 1 addition & 1 deletion tests/baselines/reference/asyncArrowFunction6_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ var foo = async (a = await): Promise<void> => {
}

//// [asyncArrowFunction6_es6.js]
var foo = (a = yield ) => __awaiter(this, void 0, void 0, function* () {
var foo = (a = yield ) => __awaiter(this, void 0, Promise, function* () {
});
4 changes: 2 additions & 2 deletions tests/baselines/reference/asyncArrowFunction7_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ var bar = async (): Promise<void> => {
}

//// [asyncArrowFunction7_es6.js]
var bar = () => __awaiter(this, void 0, void 0, function* () {
var bar = () => __awaiter(this, void 0, Promise, function* () {
// 'await' here is an identifier, and not an await expression.
var foo = (a = yield ) => __awaiter(this, void 0, void 0, function* () {
var foo = (a = yield ) => __awaiter(this, void 0, Promise, function* () {
});
});
2 changes: 1 addition & 1 deletion tests/baselines/reference/asyncArrowFunction8_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ var foo = async (): Promise<void> => {
}

//// [asyncArrowFunction8_es6.js]
var foo = () => __awaiter(this, void 0, void 0, function* () {
var foo = () => __awaiter(this, void 0, Promise, function* () {
var v = { [yield ]: foo };
});
28 changes: 14 additions & 14 deletions tests/baselines/reference/asyncAwaitIsolatedModules_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,56 +52,56 @@ function f0() {
return __awaiter(this, void 0, void 0, function* () { });
}
function f1() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
}
function f3() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
}
let f4 = function () {
return __awaiter(this, void 0, void 0, function* () { });
};
let f5 = function () {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
};
let f6 = function () {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
};
let f7 = () => __awaiter(this, void 0, void 0, function* () { });
let f8 = () => __awaiter(this, void 0, void 0, function* () { });
let f9 = () => __awaiter(this, void 0, void 0, function* () { });
let f8 = () => __awaiter(this, void 0, Promise, function* () { });
let f9 = () => __awaiter(this, void 0, MyPromise, function* () { });
let f10 = () => __awaiter(this, void 0, void 0, function* () { return p; });
let f11 = () => __awaiter(this, void 0, void 0, function* () { return mp; });
let f12 = () => __awaiter(this, void 0, void 0, function* () { return mp; });
let f13 = () => __awaiter(this, void 0, void 0, function* () { return p; });
let f12 = () => __awaiter(this, void 0, Promise, function* () { return mp; });
let f13 = () => __awaiter(this, void 0, MyPromise, function* () { return p; });
let o = {
m1() {
return __awaiter(this, void 0, void 0, function* () { });
},
m2() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
},
m3() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
}
};
class C {
m1() {
return __awaiter(this, void 0, void 0, function* () { });
}
m2() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
}
m3() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
}
static m4() {
return __awaiter(this, void 0, void 0, function* () { });
}
static m5() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
}
static m6() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
}
}
var M;
Expand Down
28 changes: 14 additions & 14 deletions tests/baselines/reference/asyncAwait_es6.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,56 +52,56 @@ function f0() {
return __awaiter(this, void 0, void 0, function* () { });
}
function f1() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
}
function f3() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
}
let f4 = function () {
return __awaiter(this, void 0, void 0, function* () { });
};
let f5 = function () {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
};
let f6 = function () {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
};
let f7 = () => __awaiter(this, void 0, void 0, function* () { });
let f8 = () => __awaiter(this, void 0, void 0, function* () { });
let f9 = () => __awaiter(this, void 0, void 0, function* () { });
let f8 = () => __awaiter(this, void 0, Promise, function* () { });
let f9 = () => __awaiter(this, void 0, MyPromise, function* () { });
let f10 = () => __awaiter(this, void 0, void 0, function* () { return p; });
let f11 = () => __awaiter(this, void 0, void 0, function* () { return mp; });
let f12 = () => __awaiter(this, void 0, void 0, function* () { return mp; });
let f13 = () => __awaiter(this, void 0, void 0, function* () { return p; });
let f12 = () => __awaiter(this, void 0, Promise, function* () { return mp; });
let f13 = () => __awaiter(this, void 0, MyPromise, function* () { return p; });
let o = {
m1() {
return __awaiter(this, void 0, void 0, function* () { });
},
m2() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
},
m3() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
}
};
class C {
m1() {
return __awaiter(this, void 0, void 0, function* () { });
}
m2() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
}
m3() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
}
static m4() {
return __awaiter(this, void 0, void 0, function* () { });
}
static m5() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, Promise, function* () { });
}
static m6() {
return __awaiter(this, void 0, void 0, function* () { });
return __awaiter(this, void 0, MyPromise, function* () { });
}
}
var M;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ async function await(): Promise<void> {

//// [asyncFunctionDeclaration11_es6.js]
function await() {
return __awaiter(this, void 0, void 0, function* () {
return __awaiter(this, void 0, Promise, function* () {
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ async function foo(): Promise<void> {

//// [asyncFunctionDeclaration13_es6.js]
function foo() {
return __awaiter(this, void 0, void 0, function* () {
return __awaiter(this, void 0, Promise, function* () {
// Legal to use 'await' in a type context.
var v;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ async function foo(): Promise<void> {

//// [asyncFunctionDeclaration14_es6.js]
function foo() {
return __awaiter(this, void 0, void 0, function* () {
return __awaiter(this, void 0, Promise, function* () {
return;
});
}
Loading