[analyzer] Add correction for adding '?' before null-aware elements

Part of https://github.com/dart-lang/sdk/issues/56989

Change-Id: I487790e796a37679fd5fe1c9bc1e72ccb6248249
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/405520
Reviewed-by: Keerti Parthasarathy <keertip@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_list_element.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_list_element.dart
new file mode 100644
index 0000000..523af3d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_list_element.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2025, 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/services/correction/fix.dart';
+import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ConvertToNullAwareListElement extends ResolvedCorrectionProducer {
+  ConvertToNullAwareListElement({required super.context});
+
+  @override
+  CorrectionApplicability get applicability =>
+          // TODO(applicability): comment on why.
+          CorrectionApplicability
+          .singleLocation;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_NULL_AWARE_LIST_ELEMENT;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    var parent = coveringNode?.parent;
+    if (parent is ListLiteral && coveringNode is! NullAwareElement) {
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addSimpleInsertion(coveringNode!.offset, '?');
+      });
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_map_entry.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_map_entry.dart
new file mode 100644
index 0000000..bda7c33
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_map_entry.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2025, 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/services/correction/fix.dart';
+import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ConvertToNullAwareMapEntryKey extends ResolvedCorrectionProducer {
+  ConvertToNullAwareMapEntryKey({required super.context});
+
+  @override
+  CorrectionApplicability get applicability =>
+          // TODO(applicability): comment on why.
+          CorrectionApplicability
+          .singleLocation;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_NULL_AWARE_MAP_ENTRY_KEY;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    var parent = coveringNode?.parent;
+    if (parent is MapLiteralEntry &&
+        coveringNode == parent.key &&
+        parent.keyQuestion == null) {
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addSimpleInsertion(coveringNode!.offset, '?');
+      });
+    }
+  }
+}
+
+class ConvertToNullAwareMapEntryValue extends ResolvedCorrectionProducer {
+  ConvertToNullAwareMapEntryValue({required super.context});
+
+  @override
+  CorrectionApplicability get applicability =>
+          // TODO(applicability): comment on why.
+          CorrectionApplicability
+          .singleLocation;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_NULL_AWARE_MAP_ENTRY_VALUE;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    var parent = coveringNode?.parent;
+    if (parent is MapLiteralEntry &&
+        coveringNode == parent.value &&
+        parent.valueQuestion == null) {
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addSimpleInsertion(coveringNode!.offset, '?');
+      });
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_set_element.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_set_element.dart
new file mode 100644
index 0000000..65a9944
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware_set_element.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2025, 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/services/correction/fix.dart';
+import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ConvertToNullAwareSetElement extends ResolvedCorrectionProducer {
+  ConvertToNullAwareSetElement({required super.context});
+
+  @override
+  CorrectionApplicability get applicability =>
+          // TODO(applicability): comment on why.
+          CorrectionApplicability
+          .singleLocation;
+
+  @override
+  FixKind get fixKind => DartFixKind.CONVERT_TO_NULL_AWARE_SET_ELEMENT;
+
+  @override
+  Future<void> compute(ChangeBuilder builder) async {
+    var parent = coveringNode?.parent;
+    if (parent is SetOrMapLiteral &&
+        parent.isSet &&
+        coveringNode is! NullAwareElement) {
+      await builder.addDartFileEdit(file, (builder) {
+        builder.addSimpleInsertion(coveringNode!.offset, '?');
+      });
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index e12691b..125dc93 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -1019,8 +1019,10 @@
     Remove `const`.
 CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED:
   status: hasFix
+CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY:
+  status: hasFix
 CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE:
-  status: noFix
+  status: needsEvaluation
 CompileTimeErrorCode.MACRO_DECLARATIONS_PHASE_INTROSPECTION_CYCLE:
   status: needsEvaluation
 CompileTimeErrorCode.MACRO_DEFINITION_APPLICATION_SAME_LIBRARY_CYCLE:
@@ -1049,8 +1051,12 @@
   status: noFix
 CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP:
   status: noFix
+CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY:
+  status: hasFix
 CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE:
   status: noFix
+CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY:
+  status: hasFix
 CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE:
   status: noFix
 CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL:
@@ -1444,6 +1450,8 @@
   status: needsFix
   notes: |-
     Remove the `deferred` keyword from the import.
+CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY:
+  status: hasFix
 CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE:
   status: noFix
 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX:
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index d7932f9..ae23d25 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -577,6 +577,26 @@
     DartFixKindPriority.standard,
     "Convert to use '?.'",
   );
+  static const CONVERT_TO_NULL_AWARE_LIST_ELEMENT = FixKind(
+    'dart.fix.convert.toNullAwareListElement',
+    DartFixKindPriority.standard,
+    "Convert to use '?'",
+  );
+  static const CONVERT_TO_NULL_AWARE_MAP_ENTRY_KEY = FixKind(
+    'dart.fix.convert.toNullAwareMapEntryKey',
+    DartFixKindPriority.standard,
+    "Convert to use '?'",
+  );
+  static const CONVERT_TO_NULL_AWARE_MAP_ENTRY_VALUE = FixKind(
+    'dart.fix.convert.toNullAwareMayEntryValue',
+    DartFixKindPriority.standard,
+    "Convert to use '?'",
+  );
+  static const CONVERT_TO_NULL_AWARE_SET_ELEMENT = FixKind(
+    'dart.fix.convert.toNullAwareSetElement',
+    DartFixKindPriority.standard,
+    "Convert to use '?'",
+  );
   static const CONVERT_TO_NULL_AWARE_MULTI = FixKind(
     'dart.fix.convert.toNullAware.multi',
     DartFixKindPriority.inFile,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index e6fd1f8..3043784 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -69,6 +69,9 @@
 import 'package:analysis_server/src/services/correction/dart/convert_to_map_literal.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_named_arguments.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware_list_element.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware_map_entry.dart';
+import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware_set_element.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_null_aware_spread.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_on_type.dart';
 import 'package:analysis_server/src/services/correction/dart/convert_to_package_import.dart';
@@ -848,6 +851,15 @@
   CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED: [
     MakeVariableNotFinal.new,
   ],
+  CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY: [
+    ConvertToNullAwareListElement.new,
+  ],
+  CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY: [
+    ConvertToNullAwareMapEntryKey.new,
+  ],
+  CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY: [
+    ConvertToNullAwareMapEntryValue.new,
+  ],
   CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER: [
     AddRequiredKeyword.new,
     MakeVariableNullable.new,
@@ -971,6 +983,9 @@
     MakeReturnTypeNullable.new,
     ReplaceReturnType.new,
   ],
+  CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY: [
+    ConvertToNullAwareSetElement.new,
+  ],
   CompileTimeErrorCode.SUBTYPE_OF_BASE_IS_NOT_BASE_FINAL_OR_SEALED: [
     AddClassModifier.baseModifier,
     AddClassModifier.finalModifier,
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_list_element_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_list_element_test.dart
new file mode 100644
index 0000000..8bddb9b
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_list_element_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2025, 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/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToNullAwareListElementTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToNullAwareListElementTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_TO_NULL_AWARE_LIST_ELEMENT;
+
+  Future<void> test_const_list_withGeneralUnassignable() async {
+    // Check that the fix isn't suggested when the assignability issue can't be
+    // fixed by removing nullability.
+    await resolveTestCode('''
+void f () {
+  const <String>[0];
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_const_list_withNullabilityUnassignable() async {
+    await resolveTestCode('''
+void f () {
+  const String? s = null;
+  const <String>[s];
+}
+''');
+    await assertHasFix('''
+void f () {
+  const String? s = null;
+  const <String>[?s];
+}
+''', errorFilter: (error) => error.message.contains('String?'));
+  }
+
+  Future<void> test_nonConst_list_withGeneralUnassignable() async {
+    // Check that the fix isn't suggested when the assignability issue can't be
+    // fixed by removing nullability.
+    await resolveTestCode('''
+void f (int arg) {
+  <String>[arg];
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_nonConst_list_withNullabilityUnassignable() async {
+    await resolveTestCode('''
+void f (String? arg) {
+  <String>[arg];
+}
+''');
+    await assertHasFix('''
+void f (String? arg) {
+  <String>[?arg];
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_map_entry_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_map_entry_test.dart
new file mode 100644
index 0000000..a19bc9e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_map_entry_test.dart
@@ -0,0 +1,128 @@
+// Copyright (c) 2025, 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/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToNullAwareMapEntryKeyTest);
+    defineReflectiveTests(ConvertToNullAwareMapEntryValueTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToNullAwareMapEntryKeyTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_TO_NULL_AWARE_MAP_ENTRY_KEY;
+
+  Future<void> test_const_mapKey_withGeneralUnassignable() async {
+    // Check that the fix isn't suggested when the assignability issue can't be
+    // fixed by removing nullability.
+    await resolveTestCode('''
+void f () {
+  const <String, Symbol>{0: #value};
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_const_mapKey_withNullabilityUnassignable() async {
+    await resolveTestCode('''
+void f () {
+  const String? s = null;
+  const <String, double>{s: 0.1};
+}
+''');
+    await assertHasFix('''
+void f () {
+  const String? s = null;
+  const <String, double>{?s: 0.1};
+}
+''', errorFilter: (error) => error.message.contains('String?'));
+  }
+
+  Future<void> test_nonConst_mapKey_withGeneralUnassignable() async {
+    // Check that the fix isn't suggested when the assignability issue can't be
+    // fixed by removing nullability.
+    await resolveTestCode('''
+void f (int arg) {
+  <String, bool>{arg: true};
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_nonConst_mapKey_withNullabilityUnassignable() async {
+    await resolveTestCode('''
+void f (String? arg) {
+  <String, String>{arg: ""};
+}
+''');
+    await assertHasFix('''
+void f (String? arg) {
+  <String, String>{?arg: ""};
+}
+''');
+  }
+}
+
+@reflectiveTest
+class ConvertToNullAwareMapEntryValueTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_TO_NULL_AWARE_MAP_ENTRY_VALUE;
+
+  Future<void> test_const_mapValue_withGeneralUnassignable() async {
+    // Check that the fix isn't suggested when the assignability issue can't be
+    // fixed by removing nullability.
+    await resolveTestCode('''
+void f () {
+  const <bool, String>{false: 0};
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_const_mapValue_withNullabilityUnassignable() async {
+    await resolveTestCode('''
+void f () {
+  const String? s = null;
+  const <Symbol, String>{#key: s};
+}
+''');
+    await assertHasFix('''
+void f () {
+  const String? s = null;
+  const <Symbol, String>{#key: ?s};
+}
+''', errorFilter: (error) => error.message.contains('String?'));
+  }
+
+  Future<void> test_nonConst_mapValue_withGeneralUnassignable() async {
+    // Check that the fix isn't suggested when the assignability issue can't be
+    // fixed by removing nullability.
+    await resolveTestCode('''
+void f (int arg) {
+  <int, String>{0: arg};
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_nonConst_mapValue_withNullabilityUnassignable() async {
+    await resolveTestCode('''
+void f (String? arg) {
+  <bool, String>{true: arg};
+}
+''');
+    await assertHasFix('''
+void f (String? arg) {
+  <bool, String>{true: ?arg};
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_set_element_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_set_element_test.dart
new file mode 100644
index 0000000..aa45008
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_null_aware_set_element_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2025, 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/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToNullAwareSetElementTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToNullAwareSetElementTest extends FixProcessorTest {
+  @override
+  FixKind get kind => DartFixKind.CONVERT_TO_NULL_AWARE_SET_ELEMENT;
+
+  Future<void> test_const_set_withGeneralUnassignable() async {
+    // Check that the fix isn't suggested when the assignability issue can't be
+    // fixed by removing nullability.
+    await resolveTestCode('''
+void f () {
+  const <String>{0};
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_const_set_withNullabilityUnassignable() async {
+    await resolveTestCode('''
+void f () {
+  const String? s = null;
+  const <String>{s};
+}
+''');
+    await assertHasFix('''
+void f () {
+  const String? s = null;
+  const <String>{?s};
+}
+''', errorFilter: (error) => error.message.contains('String?'));
+  }
+
+  Future<void> test_nonConst_set_withGeneralUnassignable() async {
+    // Check that the fix isn't suggested when the assignability issue can't be
+    // fixed by removing nullability.
+    await resolveTestCode('''
+void f (int arg) {
+  <String>{arg};
+}
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_nonConst_set_withNullabilityUnassignable() async {
+    await resolveTestCode('''
+void f (String? arg) {
+  <String>{arg};
+}
+''');
+    await assertHasFix('''
+void f (String? arg) {
+  <String>{?arg};
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index bc7b2cc..04bf16c 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -92,6 +92,12 @@
 import 'convert_to_int_literal_test.dart' as convert_to_int_literal;
 import 'convert_to_map_literal_test.dart' as convert_to_map_literal;
 import 'convert_to_named_arguments_test.dart' as convert_to_named_arguments;
+import 'convert_to_null_aware_list_element_test.dart'
+    as convert_to_null_aware_list_element_test;
+import 'convert_to_null_aware_map_entry_test.dart'
+    as convert_to_null_aware_map_entry_test;
+import 'convert_to_null_aware_set_element_test.dart'
+    as convert_to_null_aware_set_element_test;
 import 'convert_to_null_aware_spread_test.dart' as convert_to_null_aware_spread;
 import 'convert_to_null_aware_test.dart' as convert_to_null_aware;
 import 'convert_to_on_type_test.dart' as convert_to_on_type;
@@ -381,6 +387,9 @@
     convert_to_map_literal.main();
     convert_to_named_arguments.main();
     convert_to_null_aware.main();
+    convert_to_null_aware_list_element_test.main();
+    convert_to_null_aware_map_entry_test.main();
+    convert_to_null_aware_set_element_test.main();
     convert_to_null_aware_spread.main();
     convert_to_on_type.main();
     convert_to_package_import.main();
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 27223f0..17d775e 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -1229,11 +1229,20 @@
   bool _validateListExpression(
       DartType listElementType, Expression expression, DartObjectImpl value) {
     if (!verifier._runtimeTypeMatch(value, listElementType)) {
-      verifier._errorReporter.atNode(
-        expression,
-        CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
-        arguments: [value.type, listElementType],
-      );
+      if (verifier._runtimeTypeMatch(
+          value, verifier._typeSystem.makeNullable(listElementType))) {
+        verifier._errorReporter.atNode(
+          expression,
+          CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          arguments: [value.type, listElementType],
+        );
+      } else {
+        verifier._errorReporter.atNode(
+          expression,
+          CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+          arguments: [value.type, listElementType],
+        );
+      }
       return false;
     }
 
@@ -1316,11 +1325,21 @@
       }
 
       if (!verifier._runtimeTypeMatch(keyValue, expectedKeyType)) {
-        verifier._errorReporter.atNode(
-          keyExpression,
-          CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
-          arguments: [keyType, expectedKeyType],
-        );
+        if (!isKeyNullAware &&
+            verifier._runtimeTypeMatch(
+                keyValue, verifier._typeSystem.makeNullable(expectedKeyType))) {
+          verifier._errorReporter.atNode(
+            keyExpression,
+            CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+            arguments: [keyType, expectedKeyType],
+          );
+        } else {
+          verifier._errorReporter.atNode(
+            keyExpression,
+            CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+            arguments: [keyType, expectedKeyType],
+          );
+        }
       }
 
       var featureSet = verifier._currentLibrary.featureSet;
@@ -1354,11 +1373,21 @@
     }
     if (valueValue is DartObjectImpl) {
       if (!verifier._runtimeTypeMatch(valueValue, expectedValueType)) {
-        verifier._errorReporter.atNode(
-          valueExpression,
-          CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
-          arguments: [valueValue.type, expectedValueType],
-        );
+        if (!isValueNullAware &&
+            verifier._runtimeTypeMatch(valueValue,
+                verifier._typeSystem.makeNullable(expectedValueType))) {
+          verifier._errorReporter.atNode(
+            valueExpression,
+            CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+            arguments: [valueValue.type, expectedValueType],
+          );
+        } else {
+          verifier._errorReporter.atNode(
+            valueExpression,
+            CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+            arguments: [valueValue.type, expectedValueType],
+          );
+        }
       }
     }
 
@@ -1402,11 +1431,20 @@
     DartObjectImpl value,
   ) {
     if (!verifier._runtimeTypeMatch(value, config.elementType)) {
-      verifier._errorReporter.atNode(
-        expression,
-        CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE,
-        arguments: [value.type, config.elementType],
-      );
+      if (verifier._runtimeTypeMatch(
+          value, verifier._typeSystem.makeNullable(config.elementType))) {
+        verifier._errorReporter.atNode(
+          expression,
+          CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          arguments: [value.type, config.elementType],
+        );
+      } else {
+        verifier._errorReporter.atNode(
+          expression,
+          CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE,
+          arguments: [value.type, config.elementType],
+        );
+      }
       return false;
     }
 
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index 1d62c7f..3f9b5c4 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -3145,6 +3145,17 @@
     hasPublishedDocs: true,
   );
 
+  ///  Parameters:
+  ///  0: the actual type of the list element
+  ///  1: the expected type of the list element
+  static const CompileTimeErrorCode
+      LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY = CompileTimeErrorCode(
+    'LIST_ELEMENT_TYPE_NOT_ASSIGNABLE',
+    "The element type '{0}' can't be assigned to the list type '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY',
+  );
+
   ///  Reported when there is an issue converting a macro application argument
   ///  into a value. So, we cannot instantiate the macro, and run it.
   ///  Parameters:
@@ -3270,6 +3281,17 @@
   );
 
   ///  Parameters:
+  ///  0: the type of the expression being used as a key
+  ///  1: the type of keys declared for the map
+  static const CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY =
+      CompileTimeErrorCode(
+    'MAP_KEY_TYPE_NOT_ASSIGNABLE',
+    "The element type '{0}' can't be assigned to the map key type '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY',
+  );
+
+  ///  Parameters:
   ///  0: the type of the expression being used as a value
   ///  1: the type of values declared for the map
   static const CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE =
@@ -3279,6 +3301,17 @@
     hasPublishedDocs: true,
   );
 
+  ///  Parameters:
+  ///  0: the type of the expression being used as a value
+  ///  1: the type of values declared for the map
+  static const CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY =
+      CompileTimeErrorCode(
+    'MAP_VALUE_TYPE_NOT_ASSIGNABLE',
+    "The element type '{0}' can't be assigned to the map value type '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY',
+  );
+
   ///  12.1 Constants: A constant expression is ... a constant list literal.
   ///
   ///  Note: This diagnostic is never displayed to the user, so it doesn't need
@@ -4988,6 +5021,17 @@
     hasPublishedDocs: true,
   );
 
+  ///  Parameters:
+  ///  0: the actual type of the set element
+  ///  1: the expected type of the set element
+  static const CompileTimeErrorCode
+      SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY = CompileTimeErrorCode(
+    'SET_ELEMENT_TYPE_NOT_ASSIGNABLE',
+    "The element type '{0}' can't be assigned to the set type '{1}'.",
+    hasPublishedDocs: true,
+    uniqueName: 'SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY',
+  );
+
   ///  No parameters.
   static const CompileTimeErrorCode SHARED_DEFERRED_PREFIX =
       CompileTimeErrorCode(
diff --git a/pkg/analyzer/lib/src/error/error_code_values.g.dart b/pkg/analyzer/lib/src/error/error_code_values.g.dart
index 467f750..94fa6ed 100644
--- a/pkg/analyzer/lib/src/error/error_code_values.g.dart
+++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart
@@ -334,6 +334,7 @@
   CompileTimeErrorCode.LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR,
   CompileTimeErrorCode.LATE_FINAL_LOCAL_ALREADY_ASSIGNED,
   CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+  CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
   CompileTimeErrorCode.MACRO_APPLICATION_ARGUMENT_ERROR,
   CompileTimeErrorCode.MACRO_DECLARATIONS_PHASE_INTROSPECTION_CYCLE,
   CompileTimeErrorCode.MACRO_DEFINITION_APPLICATION_SAME_LIBRARY_CYCLE,
@@ -346,7 +347,9 @@
   CompileTimeErrorCode.MAIN_IS_NOT_FUNCTION,
   CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP,
   CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+  CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY,
   CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+  CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY,
   CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL,
   CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL,
   CompileTimeErrorCode.MISSING_CONST_IN_SET_LITERAL,
@@ -506,6 +509,7 @@
   CompileTimeErrorCode.SEALED_CLASS_SUBTYPE_OUTSIDE_OF_LIBRARY,
   CompileTimeErrorCode.SET_ELEMENT_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE,
+  CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
   CompileTimeErrorCode.SHARED_DEFERRED_PREFIX,
   CompileTimeErrorCode.SPREAD_EXPRESSION_FROM_DEFERRED_LIBRARY,
   CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
index 9efb88b..46d98d3 100644
--- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart
+++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -56,9 +56,22 @@
 
     if (!typeSystem.isAssignableTo(type, elementType!,
         strictCasts: _strictCasts)) {
-      var errorCode = forList
-          ? CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
-          : CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE;
+      bool assignableWhenNullable = typeSystem.isAssignableTo(
+          type, typeSystem.makeNullable(elementType),
+          strictCasts: _strictCasts);
+      var errorCode = switch ((
+        forList: forList,
+        assignableWhenNullable: assignableWhenNullable
+      )) {
+        (forList: false, assignableWhenNullable: false) =>
+          CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE,
+        (forList: false, assignableWhenNullable: true) =>
+          CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+        (forList: true, assignableWhenNullable: false) =>
+          CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
+        (forList: true, assignableWhenNullable: true) =>
+          CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+      };
       errorReporter.atNode(
         errorNode,
         errorCode,
@@ -148,11 +161,22 @@
     }
     if (!typeSystem.isAssignableTo(keyType, mapKeyType,
         strictCasts: _strictCasts)) {
-      errorReporter.atNode(
-        entry.key,
-        CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
-        arguments: [keyType, mapKeyType],
-      );
+      if (entry.keyQuestion == null &&
+          typeSystem.isAssignableTo(
+              keyType, typeSystem.makeNullable(mapKeyType),
+              strictCasts: _strictCasts)) {
+        errorReporter.atNode(
+          entry.key,
+          CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          arguments: [keyType, mapKeyType],
+        );
+      } else {
+        errorReporter.atNode(
+          entry.key,
+          CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
+          arguments: [keyType, mapKeyType],
+        );
+      }
     }
 
     var valueType = entry.value.typeOrThrow;
@@ -163,11 +187,22 @@
     }
     if (!typeSystem.isAssignableTo(valueType, mapValueType,
         strictCasts: _strictCasts)) {
-      errorReporter.atNode(
-        entry.value,
-        CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
-        arguments: [valueType, mapValueType],
-      );
+      if (entry.valueQuestion == null &&
+          typeSystem.isAssignableTo(
+              valueType, typeSystem.makeNullable(mapValueType),
+              strictCasts: _strictCasts)) {
+        errorReporter.atNode(
+          entry.value,
+          CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          arguments: [valueType, mapValueType],
+        );
+      } else {
+        errorReporter.atNode(
+          entry.value,
+          CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+          arguments: [valueType, mapValueType],
+        );
+      }
     }
   }
 
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 926a2ee..3f5c018 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -9625,6 +9625,14 @@
         return v;
       }
       ```
+  LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY:
+    sharedName: LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+    problemMessage: "The element type '{0}' can't be assigned to the list type '{1}'."
+    hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the actual type of the list element
+      1: the expected type of the list element
   LIST_ELEMENT_TYPE_NOT_ASSIGNABLE:
     problemMessage: "The element type '{0}' can't be assigned to the list type '{1}'."
     hasPublishedDocs: true
@@ -9896,6 +9904,14 @@
       ```dart
       var collection = <String>{'a', 'b'};
       ```
+  MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY:
+    sharedName: MAP_KEY_TYPE_NOT_ASSIGNABLE
+    problemMessage: "The element type '{0}' can't be assigned to the map key type '{1}'."
+    hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the type of the expression being used as a key
+      1: the type of keys declared for the map
   MAP_KEY_TYPE_NOT_ASSIGNABLE:
     problemMessage: "The element type '{0}' can't be assigned to the map key type '{1}'."
     hasPublishedDocs: true
@@ -9932,6 +9948,14 @@
       ```dart
       var m = <int, String>{2 : 'a'};
       ```
+  MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY:
+    sharedName: MAP_VALUE_TYPE_NOT_ASSIGNABLE
+    problemMessage: "The element type '{0}' can't be assigned to the map value type '{1}'."
+    hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the type of the expression being used as a value
+      1: the type of values declared for the map
   MAP_VALUE_TYPE_NOT_ASSIGNABLE:
     problemMessage: "The element type '{0}' can't be assigned to the map value type '{1}'."
     hasPublishedDocs: true
@@ -15262,6 +15286,14 @@
     comment: |-
       Parameters:
       0: the name of the sealed class being extended, implemented, or mixed in
+  SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY:
+    sharedName: SET_ELEMENT_TYPE_NOT_ASSIGNABLE
+    problemMessage: "The element type '{0}' can't be assigned to the set type '{1}'."
+    hasPublishedDocs: true
+    comment: |-
+      Parameters:
+      0: the actual type of the set element
+      1: the expected type of the set element
   SET_ELEMENT_TYPE_NOT_ASSIGNABLE:
     problemMessage: "The element type '{0}' can't be assigned to the set type '{1}'."
     hasPublishedDocs: true
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 1623128..0278ff4 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -3582,7 +3582,8 @@
 List<Object> ddd = [1 as dynamic];
 List<Object> eee = [new Object()];
 ''', [
-      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 73, 4),
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          73, 4),
     ]);
     expectInitializerType('aaa', 'List<Object>');
     expectInitializerType('bbb', 'List<Object>');
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
index 4f3dfa1..c55c0cf 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/list_literal_test.dart
@@ -458,6 +458,16 @@
     assertType(findNode.listLiteral('['), 'List<String>');
   }
 
+  test_noContext_typeArgs_expression_conflict_nullable() async {
+    await assertErrorsInCode('''
+var a = <String>[(null as String?)];
+''', [
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          17, 17),
+    ]);
+    assertType(findNode.listLiteral('['), 'List<String>');
+  }
+
   test_noContext_typeArgs_expression_noConflict() async {
     await assertNoErrorsInCode('''
 var a = <int>[1];
diff --git a/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
index da974b0..c6868a1 100644
--- a/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/list_element_type_not_assignable_test.dart
@@ -77,7 +77,8 @@
 const a = null;
 var v = const <int>[a];
 ''', [
-      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 36, 1),
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          36, 1),
     ]);
   }
 
@@ -85,7 +86,8 @@
     await assertErrorsInCode('''
 var v = const <int>[null];
 ''', [
-      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 20, 4),
+      error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          20, 4),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
index fe6dbe3..6e69716 100644
--- a/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_key_type_not_assignable_test.dart
@@ -86,7 +86,8 @@
 const dynamic a = null;
 var v = const <int, bool>{a : true};
 ''', [
-      error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 50, 1),
+      error(
+          CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY, 50, 1),
     ]);
   }
 
@@ -94,7 +95,8 @@
     await assertErrorsInCode('''
 var v = const <int, bool>{null : true};
 ''', [
-      error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 26, 4),
+      error(
+          CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE_NULLABILITY, 26, 4),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
index 8780baf..7da431e 100644
--- a/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/map_value_type_not_assignable_test.dart
@@ -86,7 +86,8 @@
 const dynamic a = null;
 var v = const <bool, int>{true: a};
 ''', [
-      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 56, 1),
+      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY, 56,
+          1),
     ]);
   }
 
@@ -94,7 +95,8 @@
     await assertErrorsInCode('''
 var v = const <bool, int>{true: null};
 ''', [
-      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 32, 4),
+      error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE_NULLABILITY, 32,
+          4),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
index 2b95f64..d7be61c 100644
--- a/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/set_element_type_not_assignable_test.dart
@@ -83,7 +83,8 @@
 const a = null;
 var v = const <int>{a};
 ''', [
-      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 36, 1),
+      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          36, 1),
     ]);
   }
 
@@ -91,7 +92,8 @@
     await assertErrorsInCode('''
 var v = const <int>{null};
 ''', [
-      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 20, 4),
+      error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE_NULLABILITY,
+          20, 4),
     ]);
   }