Version 2.14.0-129.0.dev

Merge commit '6f2eeae1a4c632a569ccb1858c8b585b1c0b0cd3' into 'dev'
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
index 9d6fe11..8f88db8 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
@@ -254,6 +254,20 @@
         // Otherwise call the map function
         : f(result);
   }
+
+  /// Converts a [List<ErrorOr<T>>] into an [ErrorOr<List<T>>]. If any of the
+  /// items represents an error, that error will be returned. Otherwise, the
+  /// list of results will be returned in a success response.
+  static ErrorOr<List<T>> all<T>(Iterable<ErrorOr<T>> items) {
+    final results = <T>[];
+    for (final item in items) {
+      if (item.isError) {
+        return failure(item);
+      }
+      results.add(item.result);
+    }
+    return success(results);
+  }
 }
 
 /// A base class containing the fields common to RequestMessage and
diff --git a/pkg/analysis_server/lib/src/computer/computer_selection_ranges.dart b/pkg/analysis_server/lib/src/computer/computer_selection_ranges.dart
new file mode 100644
index 0000000..4f4b6b3
--- /dev/null
+++ b/pkg/analysis_server/lib/src/computer/computer_selection_ranges.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+
+/// Computes selection ranges for a specific offset of a Dart [CompilationUnit].
+///
+/// Select ranges support IDE functionality for "expand range" to increase the
+/// selection based on the syntax node of the language.
+class DartSelectionRangeComputer {
+  final CompilationUnit _unit;
+  final int _offset;
+  final _selectionRanges = <SelectionRange>[];
+
+  DartSelectionRangeComputer(this._unit, this._offset);
+
+  /// Returns selection ranges for nodes containing [_offset], starting with the
+  /// closest working up to the outer-most node.
+  List<SelectionRange> compute() {
+    var node = NodeLocator(_offset).searchWithin(_unit);
+    if (node == null) {
+      return [];
+    }
+
+    while (node != null && node != _unit) {
+      _recordRange(node);
+      node = node.parent;
+    }
+
+    return _selectionRanges;
+  }
+
+  /// Record the range for [node] if it is not the same as the last-recorded
+  /// range.
+  void _recordRange(AstNode node) {
+    // Ignore this node if its range is the same as the last one.
+    if (_selectionRanges.isNotEmpty) {
+      final last = _selectionRanges.last;
+      if (node.offset == last.offset && node.length == last.length) {
+        return;
+      }
+    }
+
+    _selectionRanges.add(SelectionRange(node.offset, node.length));
+  }
+}
+
+class SelectionRange {
+  final int offset;
+  final int length;
+
+  SelectionRange(this.offset, this.length);
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_select_range.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_select_range.dart
new file mode 100644
index 0000000..193002f
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_select_range.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/computer/computer_selection_ranges.dart'
+    hide SelectionRange;
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/source/line_info.dart';
+
+class SelectionRangeHandler
+    extends MessageHandler<SelectionRangeParams, List<SelectionRange>?> {
+  SelectionRangeHandler(LspAnalysisServer server) : super(server);
+  @override
+  Method get handlesMessage => Method.textDocument_selectionRange;
+
+  @override
+  LspJsonHandler<SelectionRangeParams> get jsonHandler =>
+      SelectionRangeParams.jsonHandler;
+
+  @override
+  Future<ErrorOr<List<SelectionRange>?>> handle(
+      SelectionRangeParams params, CancellationToken token) async {
+    if (!isDartDocument(params.textDocument)) {
+      return success(null);
+    }
+
+    final path = pathOfDoc(params.textDocument);
+    return path.mapResult((path) async {
+      final lineInfo = server.getLineInfo(path);
+      // If there is no lineInfo, the request cannot be translated from LSP
+      // line/col to server offset/length.
+      if (lineInfo == null) {
+        return success(null);
+      }
+
+      final unit = requireUnresolvedUnit(path);
+      final positions = params.positions;
+      final offsets = await unit.mapResult((unit) =>
+          ErrorOr.all(positions.map((pos) => toOffset(unit.lineInfo, pos))));
+      final allRanges = await offsets.mapResult((offsets) =>
+          success(_getSelectionRangesForOffsets(offsets, unit, lineInfo)));
+
+      return allRanges;
+    });
+  }
+
+  SelectionRange _getSelectionRangesForOffset(
+      CompilationUnit unit, LineInfo lineInfo, int offset) {
+    final computer = DartSelectionRangeComputer(unit, offset);
+    final ranges = computer.compute();
+    // Loop through the items starting at the end (the outermost range), using
+    // each item as the parent for the next item.
+    SelectionRange? last;
+    for (var i = ranges.length - 1; i >= 0; i--) {
+      final range = ranges[i];
+      last = SelectionRange(
+        range: toRange(lineInfo, range.offset, range.length),
+        parent: last,
+      );
+    }
+
+    // It's not clear how to respond if a subset of the results
+    // do not have results, so for now if the list is empty just return a single
+    // range that is exactly the same as the position.
+    // TODO(dantup): Update this based on the response to
+    // https://github.com/microsoft/language-server-protocol/issues/1270
+
+    return last ?? SelectionRange(range: toRange(lineInfo, offset, 0));
+  }
+
+  List<SelectionRange> _getSelectionRangesForOffsets(
+      List<int> offsets, ErrorOr<ParsedUnitResult> unit, LineInfo lineInfo) {
+    return offsets
+        .map((offset) =>
+            _getSelectionRangesForOffset(unit.result.unit, lineInfo, offset))
+        .toList();
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index c8b201d..c0e413d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -29,6 +29,7 @@
 import 'package:analysis_server/src/lsp/handlers/handler_initialized.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_references.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_rename.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_select_range.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_semantic_tokens.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_shutdown.dart';
 import 'package:analysis_server/src/lsp/handlers/handler_signature_help.dart';
@@ -103,6 +104,7 @@
     registerHandler(WorkspaceDidChangeConfigurationMessageHandler(server));
     registerHandler(ReanalyzeHandler(server));
     registerHandler(WillRenameFilesHandler(server));
+    registerHandler(SelectionRangeHandler(server));
     registerHandler(SemanticTokensFullHandler(server));
     registerHandler(SemanticTokensRangeHandler(server));
   }
diff --git a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
index 65af61f..ca0b352 100644
--- a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
@@ -37,6 +37,7 @@
     Method.textDocument_codeAction,
     Method.textDocument_rename,
     Method.textDocument_foldingRange,
+    Method.textDocument_selectionRange,
     // workspace.fileOperations covers all file operation methods but we only
     // support this one.
     Method.workspace_willRenameFiles,
@@ -92,6 +93,9 @@
   bool get rename =>
       _capabilities.textDocument?.rename?.dynamicRegistration ?? false;
 
+  bool get selectionRange =>
+      _capabilities.textDocument?.selectionRange?.dynamicRegistration ?? false;
+
   bool get semanticTokens =>
       _capabilities.textDocument?.semanticTokens?.dynamicRegistration ?? false;
 
@@ -231,6 +235,10 @@
               FoldingRangeRegistrationOptions>.t1(
               true,
             ),
+      selectionRangeProvider: dynamicRegistrations.selectionRange
+          ? null
+          : Either3<bool, SelectionRangeOptions,
+              SelectionRangeRegistrationOptions>.t1(true),
       semanticTokensProvider: dynamicRegistrations.semanticTokens
           ? null
           : Either2<SemanticTokensOptions,
@@ -457,6 +465,13 @@
       Method.workspace_didChangeConfiguration,
     );
     register(
+      dynamicRegistrations.selectionRange,
+      Method.textDocument_selectionRange,
+      SelectionRangeRegistrationOptions(
+        documentSelector: [dartFiles],
+      ),
+    );
+    register(
       dynamicRegistrations.semanticTokens,
       CustomMethods.semanticTokenDynamicRegistration,
       SemanticTokensRegistrationOptions(
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index bf400ba..2fb7918 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -201,7 +201,7 @@
     final crashReportSender =
         CrashReportSender.prod(crashProductId, shouldSendCallback);
 
-    if (telemetry.SHOW_ANALYTICS_UI) {
+    if (telemetry.showAnalyticsUI) {
       if (results.wasParsed(ANALYTICS_FLAG)) {
         analytics.enabled = results[ANALYTICS_FLAG];
         print(telemetry.createAnalyticsStatusMessage(analytics.enabled));
@@ -537,7 +537,7 @@
     print('Supported flags are:');
     print(parser.usage);
 
-    if (telemetry.SHOW_ANALYTICS_UI) {
+    if (telemetry.showAnalyticsUI) {
       // Print analytics status and information.
       if (fromHelp) {
         print('');
@@ -648,11 +648,11 @@
     //
     parser.addFlag(ANALYTICS_FLAG,
         help: 'enable or disable sending analytics information to Google',
-        hide: !telemetry.SHOW_ANALYTICS_UI);
+        hide: !telemetry.showAnalyticsUI);
     parser.addFlag(SUPPRESS_ANALYTICS_FLAG,
         negatable: false,
         help: 'suppress analytics for this session',
-        hide: !telemetry.SHOW_ANALYTICS_UI);
+        hide: !telemetry.showAnalyticsUI);
 
     //
     // Hidden; these are for internal development.
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index cdc4cc8..e7eb40b 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -191,6 +191,7 @@
     expect(initResult.capabilities.foldingRangeProvider, isNotNull);
     expect(initResult.capabilities.workspace!.fileOperations!.willRename,
         equals(ServerCapabilitiesComputer.fileOperationRegistrationOptions));
+    expect(initResult.capabilities.selectionRangeProvider, isNotNull);
     expect(initResult.capabilities.semanticTokensProvider, isNotNull);
 
     expect(didGetRegisterCapabilityRequest, isFalse);
@@ -247,6 +248,7 @@
     expect(initResult.capabilities.renameProvider, isNull);
     expect(initResult.capabilities.foldingRangeProvider, isNull);
     expect(initResult.capabilities.workspace!.fileOperations, isNull);
+    expect(initResult.capabilities.selectionRangeProvider, isNull);
     expect(initResult.capabilities.semanticTokensProvider, isNull);
 
     // Ensure all expected dynamic registrations.
diff --git a/pkg/analysis_server/test/lsp/selection_range_test.dart b/pkg/analysis_server/test/lsp/selection_range_test.dart
new file mode 100644
index 0000000..2a4da46
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/selection_range_test.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SelectionRangeTest);
+  });
+}
+
+/// Additional tests are in
+///
+/// test/src/computer/selection_range_computer_test.dart
+@reflectiveTest
+class SelectionRangeTest extends AbstractLspAnalysisServerTest {
+  Future<void> test_multiple() async {
+    final content = '''
+class Foo {
+  void a() { /*1*/ }
+  void b() { /*2*/ }
+}
+''';
+
+    await initialize();
+    await openFile(mainFileUri, content);
+    final lineInfo = LineInfo.fromContent(content);
+
+    // Send a request for two positions.
+    final regions = await getSelectionRanges(mainFileUri, [
+      positionFromOffset(content.indexOf('/*1*/'), content),
+      positionFromOffset(content.indexOf('/*2*/'), content),
+    ]);
+    expect(regions!.length, equals(2));
+    final firstTexts =
+        _getSelectionRangeText(lineInfo, content, regions[0]).toList();
+    final secondTexts =
+        _getSelectionRangeText(lineInfo, content, regions[1]).toList();
+
+    expect(
+        firstTexts,
+        equals([
+          '{ /*1*/ }',
+          'void a() { /*1*/ }',
+          content.trim(), // Whole content minus the trailing newline
+        ]));
+    expect(
+        secondTexts,
+        equals([
+          '{ /*2*/ }',
+          'void b() { /*2*/ }',
+          content.trim(), // Whole content minus the trailing newline
+        ]));
+  }
+
+  Future<void> test_single() async {
+    final content = '''
+class Foo<T> {
+  void a(String b) {
+    print((1 ^+ 2) * 3);
+  }
+}
+''';
+    final contentWithoutMarker = withoutMarkers(content);
+
+    await initialize();
+    await openFile(mainFileUri, contentWithoutMarker);
+    final lineInfo = LineInfo.fromContent(contentWithoutMarker);
+
+    // The returned List corresponds to the input list of positions, and not
+    // the set of ranges - each range within that list has a (recusrive) parent
+    // to walk up all ranges for that position.
+    final regions =
+        await getSelectionRanges(mainFileUri, [positionFromMarker(content)]);
+    expect(regions!.length, equals(1)); // Only one position was sent.
+    final regionTexts =
+        _getSelectionRangeText(lineInfo, contentWithoutMarker, regions.first)
+            .toList();
+
+    expect(
+        regionTexts,
+        equals([
+          '1 + 2',
+          '(1 + 2)',
+          '(1 + 2) * 3',
+          '((1 + 2) * 3)',
+          'print((1 + 2) * 3)',
+          'print((1 + 2) * 3);',
+          '{\n    print((1 + 2) * 3);\n  }',
+          'void a(String b) {\n    print((1 + 2) * 3);\n  }',
+          'class Foo<T> {\n  void a(String b) {\n    print((1 + 2) * 3);\n  }\n}',
+        ]));
+  }
+
+  Iterable<String> _getSelectionRangeText(
+      LineInfo lineInfo, String content, SelectionRange range) sync* {
+    yield _rangeOfText(lineInfo, content, range.range);
+    final parent = range.parent;
+    if (parent != null) {
+      yield* _getSelectionRangeText(lineInfo, content, parent);
+    }
+  }
+
+  String _rangeOfText(LineInfo lineInfo, String content, Range range) {
+    final startPos = range.start;
+    final endPos = range.end;
+    final start = lineInfo.getOffsetOfLine(startPos.line) + startPos.character;
+    final end = lineInfo.getOffsetOfLine(endPos.line) + endPos.character;
+    return content.substring(start, end);
+  }
+}
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 4bdc585..78b1ba8 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -254,6 +254,7 @@
       'codeAction': {'dynamicRegistration': true},
       'rename': {'dynamicRegistration': true},
       'foldingRange': {'dynamicRegistration': true},
+      'selectionRange': {'dynamicRegistration': true},
       'semanticTokens': SemanticTokensClientCapabilities(
           dynamicRegistration: true,
           requests: SemanticTokensClientCapabilitiesRequests(),
@@ -1134,6 +1135,18 @@
     return resolveCompletion(completion);
   }
 
+  Future<List<SelectionRange>?> getSelectionRanges(
+      Uri uri, List<Position> positions) {
+    final request = makeRequest(
+      Method.textDocument_selectionRange,
+      SelectionRangeParams(
+          textDocument: TextDocumentIdentifier(uri: uri.toString()),
+          positions: positions),
+    );
+    return expectSuccessfulResponseTo(
+        request, _fromJsonList(SelectionRange.fromJson));
+  }
+
   Future<SemanticTokens> getSemanticTokens(Uri uri) {
     final request = makeRequest(
       Method.textDocument_semanticTokens_full,
diff --git a/pkg/analysis_server/test/lsp/test_all.dart b/pkg/analysis_server/test/lsp/test_all.dart
index dd27eb3..fbdd56c 100644
--- a/pkg/analysis_server/test/lsp/test_all.dart
+++ b/pkg/analysis_server/test/lsp/test_all.dart
@@ -35,6 +35,7 @@
 import 'reanalyze_test.dart' as reanalyze;
 import 'references_test.dart' as references;
 import 'rename_test.dart' as rename;
+import 'selection_range_test.dart' as selection_range;
 import 'semantic_tokens_test.dart' as semantic_tokens;
 import 'server_test.dart' as server;
 import 'signature_help_test.dart' as signature_help;
@@ -76,6 +77,7 @@
     reanalyze.main();
     references.main();
     rename.main();
+    selection_range.main();
     semantic_tokens.main();
     server.main();
     signature_help.main();
diff --git a/pkg/analysis_server/test/src/computer/selection_range_computer_test.dart b/pkg/analysis_server/test/src/computer/selection_range_computer_test.dart
new file mode 100644
index 0000000..cbb6cf8
--- /dev/null
+++ b/pkg/analysis_server/test/src/computer/selection_range_computer_test.dart
@@ -0,0 +1,212 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analysis_server/src/computer/computer_selection_ranges.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../abstract_context.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SelectionRangeComputerTest);
+  });
+}
+
+@reflectiveTest
+class SelectionRangeComputerTest extends AbstractContextTest {
+  late String sourcePath;
+
+  @override
+  void setUp() {
+    super.setUp();
+    sourcePath = convertPath('/home/test/lib/test.dart');
+  }
+
+  Future<void> test_arguments() async {
+    final content = '''
+class Foo {
+  Foo({String arg1});
+}
+final foo = Foo(arg1: "test");
+''';
+    final offset = content.indexOf('test');
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(
+      regions,
+      content,
+      [
+        '"test"',
+        'arg1: "test"',
+        '(arg1: "test")',
+        'Foo(arg1: "test")',
+        'foo = Foo(arg1: "test")',
+        'final foo = Foo(arg1: "test")',
+        'final foo = Foo(arg1: "test");',
+      ],
+    );
+  }
+
+  Future<void> test_class_definition() async {
+    final content = 'class Foo<T> {}';
+    final offset = 0;
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(regions, content, ['class Foo<T> {}']);
+  }
+
+  Future<void> test_class_fields() async {
+    final content = '''
+class Foo<T> {
+  String a = 'test';
+}
+''';
+    final offset = content.indexOf('String');
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(
+      regions,
+      content,
+      [
+        'String',
+        "String a = 'test'",
+        "String a = 'test';",
+        "class Foo<T> {\n  String a = 'test';\n}",
+      ],
+    );
+  }
+
+  Future<void> test_constructorCall() async {
+    final content = '''
+class Foo {
+  Foo(String b);
+}
+final foo = Foo("test");
+''';
+    final offset = content.indexOf('test');
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(
+      regions,
+      content,
+      [
+        '"test"',
+        '("test")',
+        'Foo("test")',
+        'foo = Foo("test")',
+        'final foo = Foo("test")',
+        'final foo = Foo("test");',
+      ],
+    );
+  }
+
+  Future<void> test_method() async {
+    final content = '''
+class Foo<T> {
+  void a(String b) {
+    print((1 + 2) * 3);
+  }
+}
+''';
+    final offset = content.indexOf('+');
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(
+      regions,
+      content,
+      [
+        '1 + 2',
+        '(1 + 2)',
+        '(1 + 2) * 3',
+        '((1 + 2) * 3)',
+        'print((1 + 2) * 3)',
+        'print((1 + 2) * 3);',
+        '{\n    print((1 + 2) * 3);\n  }',
+        'void a(String b) {\n    print((1 + 2) * 3);\n  }',
+        'class Foo<T> {\n  void a(String b) {\n    print((1 + 2) * 3);\n  }\n}',
+      ],
+    );
+  }
+
+  Future<void> test_methodLambda() async {
+    final content = '''
+class Foo<T> {
+  void a(String b) => print((1 + 2) * 3);
+}
+''';
+    final offset = content.indexOf('+');
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(
+      regions,
+      content,
+      [
+        '1 + 2',
+        '(1 + 2)',
+        '(1 + 2) * 3',
+        '((1 + 2) * 3)',
+        'print((1 + 2) * 3)',
+        '=> print((1 + 2) * 3);',
+        'void a(String b) => print((1 + 2) * 3);',
+        'class Foo<T> {\n  void a(String b) => print((1 + 2) * 3);\n}',
+      ],
+    );
+  }
+
+  Future<void> test_topLevelFunction() async {
+    final content = '''
+void a(String b) {
+  print((1 + 2) * 3);
+}
+''';
+    final offset = content.indexOf('+');
+
+    final regions = await _computeSelectionRanges(content, offset);
+    _expectRegions(
+      regions,
+      content,
+      [
+        '1 + 2',
+        '(1 + 2)',
+        '(1 + 2) * 3',
+        '((1 + 2) * 3)',
+        'print((1 + 2) * 3)',
+        'print((1 + 2) * 3);',
+        '{\n  print((1 + 2) * 3);\n}',
+        '(String b) {\n  print((1 + 2) * 3);\n}',
+        'void a(String b) {\n  print((1 + 2) * 3);\n}',
+      ],
+    );
+  }
+
+  Future<void> test_whitespace() async {
+    final content = '    class Foo {}';
+    final offset = 0;
+
+    final regions = await _computeSelectionRanges(content, offset);
+    expect(regions, isEmpty);
+  }
+
+  Future<List<SelectionRange>?> _computeSelectionRanges(
+      String sourceContent, int offset) async {
+    newFile(sourcePath, content: sourceContent);
+    var result =
+        await session.getResolvedUnit2(sourcePath) as ResolvedUnitResult;
+    var computer = DartSelectionRangeComputer(result.unit!, offset);
+    return computer.compute();
+  }
+
+  /// Checks the text of [regions] against [expected].
+  void _expectRegions(
+      List<SelectionRange>? regions, String content, List<String> expected) {
+    final actual = regions!
+        .map((region) =>
+            content.substring(region.offset, region.offset + region.length))
+        .toList();
+
+    expect(actual, equals(expected));
+  }
+}
diff --git a/pkg/analysis_server/test/src/computer/test_all.dart b/pkg/analysis_server/test/src/computer/test_all.dart
index 1a04173..6f67c7a 100644
--- a/pkg/analysis_server/test/src/computer/test_all.dart
+++ b/pkg/analysis_server/test/src/computer/test_all.dart
@@ -10,6 +10,7 @@
 import 'import_elements_computer_test.dart' as import_elements_computer;
 import 'imported_elements_computer_test.dart' as imported_elements_computer;
 import 'outline_computer_test.dart' as outline_computer;
+import 'selection_range_computer_test.dart' as selection_range;
 
 void main() {
   defineReflectiveSuite(() {
@@ -19,5 +20,6 @@
     import_elements_computer.main();
     imported_elements_computer.main();
     outline_computer.main();
+    selection_range.main();
   });
 }
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index e70af29..1ef02d9 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -89,6 +89,7 @@
 | textDocument/references | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/documentHighlight | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/documentSymbol | ✅ | ✅ | | ✅ | ✅ |
+| textDocument/selectionRanges | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/codeAction (sortMembers) | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/codeAction (organiseImports) | ✅ | ✅ | | ✅ | ✅ |
 | textDocument/codeAction (refactors) | ✅ | ✅ | | ✅ | ✅ |
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index edfcd2e..596c1b6 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -601,6 +601,10 @@
   /// Return `true` if this element has an annotation of the form `@sealed`.
   bool get hasSealed;
 
+  /// Return `true` if this element has an annotation of the form `@useResult`
+  /// or `@UseResult('..')`.
+  bool get hasUseResult;
+
   /// Return `true` if this element has an annotation of the form
   /// `@visibleForTemplate`.
   bool get hasVisibleForTemplate;
@@ -807,6 +811,10 @@
   /// intended to be used as an annotation.
   bool get isTarget;
 
+  /// Return `true` if this annotation marks the associated returned element as
+  /// requiring use.
+  bool get isUseResult;
+
   /// Return `true` if this annotation marks the associated member as being
   /// visible for template files.
   bool get isVisibleForTemplate;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index a0f2061..c77e160 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -607,6 +607,8 @@
   HintCode.UNUSED_IMPORT,
   HintCode.UNUSED_LABEL,
   HintCode.UNUSED_LOCAL_VARIABLE,
+  HintCode.UNUSED_RESULT,
+  HintCode.UNUSED_RESULT_WITH_MESSAGE,
   HintCode.UNUSED_SHOWN_NAME,
   LanguageCode.IMPLICIT_DYNAMIC_FIELD,
   LanguageCode.IMPLICIT_DYNAMIC_FUNCTION,
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 5f12fdb..daea242 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 137;
+  static const int DATA_VERSION = 138;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index f6fae99..2d9f7ff 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2006,6 +2006,13 @@
   /// specific set of target element kinds.
   static const String _TARGET_CLASS_NAME = 'Target';
 
+  /// The name of the class used to mark a returned element as requiring use.
+  static const String _USE_RESULT_CLASS_NAME = "UseResult";
+
+  /// The name of the top-level variable used to mark a returned element as
+  /// requiring use.
+  static const String _USE_RESULT_VARIABLE_NAME = "useResult";
+
   /// The name of the top-level variable used to mark a method as being
   /// visible for templates.
   static const String _VISIBLE_FOR_TEMPLATE_VARIABLE_NAME =
@@ -2119,6 +2126,12 @@
       libraryName: _META_META_LIB_NAME, className: _TARGET_CLASS_NAME);
 
   @override
