[cfe] Enforce override check on Object.==
This enforces the override check for when Object.== implements through inheritance. Closes #42199 Change-Id: I1be1f7dd1b188834e239d2256ad4c312257f2950 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/493340 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
Commit Queue
parent
b6e0d1ad18
commit
22581060b2
@@ -7,7 +7,6 @@ import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/class_hierarchy.dart'
|
||||
show ClassHierarchy, ClassHierarchyMembers;
|
||||
import 'package:kernel/core_types.dart';
|
||||
import 'package:kernel/names.dart' show equalsName;
|
||||
import 'package:kernel/reference_from_index.dart'
|
||||
show IndexedClass, IndexedLibrary;
|
||||
import 'package:kernel/src/bounds_checks.dart';
|
||||
@@ -1744,7 +1743,7 @@ class SourceClassBuilder extends ClassBuilderImpl
|
||||
],
|
||||
localMember: localMember,
|
||||
);
|
||||
} else if (declaredFunction?.typeParameters != null) {
|
||||
} else if (declaredFunction?.typeParameters.isNotEmpty ?? false) {
|
||||
// Since the bound of `interfaceFunction!.parameter[i]` may have changed
|
||||
// during substitution, it can affect the nullabilities of the types in
|
||||
// the substitution map. The first parameter to
|
||||
@@ -2088,16 +2087,6 @@ class SourceClassBuilder extends ClassBuilderImpl
|
||||
if (interfaceSignatureType != null) {
|
||||
interfaceParameterType = interfaceSignatureType.positionalParameters[i];
|
||||
}
|
||||
if (i == 0 &&
|
||||
declaredMember.name == equalsName &&
|
||||
declaredParameterType ==
|
||||
types.hierarchy.coreTypes.objectNonNullableRawType &&
|
||||
interfaceParameter.type is DynamicType) {
|
||||
// TODO(johnniwinther): Add check for opt-in overrides of operator ==.
|
||||
// `operator ==` methods in opt-out classes have type
|
||||
// `bool Function(dynamic)`.
|
||||
continue;
|
||||
}
|
||||
|
||||
_checkTypes(
|
||||
types,
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/nnbd/issue42199.dart:5:7: Error: The implementation of '==' in the non-abstract class 'A' does not conform to its interface.
|
||||
// class A {
|
||||
// ^
|
||||
// sdk/lib/_internal/vm/lib/object_patch.dart:*: Context: The parameter 'other' of the method 'Object.==' has type 'Object', which does not match the corresponding type, 'dynamic', in the overridden method, 'A.=='.
|
||||
// - 'Object' is from 'dart:core'.
|
||||
// Change to a supertype of 'dynamic', or, for a covariant parameter, a subtype.
|
||||
// external bool operator ==(Object other);
|
||||
// ^
|
||||
// pkg/front_end/testcases/nnbd/issue42199.dart:6:12: Context: This is the overridden method ('==').
|
||||
// operator ==(dynamic other);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
@@ -6,6 +21,6 @@ class A extends core::Object {
|
||||
synthetic constructor •() → self::A
|
||||
: super core::Object::•()
|
||||
;
|
||||
abstract operator ==(dynamic other) → core::bool;
|
||||
abstract erroneous operator ==(dynamic other) → core::bool;
|
||||
}
|
||||
static method main() → dynamic {}
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/nnbd/issue42199.dart:5:7: Error: The implementation of '==' in the non-abstract class 'A' does not conform to its interface.
|
||||
// class A {
|
||||
// ^
|
||||
// sdk/lib/_internal/vm/lib/object_patch.dart:*: Context: The parameter 'other' of the method 'Object.==' has type 'Object', which does not match the corresponding type, 'dynamic', in the overridden method, 'A.=='.
|
||||
// - 'Object' is from 'dart:core'.
|
||||
// Change to a supertype of 'dynamic', or, for a covariant parameter, a subtype.
|
||||
// external bool operator ==(Object other);
|
||||
// ^
|
||||
// pkg/front_end/testcases/nnbd/issue42199.dart:6:12: Context: This is the overridden method ('==').
|
||||
// operator ==(dynamic other);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
@@ -6,6 +21,6 @@ class A extends core::Object {
|
||||
synthetic constructor •() → self::A
|
||||
: super core::Object::•()
|
||||
;
|
||||
abstract operator ==(dynamic other) → core::bool;
|
||||
abstract erroneous operator ==(dynamic other) → core::bool;
|
||||
}
|
||||
static method main() → dynamic {}
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/nnbd/issue42199.dart:5:7: Error: The implementation of '==' in the non-abstract class 'A' does not conform to its interface.
|
||||
// class A {
|
||||
// ^
|
||||
// sdk/lib/_internal/vm/lib/object_patch.dart:*: Context: The parameter 'other' of the method 'Object.==' has type 'Object', which does not match the corresponding type, 'dynamic', in the overridden method, 'A.=='.
|
||||
// - 'Object' is from 'dart:core'.
|
||||
// Change to a supertype of 'dynamic', or, for a covariant parameter, a subtype.
|
||||
// external bool operator ==(Object other);
|
||||
// ^
|
||||
// pkg/front_end/testcases/nnbd/issue42199.dart:6:12: Context: This is the overridden method ('==').
|
||||
// operator ==(dynamic other);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A extends core::Object {
|
||||
synthetic constructor •() → self::A
|
||||
;
|
||||
abstract operator ==(dynamic other) → core::bool;
|
||||
abstract erroneous operator ==(dynamic other) → core::bool;
|
||||
}
|
||||
static method main() → dynamic
|
||||
;
|
||||
|
||||
@@ -1,4 +1,19 @@
|
||||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/nnbd/issue42199.dart:5:7: Error: The implementation of '==' in the non-abstract class 'A' does not conform to its interface.
|
||||
// class A {
|
||||
// ^
|
||||
// sdk/lib/_internal/vm/lib/object_patch.dart:*: Context: The parameter 'other' of the method 'Object.==' has type 'Object', which does not match the corresponding type, 'dynamic', in the overridden method, 'A.=='.
|
||||
// - 'Object' is from 'dart:core'.
|
||||
// Change to a supertype of 'dynamic', or, for a covariant parameter, a subtype.
|
||||
// external bool operator ==(Object other);
|
||||
// ^
|
||||
// pkg/front_end/testcases/nnbd/issue42199.dart:6:12: Context: This is the overridden method ('==').
|
||||
// operator ==(dynamic other);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
@@ -6,6 +21,6 @@ class A extends core::Object {
|
||||
synthetic constructor •() → self::A
|
||||
: super core::Object::•()
|
||||
;
|
||||
abstract operator ==(dynamic other) → core::bool;
|
||||
abstract erroneous operator ==(dynamic other) → core::bool;
|
||||
}
|
||||
static method main() → dynamic {}
|
||||
|
||||
@@ -122,7 +122,7 @@ class DateTime {
|
||||
}
|
||||
|
||||
@patch
|
||||
bool operator ==(dynamic other) =>
|
||||
bool operator ==(Object other) =>
|
||||
other is DateTime &&
|
||||
_value == other.microsecondsSinceEpoch &&
|
||||
isUtc == other.isUtc;
|
||||
|
||||
Reference in New Issue
Block a user