mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:59:47 +00:00
[cfe] Implement pointwise implicit downcasts for record literals
This CL implements the adjustment of the static semantics for records
as described in
d19f6d5644
. The
adjustment is based on the discussion at
https://github.com/dart-lang/language/issues/2488.
Part of https://github.com/dart-lang/sdk/issues/49713
Change-Id: I7a9d456f702ad0fb14aa3bd121ba9d2bbd104414
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/262202
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
parent
d968be9021
commit
7e57f6e371
|
@ -303,7 +303,21 @@ class ExpressionInferenceResult {
|
||||||
/// The inferred expression.
|
/// The inferred expression.
|
||||||
final Expression expression;
|
final Expression expression;
|
||||||
|
|
||||||
ExpressionInferenceResult(this.inferredType, this.expression)
|
/// More precise type of the expression after coercion.
|
||||||
|
///
|
||||||
|
/// Consider the following code:
|
||||||
|
///
|
||||||
|
/// dynamic foo = 3;
|
||||||
|
/// int bar = foo;
|
||||||
|
///
|
||||||
|
/// In the example above `foo` is coerced to `foo as int`, but
|
||||||
|
/// [inferredType]` of `foo` stays `dynamic`. In some situations, like
|
||||||
|
/// coercing elements of record literals, we want to know the more precise
|
||||||
|
/// type of the expression after coercion, `int` in the example above.
|
||||||
|
final DartType? postCoercionType;
|
||||||
|
|
||||||
|
ExpressionInferenceResult(this.inferredType, this.expression,
|
||||||
|
{this.postCoercionType = null})
|
||||||
// ignore: unnecessary_null_comparison
|
// ignore: unnecessary_null_comparison
|
||||||
: assert(expression != null);
|
: assert(expression != null);
|
||||||
|
|
||||||
|
@ -416,6 +430,9 @@ class NullAwareExpressionInferenceResult implements ExpressionInferenceResult {
|
||||||
'NullAwareExpressionInferenceResult');
|
'NullAwareExpressionInferenceResult');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
DartType? get postCoercionType => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ExpressionInferenceResult stopShorting() {
|
ExpressionInferenceResult stopShorting() {
|
||||||
Expression expression = nullAwareAction;
|
Expression expression = nullAwareAction;
|
||||||
|
|
|
@ -7362,7 +7362,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||||
ExpressionInferenceResult visitInternalRecordLiteral(
|
ExpressionInferenceResult visitInternalRecordLiteral(
|
||||||
InternalRecordLiteral node, DartType typeContext) {
|
InternalRecordLiteral node, DartType typeContext) {
|
||||||
List<Expression> positional = node.positional;
|
List<Expression> positional = node.positional;
|
||||||
List<NamedExpression> named = node.named;
|
List<NamedExpression> namedUnsorted = node.named;
|
||||||
|
List<NamedExpression> named = namedUnsorted;
|
||||||
Map<String, NamedExpression>? namedElements = node.namedElements;
|
Map<String, NamedExpression>? namedElements = node.namedElements;
|
||||||
List<Object> originalElementOrder = node.originalElementOrder;
|
List<Object> originalElementOrder = node.originalElementOrder;
|
||||||
List<VariableDeclaration>? hoistedExpressions;
|
List<VariableDeclaration>? hoistedExpressions;
|
||||||
|
@ -7371,19 +7372,23 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||||
Map<String, DartType>? namedTypeContexts;
|
Map<String, DartType>? namedTypeContexts;
|
||||||
if (typeContext is RecordType &&
|
if (typeContext is RecordType &&
|
||||||
typeContext.positional.length == positional.length &&
|
typeContext.positional.length == positional.length &&
|
||||||
typeContext.named.length == named.length) {
|
typeContext.named.length == namedUnsorted.length) {
|
||||||
|
namedTypeContexts = <String, DartType>{};
|
||||||
|
for (NamedType namedType in typeContext.named) {
|
||||||
|
namedTypeContexts[namedType.name] = namedType.type;
|
||||||
|
}
|
||||||
|
|
||||||
bool sameNames = true;
|
bool sameNames = true;
|
||||||
for (int i = 0; sameNames && i < named.length; i++) {
|
for (int i = 0; sameNames && i < namedUnsorted.length; i++) {
|
||||||
if (typeContext.named[i].name != named[i].name) {
|
if (!namedTypeContexts.containsKey(namedUnsorted[i].name)) {
|
||||||
sameNames = false;
|
sameNames = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sameNames) {
|
if (sameNames) {
|
||||||
positionalTypeContexts = typeContext.positional;
|
positionalTypeContexts = typeContext.positional;
|
||||||
namedTypeContexts = <String, DartType>{};
|
} else {
|
||||||
for (NamedType namedType in typeContext.named) {
|
namedTypeContexts = null;
|
||||||
namedTypeContexts[namedType.name] = namedType.type;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7396,9 +7401,18 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||||
namedTypes = [];
|
namedTypes = [];
|
||||||
for (int index = 0; index < positional.length; index++) {
|
for (int index = 0; index < positional.length; index++) {
|
||||||
Expression expression = positional[index];
|
Expression expression = positional[index];
|
||||||
ExpressionInferenceResult expressionResult = inferExpression(expression,
|
|
||||||
positionalTypeContexts?[index] ?? const UnknownType(), true);
|
DartType contextType =
|
||||||
positionalTypes.add(expressionResult.inferredType);
|
positionalTypeContexts?[index] ?? const UnknownType();
|
||||||
|
ExpressionInferenceResult expressionResult =
|
||||||
|
inferExpression(expression, contextType, true);
|
||||||
|
if (contextType is! UnknownType) {
|
||||||
|
expressionResult =
|
||||||
|
ensureAssignableResult(contextType, expressionResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
positionalTypes.add(
|
||||||
|
expressionResult.postCoercionType ?? expressionResult.inferredType);
|
||||||
positional[index] = expressionResult.expression;
|
positional[index] = expressionResult.expression;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -7436,12 +7450,17 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||||
for (int index = originalElementOrder.length - 1; index >= 0; index--) {
|
for (int index = originalElementOrder.length - 1; index >= 0; index--) {
|
||||||
Object element = originalElementOrder[index];
|
Object element = originalElementOrder[index];
|
||||||
if (element is NamedExpression) {
|
if (element is NamedExpression) {
|
||||||
ExpressionInferenceResult expressionResult = inferExpression(
|
DartType contextType =
|
||||||
element.value,
|
namedTypeContexts?[element.name] ?? const UnknownType();
|
||||||
namedTypeContexts?[element.name] ?? const UnknownType(),
|
ExpressionInferenceResult expressionResult =
|
||||||
true);
|
inferExpression(element.value, contextType, true);
|
||||||
|
if (contextType is! UnknownType) {
|
||||||
|
expressionResult =
|
||||||
|
ensureAssignableResult(contextType, expressionResult);
|
||||||
|
}
|
||||||
Expression expression = expressionResult.expression;
|
Expression expression = expressionResult.expression;
|
||||||
DartType type = expressionResult.inferredType;
|
DartType type = expressionResult.postCoercionType ??
|
||||||
|
expressionResult.inferredType;
|
||||||
// TODO(johnniwinther): Should we use [isPureExpression] as is, make
|
// TODO(johnniwinther): Should we use [isPureExpression] as is, make
|
||||||
// it include (simple) literals, or add a new predicate?
|
// it include (simple) literals, or add a new predicate?
|
||||||
if (needsHoisting && !isPureExpression(expression)) {
|
if (needsHoisting && !isPureExpression(expression)) {
|
||||||
|
@ -7462,12 +7481,17 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||||
}
|
}
|
||||||
nameIndex--;
|
nameIndex--;
|
||||||
} else {
|
} else {
|
||||||
ExpressionInferenceResult expressionResult = inferExpression(
|
DartType contextType =
|
||||||
element as Expression,
|
positionalTypeContexts?[positionalIndex] ?? const UnknownType();
|
||||||
positionalTypeContexts?[positionalIndex] ?? const UnknownType(),
|
ExpressionInferenceResult expressionResult =
|
||||||
true);
|
inferExpression(element as Expression, contextType, true);
|
||||||
|
if (contextType is! UnknownType) {
|
||||||
|
expressionResult =
|
||||||
|
ensureAssignableResult(contextType, expressionResult);
|
||||||
|
}
|
||||||
Expression expression = expressionResult.expression;
|
Expression expression = expressionResult.expression;
|
||||||
DartType type = expressionResult.inferredType;
|
DartType type = expressionResult.postCoercionType ??
|
||||||
|
expressionResult.inferredType;
|
||||||
// TODO(johnniwinther): Should we use [isPureExpression] as is, make
|
// TODO(johnniwinther): Should we use [isPureExpression] as is, make
|
||||||
// it include (simple) literals, or add a new predicate?
|
// it include (simple) literals, or add a new predicate?
|
||||||
if (needsHoisting && !isPureExpression(expression)) {
|
if (needsHoisting && !isPureExpression(expression)) {
|
||||||
|
|
|
@ -529,6 +529,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
||||||
DartType expressionType = inferenceResult.inferredType;
|
DartType expressionType = inferenceResult.inferredType;
|
||||||
Expression expression = inferenceResult.expression;
|
Expression expression = inferenceResult.expression;
|
||||||
Expression result;
|
Expression result;
|
||||||
|
DartType? postCoercionType;
|
||||||
switch (assignabilityResult.kind) {
|
switch (assignabilityResult.kind) {
|
||||||
case AssignabilityKind.assignable:
|
case AssignabilityKind.assignable:
|
||||||
result = expression;
|
result = expression;
|
||||||
|
@ -540,6 +541,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
||||||
..isForNonNullableByDefault = isNonNullableByDefault
|
..isForNonNullableByDefault = isNonNullableByDefault
|
||||||
..isForDynamic = expressionType is DynamicType
|
..isForDynamic = expressionType is DynamicType
|
||||||
..fileOffset = fileOffset;
|
..fileOffset = fileOffset;
|
||||||
|
postCoercionType = initialContextType;
|
||||||
break;
|
break;
|
||||||
case AssignabilityKind.unassignable:
|
case AssignabilityKind.unassignable:
|
||||||
// Error: not assignable. Perform error recovery.
|
// Error: not assignable. Perform error recovery.
|
||||||
|
@ -624,7 +626,8 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
||||||
|
|
||||||
if (!identical(result, expression)) {
|
if (!identical(result, expression)) {
|
||||||
flowAnalysis.forwardExpression(result, expression);
|
flowAnalysis.forwardExpression(result, expression);
|
||||||
return new ExpressionInferenceResult(expressionType, result);
|
return new ExpressionInferenceResult(expressionType, result,
|
||||||
|
postCoercionType: postCoercionType);
|
||||||
} else {
|
} else {
|
||||||
return inferenceResult;
|
return inferenceResult;
|
||||||
}
|
}
|
||||||
|
|
|
@ -491,6 +491,9 @@ closures
|
||||||
clue
|
clue
|
||||||
code
|
code
|
||||||
coerce
|
coerce
|
||||||
|
coerced
|
||||||
|
coercing
|
||||||
|
coercion
|
||||||
coincides
|
coincides
|
||||||
coinductively
|
coinductively
|
||||||
collapses
|
collapses
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright (c) 2022, 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 Callable {
|
||||||
|
void call() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
T id<T>(T x) => x;
|
||||||
|
|
||||||
|
foo() {
|
||||||
|
// No static error.
|
||||||
|
// Inferred type of the record is (int, double, int Function(int), void Function()).
|
||||||
|
var c = Callable();
|
||||||
|
dynamic d = 3;
|
||||||
|
(num, double, int Function(int), void Function()) r = (d, 3, id, c);
|
||||||
|
({num x, double y, int Function(int) f, void Function() g}) r2 = (x: d, y: 3, f: id, g: c);
|
||||||
|
(num, double, {int Function(int) f, void Function() g}) r3 = (d, 3, f: id, g: c);
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {}
|
|
@ -0,0 +1,25 @@
|
||||||
|
library /*isNonNullableByDefault*/;
|
||||||
|
import self as self;
|
||||||
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
class Callable extends core::Object {
|
||||||
|
synthetic constructor •() → self::Callable
|
||||||
|
: super core::Object::•()
|
||||||
|
;
|
||||||
|
method call() → void {}
|
||||||
|
}
|
||||||
|
static method id<T extends core::Object? = dynamic>(self::id::T% x) → self::id::T%
|
||||||
|
return x;
|
||||||
|
static method foo() → dynamic {
|
||||||
|
self::Callable c = new self::Callable::•();
|
||||||
|
dynamic d = 3;
|
||||||
|
(core::num, core::double, (core::int) → core::int, () → void) r = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, #C2, let final self::Callable #t1 = c in #t1 == null ?{() → void} null : #t1.{self::Callable::call}{() → void});
|
||||||
|
({required f: (core::int) → core::int, required g: () → void, required x: core::num, required y: core::double}) r2 = let final core::num #t2 = d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num in let final core::double #t3 = 3.0 in let final (core::int) → core::int #t4 = #C2 in ({f: #t4, g: let final self::Callable #t5 = c in #t5 == null ?{() → void} null : #t5.{self::Callable::call}{() → void}, x: #t2, y: #t3});
|
||||||
|
(core::num, core::double, {required f: (core::int) → core::int, required g: () → void}) r3 = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, {f: #C2, g: let final self::Callable #t6 = c in #t6 == null ?{() → void} null : #t6.{self::Callable::call}{() → void}});
|
||||||
|
}
|
||||||
|
static method main() → dynamic {}
|
||||||
|
|
||||||
|
constants {
|
||||||
|
#C1 = static-tearoff self::id
|
||||||
|
#C2 = instantiation #C1 <core::int>
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
library /*isNonNullableByDefault*/;
|
||||||
|
import self as self;
|
||||||
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
class Callable extends core::Object {
|
||||||
|
synthetic constructor •() → self::Callable
|
||||||
|
: super core::Object::•()
|
||||||
|
;
|
||||||
|
method call() → void {}
|
||||||
|
}
|
||||||
|
static method id<T extends core::Object? = dynamic>(self::id::T% x) → self::id::T%
|
||||||
|
return x;
|
||||||
|
static method foo() → dynamic {
|
||||||
|
self::Callable c = new self::Callable::•();
|
||||||
|
dynamic d = 3;
|
||||||
|
(core::num, core::double, (core::int) → core::int, () → void) r = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, #C2, let final self::Callable #t1 = c in #t1 == null ?{() → void} null : #t1.{self::Callable::call}{() → void});
|
||||||
|
({required f: (core::int) → core::int, required g: () → void, required x: core::num, required y: core::double}) r2 = let final core::num #t2 = d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num in let final core::double #t3 = 3.0 in let final (core::int) → core::int #t4 = #C2 in ({f: #t4, g: let final self::Callable #t5 = c in #t5 == null ?{() → void} null : #t5.{self::Callable::call}{() → void}, x: #t2, y: #t3});
|
||||||
|
(core::num, core::double, {required f: (core::int) → core::int, required g: () → void}) r3 = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, {f: #C2, g: let final self::Callable #t6 = c in #t6 == null ?{() → void} null : #t6.{self::Callable::call}{() → void}});
|
||||||
|
}
|
||||||
|
static method main() → dynamic {}
|
||||||
|
|
||||||
|
constants {
|
||||||
|
#C1 = static-tearoff self::id
|
||||||
|
#C2 = instantiation #C1 <core::int>
|
||||||
|
}
|
||||||
|
|
||||||
|
Extra constant evaluation status:
|
||||||
|
Evaluated: VariableGet @ org-dartlang-testcase:///pointwise_implicit_downcasts.dart:17:84 -> InstantiationConstant(id<int>)
|
||||||
|
Evaluated: VariableGet @ org-dartlang-testcase:///pointwise_implicit_downcasts.dart:17:78 -> DoubleConstant(3.0)
|
||||||
|
Extra constant evaluation: evaluated: 38, effectively constant: 2
|
|
@ -0,0 +1,7 @@
|
||||||
|
class Callable {
|
||||||
|
void call() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
T id<T>(T x) => x;
|
||||||
|
foo() {}
|
||||||
|
main() {}
|
|
@ -0,0 +1,8 @@
|
||||||
|
T id<T>(T x) => x;
|
||||||
|
|
||||||
|
class Callable {
|
||||||
|
void call() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
foo() {}
|
||||||
|
main() {}
|
|
@ -0,0 +1,25 @@
|
||||||
|
library /*isNonNullableByDefault*/;
|
||||||
|
import self as self;
|
||||||
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
class Callable extends core::Object {
|
||||||
|
synthetic constructor •() → self::Callable
|
||||||
|
: super core::Object::•()
|
||||||
|
;
|
||||||
|
method call() → void {}
|
||||||
|
}
|
||||||
|
static method id<T extends core::Object? = dynamic>(self::id::T% x) → self::id::T%
|
||||||
|
return x;
|
||||||
|
static method foo() → dynamic {
|
||||||
|
self::Callable c = new self::Callable::•();
|
||||||
|
dynamic d = 3;
|
||||||
|
(core::num, core::double, (core::int) → core::int, () → void) r = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, #C2, let final self::Callable #t1 = c in #t1 == null ?{() → void} null : #t1.{self::Callable::call}{() → void});
|
||||||
|
({required f: (core::int) → core::int, required g: () → void, required x: core::num, required y: core::double}) r2 = let final core::num #t2 = d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num in let final core::double #t3 = 3.0 in let final (core::int) → core::int #t4 = #C2 in ({f: #t4, g: let final self::Callable #t5 = c in #t5 == null ?{() → void} null : #t5.{self::Callable::call}{() → void}, x: #t2, y: #t3});
|
||||||
|
(core::num, core::double, {required f: (core::int) → core::int, required g: () → void}) r3 = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, {f: #C2, g: let final self::Callable #t6 = c in #t6 == null ?{() → void} null : #t6.{self::Callable::call}{() → void}});
|
||||||
|
}
|
||||||
|
static method main() → dynamic {}
|
||||||
|
|
||||||
|
constants {
|
||||||
|
#C1 = static-tearoff self::id
|
||||||
|
#C2 = instantiation #C1 <core::int*>
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
library /*isNonNullableByDefault*/;
|
||||||
|
import self as self;
|
||||||
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
class Callable extends core::Object {
|
||||||
|
synthetic constructor •() → self::Callable
|
||||||
|
: super core::Object::•()
|
||||||
|
;
|
||||||
|
method call() → void {}
|
||||||
|
}
|
||||||
|
static method id<T extends core::Object? = dynamic>(self::id::T% x) → self::id::T%
|
||||||
|
return x;
|
||||||
|
static method foo() → dynamic {
|
||||||
|
self::Callable c = new self::Callable::•();
|
||||||
|
dynamic d = 3;
|
||||||
|
(core::num, core::double, (core::int) → core::int, () → void) r = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, #C2, let final self::Callable #t1 = c in #t1 == null ?{() → void} null : #t1.{self::Callable::call}{() → void});
|
||||||
|
({required f: (core::int) → core::int, required g: () → void, required x: core::num, required y: core::double}) r2 = let final core::num #t2 = d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num in let final core::double #t3 = 3.0 in let final (core::int) → core::int #t4 = #C2 in ({f: #t4, g: let final self::Callable #t5 = c in #t5 == null ?{() → void} null : #t5.{self::Callable::call}{() → void}, x: #t2, y: #t3});
|
||||||
|
(core::num, core::double, {required f: (core::int) → core::int, required g: () → void}) r3 = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, {f: #C2, g: let final self::Callable #t6 = c in #t6 == null ?{() → void} null : #t6.{self::Callable::call}{() → void}});
|
||||||
|
}
|
||||||
|
static method main() → dynamic {}
|
||||||
|
|
||||||
|
constants {
|
||||||
|
#C1 = static-tearoff self::id
|
||||||
|
#C2 = instantiation #C1 <core::int*>
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
library /*isNonNullableByDefault*/;
|
||||||
|
import self as self;
|
||||||
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
class Callable extends core::Object {
|
||||||
|
synthetic constructor •() → self::Callable
|
||||||
|
;
|
||||||
|
method call() → void
|
||||||
|
;
|
||||||
|
}
|
||||||
|
static method id<T extends core::Object? = dynamic>(self::id::T% x) → self::id::T%
|
||||||
|
;
|
||||||
|
static method foo() → dynamic
|
||||||
|
;
|
||||||
|
static method main() → dynamic
|
||||||
|
;
|
|
@ -0,0 +1,30 @@
|
||||||
|
library /*isNonNullableByDefault*/;
|
||||||
|
import self as self;
|
||||||
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
class Callable extends core::Object {
|
||||||
|
synthetic constructor •() → self::Callable
|
||||||
|
: super core::Object::•()
|
||||||
|
;
|
||||||
|
method call() → void {}
|
||||||
|
}
|
||||||
|
static method id<T extends core::Object? = dynamic>(self::id::T% x) → self::id::T%
|
||||||
|
return x;
|
||||||
|
static method foo() → dynamic {
|
||||||
|
self::Callable c = new self::Callable::•();
|
||||||
|
dynamic d = 3;
|
||||||
|
(core::num, core::double, (core::int) → core::int, () → void) r = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, #C2, let final self::Callable #t1 = c in #t1 == null ?{() → void} null : #t1.{self::Callable::call}{() → void});
|
||||||
|
({required f: (core::int) → core::int, required g: () → void, required x: core::num, required y: core::double}) r2 = let final core::num #t2 = d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num in let final core::double #t3 = 3.0 in let final (core::int) → core::int #t4 = #C2 in ({f: #t4, g: let final self::Callable #t5 = c in #t5 == null ?{() → void} null : #t5.{self::Callable::call}{() → void}, x: #t2, y: #t3});
|
||||||
|
(core::num, core::double, {required f: (core::int) → core::int, required g: () → void}) r3 = (d as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.0, {f: #C2, g: let final self::Callable #t6 = c in #t6 == null ?{() → void} null : #t6.{self::Callable::call}{() → void}});
|
||||||
|
}
|
||||||
|
static method main() → dynamic {}
|
||||||
|
|
||||||
|
constants {
|
||||||
|
#C1 = static-tearoff self::id
|
||||||
|
#C2 = instantiation #C1 <core::int*>
|
||||||
|
}
|
||||||
|
|
||||||
|
Extra constant evaluation status:
|
||||||
|
Evaluated: VariableGet @ org-dartlang-testcase:///pointwise_implicit_downcasts.dart:17:84 -> InstantiationConstant(id<int*>)
|
||||||
|
Evaluated: VariableGet @ org-dartlang-testcase:///pointwise_implicit_downcasts.dart:17:78 -> DoubleConstant(3.0)
|
||||||
|
Extra constant evaluation: evaluated: 38, effectively constant: 2
|
|
@ -15,7 +15,7 @@ foo3() {
|
||||||
}
|
}
|
||||||
|
|
||||||
foo4() {
|
foo4() {
|
||||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
(num, num) r = (3 as dynamic, 3.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
foo5((int, String?) r, (int, X) Function<X>() f) {
|
foo5((int, String?) r, (int, X) Function<X>() f) {
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
|
||||||
// (num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
// ^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
||||||
} =>#t1;
|
} =>#t1;
|
||||||
}
|
}
|
||||||
static method foo4() → dynamic {
|
static method foo4() → dynamic {
|
||||||
(core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
|
||||||
}
|
}
|
||||||
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
||||||
r = f<core::String?>(){() → (core::int, core::String?)};
|
r = f<core::String?>(){() → (core::int, core::String?)};
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
|
||||||
// (num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
// ^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
||||||
} =>#t1;
|
} =>#t1;
|
||||||
}
|
}
|
||||||
static method foo4() → dynamic {
|
static method foo4() → dynamic {
|
||||||
(core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
|
||||||
}
|
}
|
||||||
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
||||||
r = f<core::String?>(){() → (core::int, core::String?)};
|
r = f<core::String?>(){() → (core::int, core::String?)};
|
||||||
|
@ -53,4 +44,5 @@ Extra constant evaluation status:
|
||||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
||||||
Evaluated: VariableGetImpl @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
Evaluated: VariableGetImpl @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
||||||
Evaluated: VariableGet @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
Evaluated: VariableGet @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
||||||
Extra constant evaluation: evaluated: 24, effectively constant: 3
|
Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:18:18 -> RecordConstant(const (3, 3.5))
|
||||||
|
Extra constant evaluation: evaluated: 25, effectively constant: 4
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
|
||||||
// (num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
// ^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
||||||
} =>#t1;
|
} =>#t1;
|
||||||
}
|
}
|
||||||
static method foo4() → dynamic {
|
static method foo4() → dynamic {
|
||||||
(core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
|
||||||
}
|
}
|
||||||
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
||||||
r = f<core::String?>(){() → (core::int, core::String?)};
|
r = f<core::String?>(){() → (core::int, core::String?)};
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
|
||||||
// (num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
// ^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
||||||
} =>#t1;
|
} =>#t1;
|
||||||
}
|
}
|
||||||
static method foo4() → dynamic {
|
static method foo4() → dynamic {
|
||||||
(core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
|
||||||
}
|
}
|
||||||
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
||||||
r = f<core::String?>(){() → (core::int, core::String?)};
|
r = f<core::String?>(){() → (core::int, core::String?)};
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
|
||||||
// (num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
// ^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
||||||
} =>#t1;
|
} =>#t1;
|
||||||
}
|
}
|
||||||
static method foo4() → dynamic {
|
static method foo4() → dynamic {
|
||||||
(core::num, core::num) r = invalid-expression "pkg/front_end/testcases/records/simple_inference.dart:18:18: Error: A value of type '(dynamic, double)' can't be assigned to a variable of type '(num, num)'.
|
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
|
||||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
|
||||||
}
|
}
|
||||||
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
static method foo5((core::int, core::String?) r, <X extends core::Object? = dynamic>() → (core::int, X%) f) → dynamic {
|
||||||
r = f<core::String?>(){() → (core::int, core::String?)};
|
r = f<core::String?>(){() → (core::int, core::String?)};
|
||||||
|
@ -53,4 +44,5 @@ Extra constant evaluation status:
|
||||||
Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
||||||
Evaluated: VariableGetImpl @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
Evaluated: VariableGetImpl @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
||||||
Evaluated: VariableGet @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
Evaluated: VariableGet @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5))
|
||||||
Extra constant evaluation: evaluated: 24, effectively constant: 3
|
Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:18:18 -> RecordConstant(const (3, 3.5))
|
||||||
|
Extra constant evaluation: evaluated: 25, effectively constant: 4
|
||||||
|
|
Loading…
Reference in a new issue