+  bool get isUseResult =>
+      _isConstructor(
+          libraryName: _META_LIB_NAME, className: _USE_RESULT_CLASS_NAME) ||
+      _isPackageMetaGetter(_USE_RESULT_VARIABLE_NAME);
+
+  @override
   bool get isVisibleForTemplate => _isTopGetter(
       libraryName: _NG_META_LIB_NAME,
       name: _VISIBLE_FOR_TEMPLATE_VARIABLE_NAME);
@@ -2498,6 +2511,18 @@
   }
 
   @override
+  bool get hasUseResult {
+    final metadata = this.metadata;
+    for (var i = 0; i < metadata.length; i++) {
+      var annotation = metadata[i];
+      if (annotation.isUseResult) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
   bool get hasVisibleForTemplate {
     final metadata = this.metadata;
     for (var i = 0; i < metadata.length; i++) {
@@ -3668,22 +3693,14 @@
   DartType? _returnType;
 
   /// The elements representing the parameters of the function.
-  List<ParameterElement> _parameters = _Sentinel.parameterElement;
+  List<ParameterElement> _parameters = const [];
 
   /// Is `true` if the type has the question mark, so is nullable.
-  bool _isNullable = false;
+  bool isNullable = false;
 
   /// The type defined by this element.
   FunctionType? _type;
 
-  GenericFunctionTypeElementImpl.forLinkedNode(
-      ElementImpl enclosingElement, AstNode linkedNode)
-      : super.forLinkedNode(enclosingElement, null, linkedNode) {
-    if (linkedNode is GenericFunctionTypeImpl) {
-      linkedNode.declaredElement = this;
-    }
-  }
-
   /// Initialize a newly created function element to have no name and the given
   /// [nameOffset]. This is used for function expressions, that have no name.
   GenericFunctionTypeElementImpl.forOffset(int nameOffset)
@@ -3692,41 +3709,11 @@
   @override
   String get identifier => '-';
 
-  bool get isNullable {
-    if (linkedNode != null) {
-      var node = linkedNode;
-      if (node is GenericFunctionType) {
-        return _isNullable = node.question != null;
-      } else {
-        return _isNullable = false;
-      }
-    }
-    return _isNullable;
-  }
-
-  set isNullable(bool isNullable) {
-    _isNullable = isNullable;
-  }
-
   @override
   ElementKind get kind => ElementKind.GENERIC_FUNCTION_TYPE;
 
   @override
   List<ParameterElement> get parameters {
-    if (!identical(_parameters, _Sentinel.parameterElement)) {
-      return _parameters;
-    }
-
-    if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext!;
-      return _parameters = ParameterElementImpl.forLinkedNodeList(
-        this,
-        context,
-        null,
-        context.getFormalParameters(linkedNode!),
-      );
-    }
-
     return _parameters;
   }
 
@@ -3752,12 +3739,6 @@
 
   @override
   DartType get returnTypeInternal {
-    if (_returnType == null) {
-      if (linkedNode != null) {
-        var context = enclosingUnit.linkedContext!;
-        return _returnType = context.getReturnType(linkedNode!);
-      }
-    }
     return _returnType!;
   }
 
@@ -3786,12 +3767,8 @@
 
   @override
   List<TypeParameterElement> get typeParameters {
-    if (linkedNode != null) {
-      if (linkedNode is FunctionTypeAlias) {
-        return const <TypeParameterElement>[];
-      }
-    }
-    return super.typeParameters;
+    // TODO(scheglov) remove the method
+    return _typeParameterElements;
   }
 
   /// Set the type parameters defined by this function type element to the given
@@ -4919,6 +4896,9 @@
   bool get hasSealed => false;
 
   @override
+  bool get hasUseResult => false;
+
+  @override
   bool get hasVisibleForTemplate => false;
 
   @override
@@ -5960,7 +5940,6 @@
 
   ElementLinkedData? linkedData;
 
-  bool _isAliasedElementReady = false;
   ElementImpl? _aliasedElement;
   DartType? _aliasedType;
 
@@ -6002,12 +5981,11 @@
 
   @override
   ElementImpl? get aliasedElement {
-    _ensureAliasedElement();
+    linkedData?.read(this);
     return _aliasedElement;
   }
 
   set aliasedElement(ElementImpl? aliasedElement) {
-    _isAliasedElementReady = true;
     _aliasedElement = aliasedElement;
     aliasedElement?.enclosingElement = this;
   }
@@ -6017,8 +5995,6 @@
     linkedData?.read(this);
     if (_aliasedType != null) return _aliasedType!;
 
-    _ensureAliasedElement();
-
     final linkedNode = this.linkedNode;
     if (linkedNode is GenericTypeAlias) {
       var typeNode = linkedNode.type;
@@ -6162,44 +6138,6 @@
     this.linkedData = linkedData;
   }
 
-  void _ensureAliasedElement() {
-    if (_isAliasedElementReady) return;
-    _isAliasedElementReady = true;
-
-    linkedData?.read(this);
-
-    final linkedNode = this.linkedNode;
-    if (linkedNode != null) {
-      if (linkedNode is GenericTypeAlias) {
-        var type = linkedNode.type;
-        if (type is GenericFunctionTypeImpl) {
-          _aliasedElement =
-              type.declaredElement as GenericFunctionTypeElementImpl?;
-          // TODO(scheglov) Do we need this?
-          // We probably should set it when linking and when applying.
-          _aliasedElement ??= GenericFunctionTypeElementImpl.forLinkedNode(
-            this,
-            type,
-          );
-        } else if (isNonFunctionTypeAliasesEnabled) {
-          // No element for `typedef A<T> = List<T>;`
-        } else {
-          _aliasedElement = GenericFunctionTypeElementImpl.forOffset(-1)
-            ..enclosingElement = this
-            ..typeParameters = const <TypeParameterElement>[]
-            ..parameters = const <ParameterElement>[]
-            ..returnType = DynamicTypeImpl.instance;
-        }
-      } else {
-        // TODO(scheglov) Same as above.
-        _aliasedElement = GenericFunctionTypeElementImpl.forLinkedNode(
-          this,
-          linkedNode,
-        );
-      }
-    }
-  }
-
   FunctionTypeImpl _errorFunctionType(NullabilitySuffix nullabilitySuffix) {
     return FunctionTypeImpl(
       typeFormals: const [],
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index aa87517..0cb160f 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -519,6 +519,9 @@
   bool get hasSealed => _declaration.hasSealed;
 
   @override
+  bool get hasUseResult => _declaration.hasUseResult;
+
+  @override
   bool get hasVisibleForTemplate => _declaration.hasVisibleForTemplate;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index da49e89..a4a3347 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -96,6 +96,37 @@
       correction: "Replace the '.' with a '?.' in the invocation.");
 
   /**
+   * Generate a hint for method, property or function annotated with
+   * `@useResult` whose invocation is unchecked.
+   *
+   * Parameters:
+   * 0: the name of the annotated method, property or function
+   */
+  static const HintCode UNUSED_RESULT = HintCode(
+      'UNUSED_RESULT', "'{0}' should be used.",
+      correction:
+          "Try using the result by invoking a member, passing it to a function, or returning it from this function.",
+      hasPublishedDocs: false);
+
+  /**
+   * Generate a hint for method, property or function annotated with
+   * `@useResult` whose invocation is unchecked.
+   *
+   * Parameters:
+   * 0: the name of the annotated method, property or function
+   * 1: message details
+   */
+  static const HintCode UNUSED_RESULT_WITH_MESSAGE = HintCode(
+    'UNUSED_RESULT',
+    "'{0}' should be used. {1}.",
+    // todo(pq): consider passing in correction details: https://github.com/dart-lang/sdk/issues/46066
+    correction:
+        "Try using the result by invoking a member, passing it to a function, or returning it from this function.",
+    hasPublishedDocs: false,
+    uniqueName: 'HintCode.UNUSED_RESULT_WITH_MESSAGE',
+  );
+
+  /**
    * Dead code is code that is never reached, this can happen for instance if a
    * statement follows a return statement.
    *
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index 4635774..63b77b3 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -71,7 +71,7 @@
     required ErrorReporter errorReporter,
     required TypeSystemImpl typeSystem,
     required MigrationResolutionHooks? migrationResolutionHooks,
-  })   : _resolver = resolver,
+  })  : _resolver = resolver,
         _errorReporter = errorReporter,
         _typeSystem = typeSystem,
         _migrationResolutionHooks = migrationResolutionHooks,
@@ -110,6 +110,10 @@
         } else {
           var name = constructorIdentifier.name;
           rawElement = typeElement.getNamedConstructor(name);
+          if (rawElement != null &&
+              !rawElement.isAccessibleIn(definingLibrary)) {
+            rawElement = null;
+          }
         }
       }
     } else if (typeElement is TypeAliasElement) {
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 2cfb030..9304693 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -98,7 +98,7 @@
     required DeclaredVariables declaredVariables,
     required AnalysisOptions analysisOptions,
     required WorkspacePackage? workspacePackage,
-  })   : _nullType = typeProvider.nullType,
+  })  : _nullType = typeProvider.nullType,
         _typeSystem = typeSystem,
         _isNonNullableByDefault = typeSystem.isNonNullableByDefault,
         _strictInference =
@@ -2007,6 +2007,8 @@
         return 'parameters';
       case TargetKind.setter:
         return 'setters';
+      case TargetKind.topLevelVariable:
+        return 'top-level variables';
       case TargetKind.type:
         return 'types (classes, enums, mixins, or typedefs)';
       case TargetKind.typedefType:
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 907c52c..a1ab43c 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -759,7 +759,7 @@
         node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
     _checkForMainFunction(node.name);
     _checkForTypeAliasCannotReferenceItself(
-        node, node.declaredElement as TypeAliasElementImpl);
+        node.name, node.declaredElement as TypeAliasElementImpl);
     super.visitFunctionTypeAlias(node);
   }
 
@@ -794,7 +794,7 @@
         node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
     _checkForMainFunction(node.name);
     _checkForTypeAliasCannotReferenceItself(
-        node, node.declaredElement as TypeAliasElementImpl);
+        node.name, node.declaredElement as TypeAliasElementImpl);
     super.visitGenericTypeAlias(node);
   }
 
@@ -3962,13 +3962,13 @@
   ///
   /// See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF].
   void _checkForTypeAliasCannotReferenceItself(
-    AstNode node,
+    SimpleIdentifier nameNode,
     TypeAliasElementImpl element,
   ) {
     if (element.hasSelfReference) {
       errorReporter.reportErrorForNode(
         CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
-        node,
+        nameNode,
       );
     }
   }
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index e75ff62..422e337 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -1457,7 +1457,7 @@
     if (tag == AliasedElementTag.nothing) {
       return null;
     } else if (tag == AliasedElementTag.genericFunctionElement) {
-      var typeParameters = _readTypeParameters();
+      var typeParameters = _readTypeParameters(unitElement);
       var formalParameters = _readFormalParameters(unitElement);
       var returnType = readRequiredType();
 
@@ -1536,7 +1536,7 @@
       var kindIndex = _reader.readByte();
       var kind = _formalParameterKind(kindIndex);
       var isInitializingFormal = _reader.readBool();
-      var typeParameters = _readTypeParameters();
+      var typeParameters = _readTypeParameters(unitElement);
       var type = readRequiredType();
       var name = readStringReference();
       if (kind.isRequiredPositional) {
@@ -1577,7 +1577,7 @@
   /// TODO(scheglov) Optimize for write/read of types without type parameters.
   FunctionType _readFunctionType() {
     // TODO(scheglov) reuse for formal parameters
-    var typeParameters = _readTypeParameters();
+    var typeParameters = _readTypeParameters(null);
     var returnType = readRequiredType();
     var formalParameters = _readFormalParameters(null);
 
@@ -1666,7 +1666,9 @@
     return types;
   }
 
-  List<TypeParameterElementImpl> _readTypeParameters() {
+  List<TypeParameterElementImpl> _readTypeParameters(
+    CompilationUnitElementImpl? unitElement,
+  ) {
     var typeParameterCount = _reader.readUInt30();
     var typeParameters = List.generate(typeParameterCount, (_) {
       var name = readStringReference();
@@ -1677,6 +1679,9 @@
 
     for (var typeParameter in typeParameters) {
       typeParameter.bound = readType();
+      if (unitElement != null) {
+        typeParameter.metadata = _readAnnotationList(unitElement: unitElement);
+      }
     }
     return typeParameters;
   }
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 5428c87..9dc8c56 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -630,7 +630,7 @@
       _writeTypeParameters(element.typeParameters, () {
         _writeFormalParameters(element.parameters, withAnnotations: true);
         writeType(element.returnType);
-      });
+      }, withAnnotations: true);
     } else {
       throw UnimplementedError('${element.runtimeType}');
     }
@@ -665,7 +665,7 @@
           parameter.parameters,
           withAnnotations: withAnnotations,
         );
-      });
+      }, withAnnotations: withAnnotations);
       if (withAnnotations) {
         _writeAnnotationList(parameter.metadata);
       }
@@ -680,7 +680,7 @@
     _writeTypeParameters(type.typeFormals, () {
       writeType(type.returnType);
       _writeFormalParameters(type.parameters, withAnnotations: false);
-    });
+    }, withAnnotations: false);
     _writeNullabilitySuffix(type.nullabilitySuffix);
   }
 
@@ -736,8 +736,9 @@
 
   void _writeTypeParameters(
     List<TypeParameterElement> typeParameters,
-    void Function() f,
-  ) {
+    void Function() f, {
+    required bool withAnnotations,
+  }) {
     localElements.pushScope();
     localElements.declareAll(typeParameters);
     try {
@@ -747,6 +748,9 @@
       }
       for (var typeParameter in typeParameters) {
         writeType(typeParameter.bound);
+        if (withAnnotations) {
+          _writeAnnotationList(typeParameter.metadata);
+        }
       }
       f();
     } finally {
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index d4aa9f2..3784428 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -36,17 +36,7 @@
   Linker get _linker => _libraryBuilder.linker;
 
   void buildDeclarationElements(CompilationUnit unit) {
-    // TODO(scheglov) Use `unit.accept` when all nodes handled.
-    for (var declaration in unit.declarations) {
-      if (declaration is ClassDeclaration ||
-          declaration is EnumDeclaration ||
-          declaration is ExtensionDeclaration ||
-          declaration is FunctionDeclaration ||
-          declaration is MixinDeclaration ||
-          declaration is TopLevelVariableDeclaration) {
-        declaration.accept(this);
-      }
-    }
+    unit.declarations.accept(this);
     _unitElement.accessors = _enclosingContext.propertyAccessors;
     _unitElement.enums = _enclosingContext.enums;
     _unitElement.functions = _enclosingContext.functions;
@@ -74,10 +64,22 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
+    node.typeParameters?.accept(this);
+    node.extendsClause?.accept(this);
+    node.withClause?.accept(this);
+    node.implementsClause?.accept(this);
     _buildClassOrMixin(node);
   }
 
   @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    node.typeParameters?.accept(this);
+    node.superclass.accept(this);
+    node.withClause.accept(this);
+    node.implementsClause?.accept(this);
+  }
+
+  @override
   void visitConstructorDeclaration(
     covariant ConstructorDeclarationImpl node,
   ) {
@@ -139,12 +141,19 @@
   }
 
   @override
+  void visitExtendsClause(ExtendsClause node) {
+    node.superclass.accept(this);
+  }
+
+  @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     var element = node.declaredElement as ExtensionElementImpl;
     var holder = _buildClassMembers(element, node.members);
     element.accessors = holder.propertyAccessors;
     element.fields = holder.properties.whereType<FieldElement>().toList();
     element.methods = holder.methods;
+
+    node.extendedType.accept(this);
   }
 
   @override
@@ -197,6 +206,7 @@
         _enclosingContext.addSetter(name, setter);
       }
     }
+    _buildType(node.fields.type);
   }
 
   @override
@@ -247,6 +257,8 @@
         element.typeParameters = holder.typeParameters;
       }
     });
+
+    _buildType(node.type);
   }
 
   @override
@@ -310,6 +322,27 @@
     } else {
       localScope.declare(name, reference);
     }
+
+    _buildType(node.returnType);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    node.returnType?.accept(this);
+    node.typeParameters?.accept(this);
+    node.parameters.accept(this);
+
+    var element = node.declaredElement as TypeAliasElementImpl;
+
+    var aliasedElement = GenericFunctionTypeElementImpl.forOffset(
+      node.name.offset,
+    );
+    // TODO(scheglov) Use enclosing context?
+    aliasedElement.parameters = node.parameters.parameters
+        .map((parameterNode) => parameterNode.declaredElement!)
+        .toList();
+
+    element.aliasedElement = aliasedElement;
   }
 
   @override
@@ -353,6 +386,51 @@
         element.typeParameters = holder.typeParameters;
       }
     });
+
+    _buildType(node.returnType);
+  }
+
+  @override
+  void visitGenericFunctionType(covariant GenericFunctionTypeImpl node) {
+    var element = GenericFunctionTypeElementImpl.forOffset(node.offset);
+    _unitElement.encloseElement(element);
+
+    node.declaredElement = element;
+    _linker.elementNodes[element] = node;
+
+    var fakeReference = Reference.root();
+    var holder = _EnclosingContext(fakeReference, element);
+    _withEnclosing(holder, () {
+      var formalParameters = node.parameters;
+      formalParameters.accept(this);
+      element.parameters = holder.parameters;
+
+      var typeParameters = node.typeParameters;
+      if (typeParameters != null) {
+        typeParameters.accept(this);
+        element.typeParameters = holder.typeParameters;
+      }
+    });
+
+    _buildType(node.returnType);
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    node.typeParameters?.accept(this);
+    node.type.accept(this);
+
+    var typeNode = node.type;
+    if (typeNode is GenericFunctionTypeImpl) {
+      var element = node.declaredElement as TypeAliasElementImpl;
+      element.aliasedElement =
+          typeNode.declaredElement as GenericFunctionTypeElementImpl;
+    }
+  }
+
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    node.interfaces.accept(this);
   }
 
   @override
@@ -448,14 +526,24 @@
       formalParameters: node.parameters,
       typeParameters: node.typeParameters,
     );
+
+    _buildType(node.returnType);
   }
 
   @override
   void visitMixinDeclaration(MixinDeclaration node) {
+    node.typeParameters?.accept(this);
+    node.onClause?.accept(this);
+    node.implementsClause?.accept(this);
     _buildClassOrMixin(node);
   }
 
   @override
+  void visitOnClause(OnClause node) {
+    node.superclassConstraints.accept(this);
+  }
+
+  @override
   void visitPartDirective(PartDirective node) {}
 
   @override
@@ -494,6 +582,8 @@
 
     node.declaredElement = element;
     nameNode?.staticElement = element;
+
+    _buildType(node.type);
   }
 
   @override
@@ -546,6 +636,18 @@
         localScope.declare('$name=', setter.reference!);
       }
     }
+
+    _buildType(node.variables.type);
+  }
+
+  @override
+  void visitTypeArgumentList(TypeArgumentList node) {
+    node.arguments.accept(this);
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    node.typeArguments?.accept(this);
   }
 
   @override
@@ -556,8 +658,11 @@
     var element = TypeParameterElementImpl(name, nameNode.offset);
     element.metadata = _buildAnnotations(node.metadata);
 
+    nameNode.staticElement = element;
     _linker.elementNodes[element] = node;
     _enclosingContext.addTypeParameter(name, element);
+
+    _buildType(node.bound);
   }
 
   @override
@@ -565,6 +670,11 @@
     node.typeParameters.accept(this);
   }
 
+  @override
+  void visitWithClause(WithClause node) {
+    node.mixinTypes.accept(this);
+  }
+
   List<ElementAnnotation> _buildAnnotations(List<Annotation> nodeList) {
     return _buildAnnotationsWithUnit(_unitElement, nodeList);
   }
@@ -670,6 +780,11 @@
     }
   }
 
+  /// TODO(scheglov) Maybe inline?
+  void _buildType(TypeAnnotation? node) {
+    node?.accept(this);
+  }
+
   Uri? _selectAbsoluteUri(NamespaceDirective directive) {
     var relativeUriStr = _selectRelativeUri(
       directive.configurations,
@@ -892,9 +1007,9 @@
     return _bindReference('@variable', name, element);
   }
 
-  Reference addTypeParameter(String name, TypeParameterElementImpl element) {
+  void addTypeParameter(String name, TypeParameterElementImpl element) {
     typeParameters.add(element);
-    return _bindReference('@typeParameter', name, element);
+    this.element.encloseElement(element);
   }
 
   Reference _bindReference(
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 3fc1536..3b9c95d 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -263,6 +263,7 @@
       var unitRef = reference.getChild('@unit');
       var unitReference = unitRef.getChild(unitContext.uriStr);
       var resolver = ReferenceResolver(
+        linker,
         nodesToBuildType,
         linker.elementFactory,
         element,
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 64c3567..ed8df04 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
 import 'package:analyzer/src/summary2/function_type_builder.dart';
+import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/linking_node_scope.dart';
 import 'package:analyzer/src/summary2/named_type_builder.dart';
@@ -29,6 +30,7 @@
 /// the type is set, otherwise we keep it empty, so we will attempt to infer
 /// it later).
 class ReferenceResolver extends ThrowingAstVisitor<void> {
+  final Linker linker;
   final TypeSystemImpl _typeSystem;
   final NodesToBuildType nodesToBuildType;
   final LinkedElementFactory elementFactory;
@@ -40,6 +42,7 @@
   Scope scope;
 
   ReferenceResolver(
+    this.linker,
     this.nodesToBuildType,
     this.elementFactory,
     LibraryElementImpl libraryElement,
@@ -253,13 +256,7 @@
     var nodeImpl = node as GenericFunctionTypeImpl;
     var outerScope = scope;
 
-    var element = GenericFunctionTypeElementImpl.forLinkedNode(
-      unitReference.element as CompilationUnitElementImpl,
-      node,
-    );
-    element.parameters; // create elements
-
-    _createTypeParameterElements(element, node.typeParameters);
+    var element = node.declaredElement as GenericFunctionTypeElementImpl;
     scope = TypeParameterScope(outerScope, element.typeParameters);
 
     node.returnType?.accept(this);
@@ -423,7 +420,15 @@
 
   @override
   void visitTypeParameter(TypeParameter node) {
-    node.bound?.accept(this);
+    var bound = node.bound;
+    if (bound != null) {
+      bound.accept(this);
+      var element = node.declaredElement as TypeParameterElementImpl;
+      element.bound = bound.type;
+      // TODO(scheglov) We should not need to do it here.
+      // Only in the element builder, eventually.z
+      linker.elementNodes[element] = node;
+    }
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index f502211..b3446f2 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -48,18 +48,22 @@
       builder.build();
     }
 
-    _MixinsInference().perform(nodes.declarations);
-
     for (var declaration in nodes.declarations) {
       _declaration(declaration);
     }
 
     // TODO(scheglov) generalize
     _linker.elementNodes.forEach((element, node) {
+      if (element is GenericFunctionTypeElementImpl &&
+          node is GenericFunctionType) {
+        element.returnType = node.returnType?.type ?? _dynamicType;
+      }
       if (element is TypeParameterElementImpl && node is TypeParameter) {
         element.bound = node.bound?.type;
       }
     });
+
+    _MixinsInference().perform(nodes.declarations);
   }
 
   FunctionType _buildFunctionType(
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_packages.dart b/pkg/analyzer/lib/src/test_utilities/mock_packages.dart
index 9482e66..dc79ac0 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_packages.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_packages.dart
@@ -36,11 +36,19 @@
 const _Protected protected = const _Protected();
 const Required required = const Required();
 const _Sealed sealed = const _Sealed();
+const UseResult useResult = UseResult();
 const _VisibleForTesting visibleForTesting = const _VisibleForTesting();
 
 class _AlwaysThrows {
   const _AlwaysThrows();
 }
+@Target({
+  TargetKind.field,
+  TargetKind.function,
+  TargetKind.getter,
+  TargetKind.method,
+  TargetKind.topLevelVariable,
+})
 class _DoNotStore {
   const _DoNotStore();
 }
@@ -76,6 +84,10 @@
 class _Sealed {
   const _Sealed();
 }
+class UseResult {
+  final String reason;
+  const UseResult([this.reason = '']);
+}
 class _VisibleForTesting {
   const _VisibleForTesting();
 }
@@ -99,6 +111,7 @@
   mixinType,
   parameter,
   setter,
+  topLevelVariable,
   type,
   typedefType,
 }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_annotation_target_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_annotation_target_test.dart
index 5ca4280..1ca267c 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_annotation_target_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_annotation_target_test.dart
@@ -13,6 +13,7 @@
   });
 }
 
+/// todo(pq): add tests for topLevelVariables: https://dart-review.googlesource.com/c/sdk/+/200301
 @reflectiveTest
 class InvalidAnnotationTargetTest extends PubPackageResolutionTest {
   void test_classType_class() async {
diff --git a/pkg/analyzer/test/src/diagnostics/new_with_undefined_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/new_with_undefined_constructor_test.dart
index 5e3e722..602e5ff 100644
--- a/pkg/analyzer/test/src/diagnostics/new_with_undefined_constructor_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/new_with_undefined_constructor_test.dart
@@ -62,4 +62,52 @@
       error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, 35, 4),
     ]);
   }
+
+  test_private_named() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+  A._named() {}
+}
+''');
+    await assertErrorsInCode(r'''
+import 'a.dart';
+void f() {
+  new A._named();
+}
+''', [
+      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, 36, 6),
+    ]);
+  }
+
+  test_private_named_genericClass_noTypeArguments() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A<T> {
+  A._named() {}
+}
+''');
+    await assertErrorsInCode(r'''
+import 'a.dart';
+void f() {
+  new A._named();
+}
+''', [
+      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, 36, 6),
+    ]);
+  }
+
+  test_private_named_genericClass_withTypeArguments() async {
+    newFile('$testPackageLibPath/a.dart', content: r'''
+class A<T> {
+  A._named() {}
+}
+''');
+    await assertErrorsInCode(r'''
+import 'a.dart';
+void f() {
+  new A<int>._named();
+}
+''', [
+      error(CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, 41, 6),
+    ]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart b/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
index c7254f7..930f6f4 100644
--- a/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/not_instantiated_bound_test.dart
@@ -116,7 +116,7 @@
 class C<T extends F> {}
 class D<T extends C> {}
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 19),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
       error(CompileTimeErrorCode.NOT_INSTANTIATED_BOUND, 38, 1),
       error(CompileTimeErrorCode.NOT_INSTANTIATED_BOUND, 62, 1),
     ]);
diff --git a/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart b/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
index 68ba41b..f863edb 100644
--- a/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/type_alias_cannot_reference_itself_test.dart
@@ -19,7 +19,7 @@
     await assertErrorsInCode('''
 typedef A<T extends A<int>>();
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 30),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -27,7 +27,7 @@
     await assertErrorsInCode('''
 typedef A(A b());
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 17),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -40,8 +40,8 @@
   foo(null);
 }
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 37),
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 38, 37),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 46, 1),
     ]);
   }
 
@@ -49,7 +49,7 @@
     await assertErrorsInCode('''
 typedef A<T extends A<int>> = void Function();
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 46),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -57,7 +57,7 @@
     await assertErrorsInCode(r'''
 typedef F<X extends F<X>> = F Function();
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 41),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -70,8 +70,8 @@
   foo(null);
 }
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 26),
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 27, 26),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 13, 1),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 40, 1),
     ]);
   }
 
@@ -93,8 +93,8 @@
 typedef T1 = T2;
 typedef T2 = T1;
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 16),
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 17, 16),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 2),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 25, 2),
     ]);
   }
 
@@ -102,7 +102,7 @@
     await assertErrorsInCode('''
 typedef T = void Function(T);
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 29),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -110,7 +110,7 @@
     await assertErrorsInCode('''
 typedef T = T;
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 14),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -118,7 +118,7 @@
     await assertErrorsInCode('''
 typedef T = T?;
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 15),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -126,7 +126,7 @@
     await assertErrorsInCode('''
 typedef T = List<T>;
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 20),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -134,7 +134,7 @@
     await assertErrorsInCode('''
 typedef T<X extends T<Never>> = List<X>;
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 40),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -142,7 +142,7 @@
     await assertErrorsInCode('''
 typedef A({A a});
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 17),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -150,7 +150,7 @@
     await assertErrorsInCode('''
 typedef A([A a]);
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 17),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -158,7 +158,7 @@
     await assertErrorsInCode('''
 typedef A(A a);
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 15),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -166,7 +166,7 @@
     await assertErrorsInCode('''
 typedef A(List<A> a);
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 21),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
     ]);
   }
 
@@ -194,7 +194,7 @@
     await assertErrorsInCode('''
 typedef A A();
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 14),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 10, 1),
     ]);
   }
 
@@ -203,8 +203,8 @@
 typedef B A();
 typedef A B();
 ''', [
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 0, 14),
-      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 15, 14),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 10, 1),
+      error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 25, 1),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 38c1c87..51f3b5b 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -1084,6 +1084,21 @@
     }
 
     buffer.writeln(';');
+
+    if (withFullyResolvedAst) {
+      _withIndent(() {
+        _writeResolvedMetadata(e.metadata);
+        _writeResolvedTypeParameters(e.typeParameters);
+        var aliasedElement = e.aliasedElement;
+        if (aliasedElement is GenericFunctionTypeElement) {
+          _writelnWithIndent('aliasedElement');
+          _withIndent(() {
+            _writeResolvedTypeParameters(aliasedElement.typeParameters);
+            _writeResolvedParameterElements(aliasedElement.parameters);
+          });
+        }
+      });
+    }
   }
 
   void writeTypeInferenceError(Element e) {
@@ -1319,6 +1334,37 @@
     );
   }
 
+  void _writeResolvedParameterElements(
+    List<ParameterElement> parameters, {
+    String enclosingNames = '',
+  }) {
+    if (parameters.isNotEmpty) {
+      _writelnWithIndent('parameters');
+      _withIndent(() {
+        var index = 0;
+        for (var formalParameter in parameters) {
+          var metadata = formalParameter.metadata;
+          var name = formalParameter.name;
+          if (name.isEmpty) {
+            name = '$index';
+          }
+          _writelnWithIndent(name);
+          _withIndent(() {
+            _writeResolvedMetadata(metadata);
+            var subParameters = formalParameter.parameters;
+            _withIndent(() {
+              _writeResolvedParameterElements(
+                subParameters,
+                enclosingNames: enclosingNames + name + '::',
+              );
+            });
+          });
+          index++;
+        }
+      });
+    }
+  }
+
   void _writeResolvedTypeParameters(List<TypeParameterElement> elements) {
     if (elements.isNotEmpty) {
       _writelnWithIndent('typeParameters');
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 2cf8b1b..ef090f9 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -7921,6 +7921,33 @@
 ''');
   }
 
+  test_genericFunction_boundOf_typeParameter_ofMixin() async {
+    var library = await checkLibrary(r'''
+mixin B<X extends void Function()> {}
+''');
+    checkElementText(library, r'''
+mixin B<X extends void Function() = void Function()> on Object {
+}
+''');
+  }
+
+  test_genericFunction_typeArgument_ofSuperclass_ofClassAlias() async {
+    var library = await checkLibrary(r'''
+class A<T> {}
+mixin M {}
+class B = A<void Function()> with M;
+''');
+    checkElementText(library, r'''
+class A<T> {
+}
+class alias B extends A<void Function()> with M {
+  synthetic B() : super();
+}
+mixin M on Object {
+}
+''');
+  }
+
   test_genericFunction_typeParameter_asTypedefArgument() async {
     var library = await checkLibrary(r'''
 typedef F1 = Function<V1>(F2<V1>);
@@ -11027,6 +11054,96 @@
         withFullyResolvedAst: true);
   }
 
+  test_metadata_inAliasedElement_formalParameter() async {
+    var library = await checkLibrary('''
+const a = 42;
+typedef F = void Function(@a int first)
+''');
+    checkElementText(
+        library,
+        r'''
+typedef F = void Function(int first);
+  aliasedElement
+    parameters
+      first
+        metadata
+          Annotation
+            element: self::@getter::a
+            name: SimpleIdentifier
+              staticElement: self::@getter::a
+              staticType: null
+              token: a
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 42
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_inAliasedElement_formalParameter2() async {
+    var library = await checkLibrary('''
+const a = 42;
+typedef F = void Function(int foo(@a int bar))
+''');
+    checkElementText(
+        library,
+        r'''
+typedef F = void Function(int Function(int) foo);
+  aliasedElement
+    parameters
+      foo
+          parameters
+            bar
+              metadata
+                Annotation
+                  element: self::@getter::a
+                  name: SimpleIdentifier
+                    staticElement: self::@getter::a
+                    staticType: null
+                    token: a
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 42
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
+  test_metadata_inAliasedElement_typeParameter() async {
+    var library = await checkLibrary('''
+const a = 42;
+typedef F = void Function<@a T>(int first)
+''');
+    checkElementText(
+        library,
+        r'''
+typedef F = void Function(int first);
+  aliasedElement
+    typeParameters
+      T
+        bound: null
+        defaultType: null
+        metadata
+          Annotation
+            element: self::@getter::a
+            name: SimpleIdentifier
+              staticElement: self::@getter::a
+              staticType: null
+              token: a
+    parameters
+      first
+const int a;
+  constantInitializer
+    IntegerLiteral
+      literal: 42
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_invalid_classDeclaration() async {
     var library = await checkLibrary('f(_) {} @f(42) class C {}');
     checkElementText(library, r'''
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 4ad11c96..851918e 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -519,12 +519,15 @@
   }
 
   void configureForPath(String path) {
-    var parentFolder = _resourceProvider.getFile(path).parent2;
+    var folder = _resourceProvider.getFolder(path);
+    if (!folder.exists) {
+      folder = _resourceProvider.getFile(path).parent2;
+    }
 
     // In batch mode we are given separate file paths to analyze.
     // All files of a folder have the same configuration.
     // So, reuse the corresponding analysis context.
-    _analysisContext = _folderContexts[parentFolder];
+    _analysisContext = _folderContexts[folder];
     if (_analysisContext != null) {
       return;
     }
@@ -550,7 +553,7 @@
     );
 
     _setContextForPath(path);
-    _folderContexts[parentFolder] = _analysisContext;
+    _folderContexts[folder] = _analysisContext;
   }
 
   void setCommandLineOptions(
diff --git a/pkg/analyzer_cli/test/data/multiple_inputs_two_directories/bin/a.dart b/pkg/analyzer_cli/test/data/multiple_inputs_two_directories/bin/a.dart
new file mode 100644
index 0000000..4235844
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/multiple_inputs_two_directories/bin/a.dart
@@ -0,0 +1 @@
+Unresolved a;
diff --git a/pkg/analyzer_cli/test/data/multiple_inputs_two_directories/lib/b.dart b/pkg/analyzer_cli/test/data/multiple_inputs_two_directories/lib/b.dart
new file mode 100644
index 0000000..c7ce226
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/multiple_inputs_two_directories/lib/b.dart
@@ -0,0 +1 @@
+Unresolved b;
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index c5e003e..419aceb 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -470,6 +470,22 @@
     expect(outSink.toString(), contains('Avoid empty else statements'));
   }
 
+  Future<void> test_multiple_inputs_two_directories() async {
+    await driveMany([
+      'data/multiple_inputs_two_directories/bin',
+      'data/multiple_inputs_two_directories/lib',
+    ]);
+    expect(outSink.toString(), contains('2 errors found.'));
+  }
+
+  Future<void> test_multiple_inputs_two_files() async {
+    await driveMany([
+      'data/multiple_inputs_two_directories/bin/a.dart',
+      'data/multiple_inputs_two_directories/lib/b.dart',
+    ]);
+    expect(outSink.toString(), contains('2 errors found.'));
+  }
+
   Future<void> test_todo() async {
     await drive('data/file_with_todo.dart');
     expect(outSink.toString().contains('[info]'), isFalse);
diff --git a/pkg/dartdev/lib/src/commands/create.dart b/pkg/dartdev/lib/src/commands/create.dart
index c7a3ca9..da41f79 100644
--- a/pkg/dartdev/lib/src/commands/create.dart
+++ b/pkg/dartdev/lib/src/commands/create.dart
@@ -138,8 +138,10 @@
         'Created project $projectName in ${p.relative(dir)}! In order to get '
         'started, run the following commands:');
     log.stdout('');
-    log.stdout(log.ansi.emphasized('  cd ${p.relative(dir)}'));
-    log.stdout(log.ansi.emphasized('  dart run'));
+    log.stdout(generator.getInstallInstructions(
+      dir,
+      projectName,
+    ));
     log.stdout('');
 
     return 0;
diff --git a/pkg/dartdev/lib/src/templates.dart b/pkg/dartdev/lib/src/templates.dart
index 53666a3..041ded0 100644
--- a/pkg/dartdev/lib/src/templates.dart
+++ b/pkg/dartdev/lib/src/templates.dart
@@ -5,6 +5,7 @@
 import 'dart:convert' show utf8;
 
 import 'package:meta/meta.dart';
+import 'package:path/path.dart' as p;
 
 import 'templates/console_full.dart';
 import 'templates/console_simple.dart';
@@ -99,7 +100,25 @@
 
   /// Return some user facing instructions about how to finish installation of
   /// the template.
-  String getInstallInstructions() => '';
+  ///
+  /// [directory] is the directory of the generated project.
+  ///
+  /// [scriptPath] is the path of the default target script
+  /// (e.g., bin/foo.dart) **without** an extension. If null, the implicit run
+  /// command will be output by default (e.g., dart run).
+  String getInstallInstructions(
+    String directory,
+    String scriptPath,
+  ) {
+    final buffer = StringBuffer();
+    buffer.writeln('  cd ${p.relative(directory)}');
+    if (scriptPath != null) {
+      buffer.write('  dart run $scriptPath.dart');
+    } else {
+      buffer.write('  dart run');
+    }
+    return buffer.toString();
+  }
 
   @override
   String toString() => '[$id: $description]';
diff --git a/pkg/dartdev/lib/src/templates/console_full.dart b/pkg/dartdev/lib/src/templates/console_full.dart
index f17c05c..f2e8b7a 100644
--- a/pkg/dartdev/lib/src/templates/console_full.dart
+++ b/pkg/dartdev/lib/src/templates/console_full.dart
@@ -24,8 +24,11 @@
   }
 
   @override
-  String getInstallInstructions() => '${super.getInstallInstructions()}\n'
-      'run your app using `dart ${entrypoint.path}`.';
+  String getInstallInstructions(
+    String directory,
+    String scriptName,
+  ) =>
+      super.getInstallInstructions(directory, null);
 }
 
 final String _pubspec = '''
diff --git a/pkg/dartdev/lib/src/templates/console_simple.dart b/pkg/dartdev/lib/src/templates/console_simple.dart
index 22f9d9a..a90c2ef6 100644
--- a/pkg/dartdev/lib/src/templates/console_simple.dart
+++ b/pkg/dartdev/lib/src/templates/console_simple.dart
@@ -22,8 +22,11 @@
   }
 
   @override
-  String getInstallInstructions() => '${super.getInstallInstructions()}\n'
-      'run your app using `dart ${entrypoint.path}`.';
+  String getInstallInstructions(
+    String directory,
+    String scriptName,
+  ) =>
+      super.getInstallInstructions(directory, null);
 }
 
 final String _pubspec = '''
diff --git a/pkg/dartdev/lib/src/templates/package_simple.dart b/pkg/dartdev/lib/src/templates/package_simple.dart
index 586c799..9d9eb59 100644
--- a/pkg/dartdev/lib/src/templates/package_simple.dart
+++ b/pkg/dartdev/lib/src/templates/package_simple.dart
@@ -25,8 +25,14 @@
   }
 
   @override
-  String getInstallInstructions() => '${super.getInstallInstructions()}\n'
-      'run your app using `dart ${entrypoint.path}`.';
+  String getInstallInstructions(
+    String directory,
+    String projectName,
+  ) =>
+      super.getInstallInstructions(
+        directory,
+        'example/${projectName}_example',
+      );
 }
 
 final String _gitignore = '''
diff --git a/pkg/dartdev/lib/src/templates/server_shelf.dart b/pkg/dartdev/lib/src/templates/server_shelf.dart
index 15f5898..fcd674f 100644
--- a/pkg/dartdev/lib/src/templates/server_shelf.dart
+++ b/pkg/dartdev/lib/src/templates/server_shelf.dart
@@ -25,8 +25,14 @@
   }
 
   @override
-  String getInstallInstructions() => '${super.getInstallInstructions()}\n'
-      'run your app using `dart run ${entrypoint.path}`.';
+  String getInstallInstructions(
+    String directory,
+    String scriptName,
+  ) =>
+      super.getInstallInstructions(
+        directory,
+        'bin/server',
+      );
 }
 
 final String _pubspec = '''
diff --git a/pkg/dartdev/lib/src/templates/web_simple.dart b/pkg/dartdev/lib/src/templates/web_simple.dart
index 836ec57..73ae51a 100644
--- a/pkg/dartdev/lib/src/templates/web_simple.dart
+++ b/pkg/dartdev/lib/src/templates/web_simple.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:path/path.dart' as p;
+
 import '../templates.dart';
 import 'common.dart' as common;
 
@@ -22,6 +24,15 @@
     );
     addFile('web/styles.css', _styles);
   }
+
+  @override
+  String getInstallInstructions(
+    String directory,
+    String scriptName,
+  ) =>
+      '  cd ${p.relative(directory)}\n'
+      '  dart pub global activate webdev\n'
+      '  webdev serve';
 }
 
 final String _pubspec = '''
diff --git a/pkg/dartdev/test/commands/create_test.dart b/pkg/dartdev/test/commands/create_test.dart
index 969120c..0982a0c 100644
--- a/pkg/dartdev/test/commands/create_test.dart
+++ b/pkg/dartdev/test/commands/create_test.dart
@@ -95,7 +95,7 @@
     expect(result.exitCode, 73);
   });
 
-  test('create project in current directory', () {
+  test('project in current directory', () {
     p = project();
     final projectDir = Directory('foo')..createSync();
     final result = p.runSync(
@@ -107,7 +107,7 @@
     expect(result.exitCode, 0);
   });
 
-  test('create project with normalized package name', () {
+  test('project with normalized package name', () {
     p = project();
     final result = p.runSync(['create', 'requires-normalization']);
     expect(result.stderr, isEmpty);
@@ -118,7 +118,7 @@
     expect(result.exitCode, 0);
   });
 
-  test('create project with an invalid package name', () {
+  test('project with an invalid package name', () {
     p = project();
     final result = p.runSync(['create', 'bad-package^name']);
     expect(
@@ -141,7 +141,7 @@
 
   // Create tests for each template.
   for (String templateId in CreateCommand.legalTemplateIds) {
-    test('create $templateId', () {
+    test('$templateId', () {
       p = project();
       const projectName = 'template_project';
       ProcessResult result = p.runSync([
@@ -162,4 +162,34 @@
           reason: 'File not found: ${entryFile.path}');
     });
   }
+
+  for (final generator in templates.generators) {
+    test('${generator.id} getting started message', () {
+      const dir = 'foo';
+      const projectName = dir;
+      final lines = generator
+          .getInstallInstructions(dir, projectName)
+          .split('\n')
+          .map((e) => e.trim())
+          .toList();
+      if (generator.categories.contains('web')) {
+        expect(lines.length, 3);
+        expect(lines[0], 'cd $dir');
+        expect(lines[1], 'dart pub global activate webdev');
+        expect(lines[2], 'webdev serve');
+      } else if (generator.categories.contains('console')) {
+        expect(lines.length, 2);
+        expect(lines[0], 'cd $dir');
+        expect(lines[1], 'dart run');
+      } else if (generator.categories.contains('server')) {
+        expect(lines.length, 2);
+        expect(lines[0], 'cd $dir');
+        expect(lines[1], 'dart run bin/server.dart');
+      } else {
+        expect(lines.length, 2);
+        expect(lines[0], 'cd $dir');
+        expect(lines[1], 'dart run example/${projectName}_example.dart');
+      }
+    });
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/fixed_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/fixed_type_builder.dart
index b0ba617..d405be6 100644
--- a/pkg/front_end/lib/src/fasta/builder/fixed_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/fixed_type_builder.dart
@@ -7,6 +7,7 @@
 import 'package:kernel/ast.dart';
 
 import '../problems.dart';
+import '../source/source_library_builder.dart';
 import 'library_builder.dart';
 import 'nullability_builder.dart';
 import 'type_builder.dart';
@@ -18,7 +19,12 @@
 
   const FixedTypeBuilder(this.type, this.fileUri, this.charOffset);
 
-  TypeBuilder clone(List<TypeBuilder> newTypes) => this;
+  TypeBuilder clone(
+      List<TypeBuilder> newTypes,
+      SourceLibraryBuilder contextLibrary,
+      TypeParameterScopeBuilder contextDeclaration) {
+    return this;
+  }
 
   Object get name => null;
 
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index 1b034996..306222e 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -29,7 +29,7 @@
 
 import '../scope.dart' show Scope;
 
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_library_builder.dart';
 
 import '../source/source_loader.dart' show SourceLoader;
 
@@ -141,12 +141,21 @@
     return variable;
   }
 
-  FormalParameterBuilder clone(List<TypeBuilder> newTypes) {
+  FormalParameterBuilder clone(
+      List<TypeBuilder> newTypes,
+      SourceLibraryBuilder contextLibrary,
+      TypeParameterScopeBuilder contextDeclaration) {
     // TODO(dmitryas):  It's not clear how [metadata] is used currently, and
     // how it should be cloned.  Consider cloning it instead of reusing it.
     return new FormalParameterBuilder(
-        metadata, modifiers, type?.clone(newTypes), name, parent, charOffset,
-        fileUri: fileUri, isExtensionThis: isExtensionThis)
+        metadata,
+        modifiers,
+        type?.clone(newTypes, contextLibrary, contextDeclaration),
+        name,
+        parent,
+        charOffset,
+        fileUri: fileUri,
+        isExtensionThis: isExtensionThis)
       ..kind = kind;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index 26f56fc..2204d0d 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -18,6 +18,8 @@
 
 import '../fasta_codes.dart' show messageSupertypeIsFunction, noLength;
 
+import '../source/source_library_builder.dart';
+
 import 'formal_parameter_builder.dart';
 import 'library_builder.dart';
 import 'nullability_builder.dart';
@@ -131,14 +133,14 @@
     return buildSupertype(library, charOffset, fileUri);
   }
 
-  FunctionTypeBuilder clone(List<TypeBuilder> newTypes) {
+  FunctionTypeBuilder clone(
+      List<TypeBuilder> newTypes,
+      SourceLibraryBuilder contextLibrary,
+      TypeParameterScopeBuilder contextDeclaration) {
     List<TypeVariableBuilder> clonedTypeVariables;
     if (typeVariables != null) {
       clonedTypeVariables =
-          new List<TypeVariableBuilder>.filled(typeVariables.length, null);
-      for (int i = 0; i < clonedTypeVariables.length; i++) {
-        clonedTypeVariables[i] = typeVariables[i].clone(newTypes);
-      }
+          contextLibrary.copyTypeVariables(typeVariables, contextDeclaration);
     }
     List<FormalParameterBuilder> clonedFormals;
     if (formals != null) {
@@ -146,11 +148,12 @@
           new List<FormalParameterBuilder>.filled(formals.length, null);
       for (int i = 0; i < clonedFormals.length; i++) {
         FormalParameterBuilder formal = formals[i];
-        clonedFormals[i] = formal.clone(newTypes);
+        clonedFormals[i] =
+            formal.clone(newTypes, contextLibrary, contextDeclaration);
       }
     }
     FunctionTypeBuilder newType = new FunctionTypeBuilder(
-        returnType?.clone(newTypes),
+        returnType?.clone(newTypes, contextLibrary, contextDeclaration),
         clonedTypeVariables,
         clonedFormals,
         nullabilityBuilder,
diff --git a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
index e1439c5..2ea95bb 100644
--- a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
@@ -9,6 +9,7 @@
 import 'package:kernel/ast.dart' show InterfaceType, Supertype, TypedefType;
 
 import '../problems.dart' show unsupported;
+import '../source/source_library_builder.dart';
 
 import 'library_builder.dart';
 import 'nullability_builder.dart';
@@ -75,7 +76,10 @@
     return unsupported("withNullabilityBuilder", -1, null);
   }
 
-  MixinApplicationBuilder clone(List<TypeBuilder> newTypes) {
+  MixinApplicationBuilder clone(
+      List<TypeBuilder> newTypes,
+      SourceLibraryBuilder contextLibrary,
+      TypeParameterScopeBuilder contextDeclaration) {
     int charOffset = -1; // TODO(dmitryas): Provide these.
     Uri fileUri = null; // TODO(dmitryas): Provide these.
     return unsupported("clone", charOffset, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 31a334d..c7e325a 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -406,12 +406,16 @@
     return this;
   }
 
-  NamedTypeBuilder clone(List<TypeBuilder> newTypes) {
+  NamedTypeBuilder clone(
+      List<TypeBuilder> newTypes,
+      SourceLibraryBuilder contextLibrary,
+      TypeParameterScopeBuilder contextDeclaration) {
     List<TypeBuilder> clonedArguments;
     if (arguments != null) {
       clonedArguments = new List<TypeBuilder>.filled(arguments.length, null);
       for (int i = 0; i < clonedArguments.length; i++) {
-        clonedArguments[i] = arguments[i].clone(newTypes);
+        clonedArguments[i] =
+            arguments[i].clone(newTypes, contextLibrary, contextDeclaration);
       }
     }
     NamedTypeBuilder newType = new NamedTypeBuilder(
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index 2aed213..57fbc8e 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -9,6 +9,7 @@
 import 'package:kernel/ast.dart' show DartType, Supertype, TypedefType;
 
 import '../scope.dart';
+import '../source/source_library_builder.dart';
 import 'library_builder.dart';
 import 'nullability_builder.dart';
 import 'type_declaration_builder.dart';
@@ -61,7 +62,10 @@
   /// existing declaration or type variable builders.  All newly built types
   /// are added to [newTypes], so that they can be added to a proper scope and
   /// resolved later.
-  TypeBuilder clone(List<TypeBuilder> newTypes);
+  TypeBuilder clone(
+      List<TypeBuilder> newTypes,
+      SourceLibraryBuilder contextLibrary,
+      TypeParameterScopeBuilder contextDeclaration);
 
   String get fullNameForErrors => "${printOn(new StringBuffer())}";
 
diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index db9c9ed..c396c39 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -174,12 +174,16 @@
     patch.actualOrigin = this;
   }
 
-  TypeVariableBuilder clone(List<TypeBuilder> newTypes) {
+  TypeVariableBuilder clone(
+      List<TypeBuilder> newTypes,
+      SourceLibraryBuilder contextLibrary,
+      TypeParameterScopeBuilder contextDeclaration) {
     // TODO(dmitryas): Figure out if using [charOffset] here is a good idea.
     // An alternative is to use the offset of the node the cloned type variable
     // is declared on.
     return new TypeVariableBuilder(name, parent, charOffset, fileUri,
-        bound: bound.clone(newTypes), variableVariance: variance);
+        bound: bound?.clone(newTypes, contextLibrary, contextDeclaration),
+        variableVariance: variance);
   }
 
   void buildOutlineExpressions(
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index a20b83a..2b2c10f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -1064,6 +1064,7 @@
     }
 
     TypeDeclarationBuilder declaration = type.declaration;
+    // TODO(dmitryas): Unalias beyond the first layer for the check.
     if (declaration is TypeAliasBuilder) {
       TypeBuilder rhsType = declaration.type;
       if (rhsType is FunctionTypeBuilder &&
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 0a1c8bb..0064a64 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -96,7 +96,7 @@
         NonSimplicityIssue,
         calculateBounds,
         computeTypeVariableBuilderVariance,
-        findGenericFunctionTypes,
+        findUnaliasedGenericFunctionTypes,
         getInboundReferenceIssuesInType,
         getNonSimplicityIssuesForDeclaration,
         getNonSimplicityIssuesForTypeVariables,
@@ -1473,13 +1473,13 @@
     for (TypeVariableBuilder type in typeVariables) {
       if (type.name == "Function") {
         addProblem(messageFunctionAsTypeParameter, type.charOffset,
-          type.name.length, type.fileUri);
+            type.name.length, type.fileUri);
       }
     }
   }
 
-  void _checkBadFunctionDeclUse(String className, TypeParameterScopeKind kind,
-      int charOffset) {
+  void _checkBadFunctionDeclUse(
+      String className, TypeParameterScopeKind kind, int charOffset) {
     String decType;
     switch (kind) {
       case TypeParameterScopeKind.classDeclaration:
@@ -2068,12 +2068,14 @@
             List<TypeBuilder> newTypes = <TypeBuilder>[];
             if (supertype is NamedTypeBuilder && supertype.arguments != null) {
               for (int i = 0; i < supertype.arguments.length; ++i) {
-                supertype.arguments[i] = supertype.arguments[i].clone(newTypes);
+                supertype.arguments[i] = supertype.arguments[i]
+                    .clone(newTypes, this, currentTypeParameterScopeBuilder);
               }
             }
             if (mixin is NamedTypeBuilder && mixin.arguments != null) {
               for (int i = 0; i < mixin.arguments.length; ++i) {
-                mixin.arguments[i] = mixin.arguments[i].clone(newTypes);
+                mixin.arguments[i] = mixin.arguments[i]
+                    .clone(newTypes, this, currentTypeParameterScopeBuilder);
               }
             }
             for (TypeBuilder newType in newTypes) {
@@ -2953,7 +2955,7 @@
     for (TypeVariableBuilder variable in original) {
       TypeVariableBuilder newVariable = new TypeVariableBuilder(
           variable.name, this, variable.charOffset, variable.fileUri,
-          bound: variable.bound?.clone(newTypes),
+          bound: variable.bound?.clone(newTypes, this, declaration),
           isExtensionTypeParameter: isExtensionTypeParameter,
           variableVariance:
               variable.parameter.isLegacyCovariant ? null : variable.variance);
@@ -3070,6 +3072,91 @@
     return count;
   }
 
+  /// Reports an error on generic function types used as bounds
+  ///
+  /// The function recursively searches for all generic function types in
+  /// [typeVariable.bound] and checks the bounds of type variables of the found
+  /// types for being generic function types.  Additionally, the function checks
+  /// [typeVariable.bound] for being a generic function type.  Returns `true` if
+  /// any errors were reported.
+  bool _recursivelyReportGenericFunctionTypesAsBoundsForVariable(
+      TypeVariableBuilder typeVariable) {
+    if (enableGenericMetadataInLibrary) return false;
+
+    bool hasReportedErrors = false;
+    hasReportedErrors =
+        _reportGenericFunctionTypeAsBoundIfNeeded(typeVariable) ||
+            hasReportedErrors;
+    hasReportedErrors = _recursivelyReportGenericFunctionTypesAsBoundsForType(
+            typeVariable.bound) ||
+        hasReportedErrors;
+    return hasReportedErrors;
+  }
+
+  /// Reports an error on generic function types used as bounds
+  ///
+  /// The function recursively searches for all generic function types in
+  /// [typeBuilder] and checks the bounds of type variables of the found types
+  /// for being generic function types.  Returns `true` if any errors were
+  /// reported.
+  bool _recursivelyReportGenericFunctionTypesAsBoundsForType(
+      TypeBuilder typeBuilder) {
+    if (enableGenericMetadataInLibrary) return false;
+
+    List<FunctionTypeBuilder> genericFunctionTypeBuilders =
+        <FunctionTypeBuilder>[];
+    findUnaliasedGenericFunctionTypes(typeBuilder,
+        result: genericFunctionTypeBuilders);
+    bool hasReportedErrors = false;
+    for (FunctionTypeBuilder genericFunctionTypeBuilder
+        in genericFunctionTypeBuilders) {
+      assert(
+          genericFunctionTypeBuilder.typeVariables != null,
+          "Function 'findUnaliasedGenericFunctionTypes' "
+          "returned a function type without type variables.");
+      for (TypeVariableBuilder typeVariable
+          in genericFunctionTypeBuilder.typeVariables) {
+        hasReportedErrors =
+            _reportGenericFunctionTypeAsBoundIfNeeded(typeVariable) ||
+                hasReportedErrors;
+      }
+    }
+    return hasReportedErrors;
+  }
+
+  /// Reports an error if [typeVariable.bound] is a generic function type
+  ///
+  /// Returns `true` if any errors were reported.
+  bool _reportGenericFunctionTypeAsBoundIfNeeded(
+      TypeVariableBuilder typeVariable) {
+    if (enableGenericMetadataInLibrary) return false;
+
+    TypeBuilder bound = typeVariable.bound;
+    bool isUnaliasedGenericFunctionType = bound is FunctionTypeBuilder &&
+        bound.typeVariables != null &&
+        bound.typeVariables.isNotEmpty;
+    bool isAliasedGenericFunctionType = false;
+    if (bound is NamedTypeBuilder) {
+      TypeDeclarationBuilder declaration = bound.declaration;
+      // TODO(dmitryas): Unalias beyond the first layer for the check.
+      if (declaration is TypeAliasBuilder) {
+        TypeBuilder rhsType = declaration.type;
+        if (rhsType is FunctionTypeBuilder &&
+            rhsType.typeVariables != null &&
+            rhsType.typeVariables.isNotEmpty) {
+          isAliasedGenericFunctionType = true;
+        }
+      }
+    }
+
+    if (isUnaliasedGenericFunctionType || isAliasedGenericFunctionType) {
+      addProblem(messageGenericFunctionTypeInBound, typeVariable.charOffset,
+          typeVariable.name.length, typeVariable.fileUri);
+      return true;
+    }
+    return false;
+  }
+
   int computeDefaultTypes(TypeBuilder dynamicType, TypeBuilder nullType,
       TypeBuilder bottomType, ClassBuilder objectClass) {
     int count = 0;
@@ -3081,16 +3168,11 @@
       bool haveErroneousBounds = false;
       if (!inErrorRecovery) {
         if (!enableGenericMetadataInLibrary) {
-          for (int i = 0; i < variables.length; ++i) {
-            TypeVariableBuilder variable = variables[i];
-            List<TypeBuilder> genericFunctionTypes = <TypeBuilder>[];
-            findGenericFunctionTypes(variable.bound,
-                result: genericFunctionTypes);
-            if (genericFunctionTypes.length > 0) {
-              haveErroneousBounds = true;
-              addProblem(messageGenericFunctionTypeInBound, variable.charOffset,
-                  variable.name.length, variable.fileUri);
-            }
+          for (TypeVariableBuilder variable in variables) {
+            haveErroneousBounds =
+                _recursivelyReportGenericFunctionTypesAsBoundsForVariable(
+                        variable) ||
+                    haveErroneousBounds;
           }
         }
 
@@ -3160,9 +3242,11 @@
             }
             if (formals != null && formals.isNotEmpty) {
               for (FormalParameterBuilder formal in formals) {
-                List<Object> issues =
+                List<NonSimplicityIssue> issues =
                     getInboundReferenceIssuesInType(formal.type);
                 reportIssues(issues);
+                _recursivelyReportGenericFunctionTypesAsBoundsForType(
+                    formal.type);
               }
             }
           });
@@ -3174,10 +3258,14 @@
             if (member.formals != null && member.formals.isNotEmpty) {
               for (FormalParameterBuilder formal in member.formals) {
                 issues.addAll(getInboundReferenceIssuesInType(formal.type));
+                _recursivelyReportGenericFunctionTypesAsBoundsForType(
+                    formal.type);
               }
             }
             if (member.returnType != null) {
               issues.addAll(getInboundReferenceIssuesInType(member.returnType));
+              _recursivelyReportGenericFunctionTypesAsBoundsForType(
+                  member.returnType);
             }
             reportIssues(issues);
             count += computeDefaultTypesForVariables(member.typeVariables,
@@ -3189,27 +3277,33 @@
             if (fieldType != null) {
               List<Object> issues = getInboundReferenceIssuesInType(fieldType);
               reportIssues(issues);
+              _recursivelyReportGenericFunctionTypesAsBoundsForType(fieldType);
             }
           }
         });
       } else if (declaration is TypeAliasBuilder) {
-        List<Object> issues = getNonSimplicityIssuesForDeclaration(declaration,
+        List<NonSimplicityIssue> issues = getNonSimplicityIssuesForDeclaration(
+            declaration,
             performErrorRecovery: true);
         issues.addAll(getInboundReferenceIssuesInType(declaration.type));
         reportIssues(issues);
         count += computeDefaultTypesForVariables(declaration.typeVariables,
             inErrorRecovery: issues.isNotEmpty);
+        _recursivelyReportGenericFunctionTypesAsBoundsForType(declaration.type);
       } else if (declaration is FunctionBuilder) {
         List<Object> issues =
             getNonSimplicityIssuesForTypeVariables(declaration.typeVariables);
         if (declaration.formals != null && declaration.formals.isNotEmpty) {
           for (FormalParameterBuilder formal in declaration.formals) {
             issues.addAll(getInboundReferenceIssuesInType(formal.type));
+            _recursivelyReportGenericFunctionTypesAsBoundsForType(formal.type);
           }
         }
         if (declaration.returnType != null) {
           issues
               .addAll(getInboundReferenceIssuesInType(declaration.returnType));
+          _recursivelyReportGenericFunctionTypesAsBoundsForType(
+              declaration.returnType);
         }
         reportIssues(issues);
         count += computeDefaultTypesForVariables(declaration.typeVariables,
@@ -3230,16 +3324,25 @@
             if (member.formals != null && member.formals.isNotEmpty) {
               for (FormalParameterBuilder formal in member.formals) {
                 issues.addAll(getInboundReferenceIssuesInType(formal.type));
+                _recursivelyReportGenericFunctionTypesAsBoundsForType(
+                    formal.type);
               }
             }
             if (member.returnType != null) {
               issues.addAll(getInboundReferenceIssuesInType(member.returnType));
+              _recursivelyReportGenericFunctionTypesAsBoundsForType(
+                  member.returnType);
             }
             reportIssues(issues);
             count += computeDefaultTypesForVariables(member.typeVariables,
                 inErrorRecovery: issues.isNotEmpty);
+          } else if (member is FieldBuilder) {
+            if (member.type != null) {
+              _recursivelyReportGenericFunctionTypesAsBoundsForType(
+                  member.type);
+            }
           } else {
-            assert(member is FieldBuilder,
+            throw new StateError(
                 "Unexpected extension member $member (${member.runtimeType}).");
           }
         });
@@ -3248,6 +3351,8 @@
           List<Object> issues =
               getInboundReferenceIssuesInType(declaration.type);
           reportIssues(issues);
+          _recursivelyReportGenericFunctionTypesAsBoundsForType(
+              declaration.type);
         }
       } else {
         assert(
@@ -3268,6 +3373,7 @@
           declaration.formals.isNotEmpty) {
         for (FormalParameterBuilder formal in declaration.formals) {
           reportIssues(getInboundReferenceIssuesInType(formal.type));
+          _recursivelyReportGenericFunctionTypesAsBoundsForType(formal.type);
         }
       }
     }
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 7b81151..5136f0f 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -165,6 +165,7 @@
 conversion
 conversions
 coo
+corge
 corners
 costly
 cov
@@ -358,6 +359,7 @@
 goo
 google
 graphic
+grault
 greeting
 gtgt
 gulp
diff --git a/pkg/front_end/testcases/general/issue45834.dart b/pkg/front_end/testcases/general/issue45834.dart
new file mode 100644
index 0000000..931523e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45834.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.6
+
+class A1<X extends Function<T>()> {
+  A1(Function<X extends Function<T>()>() f);
+  bar1(Function<X extends Function<T>()>() f) {}
+  Function<X extends Function<T>()>() bar2() => throw 42;
+  Function<X extends Function<T>()>() get baz1 => throw 42;
+  void set qux1(Function<X extends Function<T>()>() value) {}
+  Function<X extends Function<T>()>() quux1 = throw 42;
+  static Function<X extends Function<T>()>() quux2 = throw 42;
+}
+
+class A2<X extends void Function<Y extends Function<T>()>()> {}
+
+class A3<
+    X extends Function(void Function<Y extends Function(Function<T>())>())> {}
+
+foo1(Function<X extends Function<T>()>() f) {}
+foo2(Function<X extends Function(Function<T>())>() f) {}
+Function<X extends Function<T>()>() foo3() => throw 42;
+Function<X extends Function(Function<T>())>() foo4() => throw 42;
+Function<X extends Function<T>()>() get corge1 => throw 42;
+void set grault1(Function<X extends Function<T>()>() value) {}
+Function<X extends Function<T>()>() quuz1 = throw 42;
+
+typedef F1 = void Function<X extends void Function<T>()>();
+typedef F2 = void Function<X extends Function(void Function<T>())>();
+typedef F3<X extends Function<T>()> = Function();
+typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+typedef F5<X extends Function(Function<Y extends Function(Function<T>())>())>
+    = Function();
+
+class B1 {}
+
+extension E1<X extends Function<T>()> on B1 {
+  bar3(Function<X extends Function<T>()>() f) {}
+  Function<X extends Function<T>()>() bar4() => throw 42;
+  Function<X extends Function<T>()>() get baz2 => throw 42;
+  void set qux2(Function<X extends Function<T>()>() value) {}
+  static Function<X extends Function<T>()>() quux3 = throw 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45834.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue45834.dart.textual_outline.expect
new file mode 100644
index 0000000..53e0e60
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45834.dart.textual_outline.expect
@@ -0,0 +1,41 @@
+// @dart = 2.6
+class A1<X extends Function<T>()> {
+  A1(Function<X extends Function<T>()>() f);
+  bar1(Function<X extends Function<T>()>() f) {}
+  Function<X extends Function<T>()>() bar2() => throw 42;
+  Function<X extends Function<T>()>() get baz1 => throw 42;
+  void set qux1(Function<X extends Function<T>()>() value) {}
+  Function<X extends Function<T>()>() quux1 = throw 42;
+  static Function<X extends Function<T>()>() quux2 = throw 42;
+}
+
+class A2<X extends void Function<Y extends Function<T>()>()> {}
+
+class A3<
+    X extends Function(void Function<Y extends Function(Function<T>())>())> {}
+
+foo1(Function<X extends Function<T>()>() f) {}
+foo2(Function<X extends Function(Function<T>())>() f) {}
+Function<X extends Function<T>()>() foo3() => throw 42;
+Function<X extends Function(Function<T>())>() foo4() => throw 42;
+Function<X extends Function<T>()>() get corge1 => throw 42;
+void set grault1(Function<X extends Function<T>()>() value) {}
+Function<X extends Function<T>()>() quuz1 = throw 42;
+typedef F1 = void Function<X extends void Function<T>()>();
+typedef F2 = void Function<X extends Function(void Function<T>())>();
+typedef F3<X extends Function<T>()> = Function();
+typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+typedef F5<X extends Function(Function<Y extends Function(Function<T>())>())>
+    = Function();
+
+class B1 {}
+
+extension E1<X extends Function<T>()> on B1 {
+  bar3(Function<X extends Function<T>()>() f) {}
+  Function<X extends Function<T>()>() bar4() => throw 42;
+  Function<X extends Function<T>()>() get baz2 => throw 42;
+  void set qux2(Function<X extends Function<T>()>() value) {}
+  static Function<X extends Function<T>()>() quux3 = throw 42;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue45834.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/issue45834.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..2562b2d
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45834.dart.textual_outline_modelled.expect
@@ -0,0 +1,41 @@
+// @dart = 2.6
+Function<X extends Function(Function<T>())>() foo4() => throw 42;
+Function<X extends Function<T>()>() foo3() => throw 42;
+Function<X extends Function<T>()>() get corge1 => throw 42;
+Function<X extends Function<T>()>() quuz1 = throw 42;
+
+class A1<X extends Function<T>()> {
+  A1(Function<X extends Function<T>()>() f);
+  Function<X extends Function<T>()>() bar2() => throw 42;
+  Function<X extends Function<T>()>() get baz1 => throw 42;
+  Function<X extends Function<T>()>() quux1 = throw 42;
+  bar1(Function<X extends Function<T>()>() f) {}
+  static Function<X extends Function<T>()>() quux2 = throw 42;
+  void set qux1(Function<X extends Function<T>()>() value) {}
+}
+
+class A2<X extends void Function<Y extends Function<T>()>()> {}
+
+class A3<
+    X extends Function(void Function<Y extends Function(Function<T>())>())> {}
+
+class B1 {}
+
+extension E1<X extends Function<T>()> on B1 {
+  Function<X extends Function<T>()>() bar4() => throw 42;
+  Function<X extends Function<T>()>() get baz2 => throw 42;
+  bar3(Function<X extends Function<T>()>() f) {}
+  static Function<X extends Function<T>()>() quux3 = throw 42;
+  void set qux2(Function<X extends Function<T>()>() value) {}
+}
+
+foo1(Function<X extends Function<T>()>() f) {}
+foo2(Function<X extends Function(Function<T>())>() f) {}
+main() {}
+typedef F1 = void Function<X extends void Function<T>()>();
+typedef F2 = void Function<X extends Function(void Function<T>())>();
+typedef F3<X extends Function<T>()> = Function();
+typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+typedef F5<X extends Function(Function<Y extends Function(Function<T>())>())>
+    = Function();
+void set grault1(Function<X extends Function<T>()>() value) {}
diff --git a/pkg/front_end/testcases/general/issue45834.dart.weak.expect b/pkg/front_end/testcases/general/issue45834.dart.weak.expect
new file mode 100644
index 0000000..62ca870
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45834.dart.weak.expect
@@ -0,0 +1,211 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45834.dart:7:10: Error: Type variables can't have generic function types in their bounds.
+// class A1<X extends Function<T>()> {
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:8:15: Error: Type variables can't have generic function types in their bounds.
+//   A1(Function<X extends Function<T>()>() f);
+//               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:9:17: Error: Type variables can't have generic function types in their bounds.
+//   bar1(Function<X extends Function<T>()>() f) {}
+//                 ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:10:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() bar2() => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:11:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() get baz1 => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:13:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() quux1 = throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:14:19: Error: Type variables can't have generic function types in their bounds.
+//   static Function<X extends Function<T>()>() quux2 = throw 42;
+//                   ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:12:26: Error: Type variables can't have generic function types in their bounds.
+//   void set qux1(Function<X extends Function<T>()>() value) {}
+//                          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:17:10: Error: Type variables can't have generic function types in their bounds.
+// class A2<X extends void Function<Y extends Function<T>()>()> {}
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:17:34: Error: Type variables can't have generic function types in their bounds.
+// class A2<X extends void Function<Y extends Function<T>()>()> {}
+//                                  ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:22:15: Error: Type variables can't have generic function types in their bounds.
+// foo1(Function<X extends Function<T>()>() f) {}
+//               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:24:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() foo3() => throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:26:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() get corge1 => throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:28:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() quuz1 = throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:30:28: Error: Type variables can't have generic function types in their bounds.
+// typedef F1 = void Function<X extends void Function<T>()>();
+//                            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:32:12: Error: Type variables can't have generic function types in their bounds.
+// typedef F3<X extends Function<T>()> = Function();
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:33:12: Error: Type variables can't have generic function types in their bounds.
+// typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:33:31: Error: Type variables can't have generic function types in their bounds.
+// typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+//                               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:39:14: Error: Type variables can't have generic function types in their bounds.
+// extension E1<X extends Function<T>()> on B1 {
+//              ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:40:17: Error: Type variables can't have generic function types in their bounds.
+//   bar3(Function<X extends Function<T>()>() f) {}
+//                 ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:41:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() bar4() => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:42:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() get baz2 => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:44:19: Error: Type variables can't have generic function types in their bounds.
+//   static Function<X extends Function<T>()>() quux3 = throw 42;
+//                   ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:43:26: Error: Type variables can't have generic function types in their bounds.
+//   void set qux2(Function<X extends Function<T>()>() value) {}
+//                          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:27:27: Error: Type variables can't have generic function types in their bounds.
+// void set grault1(Function<X extends Function<T>()>() value) {}
+//                           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1 = <X extends <T extends core::Object* = dynamic>() →* void = dynamic>() →* void;
+typedef F2 = <X extends (<T extends core::Object* = dynamic>() →* void) →* dynamic = dynamic>() →* void;
+typedef F3<unrelated X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> = () →* dynamic;
+typedef F4<unrelated X extends <Y extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic = dynamic> = () →* dynamic;
+typedef F5<unrelated X extends (<Y extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic) →* dynamic> = () →* dynamic;
+class A1<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> extends core::Object {
+  field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quux1 = throw 42;
+  static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quux2 = throw 42;
+  constructor •(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → self::A1<self::A1::X*>*
+    : super core::Object::•()
+    ;
+  method bar1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic {}
+  method bar2() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+    return throw 42;
+  get baz1() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+    return throw 42;
+  set qux1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void {}
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class A2<X extends <Y extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* void = dynamic> extends core::Object {
+  synthetic constructor •() → self::A2<self::A2::X*>*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class A3<X extends (<Y extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* void) →* dynamic> extends core::Object {
+  synthetic constructor •() → self::A3<self::A3::X*>*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class B1 extends core::Object {
+  synthetic constructor •() → self::B1*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+extension E1<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> on self::B1* {
+  method bar3 = self::E1|bar3;
+  tearoff bar3 = self::E1|get#bar3;
+  method bar4 = self::E1|bar4;
+  tearoff bar4 = self::E1|get#bar4;
+  get baz2 = self::E1|get#baz2;
+  static field quux3 = self::E1|quux3;
+  set qux2 = self::E1|set#qux2;
+}
+static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quuz1 = throw 42;
+static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic E1|quux3 = throw 42;
+static method foo1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic {}
+static method foo2(<X extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic f) → dynamic {}
+static method foo3() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static method foo4() → <X extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static get corge1() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static set grault1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void {}
+static method E1|bar3<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this, <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic {}
+static method E1|get#bar3<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → (<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic) →* dynamic
+  return (<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic => self::E1|bar3<self::E1|get#bar3::X*>(#this, f);
+static method E1|bar4<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static method E1|get#bar4<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → () →* <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return () → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic => self::E1|bar4<self::E1|get#bar4::X*>(#this);
+static method E1|get#baz2<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static method E1|set#qux2<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this, <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue45834.dart.weak.outline.expect b/pkg/front_end/testcases/general/issue45834.dart.weak.outline.expect
new file mode 100644
index 0000000..838c120
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45834.dart.weak.outline.expect
@@ -0,0 +1,215 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45834.dart:7:10: Error: Type variables can't have generic function types in their bounds.
+// class A1<X extends Function<T>()> {
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:8:15: Error: Type variables can't have generic function types in their bounds.
+//   A1(Function<X extends Function<T>()>() f);
+//               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:9:17: Error: Type variables can't have generic function types in their bounds.
+//   bar1(Function<X extends Function<T>()>() f) {}
+//                 ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:10:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() bar2() => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:11:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() get baz1 => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:13:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() quux1 = throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:14:19: Error: Type variables can't have generic function types in their bounds.
+//   static Function<X extends Function<T>()>() quux2 = throw 42;
+//                   ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:12:26: Error: Type variables can't have generic function types in their bounds.
+//   void set qux1(Function<X extends Function<T>()>() value) {}
+//                          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:17:10: Error: Type variables can't have generic function types in their bounds.
+// class A2<X extends void Function<Y extends Function<T>()>()> {}
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:17:34: Error: Type variables can't have generic function types in their bounds.
+// class A2<X extends void Function<Y extends Function<T>()>()> {}
+//                                  ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:22:15: Error: Type variables can't have generic function types in their bounds.
+// foo1(Function<X extends Function<T>()>() f) {}
+//               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:24:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() foo3() => throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:26:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() get corge1 => throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:28:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() quuz1 = throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:30:28: Error: Type variables can't have generic function types in their bounds.
+// typedef F1 = void Function<X extends void Function<T>()>();
+//                            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:32:12: Error: Type variables can't have generic function types in their bounds.
+// typedef F3<X extends Function<T>()> = Function();
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:33:12: Error: Type variables can't have generic function types in their bounds.
+// typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:33:31: Error: Type variables can't have generic function types in their bounds.
+// typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+//                               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:39:14: Error: Type variables can't have generic function types in their bounds.
+// extension E1<X extends Function<T>()> on B1 {
+//              ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:40:17: Error: Type variables can't have generic function types in their bounds.
+//   bar3(Function<X extends Function<T>()>() f) {}
+//                 ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:41:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() bar4() => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:42:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() get baz2 => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:44:19: Error: Type variables can't have generic function types in their bounds.
+//   static Function<X extends Function<T>()>() quux3 = throw 42;
+//                   ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:43:26: Error: Type variables can't have generic function types in their bounds.
+//   void set qux2(Function<X extends Function<T>()>() value) {}
+//                          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:27:27: Error: Type variables can't have generic function types in their bounds.
+// void set grault1(Function<X extends Function<T>()>() value) {}
+//                           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1 = <X extends <T extends core::Object* = dynamic>() →* void = dynamic>() →* void;
+typedef F2 = <X extends (<T extends core::Object* = dynamic>() →* void) →* dynamic = dynamic>() →* void;
+typedef F3<unrelated X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> = () →* dynamic;
+typedef F4<unrelated X extends <Y extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic = dynamic> = () →* dynamic;
+typedef F5<unrelated X extends (<Y extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic) →* dynamic> = () →* dynamic;
+class A1<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> extends core::Object {
+  field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quux1;
+  static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quux2;
+  constructor •(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → self::A1<self::A1::X*>*
+    ;
+  method bar1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic
+    ;
+  method bar2() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+    ;
+  get baz1() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+    ;
+  set qux1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class A2<X extends <Y extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* void = dynamic> extends core::Object {
+  synthetic constructor •() → self::A2<self::A2::X*>*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class A3<X extends (<Y extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* void) →* dynamic> extends core::Object {
+  synthetic constructor •() → self::A3<self::A3::X*>*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class B1 extends core::Object {
+  synthetic constructor •() → self::B1*
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+extension E1<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> on self::B1* {
+  method bar3 = self::E1|bar3;
+  tearoff bar3 = self::E1|get#bar3;
+  method bar4 = self::E1|bar4;
+  tearoff bar4 = self::E1|get#bar4;
+  get baz2 = self::E1|get#baz2;
+  static field quux3 = self::E1|quux3;
+  set qux2 = self::E1|set#qux2;
+}
+static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quuz1;
+static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic E1|quux3;
+static method foo1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic
+  ;
+static method foo2(<X extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic f) → dynamic
+  ;
+static method foo3() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  ;
+static method foo4() → <X extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic
+  ;
+static get corge1() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  ;
+static set grault1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void
+  ;
+static method E1|bar3<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this, <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic
+  ;
+static method E1|get#bar3<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → (<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic) →* dynamic
+  return (<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic => self::E1|bar3<self::E1|get#bar3::X*>(#this, f);
+static method E1|bar4<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  ;
+static method E1|get#bar4<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → () →* <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return () → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic => self::E1|bar4<self::E1|get#bar4::X*>(#this);
+static method E1|get#baz2<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  ;
+static method E1|set#qux2<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this, <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue45834.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue45834.dart.weak.transformed.expect
new file mode 100644
index 0000000..62ca870
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue45834.dart.weak.transformed.expect
@@ -0,0 +1,211 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue45834.dart:7:10: Error: Type variables can't have generic function types in their bounds.
+// class A1<X extends Function<T>()> {
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:8:15: Error: Type variables can't have generic function types in their bounds.
+//   A1(Function<X extends Function<T>()>() f);
+//               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:9:17: Error: Type variables can't have generic function types in their bounds.
+//   bar1(Function<X extends Function<T>()>() f) {}
+//                 ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:10:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() bar2() => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:11:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() get baz1 => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:13:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() quux1 = throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:14:19: Error: Type variables can't have generic function types in their bounds.
+//   static Function<X extends Function<T>()>() quux2 = throw 42;
+//                   ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:12:26: Error: Type variables can't have generic function types in their bounds.
+//   void set qux1(Function<X extends Function<T>()>() value) {}
+//                          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:17:10: Error: Type variables can't have generic function types in their bounds.
+// class A2<X extends void Function<Y extends Function<T>()>()> {}
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:17:34: Error: Type variables can't have generic function types in their bounds.
+// class A2<X extends void Function<Y extends Function<T>()>()> {}
+//                                  ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:22:15: Error: Type variables can't have generic function types in their bounds.
+// foo1(Function<X extends Function<T>()>() f) {}
+//               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:24:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() foo3() => throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:26:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() get corge1 => throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:28:10: Error: Type variables can't have generic function types in their bounds.
+// Function<X extends Function<T>()>() quuz1 = throw 42;
+//          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:30:28: Error: Type variables can't have generic function types in their bounds.
+// typedef F1 = void Function<X extends void Function<T>()>();
+//                            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:32:12: Error: Type variables can't have generic function types in their bounds.
+// typedef F3<X extends Function<T>()> = Function();
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:33:12: Error: Type variables can't have generic function types in their bounds.
+// typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:33:31: Error: Type variables can't have generic function types in their bounds.
+// typedef F4<X extends Function<Y extends Function<T>()>()> = Function();
+//                               ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:39:14: Error: Type variables can't have generic function types in their bounds.
+// extension E1<X extends Function<T>()> on B1 {
+//              ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:40:17: Error: Type variables can't have generic function types in their bounds.
+//   bar3(Function<X extends Function<T>()>() f) {}
+//                 ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:41:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() bar4() => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:42:12: Error: Type variables can't have generic function types in their bounds.
+//   Function<X extends Function<T>()>() get baz2 => throw 42;
+//            ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:44:19: Error: Type variables can't have generic function types in their bounds.
+//   static Function<X extends Function<T>()>() quux3 = throw 42;
+//                   ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:43:26: Error: Type variables can't have generic function types in their bounds.
+//   void set qux2(Function<X extends Function<T>()>() value) {}
+//                          ^
+//
+// pkg/front_end/testcases/general/issue45834.dart:27:27: Error: Type variables can't have generic function types in their bounds.
+// void set grault1(Function<X extends Function<T>()>() value) {}
+//                           ^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1 = <X extends <T extends core::Object* = dynamic>() →* void = dynamic>() →* void;
+typedef F2 = <X extends (<T extends core::Object* = dynamic>() →* void) →* dynamic = dynamic>() →* void;
+typedef F3<unrelated X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> = () →* dynamic;
+typedef F4<unrelated X extends <Y extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic = dynamic> = () →* dynamic;
+typedef F5<unrelated X extends (<Y extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic) →* dynamic> = () →* dynamic;
+class A1<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> extends core::Object {
+  field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quux1 = throw 42;
+  static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quux2 = throw 42;
+  constructor •(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → self::A1<self::A1::X*>*
+    : super core::Object::•()
+    ;
+  method bar1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic {}
+  method bar2() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+    return throw 42;
+  get baz1() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+    return throw 42;
+  set qux1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void {}
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class A2<X extends <Y extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* void = dynamic> extends core::Object {
+  synthetic constructor •() → self::A2<self::A2::X*>*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class A3<X extends (<Y extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* void) →* dynamic> extends core::Object {
+  synthetic constructor •() → self::A3<self::A3::X*>*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class B1 extends core::Object {
+  synthetic constructor •() → self::B1*
+    : super core::Object::•()
+    ;
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+extension E1<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic> on self::B1* {
+  method bar3 = self::E1|bar3;
+  tearoff bar3 = self::E1|get#bar3;
+  method bar4 = self::E1|bar4;
+  tearoff bar4 = self::E1|get#bar4;
+  get baz2 = self::E1|get#baz2;
+  static field quux3 = self::E1|quux3;
+  set qux2 = self::E1|set#qux2;
+}
+static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic quuz1 = throw 42;
+static field <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic E1|quux3 = throw 42;
+static method foo1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic {}
+static method foo2(<X extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic f) → dynamic {}
+static method foo3() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static method foo4() → <X extends (<T extends core::Object* = dynamic>() →* dynamic) →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static get corge1() → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static set grault1(<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void {}
+static method E1|bar3<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this, <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic {}
+static method E1|get#bar3<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → (<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic) →* dynamic
+  return (<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic f) → dynamic => self::E1|bar3<self::E1|get#bar3::X*>(#this, f);
+static method E1|bar4<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static method E1|get#bar4<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → () →* <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return () → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic => self::E1|bar4<self::E1|get#bar4::X*>(#this);
+static method E1|get#baz2<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this) → <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic
+  return throw 42;
+static method E1|set#qux2<X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>(lowered final self::B1* #this, <X extends <T extends core::Object* = dynamic>() →* dynamic = dynamic>() →* dynamic value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.expect
index 3444c42..50a886c 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.expect
@@ -7,6 +7,7 @@
 //                ^
 //
 import self as self;
+import "dart:core" as core;
 
 typedef Handle = invalid-type;
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.outline.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.outline.expect
index dc3f69b..74c6c6a 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.outline.expect
@@ -7,6 +7,7 @@
 //                ^
 //
 import self as self;
+import "dart:core" as core;
 
 typedef Handle = invalid-type;
 static method main() → dynamic
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.transformed.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.transformed.expect
index 3444c42..50a886c 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.transformed.expect
@@ -7,6 +7,7 @@
 //                ^
 //
 import self as self;
+import "dart:core" as core;
 
 typedef Handle = invalid-type;
 static method main() → dynamic {
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index e5422e8..1fb72f2 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -824,7 +824,7 @@
   // TODO(johnniwinther): Make this non-nullable.
   DartType? type;
 
-  // The following two fields describe parameters of the underlying type when
+  // The following fields describe parameters of the underlying type when
   // that is a function type.  They are needed to keep such attributes as names
   // and annotations. When the underlying type is not a function type, they are
   // empty.
@@ -849,6 +849,9 @@
         this.namedParameters = namedParameters ?? <VariableDeclaration>[],
         super(reference) {
     setParents(this.typeParameters, this);
+    setParents(this.typeParametersOfFunctionType, this);
+    setParents(this.positionalParameters, this);
+    setParents(this.namedParameters, this);
   }
 
   Library get enclosingLibrary => parent as Library;
@@ -864,6 +867,9 @@
     visitList(annotations, v);
     visitList(typeParameters, v);
     type?.accept(v);
+    visitList(typeParametersOfFunctionType, v);
+    visitList(positionalParameters, v);
+    visitList(namedParameters, v);
   }
 
   @override
@@ -873,6 +879,9 @@
     if (type != null) {
       type = v.visitDartType(type!);
     }
+    v.transformList(typeParametersOfFunctionType, this);
+    v.transformList(positionalParameters, this);
+    v.transformList(namedParameters, this);
   }
 
   @override
@@ -887,6 +896,9 @@
         type = newType;
       }
     }
+    v.transformTypeParameterList(typeParametersOfFunctionType, this);
+    v.transformVariableDeclarationList(positionalParameters, this);
+    v.transformVariableDeclarationList(namedParameters, this);
   }
 
   @override
@@ -4021,6 +4033,7 @@
     receiver.accept(v);
     interfaceTarget.acceptReference(v);
     name.accept(v);
+    resultType.accept(v);
   }
 
   @override
@@ -4030,6 +4043,10 @@
       receiver = v.transform(receiver);
       receiver.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (resultType != null) {
+      resultType = v.visitDartType(resultType);
+    }
   }
 
   @override
@@ -4039,6 +4056,10 @@
       receiver = v.transform(receiver);
       receiver.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (resultType != null) {
+      resultType = v.visitDartType(resultType, cannotRemoveSentinel);
+    }
   }
 
   @override
@@ -4168,6 +4189,7 @@
     receiver.accept(v);
     interfaceTarget.acceptReference(v);
     name.accept(v);
+    resultType.accept(v);
   }
 
   @override
@@ -4177,6 +4199,10 @@
       receiver = v.transform(receiver);
       receiver.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (resultType != null) {
+      resultType = v.visitDartType(resultType);
+    }
   }
 
   @override
@@ -4186,6 +4212,10 @@
       receiver = v.transform(receiver);
       receiver.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (resultType != null) {
+      resultType = v.visitDartType(resultType, cannotRemoveSentinel);
+    }
   }
 
   @override
@@ -5284,6 +5314,7 @@
     interfaceTarget.acceptReference(v);
     name.accept(v);
     arguments.accept(v);
+    functionType.accept(v);
   }
 
   @override
@@ -5298,6 +5329,10 @@
       arguments = v.transform(arguments);
       arguments.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (functionType != null) {
+      functionType = v.visitDartType(functionType) as FunctionType;
+    }
   }
 
   @override
@@ -5312,6 +5347,11 @@
       arguments = v.transform(arguments);
       arguments.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (functionType != null) {
+      functionType =
+          v.visitDartType(functionType, cannotRemoveSentinel) as FunctionType;
+    }
   }
 
   @override
@@ -5589,6 +5629,7 @@
     receiver.accept(v);
     name.accept(v);
     arguments.accept(v);
+    functionType?.accept(v);
   }
 
   @override
@@ -5603,6 +5644,10 @@
       arguments = v.transform(arguments);
       arguments.parent = this;
     }
+    FunctionType? type = functionType;
+    if (type != null) {
+      functionType = v.visitDartType(type) as FunctionType;
+    }
   }
 
   @override
@@ -5617,6 +5662,11 @@
       arguments = v.transform(arguments);
       arguments.parent = this;
     }
+    FunctionType? type = functionType;
+    if (type != null) {
+      functionType =
+          v.visitDartType(type, cannotRemoveSentinel) as FunctionType;
+    }
   }
 
   @override
@@ -5682,6 +5732,7 @@
   @override
   void visitChildren(Visitor v) {
     arguments.accept(v);
+    functionType.accept(v);
   }
 
   @override
@@ -5691,6 +5742,10 @@
       arguments = v.transform(arguments);
       arguments.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (functionType != null) {
+      functionType = v.visitDartType(functionType) as FunctionType;
+    }
   }
 
   @override
@@ -5700,6 +5755,11 @@
       arguments = v.transform(arguments);
       arguments.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (functionType != null) {
+      functionType =
+          v.visitDartType(functionType, cannotRemoveSentinel) as FunctionType;
+    }
   }
 
   @override
@@ -5832,6 +5892,7 @@
     left.accept(v);
     interfaceTarget.acceptReference(v);
     right.accept(v);
+    functionType.accept(v);
   }
 
   @override
@@ -5846,6 +5907,10 @@
       right = v.transform(right);
       right.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (functionType != null) {
+      functionType = v.visitDartType(functionType) as FunctionType;
+    }
   }
 
   @override
@@ -5860,6 +5925,11 @@
       right = v.transform(right);
       right.parent = this;
     }
+    // ignore: unnecessary_null_comparison
+    if (functionType != null) {
+      functionType =
+          v.visitDartType(functionType, cannotRemoveSentinel) as FunctionType;
+    }
   }
 
   @override
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index ad79a99..aec9d76 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -262,7 +262,8 @@
     assert(state == null);
     typedefState[node] = TypedefState.BeingChecked;
     Set<TypeParameter> savedTypeParameters = typeParametersInScope;
-    typeParametersInScope = node.typeParameters.toSet();
+    typeParametersInScope = node.typeParameters.toSet()
+      ..addAll(node.typeParametersOfFunctionType);
     TreeNode? savedParent = currentParent;
     currentParent = node;
     // Visit children without checking the parent pointer on the typedef itself
@@ -540,7 +541,8 @@
         !(parent is ForStatement && parent.body != node) &&
         !(parent is ForInStatement && parent.body != node) &&
         parent is! Let &&
-        parent is! LocalInitializer) {
+        parent is! LocalInitializer &&
+        parent is! Typedef) {
       problem(
           node,
           "VariableDeclaration must be a direct child of a Block, "
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index 45b2e84..5841c60 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -253,6 +253,20 @@
 ///   `C` and `D` are declared in different packages.
 const _Sealed sealed = _Sealed();
 
+/// Used to annotate a method, field, or getter within a class, mixin, or
+/// extension, or a or top-level getter, variable or function to indicate that
+/// the value obtained by invoking it should be use. A value is considered used
+/// if it is assigned to a variable, passed to a function, or used as the target
+/// of an invocation, or invoked (if the result is itself a function).
+///
+/// Tools, such as the analyzer, can provide feedback if
+///
+/// * the annotation is associated with anything other than a method, field or
+///   getter, top-level variable, getter or function or
+/// * the value obtained by a method, field, getter or top-level getter,
+///   variable or function annotated with `@useResult` is not used.
+const UseResult useResult = UseResult();
+
 /// Used to annotate a field that is allowed to be overridden in Strong Mode.
 ///
 /// Deprecated: Most of strong mode is now the default in 2.0, but the notion of
@@ -314,6 +328,23 @@
   const Required([this.reason = '']);
 }
 
+/// See [useResult] for more details.
+@Target({
+  TargetKind.field,
+  TargetKind.function,
+  TargetKind.getter,
+  TargetKind.method,
+  TargetKind.topLevelVariable,
+})
+class UseResult {
+  /// A human-readable explanation of the reason why the value returned by
+  /// accessing this member should be checked.
+  final String reason;
+
+  /// Initialize a newly created instance to have the given [reason].
+  const UseResult([this.reason = '']);
+}
+
 class _AlwaysThrows {
   const _AlwaysThrows();
 }
diff --git a/pkg/meta/lib/meta_meta.dart b/pkg/meta/lib/meta_meta.dart
index 5090b05..65af6b6 100644
--- a/pkg/meta/lib/meta_meta.dart
+++ b/pkg/meta/lib/meta_meta.dart
@@ -73,6 +73,10 @@
   /// at the top-level of a library.
   setter,
 
+  /// Indicates that an annotation is valid on any top-level variable
+  /// declaration.
+  topLevelVariable,
+
   /// Indicates that an annotation is valid on any declaration that introduces a
   /// type. This includes classes, enums, mixins and typedefs, but does not
   /// include extensions because extensions don't introduce a type.
diff --git a/pkg/telemetry/analysis_options.yaml b/pkg/telemetry/analysis_options.yaml
index 250980e..0fcad72 100644
--- a/pkg/telemetry/analysis_options.yaml
+++ b/pkg/telemetry/analysis_options.yaml
@@ -1,11 +1,8 @@
+include: package:lints/recommended.yaml
+
 analyzer:
   strong-mode:
     implicit-casts: false
 linter:
   rules:
-    - annotate_overrides
-    - empty_constructor_bodies
-    - empty_statements
     - unawaited_futures
-    - unnecessary_brace_in_string_interps
-    - valid_regexps
diff --git a/pkg/telemetry/lib/crash_reporting.dart b/pkg/telemetry/lib/crash_reporting.dart
index 63d549b..5ec776f 100644
--- a/pkg/telemetry/lib/crash_reporting.dart
+++ b/pkg/telemetry/lib/crash_reporting.dart
@@ -45,7 +45,7 @@
   final String crashProductId;
   final EnablementCallback shouldSend;
   final http.Client _httpClient;
-  final Stopwatch _processStopwatch = new Stopwatch()..start();
+  final Stopwatch _processStopwatch = Stopwatch()..start();
 
   final ThrottlingBucket _throttle = ThrottlingBucket(10, Duration(minutes: 1));
   int _reportsSent = 0;
@@ -56,8 +56,8 @@
     this.shouldSend, {
     http.Client? httpClient,
     String endpointPath = _crashEndpointPathStaging,
-  })  : _httpClient = httpClient ?? new http.Client(),
-        _baseUri = new Uri(
+  })  : _httpClient = httpClient ?? http.Client(),
+        _baseUri = Uri(
             scheme: 'https', host: _crashServerHost, path: endpointPath);
 
   /// Create a new [CrashReportSender] connected to the staging endpoint.
@@ -120,7 +120,7 @@
         },
       );
 
-      final http.MultipartRequest req = new http.MultipartRequest('POST', uri);
+      final http.MultipartRequest req = http.MultipartRequest('POST', uri);
 
       Map<String, String> fields = req.fields;
       fields['product'] = crashProductId;
@@ -144,9 +144,9 @@
         fields['weight'] = weight.toString();
       }
 
-      final Chain chain = new Chain.forTrace(stackTrace);
+      final Chain chain = Chain.forTrace(stackTrace);
       req.files.add(
-        new http.MultipartFile.fromString(
+        http.MultipartFile.fromString(
           _stackTraceFileField,
           chain.terse.toString(),
           filename: _stackTraceFilename,
@@ -155,7 +155,7 @@
 
       for (var attachment in attachments) {
         req.files.add(
-          new http.MultipartFile.fromString(
+          http.MultipartFile.fromString(
             attachment._field,
             attachment._value,
             filename: attachment._field,
@@ -200,4 +200,4 @@
 
 /// A typedef to allow crash reporting to query as to whether it should send a
 /// crash report.
-typedef bool EnablementCallback();
+typedef EnablementCallback = bool Function();
diff --git a/pkg/telemetry/lib/src/utils.dart b/pkg/telemetry/lib/src/utils.dart
index 2c38478..55597ff 100644
--- a/pkg/telemetry/lib/src/utils.dart
+++ b/pkg/telemetry/lib/src/utils.dart
@@ -15,7 +15,7 @@
   final Duration replenishDuration;
 
   late int _drops = bucketSize;
-  late int _lastReplenish = new DateTime.now().millisecondsSinceEpoch;
+  late int _lastReplenish = DateTime.now().millisecondsSinceEpoch;
 
   ThrottlingBucket(this.bucketSize, this.replenishDuration);
 
@@ -31,7 +31,7 @@
   }
 
   void _checkReplenish() {
-    int now = new DateTime.now().millisecondsSinceEpoch;
+    int now = DateTime.now().millisecondsSinceEpoch;
 
     int replenishMillis = replenishDuration.inMilliseconds;
 
diff --git a/pkg/telemetry/lib/telemetry.dart b/pkg/telemetry/lib/telemetry.dart
index e76e622..d394eff 100644
--- a/pkg/telemetry/lib/telemetry.dart
+++ b/pkg/telemetry/lib/telemetry.dart
@@ -6,8 +6,11 @@
 
 import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
+// ignore: implementation_imports
 import 'package:usage/src/usage_impl.dart';
+// ignore: implementation_imports
 import 'package:usage/src/usage_impl_io.dart';
+// ignore: implementation_imports
 import 'package:usage/src/usage_impl_io.dart' as usage_io show getDartVersion;
 import 'package:usage/usage.dart';
 import 'package:usage/usage_io.dart';
@@ -15,7 +18,7 @@
 export 'package:usage/usage.dart' show Analytics;
 
 // TODO(devoncarew): Don't show the UI until we're ready to ship.
-final bool SHOW_ANALYTICS_UI = false;
+final bool showAnalyticsUI = false;
 
 final String _dartDirectoryName = '.dart';
 final String _settingsFileName = 'analytics.json';
@@ -38,7 +41,7 @@
 /// be disabled with --no-analytics).'`
 String createAnalyticsStatusMessage(
   bool enabled, {
-  String command: 'analytics',
+  String command = 'analytics',
 }) {
   String currentState = enabled ? 'enabled' : 'disabled';
   String toggleState = enabled ? 'disabled' : 'enabled';
@@ -63,7 +66,7 @@
   if (dir == null) {
     // Some systems don't support user home directories; for those, fail
     // gracefully by returning a disabled analytics object.
-    return new _DisabledAnalytics(trackingId, applicationName);
+    return _DisabledAnalytics(trackingId, applicationName);
   }
 
   if (!dir.existsSync()) {
@@ -72,12 +75,12 @@
     } catch (e) {
       // If we can't create the directory for the analytics settings, fail
       // gracefully by returning a disabled analytics object.
-      return new _DisabledAnalytics(trackingId, applicationName);
+      return _DisabledAnalytics(trackingId, applicationName);
     }
   }
 
-  File settingsFile = new File(path.join(dir.path, _settingsFileName));
-  return new _TelemetryAnalytics(
+  File settingsFile = File(path.join(dir.path, _settingsFileName));
+  return _TelemetryAnalytics(
     trackingId,
     applicationName,
     getDartVersion(),
@@ -96,10 +99,10 @@
 /// directory does not exist.
 @visibleForTesting
 Directory? getDartStorageDirectory() {
-  Directory homeDirectory = new Directory(userHomeDir());
+  Directory homeDirectory = Directory(userHomeDir());
   if (!homeDirectory.existsSync()) return null;
 
-  return new Directory(path.join(homeDirectory.path, _dartDirectoryName));
+  return Directory(path.join(homeDirectory.path, _dartDirectoryName));
 }
 
 /// Return the version of the Dart SDK.
@@ -118,8 +121,8 @@
     required this.forceEnabled,
   }) : super(
           trackingId,
-          new IOPersistentProperties.fromFile(settingsFile),
-          new IOPostHandler(),
+          IOPersistentProperties.fromFile(settingsFile),
+          IOPostHandler(),
           applicationName: applicationName,
           applicationVersion: applicationVersion,
         ) {
diff --git a/pkg/telemetry/test/crash_reporting_test.dart b/pkg/telemetry/test/crash_reporting_test.dart
index 79cf728..ef6bc6f 100644
--- a/pkg/telemetry/test/crash_reporting_test.dart
+++ b/pkg/telemetry/test/crash_reporting_test.dart
@@ -18,20 +18,21 @@
     late Request request;
 
     setUp(() {
-      mockClient = new MockClient((Request r) async {
+      mockClient = MockClient((Request r) async {
         request = r;
-        return new Response('crash-report-001', 200);
+        return Response('crash-report-001', 200);
       });
 
-      analytics = new AnalyticsMock()..enabled = true;
+      analytics = AnalyticsMock()..enabled = true;
     });
 
-    EnablementCallback shouldSend = () {
+    EnablementCallback shouldSend;
+    shouldSend = () {
       return true;
     };
 
     test('general', () async {
-      CrashReportSender sender = new CrashReportSender.prod(
+      CrashReportSender sender = CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -43,7 +44,7 @@
     });
 
     test('reportsSent', () async {
-      CrashReportSender sender = new CrashReportSender.prod(
+      CrashReportSender sender = CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -59,7 +60,7 @@
     });
 
     test('contains message', () async {
-      CrashReportSender sender = new CrashReportSender.prod(
+      CrashReportSender sender = CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -73,7 +74,7 @@
     });
 
     test('has attachments', () async {
-      CrashReportSender sender = new CrashReportSender.prod(
+      CrashReportSender sender = CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
@@ -94,7 +95,7 @@
     });
 
     test('has ptime', () async {
-      CrashReportSender sender = new CrashReportSender.prod(
+      CrashReportSender sender = CrashReportSender.prod(
           analytics.trackingId, shouldSend,
           httpClient: mockClient);
 
diff --git a/pkg/telemetry/test/utils_test.dart b/pkg/telemetry/test/utils_test.dart
index 2a9fcec..7f72c8a 100644
--- a/pkg/telemetry/test/utils_test.dart
+++ b/pkg/telemetry/test/utils_test.dart
@@ -8,12 +8,12 @@
 void main() {
   group('ThrottlingBucket', () {
     test('can send', () {
-      ThrottlingBucket bucket = new ThrottlingBucket(10, Duration(minutes: 1));
+      ThrottlingBucket bucket = ThrottlingBucket(10, Duration(minutes: 1));
       expect(bucket.removeDrop(), true);
     });
 
     test("doesn't send too many", () {
-      ThrottlingBucket bucket = new ThrottlingBucket(10, Duration(minutes: 1));
+      ThrottlingBucket bucket = ThrottlingBucket(10, Duration(minutes: 1));
       for (int i = 0; i < 10; i++) {
         expect(bucket.removeDrop(), true);
       }
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 658d67d..00d1c06 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -142,15 +142,6 @@
     super.defaultNode(node);
   }
 
-  @override
-  visitTypedef(Typedef node) {
-    super.visitTypedef(node);
-    // These sub-nodes can have annotations but are not visited by
-    // Typedef.visitChildren.
-    visitList(node.positionalParameters, this);
-    visitList(node.namedParameters, this);
-  }
-
   void _cleanupAnnotations(Node node, List<Expression> annotations) {
     if (node is VariableDeclaration ||
         node is Member ||
diff --git a/runtime/tests/vm/dart/regress_45966_test.dart b/runtime/tests/vm/dart/regress_45966_test.dart
new file mode 100644
index 0000000..ee4c70b
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_45966_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/45966.
+// Verifies that compiler doesn't crash if Typedef is only used from
+// function type of a call.
+
+import 'package:expect/expect.dart';
+
+class Message {}
+
+typedef void FooHandler(Message message);
+
+class A {
+  A(this.handler);
+  final FooHandler handler;
+}
+
+A? a;
+
+main() {
+  a?.handler(Message());
+}
diff --git a/runtime/tests/vm/dart_2/regress_45966_test.dart b/runtime/tests/vm/dart_2/regress_45966_test.dart
new file mode 100644
index 0000000..402d07c
--- /dev/null
+++ b/runtime/tests/vm/dart_2/regress_45966_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/45966.
+// Verifies that compiler doesn't crash if Typedef is only used from
+// function type of a call.
+
+import 'package:expect/expect.dart';
+
+class Message {}
+
+typedef void FooHandler(Message message);
+
+class A {
+  A(this.handler);
+  final FooHandler handler;
+}
+
+A a;
+
+main() {
+  a?.handler(Message());
+}
diff --git a/sdk/bin/dart2native b/sdk/bin/dart2native
index 29f29d7..057490f 100755
--- a/sdk/bin/dart2native
+++ b/sdk/bin/dart2native
@@ -22,4 +22,4 @@
 SNAPSHOTS_DIR="${BIN_DIR}/snapshots"
 DART="$BIN_DIR/dart"
 
-exec "$DART" "${SNAPSHOTS_DIR}/dart2native.dart.snapshot" $*
+exec "$DART" "${SNAPSHOTS_DIR}/dart2native.dart.snapshot" "$@"
diff --git a/tests/language/function/type_alias6_test.dart b/tests/language/function/type_alias6_test.dart
index f8e508d..1694d82 100644
--- a/tests/language/function/type_alias6_test.dart
+++ b/tests/language/function/type_alias6_test.dart
@@ -6,9 +6,8 @@
 import "package:expect/expect.dart";
 
 typedef F(List<F> x);
-// [error line 8, column 1, length 21]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F' has a reference to itself.
 
 typedef D C();
diff --git a/tests/language/function/type_alias9_test.dart b/tests/language/function/type_alias9_test.dart
index 71c0d7b..12ad3d6 100644
--- a/tests/language/function/type_alias9_test.dart
+++ b/tests/language/function/type_alias9_test.dart
@@ -4,12 +4,11 @@
 // Dart test for legally self referencing function type alias.
 
 typedef void F(List<G> l);
-// [error line 6, column 1, length 26]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //           ^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F' has a reference to itself.
 typedef void G(List<F> l);
-// [error line 11, column 1, length 26]
+//           ^
 // [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 
 main() {
diff --git a/tests/language/regress/regress33479_test.dart b/tests/language/regress/regress33479_test.dart
index 38b558c3..fe9ca03 100644
--- a/tests/language/regress/regress33479_test.dart
+++ b/tests/language/regress/regress33479_test.dart
@@ -3,7 +3,7 @@
 // [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
 
 typedef Fisk = void Function // don't merge lines
-// [error line 5, column 1, length 346]
+//      ^^^^
 // [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^
 // [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
diff --git a/tests/language/typedef/cyclic2_test.dart b/tests/language/typedef/cyclic2_test.dart
index cf8befc..f61cdc8 100644
--- a/tests/language/typedef/cyclic2_test.dart
+++ b/tests/language/typedef/cyclic2_test.dart
@@ -6,62 +6,53 @@
 
 // A body dependency, cycle length 1.
 typedef F1<X> = F1<X> Function();
-// [error line 8, column 1, length 33]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F1' has a reference to itself.
 
 // A body dependency (in a bound), cycle length 1.
 typedef F2<X> = Function<Y extends F2<X>>(Y);
-// [error line 15, column 1, length 45]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F2' has a reference to itself.
 
 // A bound dependency, cycle length 1.
 typedef F3<X extends F3<X>> = Function(X);
-// [error line 22, column 1, length 42]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F3' has a reference to itself.
 
 // A body dependency, cycle length 2.
 typedef F4a<X> = F4b<X> Function();
-// [error line 29, column 1, length 35]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F4a' has a reference to itself.
 
 typedef F4b<X> = F4a<X> Function();
-// [error line 35, column 1, length 35]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F4b' has a reference to itself.
 
 // A body dependency (in a bound), cycle length 2.
 typedef F5a<X> = Function<Y extends F5b<X>>(Y);
-// [error line 42, column 1, length 47]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F5a' has a reference to itself.
 
 typedef F5b<X> = Function<Y extends F5a<X>>(Y);
-// [error line 48, column 1, length 47]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F5b' has a reference to itself.
 
 // A bound dependency, cycle length 2.
 typedef F6a<X extends F6b<X>> = Function(X);
-// [error line 55, column 1, length 44]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F6a' has a reference to itself.
 
 typedef F6b<X extends F6a<X>> = Function(X);
-// [error line 61, column 1, length 44]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F6b' has a reference to itself.
 
 void main() {}
diff --git a/tests/language_2/function/type_alias6_test.dart b/tests/language_2/function/type_alias6_test.dart
index b9a8704..55ade34 100644
--- a/tests/language_2/function/type_alias6_test.dart
+++ b/tests/language_2/function/type_alias6_test.dart
@@ -8,9 +8,8 @@
 import "package:expect/expect.dart";
 
 typedef F(List<F> x);
-// [error line 10, column 1, length 21]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F' has a reference to itself.
 
 typedef D C();
diff --git a/tests/language_2/function/type_alias9_test.dart b/tests/language_2/function/type_alias9_test.dart
index bfb0db5..ed8029a 100644
--- a/tests/language_2/function/type_alias9_test.dart
+++ b/tests/language_2/function/type_alias9_test.dart
@@ -6,12 +6,11 @@
 // @dart = 2.9
 
 typedef void F(List<G> l);
-// [error line 8, column 1, length 26]
-// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //           ^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 // [cfe] The typedef 'F' has a reference to itself.
 typedef void G(List<F> l);
-// [error line 13, column 1, length 26]
+//           ^
 // [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 
 main() {
diff --git a/tests/language_2/regress/regress33479_test.dart b/tests/language_2/regress/regress33479_test.dart
index 3e038ac..492913e 100644
--- a/tests/language_2/regress/regress33479_test.dart
+++ b/tests/language_2/regress/regress33479_test.dart
@@ -7,7 +7,7 @@
 // [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
 
 typedef Fisk = void Function // don't merge lines
-// [error line 9, column 1, length 346]
+//      ^^^^
 // [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 //      ^
 // [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
diff --git a/tools/VERSION b/tools/VERSION
index 0f5b868..b247895 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 128
+PRERELEASE 129
 PRERELEASE_PATCH 0
\ No newline at end of file