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 fb6149df282..83553f41e98 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 @@ -683,6 +683,8 @@ CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT: status: noFix CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF: status: noFix +CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM: + status: noFix CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER: status: needsFix notes: |- diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart index e4e0db88ea3..389ef3b0bd9 100644 --- a/pkg/analyzer/lib/src/error/codes.g.dart +++ b/pkg/analyzer/lib/src/error/codes.g.dart @@ -1731,6 +1731,14 @@ class CompileTimeErrorCode extends AnalyzerErrorCode { correctionMessage: "Try specifying a different type.", ); + /// No parameters. + static const CompileTimeErrorCode EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM = + CompileTimeErrorCode( + 'EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM', + "The representation type can't be a bottom type.", + correctionMessage: "Try specifying a different type.", + ); + /// Parameters: /// 0: the name of the abstract method /// 1: the name of the enclosing extension type 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 9377fb5b731..28cf24030ab 100644 --- a/pkg/analyzer/lib/src/error/error_code_values.g.dart +++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart @@ -208,6 +208,7 @@ const List errorCodeValues = [ CompileTimeErrorCode.EXTENSION_TYPE_IMPLEMENTS_REPRESENTATION_NOT_SUPERTYPE, CompileTimeErrorCode.EXTENSION_TYPE_INHERITED_MEMBER_CONFLICT, CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_DEPENDS_ON_ITSELF, + CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM, CompileTimeErrorCode.EXTENSION_TYPE_WITH_ABSTRACT_MEMBER, CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart index 6750498076d..696c3e8dd02 100644 --- a/pkg/analyzer/lib/src/generated/error_verifier.dart +++ b/pkg/analyzer/lib/src/generated/error_verifier.dart @@ -714,6 +714,7 @@ class ErrorVerifier extends RecursiveAstVisitor _checkForNonCovariantTypeParameterPositionInRepresentationType( node, element); _checkForExtensionTypeRepresentationDependsOnItself(node, element); + _checkForExtensionTypeRepresentationTypeBottom(node, element); _checkForExtensionTypeImplementsDeferred(node); _checkForExtensionTypeImplementsItself(node, element); _checkForExtensionTypeMemberConflicts( @@ -2965,6 +2966,19 @@ class ErrorVerifier extends RecursiveAstVisitor } } + void _checkForExtensionTypeRepresentationTypeBottom( + ExtensionTypeDeclarationImpl node, + ExtensionTypeElementImpl element, + ) { + final representationType = element.representation.type; + if (typeSystem.isBottom(representationType)) { + errorReporter.reportErrorForNode( + CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM, + node.representation.fieldType, + ); + } + } + void _checkForExtensionTypeWithAbstractMember( ExtensionTypeDeclarationImpl node, ) { diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml index e948638f1fa..16338bc656d 100644 --- a/pkg/analyzer/messages.yaml +++ b/pkg/analyzer/messages.yaml @@ -5165,6 +5165,10 @@ CompileTimeErrorCode: problemMessage: "The extension type representation can't depend on itself." correctionMessage: Try specifying a different type. comment: No parameters. + EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM: + problemMessage: "The representation type can't be a bottom type." + correctionMessage: Try specifying a different type. + comment: No parameters. EXTENSION_TYPE_WITH_ABSTRACT_MEMBER: problemMessage: "'{0}' must have a method body because '{1}' is an extension type." correctionMessage: "Try adding a body to '{0}'." diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart index ce4df70d14e..ca744385a5a 100644 --- a/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart +++ b/pkg/analyzer/test/src/diagnostics/conflicting_generic_interfaces_test.dart @@ -224,6 +224,8 @@ class B implements I {} extension type C(Never it) implements A, B {} ''', [ error(CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES, 87, 1), + error(CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM, 89, + 5), ]); } diff --git a/pkg/analyzer/test/src/diagnostics/extension_type_representation_type_bottom_test.dart b/pkg/analyzer/test/src/diagnostics/extension_type_representation_type_bottom_test.dart new file mode 100644 index 00000000000..2278e11a33f --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/extension_type_representation_type_bottom_test.dart @@ -0,0 +1,27 @@ +// Copyright (c) 2023, 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/src/error/codes.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/context_collection_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(ExtensionTypeRepresentationTypeBottomTest); + }); +} + +@reflectiveTest +class ExtensionTypeRepresentationTypeBottomTest + extends PubPackageResolutionTest { + test_never() async { + await assertErrorsInCode(''' +extension type A(Never it) {} +''', [ + error(CompileTimeErrorCode.EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM, 17, + 5), + ]); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart index 15a81453e88..15e5a0b52ce 100644 --- a/pkg/analyzer/test/src/diagnostics/test_all.dart +++ b/pkg/analyzer/test/src/diagnostics/test_all.dart @@ -277,6 +277,8 @@ import 'extension_type_inherited_member_conflict_test.dart' as extension_type_inherited_member_conflict; import 'extension_type_representation_depends_on_itself_test.dart' as extension_type_representation_depends_on_itself; +import 'extension_type_representation_type_bottom_test.dart' + as extension_type_representation_type_bottom; import 'extension_type_with_abstract_member_test.dart' as extension_type_with_abstract_member; import 'external_field_constructor_initializer_test.dart' @@ -1097,6 +1099,7 @@ main() { extension_type_implements_representation_not_supertype.main(); extension_type_inherited_member_conflict.main(); extension_type_representation_depends_on_itself.main(); + extension_type_representation_type_bottom.main(); extension_type_with_abstract_member.main(); external_field_constructor_initializer.main(); external_field_initializer.main(); diff --git a/tests/language/extension_type/extension_type_representation_type_test.dart b/tests/language/extension_type/extension_type_representation_type_test.dart index b034ff27aa3..3e8c0129cd3 100644 --- a/tests/language/extension_type/extension_type_representation_type_test.dart +++ b/tests/language/extension_type/extension_type_representation_type_test.dart @@ -15,6 +15,8 @@ import "dart:async" show FutureOr; extension type V01(dynamic _) {} extension type V02(void _) {} extension type V03(Never _) {} +// ^^^^^ +// [analyzer] COMPILE_TIME_ERROR.EXTENSION_TYPE_REPRESENTATION_TYPE_BOTTOM extension type V04(Null _) {} extension type V05(Function _) {} extension type V06(Record _) {}