diff --git a/src/ast/nodes/ArrowFunctionExpression.ts b/src/ast/nodes/ArrowFunctionExpression.ts index 095be186886..16095f924e3 100644 --- a/src/ast/nodes/ArrowFunctionExpression.ts +++ b/src/ast/nodes/ArrowFunctionExpression.ts @@ -25,6 +25,7 @@ export default class ArrowFunctionExpression extends FunctionBase { } hasEffects(): boolean { + if (!this.deoptimized) this.applyDeoptimizations(); return false; } diff --git a/src/ast/nodes/shared/FunctionBase.ts b/src/ast/nodes/shared/FunctionBase.ts index 071db59e72e..44f5b881d84 100644 --- a/src/ast/nodes/shared/FunctionBase.ts +++ b/src/ast/nodes/shared/FunctionBase.ts @@ -175,6 +175,7 @@ export default abstract class FunctionBase extends NodeBase implements Deoptimiz includeChildrenRecursively: IncludeChildren, { includeWithoutParameterDefaults }: InclusionOptions = BLANK ): void { + if (!this.deoptimized) this.applyDeoptimizations(); this.included = true; const { brokenFlow } = context; context.brokenFlow = BROKEN_FLOW_NONE; @@ -244,6 +245,16 @@ export default abstract class FunctionBase extends NodeBase implements Deoptimiz super.parseNode(esTreeNode); } + protected applyDeoptimizations() { + // We currently do not track deoptimizations of default values, deoptimize them + // just as we deoptimize call arguments + for (const param of this.params) { + if (param instanceof AssignmentPattern) { + param.right.deoptimizePath(UNKNOWN_PATH); + } + } + } + protected abstract getObjectEntity(): ObjectEntity; } diff --git a/src/ast/nodes/shared/FunctionNode.ts b/src/ast/nodes/shared/FunctionNode.ts index 8a88d29de6e..11b0b99314d 100644 --- a/src/ast/nodes/shared/FunctionNode.ts +++ b/src/ast/nodes/shared/FunctionNode.ts @@ -39,6 +39,7 @@ export default class FunctionNode extends FunctionBase { } hasEffects(): boolean { + if (!this.deoptimized) this.applyDeoptimizations(); return !!this.id?.hasEffects(); } diff --git a/test/function/samples/parameter-defaults/function-as-default/_config.js b/test/function/samples/parameter-defaults/function-as-default/_config.js new file mode 100644 index 00000000000..5a1f0628785 --- /dev/null +++ b/test/function/samples/parameter-defaults/function-as-default/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'deoptimizes functions supplied as default values' +}; diff --git a/test/function/samples/parameter-defaults/function-as-default/main.js b/test/function/samples/parameter-defaults/function-as-default/main.js new file mode 100644 index 00000000000..f11044a0ac5 --- /dev/null +++ b/test/function/samples/parameter-defaults/function-as-default/main.js @@ -0,0 +1,4 @@ +const foo = (a = 'fallback') => a; +const bar = (a = foo) => a; + +assert.strictEqual(bar()(), 'fallback');