Skip to content

When lowering optional chaining / nullish coalescing operator, the temporary variable declaration comes before "use strict" making the function to be non-strict mode #3322

@sapphi-red

Description

@sapphi-red

When lowering optional chaining / nullish coalescing operator, the temporary variable declaration gets inject at the top of the function. Then, "use strict" becomes the non-first statement and that function becomes non-strict (sloppy) mode.

Input:

const foo = () => {
 'use strict';
  const f1 = function () {};
  const f2 = () => {};

  f1()?.foo;
  f2()?.foo;

  console.log(window.bar ?? 'foo');
};

const bar = function () {
  'use strict';
  const f1 = function () {};
  const f2 = () => {};

  f1()?.foo;
  f2()?.foo;

  console.log(window.bar ?? 'foo');
};

Options: --target es2015
Actual output:

const foo = () => {
  var _a, _b, _c;
  "use strict";
  const f1 = function() {
  };
  const f2 = () => {
  };
  (_a = f1()) == null ? void 0 : _a.foo;
  (_b = f2()) == null ? void 0 : _b.foo;
  console.log((_c = window.bar) != null ? _c : "foo");
};
const bar = function() {
  var _a, _b, _c;
  "use strict";
  const f1 = function() {
  };
  const f2 = () => {
  };
  (_a = f1()) == null ? void 0 : _a.foo;
  (_b = f2()) == null ? void 0 : _b.foo;
  console.log((_c = window.bar) != null ? _c : "foo");
};

Expected output:

const foo = () => {
  "use strict";
  var _a, _b, _c;
  const f1 = function() {
  };
  const f2 = () => {
  };
  (_a = f1()) == null ? void 0 : _a.foo;
  (_b = f2()) == null ? void 0 : _b.foo;
  console.log((_c = window.bar) != null ? _c : "foo");
};
const bar = function() {
  "use strict";
  var _a, _b, _c;
  const f1 = function() {
  };
  const f2 = () => {
  };
  (_a = f1()) == null ? void 0 : _a.foo;
  (_b = f2()) == null ? void 0 : _b.foo;
  console.log((_c = window.bar) != null ? _c : "foo");
};

esbuild try

This bug seems to exist since at least 0.5.1.

related: vitejs/vite#14094

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions