Repository: eslint/eslint
Pull request #15616 (2022-02-16 22:29:53)

fix: Avoid dirname for built-in configs.
Load eslint:recommended and eslint:all configs via import instead file paths.

Fixes: #15575

<!--
    Thank you for contributing!

    ESLint adheres to the [JS Foundation Code of Conduct](https://eslint.org/conduct).
-->

#### Prerequisites checklist

- [x] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md).

#### What is the purpose of this pull request? (put an "X" next to an item)

<!--
    The following template is intentionally not a markdown checkbox list for the reasons
    explained in https://github.com/eslint/eslint/pull/12848#issuecomment-580302888
-->

- [ ] Documentation update
- [ ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/bug-report.md))
- [ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-proposal.md))
- [ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-change-proposal.md))
- [ ] Add autofix to a rule
- [ ] Add a CLI option
- [ ] Add something to the core
- [x] Other, please explain: Avoid using `__dirname` for built-in configs, i.e. `eslint:recommended` and `eslint:all`.

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

#### What changes did you make? (Give an overview)

I made changes to *cli-engine.js* and *file-enumerator.js* to pass in callbacks for getting built-in configs instead of file paths.

#### Is there anything you'd like reviewers to focus on?

The main changes are in @eslint/eslintrc ([PR](https://github.com/eslint/eslintrc/pull/71)).
It should be merged and released first before changes here can be applied.

<!-- markdownlint-disable-file MD004 -->



Patch:
diff --git a/Makefile.js b/Makefile.js
index 54ef70606..519b9943a 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -79,7 +79,7 @@ const NODE = "node ", // intentional extra space
     PERF_MULTIFILES_TARGETS = `"${PERF_MULTIFILES_TARGET_DIR + path.sep}{lib,tests${path.sep}lib}${path.sep}**${path.sep}*.js"`,
 
     // Settings
-    MOCHA_TIMEOUT = 10000;
+    MOCHA_TIMEOUT = parseInt(process.env.ESLINT_MOCHA_TIMEOUT, 10) || 10000;
 
 //------------------------------------------------------------------------------
 // Helpers
diff --git a/README.md b/README.md
index fe9812dcc..de20af780 100644
--- a/README.md
+++ b/README.md
@@ -129,7 +129,7 @@ ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, 2018, 2
 
 ESLint's parser only officially supports the latest final ECMAScript standard. We will make changes to core rules in order to avoid crashes on stage 3 ECMAScript syntax proposals (as long as they are implemented using the correct experimental ESTree syntax). We may make changes to core rules to better work with language extensions (such as JSX, Flow, and TypeScript) on a case-by-case basis.
 
-In other cases (including if rules need to warn on more or fewer cases due to new syntax, rather than just not crashing), we recommend you use other parsers and/or rule plugins. If you are using Babel, you can use the [babel-eslint](https://github.com/babel/babel-eslint) parser and [eslint-plugin-babel](https://github.com/babel/eslint-plugin-babel) to use any option available in Babel.
+In other cases (including if rules need to warn on more or fewer cases due to new syntax, rather than just not crashing), we recommend you use other parsers and/or rule plugins. If you are using Babel, you can use [@babel/eslint-parser](https://www.npmjs.com/package/@babel/eslint-parser) and [@babel/eslint-plugin](https://www.npmjs.com/package/@babel/eslint-plugin) to use any option available in Babel.
 
 Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the [TC39 process](https://tc39.github.io/process-document/)), we will accept issues and pull requests related to the new feature, subject to our [contributing guidelines](https://eslint.org/docs/developer-guide/contributing). Until then, please use the appropriate parser and plugin(s) for your experimental feature.
 
@@ -291,7 +291,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <!-- NOTE: This section is autogenerated. Do not manually edit.-->
 <!--sponsorsstart-->
 <h3>Platinum Sponsors</h3>
-<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a> <a href="https://flux.industries"><img src="https://avatars.githubusercontent.com/u/88303769?u=1af1d13b48676ab5918770999361829fc90847c4&v=4" alt="Flux Industries" height="undefined"></a></p><h3>Gold Sponsors</h3>
+<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
 <p><a href="https://contra.com"><img src="https://images.opencollective.com/contra1/c70f93f/logo.png" alt="Contra" height="96"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="96"></a> <a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
 <p><a href="https://launchdarkly.com"><img src="https://images.opencollective.com/launchdarkly/574bb9e/logo.png" alt="launchdarkly" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
diff --git a/docs/developer-guide/contributing/README.md b/docs/developer-guide/contributing/README.md
index 25a889466..050953957 100644
--- a/docs/developer-guide/contributing/README.md
+++ b/docs/developer-guide/contributing/README.md
@@ -8,10 +8,6 @@ This guide is intended for anyone who wants to contribute to an ESLint project.
 
 ESLint welcomes contributions from everyone and adheres to the [OpenJS Foundation Code of Conduct](https://eslint.org/conduct). We kindly request that you read over our code of conduct before contributing.
 
-## [Signing the CLA](https://openjsf.org/about/the-openjs-foundation-cla/)
-
-In order to submit code or documentation to an ESLint project, you will need to electronically sign our [Contributor License Agreement](https://github.com/openjs-foundation/easycla). The CLA is the commonly used Apache-style template, and is you giving us permission to use your contribution. You only need to sign the CLA once for any OpenJS Foundation projects that use EasyCLA.
-
 ## [Bug Reporting](reporting-bugs)
 
 Think you found a problem? We'd love to hear about it. This section explains how to submit a bug, the type of information we need to properly verify it, and the overall process.
@@ -39,3 +35,7 @@ Have some extra time and want to contribute? This section talks about the proces
 ## Submitting a [Pull Request](pull-requests.md)
 
 We're always looking for contributions from the community. This section explains the requirements for pull requests and the process of contributing code.
+
+## Signing the CLA
+
+In order to submit code or documentation to an ESLint project, you will need to electronically sign our Contributor License Agreement. The CLA is the commonly used Apache-style template, and is you giving us permission to use your contribution. You only need to sign the CLA once for any OpenJS Foundation projects that use EasyCLA. You will be asked to sign the CLA in the first pull request you open.
diff --git a/docs/developer-guide/contributing/pull-requests.md b/docs/developer-guide/contributing/pull-requests.md
index e67f29669..b58d10500 100644
--- a/docs/developer-guide/contributing/pull-requests.md
+++ b/docs/developer-guide/contributing/pull-requests.md
@@ -6,7 +6,6 @@ If you want to contribute to an ESLint repo, please use a GitHub pull request. T
 
 If you'd like to work on a pull request and you've never submitted code before, follow these steps:
 
-1. Sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint).
 1. Set up a [development environment](../development-environment.md).
 1. If you want to implement a breaking change or a change to the core, ensure there's an issue that describes what you're doing and the issue has been accepted. You can create a new issue or just indicate you're [working on an existing issue](working-on-issues.md). Bug fixes, documentation changes, and other pull requests do not require an issue.
 
@@ -137,6 +136,8 @@ git push -f origin issue1234
 
 Now you're ready to send the pull request. Go to your ESLint fork and then follow the [GitHub documentation](https://help.github.com/articles/creating-a-pull-request) on how to send a pull request.
 
+In order to submit code or documentation to an ESLint project, you’ll be asked to sign our CLA when you send your first pull request. (Read more about the Open JS Foundation CLA process at <https://cla.openjsf.org/>.)
+
 ## Following Up
 
 Once your pull request is sent, it's time for the team to review it. As such, please make sure to:
diff --git a/docs/rules/block-spacing.md b/docs/rules/block-spacing.md
index 37a0a6be1..663a99d54 100644
--- a/docs/rules/block-spacing.md
+++ b/docs/rules/block-spacing.md
@@ -75,3 +75,8 @@ class C {
 ## When Not To Use It
 
 If you don't want to be notified about spacing style inside of blocks, you can safely disable this rule.
+
+## Related Rules
+
+* [space-before-blocks](space-before-blocks.md)
+* [brace-style](brace-style.md)
diff --git a/docs/rules/brace-style.md b/docs/rules/brace-style.md
index 197eeffc5..0c5502abb 100644
--- a/docs/rules/brace-style.md
+++ b/docs/rules/brace-style.md
@@ -386,6 +386,11 @@ class D { static { foo(); } }
 
 If you don't want to enforce a particular brace style, don't enable this rule.
 
+## Related Rules
+
+* [block-spacing](block-spacing.md)
+* [space-before-blocks](space-before-blocks.md)
+
 ## Further Reading
 
 * [Indent style](https://en.wikipedia.org/wiki/Indent_style)
diff --git a/docs/rules/no-confusing-arrow.md b/docs/rules/no-confusing-arrow.md
index 3671163ea..f88af8e5d 100644
--- a/docs/rules/no-confusing-arrow.md
+++ b/docs/rules/no-confusing-arrow.md
@@ -10,7 +10,9 @@ Here's an example where the usage of `=>` could be confusing:
 // The intent is not clear
 var x = a => 1 ? 2 : 3;
 // Did the author mean this
-var x = function (a) { return 1 ? 2 : 3 };
+var x = function (a) {
+    return 1 ? 2 : 3;
+};
 // Or this
 var x = a <= 1 ? 2 : 3;
 ```
@@ -32,21 +34,25 @@ Examples of **correct** code for this rule:
 ```js
 /*eslint no-confusing-arrow: "error"*/
 /*eslint-env es6*/
-
 var x = a => (1 ? 2 : 3);
 var x = (a) => (1 ? 2 : 3);
+var x = (a) => {
+    return 1 ? 2 : 3;
+};
 var x = a => { return 1 ? 2 : 3; };
-var x = (a) => { return 1 ? 2 : 3; };
 ```
 
 ## Options
 
-This rule accepts a single options argument with the following defaults:
+This rule accepts two options argument with the following defaults:
 
 ```json
 {
     "rules": {
-        "no-confusing-arrow": ["error", {"allowParens": true}]
+        "no-confusing-arrow": [
+            "error",
+            { "allowParens": true, "onlyOneSimpleParam": false }
+        ]
     }
 }
 ```
@@ -65,6 +71,24 @@ var x = a => (1 ? 2 : 3);
 var x = (a) => (1 ? 2 : 3);
 ```
 
+`onlyOneSimpleParam` is a boolean setting that can be `true` or `false`(default):
+
+1. `true` relaxes the rule and doesn't report errors if the arrow function has 0 or more than 1 parameters, or the parameter is not an identifier.
+2. `false` warns regardless of parameters.
+
+Examples of **correct** code for this rule with the `{"onlyOneSimpleParam": true}` option:
+
+```js
+/*eslint no-confusing-arrow: ["error", {"onlyOneSimpleParam": true}]*/
+/*eslint-env es6*/
+() => 1 ? 2 : 3;
+(a, b) => 1 ? 2 : 3;
+(a = b) => 1 ? 2 : 3;
+({ a }) => 1 ? 2 : 3;
+([a]) => 1 ? 2 : 3;
+(...a) => 1 ? 2 : 3;
+```
+
 ## Related Rules
 
 * [no-constant-condition](no-constant-condition.md)
diff --git a/docs/rules/no-irregular-whitespace.md b/docs/rules/no-irregular-whitespace.md
index 3545cd828..eb366915a 100644
--- a/docs/rules/no-irregular-whitespace.md
+++ b/docs/rules/no-irregular-whitespace.md
@@ -33,7 +33,7 @@ This rule disallows the following characters except where the options allow:
     \u2001 - Em Quad
     \u2002 - En Space - <ENSP>
     \u2003 - Em Space - <EMSP>
-    \u2004 - Tree-Per-Em
+    \u2004 - Three-Per-Em
     \u2005 - Four-Per-Em
     \u2006 - Six-Per-Em
     \u2007 - Figure Space
diff --git a/docs/rules/no-shadow.md b/docs/rules/no-shadow.md
index 605a0eb2d..284b7a1b9 100644
--- a/docs/rules/no-shadow.md
+++ b/docs/rules/no-shadow.md
@@ -44,11 +44,11 @@ if (true) {
 
 ## Options
 
-This rule takes one option, an object, with properties `"builtinGlobals"`, `"hoist"` and `"allow"`.
+This rule takes one option, an object, with properties `"builtinGlobals"`, `"hoist"`, `"allow"` and `"ignoreOnInitialization"`.
 
 ```json
 {
-    "no-shadow": ["error", { "builtinGlobals": false, "hoist": "functions", "allow": [] }]
+    "no-shadow": ["error", { "builtinGlobals": false, "hoist": "functions", "allow": [], "ignoreOnInitialization": false }]
 }
 ```
 
@@ -166,6 +166,34 @@ foo(function (err, result) {
 });
 ```
 
+### ignoreOnInitialization
+
+The `ignoreOnInitialization` option is `false` by default. If it is `true`, it prevents reporting shadowing of variables in their initializers when the shadowed variable is presumably still uninitialized.
+
+The shadowed variable must be on the left side. The shadowing variable must be on the right side and declared in a callback function or in an IIFE.
+
+Examples of **incorrect** code for the `{ "ignoreOnInitialization": "true" }` option:
+
+```js
+/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/
+
+var x = x => x;
+```
+
+Because the shadowing variable `x` will shadow the already initialized shadowed variable `x`.
+
+Examples of **correct** code for the `{ "ignoreOnInitialization": true }` option:
+
+```js
+/*eslint no-shadow: ["error", { "ignoreOnInitialization": true }]*/
+
+var x = foo(x => x)
+
+var y = (y => y)()
+```
+
+The rationale for callback functions is the assumption that they will be called during the initialization, so that at the time when the shadowing variable will be used, the shadowed variable has not yet been initialized.
+
 ## Related Rules
 
 * [no-shadow-restricted-names](no-shadow-restricted-names.md)
diff --git a/docs/rules/space-before-blocks.md b/docs/rules/space-before-blocks.md
index 758fda803..1271a4e1b 100644
--- a/docs/rules/space-before-blocks.md
+++ b/docs/rules/space-before-blocks.md
@@ -217,4 +217,5 @@ You can turn this rule off if you are not concerned with the consistency of spac
 * [keyword-spacing](keyword-spacing.md)
 * [arrow-spacing](arrow-spacing.md)
 * [switch-colon-spacing](switch-colon-spacing.md)
+* [block-spacing](block-spacing.md)
 * [brace-style](brace-style.md)
diff --git a/lib/cli-engine/cli-engine.js b/lib/cli-engine/cli-engine.js
index 3ae8b685c..92b875578 100644
--- a/lib/cli-engine/cli-engine.js
+++ b/lib/cli-engine/cli-engine.js
@@ -616,8 +616,8 @@ class CLIEngine {
             useEslintrc: options.useEslintrc,
             builtInRules,
             loadRules,
-            eslintRecommendedPath: path.resolve(__dirname, "../../conf/eslint-recommended.js"),
-            eslintAllPath: path.resolve(__dirname, "../../conf/eslint-all.js")
+            getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
+            getEslintAllConfig: () => require("../../conf/eslint-all.js")
         });
         const fileEnumerator = new FileEnumerator({
             configArrayFactory,
diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js
index f1442d150..674e83e54 100644
--- a/lib/cli-engine/file-enumerator.js
+++ b/lib/cli-engine/file-enumerator.js
@@ -215,8 +215,8 @@ class FileEnumerator {
         cwd = process.cwd(),
         configArrayFactory = new CascadingConfigArrayFactory({
             cwd,
-            eslintRecommendedPath: path.resolve(__dirname, "../../conf/eslint-recommended.js"),
-            eslintAllPath: path.resolve(__dirname, "../../conf/eslint-all.js")
+            getEslintRecommendedConfig: () => require("../../conf/eslint-recommended.js"),
+            getEslintAllConfig: () => require("../../conf/eslint-all.js")
         }),
         extensions = null,
         globInputPaths = true,
diff --git a/lib/config/flat-config-array.js b/lib/config/flat-config-array.js
index cd439e552..fbedf139d 100644
--- a/lib/config/flat-config-array.js
+++ b/lib/config/flat-config-array.js
@@ -14,7 +14,6 @@ const { flatConfigSchema } = require("./flat-config-schema");
 const { RuleValidator } = require("./rule-validator");
 const { defaultConfig } = require("./default-config");
 const recommendedConfig = require("../../conf/eslint-recommended");
-const allConfig = require("../../conf/eslint-all");
 
 //-----------------------------------------------------------------------------
 // Helpers
@@ -79,7 +78,13 @@ class FlatConfigArray extends ConfigArray {
         }
 
         if (config === "eslint:all") {
-            return allConfig;
+
+            /*
+             * Load `eslint-all.js` here instead of at the top level to avoid loading all rule modules
+             * when it isn't necessary. `eslint-all.js` reads `meta` of rule objects to filter out deprecated ones,
+             * so requiring `eslint-all.js` module loads all rule modules as a consequence.
+             */
+            return require("../../conf/eslint-all");
         }
 
         return config;
diff --git a/lib/linter/linter.js b/lib/linter/linter.js
index 9b9f49192..5304a612a 100644
--- a/lib/linter/linter.js
+++ b/lib/linter/linter.js
@@ -800,14 +800,21 @@ function parse(text, languageOptions, filePath) {
      * problem that ESLint identified just like any other.
      */
     try {
+        debug("Parsing:", filePath);
         const parseResult = (typeof parser.parseForESLint === "function")
             ? parser.parseForESLint(textToParse, parserOptions)
             : { ast: parser.parse(textToParse, parserOptions) };
+
+        debug("Parsing successful:", filePath);
         const ast = parseResult.ast;
         const parserServices = parseResult.services || {};
         const visitorKeys = parseResult.visitorKeys || evk.KEYS;
+
+        debug("Scope analysis:", filePath);
         const scopeManager = parseResult.scopeManager || analyzeScope(ast, languageOptions, visitorKeys);
 
+        debug("Scope analysis successful:", filePath);
+
         return {
             success: true,
 
diff --git a/lib/rules/no-confusing-arrow.js b/lib/rules/no-confusing-arrow.js
index 7b736c197..9cdd0a85d 100644
--- a/lib/rules/no-confusing-arrow.js
+++ b/lib/rules/no-confusing-arrow.js
@@ -41,7 +41,8 @@ module.exports = {
         schema: [{
             type: "object",
             properties: {
-                allowParens: { type: "boolean", default: true }
+                allowParens: { type: "boolean", default: true },
+                onlyOneSimpleParam: { type: "boolean", default: false }
             },
             additionalProperties: false
         }],
@@ -54,6 +55,7 @@ module.exports = {
     create(context) {
         const config = context.options[0] || {};
         const allowParens = config.allowParens || (config.allowParens === void 0);
+        const onlyOneSimpleParam = config.onlyOneSimpleParam;
         const sourceCode = context.getSourceCode();
 
 
@@ -65,7 +67,9 @@ module.exports = {
         function checkArrowFunc(node) {
             const body = node.body;
 
-            if (isConditional(body) && !(allowParens && astUtils.isParenthesised(sourceCode, body))) {
+            if (isConditional(body) &&
+                !(allowParens && astUtils.isParenthesised(sourceCode, body)) &&
+                !(onlyOneSimpleParam && !(node.params.length === 1 && node.params[0].type === "Identifier"))) {
                 context.report({
                     node,
                     messageId: "confusing",
diff --git a/lib/rules/no-shadow.js b/lib/rules/no-shadow.js
index bd619235a..43d7d738e 100644
--- a/lib/rules/no-shadow.js
+++ b/lib/rules/no-shadow.js
@@ -11,6 +11,15 @@
 
 const astUtils = require("./utils/ast-utils");
 
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+const FUNC_EXPR_NODE_TYPES = ["ArrowFunctionExpression", "FunctionExpression"];
+const CALL_EXPR_NODE_TYPE = ["CallExpression"];
+const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u;
+const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u;
+
 //------------------------------------------------------------------------------
 // Rule Definition
 //------------------------------------------------------------------------------
@@ -37,7 +46,8 @@ module.exports = {
                         items: {
                             type: "string"
                         }
-                    }
+                    },
+                    ignoreOnInitialization: { type: "boolean", default: false }
                 },
                 additionalProperties: false
             }
@@ -54,9 +64,109 @@ module.exports = {
         const options = {
             builtinGlobals: context.options[0] && context.options[0].builtinGlobals,
             hoist: (context.options[0] && context.options[0].hoist) || "functions",
-            allow: (context.options[0] && context.options[0].allow) || []
+            allow: (context.options[0] && context.options[0].allow) || [],
+            ignoreOnInitialization: context.options[0] && context.options[0].ignoreOnInitialization
         };
 
+        /**
+         * Checks whether or not a given location is inside of the range of a given node.
+         * @param {ASTNode} node An node to check.
+         * @param {number} location A location to check.
+         * @returns {boolean} `true` if the location is inside of the range of the node.
+         */
+        function isInRange(node, location) {
+            return node && node.range[0] <= location && location <= node.range[1];
+        }
+
+        /**
+         * Searches from the current node through its ancestry to find a matching node.
+         * @param {ASTNode} node a node to get.
+         * @param {(node: ASTNode) => boolean} match a callback that checks whether or not the node verifies its condition or not.
+         * @returns {ASTNode|null} the matching node.
+         */
+        function findSelfOrAncestor(node, match) {
+            let currentNode = node;
+
+            while (currentNode && !match(currentNode)) {
+                currentNode = currentNode.parent;
+            }
+            return currentNode;
+        }
+
+        /**
+         * Finds function's outer scope.
+         * @param {Scope} scope Function's own scope.
+         * @returns {Scope} Function's outer scope.
+         */
+        function getOuterScope(scope) {
+            const upper = scope.upper;
+
+            if (upper.type === "function-expression-name") {
+                return upper.upper;
+            }
+            return upper;
+        }
+
+        /**
+         * Checks if a variable and a shadowedVariable have the same init pattern ancestor.
+         * @param {Object} variable a variable to check.
+         * @param {Object} shadowedVariable a shadowedVariable to check.
+         * @returns {boolean} Whether or not the variable and the shadowedVariable have the same init pattern ancestor.
+         */
+        function isInitPatternNode(variable, shadowedVariable) {
+            const outerDef = shadowedVariable.defs[0];
+
+            if (!outerDef) {
+                return false;
+            }
+
+            const { variableScope } = variable.scope;
+
+
+            if (!(FUNC_EXPR_NODE_TYPES.includes(variableScope.block.type) && getOuterScope(variableScope) === shadowedVariable.scope)) {
+                return false;
+            }
+
+            const fun = variableScope.block;
+            const { parent } = fun;
+
+            const callExpression = findSelfOrAncestor(
+                parent,
+                node => CALL_EXPR_NODE_TYPE.includes(node.type)
+            );
+
+            if (!callExpression) {
+                return false;
+            }
+
+            let node = outerDef.name;
+            const location = callExpression.range[1];
+
+            while (node) {
+                if (node.type === "VariableDeclarator") {
+                    if (isInRange(node.init, location)) {
+                        return true;
+                    }
+                    if (FOR_IN_OF_TYPE.test(node.parent.parent.type) &&
+                        isInRange(node.parent.parent.right, location)
+                    ) {
+                        return true;
+                    }
+                    break;
+                } else if (node.type === "AssignmentPattern") {
+                    if (isInRange(node.right, location)) {
+                        return true;
+                    }
+                } else if (SENTINEL_TYPE.test(node.type)) {
+                    break;
+                }
+
+                node = node.parent;
+            }
+
+            return false;
+        }
+
         /**
          * Check if variable name is allowed.
          * @param {ASTNode} variable The variable to check.
@@ -99,11 +209,11 @@ module.exports = {
 
             return (
                 outer &&
-                inner &&
-                outer[0] < inner[0] &&
-                inner[1] < outer[1] &&
-                ((innerDef.type === "FunctionName" && innerDef.node.type === "FunctionExpression") || innerDef.node.type === "ClassExpression") &&
-                outerScope === innerScope.upper
+                 inner &&
+                 outer[0] < inner[0] &&
+                 inner[1] < outer[1] &&
+                 ((innerDef.type === "FunctionName" && innerDef.node.type === "FunctionExpression") || innerDef.node.type === "ClassExpression") &&
+                 outerScope === innerScope.upper
             );
         }
 
@@ -154,11 +264,11 @@ module.exports = {
 
             return (
                 inner &&
-                outer &&
-                inner[1] < outer[0] &&
+                 outer &&
+                 inner[1] < outer[0] &&
 
-                // Excepts FunctionDeclaration if is {"hoist":"function"}.
-                (options.hoist !== "functions" || !outerDef || outerDef.node.type !== "FunctionDeclaration")
+                 // Excepts FunctionDeclaration if is {"hoist":"function"}.
+                 (options.hoist !== "functions" || !outerDef || outerDef.node.type !== "FunctionDeclaration")
             );
         }
 
@@ -175,8 +285,8 @@ module.exports = {
 
                 // Skips "arguments" or variables of a class name in the class scope of ClassDeclaration.
                 if (variable.identifiers.length === 0 ||
-                    isDuplicatedClassNameVariable(variable) ||
-                    isAllowed(variable)
+                     isDuplicatedClassNameVariable(variable) ||
+                     isAllowed(variable)
                 ) {
                     continue;
                 }
@@ -185,9 +295,10 @@ module.exports = {
                 const shadowed = astUtils.getVariableByName(scope.upper, variable.name);
 
                 if (shadowed &&
-                    (shadowed.identifiers.length > 0 || (options.builtinGlobals && "writeable" in shadowed)) &&
-                    !isOnInitializer(variable, shadowed) &&
-                    !(options.hoist !== "all" && isInTdz(variable, shadowed))
+                      (shadowed.identifiers.length > 0 || (options.builtinGlobals && "writeable" in shadowed)) &&
+                      !isOnInitializer(variable, shadowed) &&
+                      !(options.ignoreOnInitialization && isInitPatternNode(variable, shadowed)) &&
+                      !(options.hoist !== "all" && isInTdz(variable, shadowed))
                 ) {
                     const location = getDeclaredLocation(shadowed);
                     const messageId = location.global ? "noShadowGlobal" : "noShadow";
diff --git a/package.json b/package.json
index b9018f7f0..4e52f0ef0 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
   "homepage": "https://eslint.org",
   "bugs": "https://github.com/eslint/eslint/issues/",
   "dependencies": {
-    "@eslint/eslintrc": "^1.1.0",
+    "@eslint/eslintrc": "^1.2.0",
     "@humanwhocodes/config-array": "^0.9.2",
     "ajv": "^6.10.0",
     "chalk": "^4.0.0",
@@ -122,6 +122,7 @@
     "node-polyfill-webpack-plugin": "^1.0.3",
     "npm-license": "^0.3.3",
     "nyc": "^15.0.1",
+    "pirates": "^4.0.5",
     "progress": "^2.0.3",
     "proxyquire": "^2.0.1",
     "puppeteer": "^9.1.1",


Test patch:
diff --git a/docs/developer-guide/unit-tests.md b/docs/developer-guide/unit-tests.md
index 46d77b590..2968a2380 100644
--- a/docs/developer-guide/unit-tests.md
+++ b/docs/developer-guide/unit-tests.md
@@ -37,3 +37,7 @@ Running individual tests is useful when you're working on a specific bug and ite
 ## More Control on Unit Testing
 
 `npm run test:cli` is an alias of the Mocha cli in `./node_modules/.bin/mocha`. [Options](https://mochajs.org/#command-line-usage) are available to be provided to help to better control the test to run.
+
+The default timeout for tests in `npm test` is 10000ms. You may change the timeout by providing `ESLINT_MOCHA_TIMEOUT` environment variable, for example:
+
+    ESLINT_MOCHA_TIMEOUT=20000 npm test
diff --git a/tests/_utils/test-lazy-loading-rules.js b/tests/_utils/test-lazy-loading-rules.js
new file mode 100644
index 000000000..bac438324
--- /dev/null
+++ b/tests/_utils/test-lazy-loading-rules.js
@@ -0,0 +1,66 @@
+/**
+ * @fileoverview Tests lazy-loading of core rules
+ * @author Milos Djermanovic
+ */
+
+/*
+ * This module should be run as a child process, with `fork()`,
+ * because it is important to run this test with a separate, clean Node process
+ * in order to add hooks before any of the ESLint modules is loaded.
+ */
+
+"use strict";
+
+const path = require("path");
+const assert = require("assert");
+const { addHook } = require("pirates");
+
+const {
+    dir: rulesDirectoryPath,
+    name: rulesDirectoryIndexFilename
+} = path.parse(require.resolve("../../lib/rules"));
+
+// Show full stack trace. The default 10 is usually not enough to find the root cause of this problem.
+Error.stackTraceLimit = Infinity;
+
+const [cwd, pattern, usedRulesCommaSeparated] = process.argv.slice(2);
+
+assert.ok(cwd, "cwd argument isn't provided");
+assert.ok(pattern, "pattern argument isn't provided");
+assert.ok(usedRulesCommaSeparated, "used rules argument isn't provided");
+
+const usedRules = usedRulesCommaSeparated.split(",");
+
+// `require()` hook
+addHook(
+    (_code, filename) => {
+        throw new Error(`Unexpected attempt to load unused rule ${filename}`);
+    },
+    {
+
+        // returns `true` if the hook (the function passed in as the first argument) should be called for this filename
+        matcher(filename) {
+            const { dir, name } = path.parse(filename);
+
+            if (dir === rulesDirectoryPath && ![rulesDirectoryIndexFilename, ...usedRules].includes(name)) {
+                return true;
+            }
+
+            return false;
+        }
+
+    }
+);
+
+/*
+ * Everything related to loading any ESLint modules should be in this IIFE
+ */
+(async () => {
+    const { ESLint } = require("../..");
+    const eslint = new ESLint({ cwd });
+
+    await eslint.lintFiles([pattern]);
+})().catch(({ message, stack }) => {
+    process.send({ message, stack });
+    process.exit(1);
+});
diff --git a/tests/fixtures/lazy-loading-rules/.eslintrc.js b/tests/fixtures/lazy-loading-rules/.eslintrc.js
new file mode 100644
index 000000000..fc6500203
--- /dev/null
+++ b/tests/fixtures/lazy-loading-rules/.eslintrc.js
@@ -0,0 +1,6 @@
+module.exports = {
+    root: true,
+    rules: {
+        semi: 2
+    }
+};
diff --git a/tests/fixtures/lazy-loading-rules/foo.js b/tests/fixtures/lazy-loading-rules/foo.js
new file mode 100644
index 000000000..9b2b3016b
--- /dev/null
+++ b/tests/fixtures/lazy-loading-rules/foo.js
@@ -0,0 +1,1 @@
+/* content is not necessary */
diff --git a/tests/lib/cli-engine/file-enumerator.js b/tests/lib/cli-engine/file-enumerator.js
index a1de4cd21..2ccf15e73 100644
--- a/tests/lib/cli-engine/file-enumerator.js
+++ b/tests/lib/cli-engine/file-enumerator.js
@@ -550,7 +550,7 @@ describe("FileEnumerator", () => {
         const files = {
             "file.js": "",
             ".eslintrc.json": JSON.stringify({
-                extends: ["eslint:recommended"]
+                extends: ["eslint:recommended", "eslint:all"]
             })
         };
         const { prepare, cleanup, getPath } = createCustomTeardown({ cwd: root, files });
diff --git a/tests/lib/eslint/eslint.js b/tests/lib/eslint/eslint.js
index 9c84e979d..29c5fa164 100644
--- a/tests/lib/eslint/eslint.js
+++ b/tests/lib/eslint/eslint.js
@@ -27,6 +27,7 @@ const {
 const hash = require("../../../lib/cli-engine/hash");
 const { unIndent, createCustomTeardown } = require("../../_utils");
 const coreRules = require("../../../lib/rules");
+const childProcess = require("child_process");
 
 //------------------------------------------------------------------------------
 // Tests
@@ -412,6 +413,55 @@ describe("ESLint", () => {
             ]);
         });
 
+        it("should use eslint:recommended rules when eslint:recommended configuration is specified", async () => {
+            eslint = new ESLint({
+                useEslintrc: false,
+                overrideConfig: {
+                    extends: ["eslint:recommended"]
+                },
+                ignore: false,
+                cwd: getFixturePath()
+            });
+            const options = { filePath: "file.js" };
+            const results = await eslint.lintText("foo ()", options);
+
+            assert.strictEqual(results.length, 1);
+            assert.strictEqual(results[0].messages.length, 1);
+            assert.strictEqual(results[0].messages[0].ruleId, "no-undef");
+            assert.strictEqual(results[0].messages[0].severity, 2);
+        });
+
+        it("should use eslint:all rules when eslint:all configuration is specified", async () => {
+            eslint = new ESLint({
+                useEslintrc: false,
+                overrideConfig: {
+                    extends: ["eslint:all"]
+                },
+                ignore: false,
+                cwd: getFixturePath()
+            });
+            const options = { filePath: "file.js" };
+            const results = await eslint.lintText("foo ()", options);
+
+            assert.strictEqual(results.length, 1);
+
+            const { messages } = results[0];
+
+            // Some rules that should report errors in the given code. Not all, as we don't want to update this test when we add new rules.
+            const expectedRules = ["no-undef", "semi", "func-call-spacing"];
+
+            expectedRules.forEach(ruleId => {
+                const messageFromRule = messages.find(message => message.ruleId === ruleId);
+
+                assert.ok(
+                    typeof messageFromRule === "object" && messageFromRule !== null, // LintMessage object
+                    `Expected a message from rule '${ruleId}'`
+                );
+                assert.strictEqual(messageFromRule.severity, 2);
+            });
+
+        });
+
         it("correctly autofixes semicolon-conflicting-fixes", async () => {
             eslint = new ESLint({
                 cwd: path.join(fixtureDir, ".."),
@@ -6694,4 +6744,45 @@ describe("ESLint", () => {
             });
         });
     });
+
+    describe("loading rules", () => {
+        it("should not load unused core rules", done => {
+            let calledDone = false;
+
+            const cwd = getFixturePath("lazy-loading-rules");
+            const pattern = "foo.js";
+            const usedRules = ["semi"];
+
+            const forkedProcess = childProcess.fork(
+                path.join(__dirname, "../../_utils/test-lazy-loading-rules.js"),
+                [cwd, pattern, String(usedRules)]
+            );
+
+            // this is an error message
+            forkedProcess.on("message", ({ message, stack }) => {
+                if (calledDone) {
+                    return;
+                }
+                calledDone = true;
+
+                const error = new Error(message);
+
+                error.stack = stack;
+                done(error);
+            });
+
+            forkedProcess.on("exit", exitCode => {
+                if (calledDone) {
+                    return;
+                }
+                calledDone = true;
+
+                if (exitCode === 0) {
+                    done();
+                } else {
+                    done(new Error("Forked process exited with a non-zero exit code"));
+                }
+            });
+        });
+    });
 });
diff --git a/tests/lib/rules/no-confusing-arrow.js b/tests/lib/rules/no-confusing-arrow.js
index 58724d9ac..372f2057b 100644
--- a/tests/lib/rules/no-confusing-arrow.js
+++ b/tests/lib/rules/no-confusing-arrow.js
@@ -30,7 +30,15 @@ ruleTester.run("no-confusing-arrow", rule, {
         { code: "var x = (a) => { return 1 ? 2 : 3; }", options: [{ allowParens: false }] },
 
         "var x = a => (1 ? 2 : 3)",
-        { code: "var x = a => (1 ? 2 : 3)", options: [{ allowParens: true }] }
+        { code: "var x = a => (1 ? 2 : 3)", options: [{ allowParens: true }] },
+
+        "var x = (a,b) => (1 ? 2 : 3)",
+        { code: "() => 1 ? 2 : 3", options: [{ onlyOneSimpleParam: true }] },
+        { code: "(a, b) => 1 ? 2 : 3", options: [{ onlyOneSimpleParam: true }] },
+        { code: "(a = b) => 1 ? 2 : 3", options: [{ onlyOneSimpleParam: true }] },
+        { code: "({ a }) => 1 ? 2 : 3", options: [{ onlyOneSimpleParam: true }] },
+        { code: "([a]) => 1 ? 2 : 3", options: [{ onlyOneSimpleParam: true }] },
+        { code: "(...a) => 1 ? 2 : 3", options: [{ onlyOneSimpleParam: true }] }
     ],
     invalid: [
         {
@@ -71,6 +79,48 @@ ruleTester.run("no-confusing-arrow", rule, {
             code: "var x = (a) => 1 ? 2 : 3",
             output: "var x = (a) => (1 ? 2 : 3)",
             errors: [{ messageId: "confusing" }]
+        },
+        {
+            code: "var x = () => 1 ? 2 : 3",
+            output: "var x = () => (1 ? 2 : 3)",
+            errors: [{ messageId: "confusing" }]
+        },
+        {
+            code: "var x = () => 1 ? 2 : 3",
+            output: "var x = () => (1 ? 2 : 3)",
+            options: [{}],
+            errors: [{ messageId: "confusing" }]
+        },
+        {
+            code: "var x = () => 1 ? 2 : 3",
+            output: "var x = () => (1 ? 2 : 3)",
+            options: [{ onlyOneSimpleParam: false }],
+            errors: [{ messageId: "confusing" }]
+        },
+        {
+            code: "var x = (a, b) => 1 ? 2 : 3",
+            output: "var x = (a, b) => (1 ? 2 : 3)",
+            errors: [{ messageId: "confusing" }]
+        },
+        {
+            code: "var x = (a = b) => 1 ? 2 : 3",
+            output: "var x = (a = b) => (1 ? 2 : 3)",
+            errors: [{ messageId: "confusing" }]
+        },
+        {
+            code: "var x = ({ a }) => 1 ? 2 : 3",
+            output: "var x = ({ a }) => (1 ? 2 : 3)",
+            errors: [{ messageId: "confusing" }]
+        },
+        {
+            code: "var x = ([a]) => 1 ? 2 : 3",
+            output: "var x = ([a]) => (1 ? 2 : 3)",
+            errors: [{ messageId: "confusing" }]
+        },
+        {
+            code: "var x = (...a) => 1 ? 2 : 3",
+            output: "var x = (...a) => (1 ? 2 : 3)",
+            errors: [{ messageId: "confusing" }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-shadow.js b/tests/lib/rules/no-shadow.js
index 13c4c1100..0afcc3ff3 100644
--- a/tests/lib/rules/no-shadow.js
+++ b/tests/lib/rules/no-shadow.js
@@ -63,7 +63,35 @@ ruleTester.run("no-shadow", rule, {
         { code: "class C { static { let x; } static { let x; } }", parserOptions: { ecmaVersion: 2022 } },
         { code: "class C { static { var x; { var x; /* redeclaration */ } } }", parserOptions: { ecmaVersion: 2022 } },
         { code: "class C { static { { var x; } { var x; /* redeclaration */ } } }", parserOptions: { ecmaVersion: 2022 } },
-        { code: "class C { static { { let x; } { let x; } } }", parserOptions: { ecmaVersion: 2022 } }
+        { code: "class C { static { { let x; } { let x; } } }", parserOptions: { ecmaVersion: 2022 } },
+        { code: "const a = [].find(a => a)", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const a = [].find(function(a) { return a; })", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const [a = [].find(a => true)] = dummy", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const { a = [].find(a => true) } = dummy", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "function func(a = [].find(a => true)) {}", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "for (const a in [].find(a => true)) {}", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "for (const a of [].find(a => true)) {}", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const a = [].map(a => true).filter(a => a === 'b')", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const a = [].map(a => true).filter(a => a === 'b').find(a => a === 'c')", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const { a } = (({ a }) => ({ a }))();", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const person = people.find(item => {const person = item.name; return person === 'foo'})", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "var y = bar || foo(y => y);", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "var y = bar && foo(y => y);", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "var z = bar(foo(z => z));", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "var z = boo(bar(foo(z => z)));", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "var match = function (person) { return person.name === 'foo'; };\nconst person = [].find(match);", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const a = foo(x || (a => {}))", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const { a = 1 } = foo(a => {})", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const person = {...people.find((person) => person.firstName.startsWith('s'))}", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 2021 } },
+        { code: "const person = { firstName: people.filter((person) => person.firstName.startsWith('s')).map((person) => person.firstName)[0]}", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 2021 } },
+        { code: "() => { const y = foo(y => y); }", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const x = (x => x)()", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "var y = bar || (y => y)();", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "var y = bar && (y => y)();", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "var x = (x => x)((y => y)());", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const { a = 1 } = (a => {})()", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "() => { const y = (y => y)(); }", options: [{ ignoreOnInitialization: true }], parserOptions: { ecmaVersion: 6 } },
+        { code: "const [x = y => y] = [].map(y => y)", parserOptions: { ecmaVersion: 6 } }
     ],
     invalid: [
         {
@@ -859,6 +887,232 @@ ruleTester.run("no-shadow", rule, {
                 line: 1,
                 column: 50
             }]
+        },
+        {
+            code: "let x = foo((x,y) => {});\nlet y;",
+            options: [{ hoist: "all" }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    messageId: "noShadow",
+                    data: {
+                        name: "x",
+                        shadowedLine: 1,
+                        shadowedColumn: 5
+                    },
+                    type: "Identifier"
+                },
+                {
+                    messageId: "noShadow",
+                    data: {
+                        name: "y",
+                        shadowedLine: 2,
+                        shadowedColumn: 5
+                    },
+                    type: "Identifier"
+                }
+            ]
+        },
+        {
+            code: "const a = fn(()=>{ class C { fn () { const a = 42; return a } } return new C() })",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "a",
+                    shadowedLine: 1,
+                    shadowedColumn: 7
+                },
+                type: "Identifier",
+                line: 1,
+                column: 44
+            }]
+        },
+        {
+            code: "function a() {}\nfoo(a => {});",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "a",
+                    shadowedLine: 1,
+                    shadowedColumn: 10
+                },
+                type: "Identifier",
+                line: 2,
+                column: 5
+            }]
+        },
+        {
+            code: "const a = fn(()=>{ function C() { this.fn=function() { const a = 42; return a } } return new C() });",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "a",
+                    shadowedLine: 1,
+                    shadowedColumn: 7
+                },
+                type: "Identifier",
+                line: 1,
+                column: 62
+            }]
+        },
+        {
+            code: "const x = foo(() => { const bar = () => { return x => {}; }; return bar; });",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "x",
+                    shadowedLine: 1,
+                    shadowedColumn: 7
+                },
+                type: "Identifier",
+                line: 1,
+                column: 50
+            }]
+        },
+        {
+            code: "const x = foo(() => { return { bar(x) {} }; });",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "x",
+                    shadowedLine: 1,
+                    shadowedColumn: 7
+                },
+                type: "Identifier",
+                line: 1,
+                column: 36
+            }]
+        },
+        {
+            code: "const x = () => { foo(x => x); }",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "x",
+                    shadowedLine: 1,
+                    shadowedColumn: 7
+                },
+                type: "Identifier",
+                line: 1,
+                column: 23
+            }]
+        },
+        {
+            code: "const foo = () => { let x; bar(x => x); }",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "x",
+                    shadowedLine: 1,
+                    shadowedColumn: 25
+                },
+                type: "Identifier",
+                line: 1,
+                column: 32
+            }]
+        },
+        {
+            code: "foo(() => { const x = x => x; });",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "x",
+                    shadowedLine: 1,
+                    shadowedColumn: 19
+                },
+                type: "Identifier",
+                line: 1,
+                column: 23
+            }]
+        },
+        {
+            code: "const foo = (x) => { bar(x => {}) }",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "x",
+                    shadowedLine: 1,
+                    shadowedColumn: 14
+                },
+                type: "Identifier",
+                line: 1,
+                column: 26
+            }]
+        },
+        {
+            code: "let x = ((x,y) => {})();\nlet y;",
+            options: [{ hoist: "all" }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    messageId: "noShadow",
+                    data: {
+                        name: "x",
+                        shadowedLine: 1,
+                        shadowedColumn: 5
+                    },
+                    type: "Identifier"
+                },
+                {
+                    messageId: "noShadow",
+                    data: {
+                        name: "y",
+                        shadowedLine: 2,
+                        shadowedColumn: 5
+                    },
+                    type: "Identifier"
+                }
+            ]
+        },
+        {
+            code: "const a = (()=>{ class C { fn () { const a = 42; return a } } return new C() })()",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "a",
+                    shadowedLine: 1,
+                    shadowedColumn: 7
+                },
+                type: "Identifier",
+                line: 1,
+                column: 42
+            }]
+        },
+        {
+            code: "const x = () => { (x => x)(); }",
+            options: [{ ignoreOnInitialization: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                messageId: "noShadow",
+                data: {
+                    name: "x",
+                    shadowedLine: 1,
+                    shadowedColumn: 7
+                },
+                type: "Identifier",
+                line: 1,
+                column: 20
+            }]
         }
     ]
 });