@@ -824,7 +824,7 @@ namespace ts {
824824 }
825825
826826 // Resolves a qualified name and any involved aliases
827- function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, location?: Node ): Symbol {
827+ function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags): Symbol {
828828 if (nodeIsMissing(name)) {
829829 return undefined;
830830 }
@@ -833,7 +833,7 @@ namespace ts {
833833 if (name.kind === SyntaxKind.Identifier) {
834834 let message = meaning === SymbolFlags.Namespace ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0;
835835
836- symbol = resolveName(location || name, (<Identifier>name).text, meaning, message, <Identifier>name);
836+ symbol = resolveName(name, (<Identifier>name).text, meaning, message, <Identifier>name);
837837 if (!symbol) {
838838 return undefined;
839839 }
@@ -842,7 +842,7 @@ namespace ts {
842842 let left = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).left : (<PropertyAccessExpression>name).expression;
843843 let right = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).right : (<PropertyAccessExpression>name).name;
844844
845- let namespace = resolveEntityName(left, SymbolFlags.Namespace, location );
845+ let namespace = resolveEntityName(left, SymbolFlags.Namespace);
846846 if (!namespace || namespace === unknownSymbol || nodeIsMissing(right)) {
847847 return undefined;
848848 }
@@ -8839,7 +8839,6 @@ namespace ts {
88398839 }
88408840
88418841 if (produceDiagnostics) {
8842- checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name);
88438842 checkCollisionWithArgumentsInGeneratedCode(node);
88448843 if (compilerOptions.noImplicitAny && !node.type) {
88458844 switch (node.kind) {
@@ -9632,18 +9631,18 @@ namespace ts {
96329631 * a `resolve` function as one of its arguments and results in an object with a
96339632 * callable `then` signature.
96349633 */
9635- function checkAsyncFunctionReturnType(node: SignatureDeclaration ): Type {
9634+ function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration ): Type {
96369635 let globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
96379636 if (globalPromiseConstructorLikeType === emptyObjectType) {
96389637 // If we couldn't resolve the global PromiseConstructorLike type we cannot verify
96399638 // compatibility with __awaiter.
96409639 return unknownType;
96419640 }
96429641
9643- // The return type of an async function will be the type of the instance. For this
9644- // to be a type compatible with our async function emit, we must also check that
9645- // the type of the declaration (e.g. the static side or "constructor" type of the
9646- // promise) is a compatible `PromiseConstructorLike`.
9642+ // As part of our emit for an async function, we will need to emit the entity name of
9643+ // the return type annotation as an expression. To meet the necessary runtime semantics
9644+ // for __awaiter, we must also check that the type of the declaration (e.g. the static
9645+ // side or "constructor" of the promise type ) is compatible `PromiseConstructorLike`.
96479646 //
96489647 // An example might be (from lib.es6.d.ts):
96499648 //
@@ -9666,36 +9665,33 @@ namespace ts {
96669665 //
96679666 // When we get the type of the `Promise` symbol here, we get the type of the static
96689667 // side of the `Promise` class, which would be `{ new <T>(...): Promise<T> }`.
9669- let returnType = getTypeFromTypeNode(node.type);
9670- let entityName = getEntityNameFromTypeNode (node.type);
9671- let resolvedName = entityName ? resolveEntityName(entityName, SymbolFlags.Value, node) : undefined ;
9672- if (!resolvedName || !returnType.symbol ) {
9673- error(node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type );
9674- return unknownType;
9668+
9669+ let promiseType = getTypeFromTypeNode (node.type);
9670+ let promiseConstructor = getMergedSymbol(promiseType.symbol) ;
9671+ if (!promiseConstructor || !symbolIsValue(promiseConstructor) ) {
9672+ error(node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeToString(promiseType) );
9673+ return unknownType
96759674 }
9676-
9677- if (getMergedSymbol(resolvedName) !== getMergedSymbol(returnType.symbol)) {
9678- // If we were unable to resolve the return type as a value, report an error.
9679- let identifier = getFirstIdentifier(entityName);
9680- error(resolvedName.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions,
9681- identifier.text,
9682- identifier.text);
9675+
9676+ // Validate the promise constructor type.
9677+ let promiseConstructorType = getTypeOfSymbol(promiseConstructor);
9678+ if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
96839679 return unknownType;
96849680 }
96859681
9686- // When we emit the async function, we need to ensure we emit any imports that might
9687- // otherwise have been elided if the return type were only ever referenced in a type
9688- // position. As such, we check the entity name as an expression.
9689- let declaredType = checkExpression(entityName );
9690-
9691- if (!isTypeAssignableTo(declaredType, globalPromiseConstructorLikeType)) {
9692- // If the declared type of the return type is not assignable to a PromiseConstructorLike, report an error.
9693- error(node, ts.Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type );
9682+ // Verify there is no local declaration that could collide with the promise constructor.
9683+ let promiseName = getEntityNameFromTypeNode(node. type);
9684+ let root = getFirstIdentifier(promiseName);
9685+ let rootSymbol = getSymbol(node.locals, root.text, SymbolFlags.Value );
9686+ if (rootSymbol) {
9687+ error(rootSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions,
9688+ root.text,
9689+ getFullyQualifiedName(promiseConstructor) );
96949690 return unknownType;
96959691 }
9696-
9692+
96979693 // Get and return the awaited type of the return type.
9698- return getAwaitedType(returnType , node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
9694+ return getAwaitedType(promiseType , node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
96999695 }
97009696
97019697 /** Check a decorator */
@@ -10093,22 +10089,6 @@ namespace ts {
1009310089 }
1009410090 }
1009510091 }
10096-
10097- function checkCollisionWithAwaiterVariablesInGeneratedCode(node: Node, name: DeclarationName): void {
10098- if (!name || name.kind !== SyntaxKind.Identifier || isTypeNode(name)) {
10099- return;
10100- }
10101-
10102- let identifier = <Identifier>name;
10103- let container = getContainingFunction(name);
10104- if (container && isAsyncFunctionLike(container) && node.kind !== SyntaxKind.Identifier) {
10105- let promiseConstructorName = getEntityNameFromTypeNode(container.type);
10106- let firstIdentifier = promiseConstructorName ? getFirstIdentifier(promiseConstructorName) : undefined;
10107- if (firstIdentifier && firstIdentifier.text === identifier.text) {
10108- error(node, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, identifier.text, getTextOfNode(promiseConstructorName));
10109- }
10110- }
10111- }
1011210092
1011310093 // Check that a parameter initializer contains no references to parameters declared to the right of itself
1011410094 function checkParameterInitializer(node: VariableLikeDeclaration): void {
@@ -10954,7 +10934,6 @@ namespace ts {
1095410934 checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0);
1095510935 checkCollisionWithCapturedThisVariable(node, node.name);
1095610936 checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
10957- checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name);
1095810937 }
1095910938 checkTypeParameters(node.typeParameters);
1096010939 checkExportsOnMergedDeclarations(node);
@@ -11398,7 +11377,6 @@ namespace ts {
1139811377 checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
1139911378 checkCollisionWithCapturedThisVariable(node, node.name);
1140011379 checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
11401- checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name);
1140211380 checkExportsOnMergedDeclarations(node);
1140311381
1140411382 computeEnumMemberValues(node);
0 commit comments