Skip to content

Commit eb4ebd3

Browse files
eernstgCommit Queue
authored andcommitted
Adjust unrelated_type_equality_checks on mixins and extension types
The lint unrelated_type_equality_checks previously considered all mixins and extension types to be (possibly) related (even any mixin and any extension type, not just any pair of mixins and any pair of extension types). This would not fit the expectations for this lint, it should certainly consider a mixin as unrelated to an extension type that isn't a subtype of the mixin, and similarly for any pair of mixins that aren't subtype related, and any pair of extension types that aren't subtype related. This PR changes the lint (that is, the underlying extension method `interfaceTypesAreUnrelated`) such that these pairs are considered unrelated. Bug: #59423 Change-Id: I370e98eb17c60ab50f1118b6e841d7eee7291e54 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/440640 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Samuel Rawlins <[email protected]>
1 parent 4a009c3 commit eb4ebd3

File tree

3 files changed

+75
-10
lines changed

3 files changed

+75
-10
lines changed

pkg/analyzer/lib/src/fine/manifest_item.dart

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ class ClassItem extends InterfaceItem<ClassElementImpl> {
3838
required EncodeContext context,
3939
required ClassElementImpl element,
4040
}) {
41-
return context.withTypeParameters(element.typeParameters, (typeParameters) {
41+
return context.withTypeParameters(element.typeParameters, (
42+
typeParameters,
43+
) {
4244
return ClassItem(
4345
id: id,
4446
metadata: ManifestMetadata.encode(context, element.metadata),
@@ -101,7 +103,9 @@ class EnumItem extends InterfaceItem<EnumElementImpl> {
101103
required EncodeContext context,
102104
required EnumElementImpl element,
103105
}) {
104-
return context.withTypeParameters(element.typeParameters, (typeParameters) {
106+
return context.withTypeParameters(element.typeParameters, (
107+
typeParameters,
108+
) {
105109
return EnumItem(
106110
id: id,
107111
metadata: ManifestMetadata.encode(context, element.metadata),
@@ -164,7 +168,9 @@ class ExtensionItem<E extends ExtensionElementImpl> extends InstanceItem<E> {
164168
required EncodeContext context,
165169
required ExtensionElementImpl element,
166170
}) {
167-
return context.withTypeParameters(element.typeParameters, (typeParameters) {
171+
return context.withTypeParameters(element.typeParameters, (
172+
typeParameters,
173+
) {
168174
return ExtensionItem(
169175
id: id,
170176
metadata: ManifestMetadata.encode(context, element.metadata),
@@ -233,7 +239,9 @@ class ExtensionTypeItem extends InterfaceItem<ExtensionTypeElementImpl> {
233239
required EncodeContext context,
234240
required ExtensionTypeElementImpl element,
235241
}) {
236-
return context.withTypeParameters(element.typeParameters, (typeParameters) {
242+
return context.withTypeParameters(element.typeParameters, (
243+
typeParameters,
244+
) {
237245
return ExtensionTypeItem(
238246
id: id,
239247
metadata: ManifestMetadata.encode(context, element.metadata),
@@ -1136,7 +1144,9 @@ class MixinItem extends InterfaceItem<MixinElementImpl> {
11361144
required EncodeContext context,
11371145
required MixinElementImpl element,
11381146
}) {
1139-
return context.withTypeParameters(element.typeParameters, (typeParameters) {
1147+
return context.withTypeParameters(element.typeParameters, (
1148+
typeParameters,
1149+
) {
11401150
return MixinItem(
11411151
id: id,
11421152
metadata: ManifestMetadata.encode(context, element.metadata),
@@ -1391,7 +1401,9 @@ class TypeAliasItem extends TopLevelItem<TypeAliasElementImpl> {
13911401
required EncodeContext context,
13921402
required TypeAliasElementImpl element,
13931403
}) {
1394-
return context.withTypeParameters(element.typeParameters, (typeParameters) {
1404+
return context.withTypeParameters(element.typeParameters, (
1405+
typeParameters,
1406+
) {
13951407
return TypeAliasItem(
13961408
id: id,
13971409
metadata: ManifestMetadata.encode(context, element.metadata),

pkg/linter/lib/src/util/dart_type_utilities.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ bool canonicalElementsFromIdentifiersAreEqual(
154154
/// * are unrelated if [leftType]'s supertype is [Object].
155155
/// * are related if their supertypes are equal, e.g. `List<dynamic>` and
156156
/// `Set<dynamic>`.
157+
/// * are unrelated if they are distinct mixins.
158+
/// * are unrelated if they are distinct extension types.
157159
/// * Two type variables are related if their bounds are related.
158160
/// * A record type is unrelated to any other type except a record type of
159161
/// the same shape.
@@ -282,11 +284,14 @@ extension on TypeSystem {
282284
// Otherwise, they might be related.
283285
return false;
284286
} else {
285-
var sameSupertypes = leftElement.supertype == rightElement.supertype;
287+
var leftSuper = leftElement.supertype;
288+
var sameSupertypes = leftSuper == rightElement.supertype;
286289

287-
// Unrelated Enums have the same supertype, but they are not the same element, so
288-
// they are unrelated.
289-
if (sameSupertypes && leftElement is EnumElement) {
290+
// Unrelated Enums have the same supertype, but they are not the same
291+
// element, so they are unrelated. Mixins always have supertype null,
292+
// and so do extension types, and they are both considered unrelated
293+
// when their elements are not equal.
294+
if (sameSupertypes && (leftElement is EnumElement || leftSuper == null)) {
290295
return true;
291296
}
292297

pkg/linter/test/rules/unrelated_type_equality_checks_test.dart

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,31 @@ void f(dynamic x) {
3737
''');
3838
}
3939

40+
test_extension_types() async {
41+
await assertDiagnostics(
42+
r'''
43+
void m(A a, B b) {
44+
if (a == b) {}
45+
}
46+
extension type A(String value) {}
47+
extension type B(String value) {}
48+
''',
49+
[lint(27, 2)],
50+
);
51+
}
52+
53+
test_extension_types_ok() async {
54+
await assertNoDiagnostics(r'''
55+
void m(A a1, A a2, B b) {
56+
if (a1 == a2) {}
57+
if (a1 == b) {}
58+
if (b == a1) {}
59+
}
60+
extension type A(String value) {}
61+
extension type B(String value) implements A {}
62+
''');
63+
}
64+
4065
test_fixnum_int32_leftSide() async {
4166
await assertNoDiagnostics(r'''
4267
import 'package:fixnum/fixnum.dart';
@@ -119,6 +144,29 @@ class C with M {}
119144
''');
120145
}
121146

147+
test_mixins() async {
148+
await assertDiagnostics(
149+
r'''
150+
void f(M1 m1, M2 m2) {
151+
if (m1 == m2) {}
152+
}
153+
mixin M1 {}
154+
mixin M2 {}
155+
''',
156+
[lint(32, 2)],
157+
);
158+
}
159+
160+
test_mixins_ok() async {
161+
await assertNoDiagnostics(r'''
162+
void f(M1 m1, M2 m2) {
163+
if (m1 == m2) {}
164+
}
165+
mixin M1 on M2 {}
166+
mixin M2 {}
167+
''');
168+
}
169+
122170
test_object_andArbitraryType() async {
123171
await assertNoDiagnostics(r'''
124172
void f(Object x, C y) {

0 commit comments

Comments
 (0)