mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Always infer the return type of operator[]= as void
.
Fixes #31779. Change-Id: Ib7c2b79271ce7eca7ec8143ceb425c73e72f7cc1 Reviewed-on: https://dart-review.googlesource.com/35005 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
4d1adf42d3
commit
52c036c6f8
|
@ -327,7 +327,9 @@ class KernelProcedureBuilder extends KernelFunctionBuilder {
|
|||
procedure.isConst = isConst;
|
||||
procedure.name = new Name(name, library.target);
|
||||
}
|
||||
if (library.loader.target.strongMode && isSetter && returnType == null) {
|
||||
if (library.loader.target.strongMode &&
|
||||
(isSetter || (isOperator && name == '[]=')) &&
|
||||
returnType == null) {
|
||||
procedure.function.returnType = const VoidType();
|
||||
}
|
||||
return procedure;
|
||||
|
|
|
@ -1068,7 +1068,12 @@ class InterfaceResolver {
|
|||
}
|
||||
if (procedure.kind != ProcedureKind.Setter &&
|
||||
ShadowProcedure.hasImplicitReturnType(procedure)) {
|
||||
return true;
|
||||
// Inference of the return type of `[]=` is handled separately by
|
||||
// KernelProcedureBuilder.build, since there are no dependencies.
|
||||
if (procedure.kind != ProcedureKind.Operator ||
|
||||
procedure.name.name != '[]=') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
var function = procedure.function;
|
||||
for (var parameter in function.positionalParameters) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2018, 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.
|
||||
|
||||
/*@testedFeatures=inference,error*/
|
||||
library test;
|
||||
|
||||
class C {
|
||||
dynamic operator []=(dynamic index, dynamic value) {}
|
||||
}
|
||||
|
||||
abstract class I {
|
||||
void operator []=(dynamic index, dynamic value) {}
|
||||
}
|
||||
|
||||
class D extends C implements I {
|
||||
operator /*@topType=void*/ []=(dynamic index, dynamic value) {}
|
||||
}
|
||||
|
||||
main() {}
|
|
@ -0,0 +1,23 @@
|
|||
library test;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class C extends core::Object {
|
||||
default constructor •() → void
|
||||
: super core::Object::•()
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → dynamic {}
|
||||
}
|
||||
abstract class I extends core::Object {
|
||||
default constructor •() → void
|
||||
: super core::Object::•()
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → void {}
|
||||
}
|
||||
class D extends self::C implements self::I {
|
||||
default constructor •() → void
|
||||
: super self::C::•()
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → dynamic {}
|
||||
}
|
||||
static method main() → dynamic {}
|
|
@ -0,0 +1,24 @@
|
|||
library test;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class C extends core::Object {
|
||||
default constructor •() → void
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → dynamic
|
||||
;
|
||||
}
|
||||
abstract class I extends core::Object {
|
||||
default constructor •() → void
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → void
|
||||
;
|
||||
}
|
||||
class D extends self::C implements self::I {
|
||||
default constructor •() → void
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → dynamic
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
;
|
|
@ -0,0 +1,23 @@
|
|||
library test;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class C extends core::Object {
|
||||
default constructor •() → void
|
||||
: super core::Object::•()
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → dynamic {}
|
||||
}
|
||||
abstract class I extends core::Object {
|
||||
default constructor •() → void
|
||||
: super core::Object::•()
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → void {}
|
||||
}
|
||||
class D extends self::C implements self::I {
|
||||
default constructor •() → void
|
||||
: super self::C::•()
|
||||
;
|
||||
operator []=(dynamic index, dynamic value) → void {}
|
||||
}
|
||||
static method main() → dynamic {}
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2018, 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.
|
||||
|
||||
class C {
|
||||
dynamic operator []=(dynamic index, dynamic value) {}
|
||||
}
|
||||
|
||||
abstract class I {
|
||||
void operator []=(dynamic index, dynamic value) {}
|
||||
}
|
||||
|
||||
class D extends C implements I {
|
||||
// Even though `C` and `I` define different return types for `operator[]=`, it
|
||||
// should still be possible to infer a return type here, since the return type
|
||||
// of `operator[]=` is always inferred as `void`.
|
||||
operator []=(dynamic index, dynamic value) {}
|
||||
}
|
||||
|
||||
main() {}
|
|
@ -45,6 +45,7 @@ generics_test: StaticWarning
|
|||
getter_declaration_negative_test: CompileTimeError
|
||||
getter_setter_in_lib_test: Fail # Issue 23286
|
||||
import_core_prefix_test: StaticWarning
|
||||
index_assign_operator_infer_return_type_test: StaticWarning
|
||||
initializing_formal_final_test: MissingCompileTimeError
|
||||
inst_field_initializer1_negative_test: CompileTimeError
|
||||
instance_call_wrong_argument_count_negative_test: Fail # Issue 11585
|
||||
|
|
Loading…
Reference in a new issue