From 5a4024dd9d2d6c67ce017eba01cec7397f446f71 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 6 Apr 2020 11:55:39 -0700 Subject: [PATCH] Generic functions are never context sensitive (#37811) * Functions with type parameters are never contextsensitive * Add tests --- src/compiler/checker.ts | 2 +- .../genericFunctionsNotContextSensitive.js | 13 +++++++++++ ...enericFunctionsNotContextSensitive.symbols | 23 +++++++++++++++++++ .../genericFunctionsNotContextSensitive.types | 22 ++++++++++++++++++ .../genericFunctionsNotContextSensitive.ts | 7 ++++++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/genericFunctionsNotContextSensitive.js create mode 100644 tests/baselines/reference/genericFunctionsNotContextSensitive.symbols create mode 100644 tests/baselines/reference/genericFunctionsNotContextSensitive.types create mode 100644 tests/cases/compiler/genericFunctionsNotContextSensitive.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index db5002d0b1b..ffec8d3cb16 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14251,7 +14251,7 @@ namespace ts { function hasContextSensitiveReturnExpression(node: FunctionLikeDeclaration) { // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value. - return !getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body); + return !node.typeParameters && !getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== SyntaxKind.Block && isContextSensitive(node.body); } function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration { diff --git a/tests/baselines/reference/genericFunctionsNotContextSensitive.js b/tests/baselines/reference/genericFunctionsNotContextSensitive.js new file mode 100644 index 00000000000..8e5cb54c736 --- /dev/null +++ b/tests/baselines/reference/genericFunctionsNotContextSensitive.js @@ -0,0 +1,13 @@ +//// [genericFunctionsNotContextSensitive.ts] +// Repro from #37110 + +const f = (x: G) => void>(_: F): F => _; + +const a = f((_: K) => _ => ({})); // (_: K) => (_: G) => {} + + +//// [genericFunctionsNotContextSensitive.js] +"use strict"; +// Repro from #37110 +var f = function (_) { return _; }; +var a = f(function (_) { return function (_) { return ({}); }; }); // (_: K) => (_: G) => {} diff --git a/tests/baselines/reference/genericFunctionsNotContextSensitive.symbols b/tests/baselines/reference/genericFunctionsNotContextSensitive.symbols new file mode 100644 index 00000000000..ed8ea65a8ee --- /dev/null +++ b/tests/baselines/reference/genericFunctionsNotContextSensitive.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/genericFunctionsNotContextSensitive.ts === +// Repro from #37110 + +const f = (x: G) => void>(_: F): F => _; +>f : Symbol(f, Decl(genericFunctionsNotContextSensitive.ts, 2, 5)) +>F : Symbol(F, Decl(genericFunctionsNotContextSensitive.ts, 2, 11)) +>args : Symbol(args, Decl(genericFunctionsNotContextSensitive.ts, 2, 22)) +>G : Symbol(G, Decl(genericFunctionsNotContextSensitive.ts, 2, 42)) +>x : Symbol(x, Decl(genericFunctionsNotContextSensitive.ts, 2, 45)) +>G : Symbol(G, Decl(genericFunctionsNotContextSensitive.ts, 2, 42)) +>_ : Symbol(_, Decl(genericFunctionsNotContextSensitive.ts, 2, 60)) +>F : Symbol(F, Decl(genericFunctionsNotContextSensitive.ts, 2, 11)) +>F : Symbol(F, Decl(genericFunctionsNotContextSensitive.ts, 2, 11)) +>_ : Symbol(_, Decl(genericFunctionsNotContextSensitive.ts, 2, 60)) + +const a = f((_: K) => _ => ({})); // (_: K) => (_: G) => {} +>a : Symbol(a, Decl(genericFunctionsNotContextSensitive.ts, 4, 5)) +>f : Symbol(f, Decl(genericFunctionsNotContextSensitive.ts, 2, 5)) +>K : Symbol(K, Decl(genericFunctionsNotContextSensitive.ts, 4, 13)) +>_ : Symbol(_, Decl(genericFunctionsNotContextSensitive.ts, 4, 31)) +>K : Symbol(K, Decl(genericFunctionsNotContextSensitive.ts, 4, 13)) +>_ : Symbol(_, Decl(genericFunctionsNotContextSensitive.ts, 4, 39)) + diff --git a/tests/baselines/reference/genericFunctionsNotContextSensitive.types b/tests/baselines/reference/genericFunctionsNotContextSensitive.types new file mode 100644 index 00000000000..f47fe0f6ff6 --- /dev/null +++ b/tests/baselines/reference/genericFunctionsNotContextSensitive.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/genericFunctionsNotContextSensitive.ts === +// Repro from #37110 + +const f = (x: G) => void>(_: F): F => _; +>f : (x: G) => void>(_: F) => F +> (x: G) => void>(_: F): F => _ : (x: G) => void>(_: F) => F +>args : any[] +>x : G +>_ : F +>_ : F + +const a = f((_: K) => _ => ({})); // (_: K) => (_: G) => {} +>a : (_: K) => (_: G) => {} +>f((_: K) => _ => ({})) : (_: K) => (_: G) => {} +>f : (x: G) => void>(_: F) => F +>(_: K) => _ => ({}) : (_: K) => (_: G) => {} +>_ : K +>_ => ({}) : (_: G) => {} +>_ : G +>({}) : {} +>{} : {} + diff --git a/tests/cases/compiler/genericFunctionsNotContextSensitive.ts b/tests/cases/compiler/genericFunctionsNotContextSensitive.ts new file mode 100644 index 00000000000..d13619d2f61 --- /dev/null +++ b/tests/cases/compiler/genericFunctionsNotContextSensitive.ts @@ -0,0 +1,7 @@ +// @strict: true + +// Repro from #37110 + +const f = (x: G) => void>(_: F): F => _; + +const a = f((_: K) => _ => ({})); // (_: K) => (_: G) => {}