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:
Paul Berry 2018-01-17 13:46:08 +00:00 committed by commit-bot@chromium.org
parent 4d1adf42d3
commit 52c036c6f8
8 changed files with 120 additions and 2 deletions

View file

@ -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;

View file

@ -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) {

View file

@ -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() {}

View file

@ -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 {}

View file

@ -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
;

View file

@ -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 {}

View file

@ -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() {}

View file

@ -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