[cfe] Handle callable type variables.

Change-Id: Ibd963206bb81fef16f3cb410fc352e636b0596e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/146580
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2020-05-05 10:02:03 +00:00 committed by commit-bot@chromium.org
parent 765c9c3a8e
commit 59e54abb0e
6 changed files with 103 additions and 0 deletions

View file

@ -1694,6 +1694,7 @@ class TypeInferrerImpl implements TypeInferrer {
}
FunctionType _getFunctionType(DartType calleeType) {
calleeType = resolveTypeParameter(calleeType);
if (calleeType is FunctionType) {
return calleeType;
}
@ -1701,6 +1702,7 @@ class TypeInferrerImpl implements TypeInferrer {
}
FunctionType getFunctionTypeForImplicitCall(DartType calleeType) {
calleeType = resolveTypeParameter(calleeType);
if (calleeType is FunctionType) {
return calleeType;
} else if (calleeType is InterfaceType) {

View file

@ -0,0 +1,33 @@
// Copyright (c) 2020, 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 Class1<T extends Function> {
T field;
Class1(this.field);
method() {
var v1 = field(); // ok
var v2 = field(0); // ok
var v3 = field.call; // ok
var v4 = field.call(); // ok
var v5 = field.call(0); // ok
}
}
class Class2<T extends String Function(int)> {
T field;
Class2(this.field);
method() {
var v1 = field(); // error
var v2 = field(0); // ok
var v3 = field.call; // ok
var v4 = field.call(); // error
var v5 = field.call(0); // ok
}
}
main() {}

View file

@ -0,0 +1,20 @@
library;
import self as self;
import "dart:core" as core;
class Class1<T extends core::Function* = core::Function*> extends core::Object {
generic-covariant-impl field self::Class1::T* field;
constructor •(self::Class1::T* field) → self::Class1<self::Class1::T*>*
;
method method() → dynamic
;
}
class Class2<T extends (core::int*) →* core::String* = (core::int*) →* core::String*> extends core::Object {
generic-covariant-impl field self::Class2::T* field;
constructor •(self::Class2::T* field) → self::Class2<self::Class2::T*>*
;
method method() → dynamic
;
}
static method main() → dynamic
;

View file

@ -0,0 +1,46 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/callable_type_variable.dart:25:19: Error: Too few positional arguments: 1 required, 0 given.
// var v1 = field(); // error
// ^
//
// pkg/front_end/testcases/general/callable_type_variable.dart:28:24: Error: Too few positional arguments: 1 required, 0 given.
// var v4 = field.call(); // error
// ^
//
import self as self;
import "dart:core" as core;
class Class1<T extends core::Function* = core::Function*> extends core::Object {
generic-covariant-impl field self::Class1::T* field;
constructor •(self::Class1::T* field) → self::Class1<self::Class1::T*>*
: self::Class1::field = field, super core::Object::•()
;
method method() → dynamic {
dynamic v1 = this.{self::Class1::field}.call();
dynamic v2 = let final core::int* #t1 = 0 in this.{self::Class1::field}.call(#t1);
self::Class1::T* v3 = this.{self::Class1::field}.call;
dynamic v4 = this.{self::Class1::field}.call();
dynamic v5 = this.{self::Class1::field}.call(0);
}
}
class Class2<T extends (core::int*) →* core::String* = (core::int*) →* core::String*> extends core::Object {
generic-covariant-impl field self::Class2::T* field;
constructor •(self::Class2::T* field) → self::Class2<self::Class2::T*>*
: self::Class2::field = field, super core::Object::•()
;
method method() → dynamic {
invalid-type v1 = let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/callable_type_variable.dart:25:19: Error: Too few positional arguments: 1 required, 0 given.
var v1 = field(); // error
^" in this.{self::Class2::field}.call();
core::String* v2 = let final core::int* #t3 = 0 in this.{self::Class2::field}.call(#t3);
self::Class2::T* v3 = this.{self::Class2::field}.call;
invalid-type v4 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/general/callable_type_variable.dart:28:24: Error: Too few positional arguments: 1 required, 0 given.
var v4 = field.call(); // error
^" in this.{self::Class2::field}.call();
core::String* v5 = this.{self::Class2::field}.call(0);
}
}
static method main() → dynamic {}

View file

@ -20,6 +20,7 @@ general/bug21938: TypeCheckError
general/bug30695: TypeCheckError
general/bug31124: RuntimeError # Test has no main method (and we shouldn't add one).
general/call: TypeCheckError
general/callable_type_variable: TypeCheckError
general/candidate_found: TypeCheckError
general/cascade: RuntimeError
general/constructor_initializer_invalid: RuntimeError # Fails execution after recovery

View file

@ -20,6 +20,7 @@ general/bug21938: TypeCheckError
general/bug30695: TypeCheckError
general/bug31124: RuntimeError
general/call: TypeCheckError
general/callable_type_variable: TypeCheckError
general/candidate_found: TypeCheckError
general/cascade: RuntimeError
general/constructor_initializer_invalid: RuntimeError