mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +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.
|
||||
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
|
||||
: assert(expression != null);
|
||||
|
||||
|
@ -416,6 +430,9 @@ class NullAwareExpressionInferenceResult implements ExpressionInferenceResult {
|
|||
'NullAwareExpressionInferenceResult');
|
||||
}
|
||||
|
||||
@override
|
||||
DartType? get postCoercionType => null;
|
||||
|
||||
@override
|
||||
ExpressionInferenceResult stopShorting() {
|
||||
Expression expression = nullAwareAction;
|
||||
|
|
|
@ -7362,7 +7362,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
ExpressionInferenceResult visitInternalRecordLiteral(
|
||||
InternalRecordLiteral node, DartType typeContext) {
|
||||
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;
|
||||
List<Object> originalElementOrder = node.originalElementOrder;
|
||||
List<VariableDeclaration>? hoistedExpressions;
|
||||
|
@ -7371,19 +7372,23 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
Map<String, DartType>? namedTypeContexts;
|
||||
if (typeContext is RecordType &&
|
||||
typeContext.positional.length == positional.length &&
|
||||
typeContext.named.length == named.length) {
|
||||
bool sameNames = true;
|
||||
for (int i = 0; sameNames && i < named.length; i++) {
|
||||
if (typeContext.named[i].name != named[i].name) {
|
||||
sameNames = false;
|
||||
}
|
||||
}
|
||||
if (sameNames) {
|
||||
positionalTypeContexts = typeContext.positional;
|
||||
typeContext.named.length == namedUnsorted.length) {
|
||||
namedTypeContexts = <String, DartType>{};
|
||||
for (NamedType namedType in typeContext.named) {
|
||||
namedTypeContexts[namedType.name] = namedType.type;
|
||||
}
|
||||
|
||||
bool sameNames = true;
|
||||
for (int i = 0; sameNames && i < namedUnsorted.length; i++) {
|
||||
if (!namedTypeContexts.containsKey(namedUnsorted[i].name)) {
|
||||
sameNames = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (sameNames) {
|
||||
positionalTypeContexts = typeContext.positional;
|
||||
} else {
|
||||
namedTypeContexts = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7396,9 +7401,18 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
namedTypes = [];
|
||||
for (int index = 0; index < positional.length; index++) {
|
||||
Expression expression = positional[index];
|
||||
ExpressionInferenceResult expressionResult = inferExpression(expression,
|
||||
positionalTypeContexts?[index] ?? const UnknownType(), true);
|
||||
positionalTypes.add(expressionResult.inferredType);
|
||||
|
||||
DartType contextType =
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
|
@ -7436,12 +7450,17 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
for (int index = originalElementOrder.length - 1; index >= 0; index--) {
|
||||
Object element = originalElementOrder[index];
|
||||
if (element is NamedExpression) {
|
||||
ExpressionInferenceResult expressionResult = inferExpression(
|
||||
element.value,
|
||||
namedTypeContexts?[element.name] ?? const UnknownType(),
|
||||
true);
|
||||
DartType contextType =
|
||||
namedTypeContexts?[element.name] ?? const UnknownType();
|
||||
ExpressionInferenceResult expressionResult =
|
||||
inferExpression(element.value, contextType, true);
|
||||
if (contextType is! UnknownType) {
|
||||
expressionResult =
|
||||
ensureAssignableResult(contextType, expressionResult);
|
||||
}
|
||||
Expression expression = expressionResult.expression;
|
||||
DartType type = expressionResult.inferredType;
|
||||
DartType type = expressionResult.postCoercionType ??
|
||||
expressionResult.inferredType;
|
||||
// TODO(johnniwinther): Should we use [isPureExpression] as is, make
|
||||
// it include (simple) literals, or add a new predicate?
|
||||
if (needsHoisting && !isPureExpression(expression)) {
|
||||
|
@ -7462,12 +7481,17 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
}
|
||||
nameIndex--;
|
||||
} else {
|
||||
ExpressionInferenceResult expressionResult = inferExpression(
|
||||
element as Expression,
|
||||
positionalTypeContexts?[positionalIndex] ?? const UnknownType(),
|
||||
true);
|
||||
DartType contextType =
|
||||
positionalTypeContexts?[positionalIndex] ?? const UnknownType();
|
||||
ExpressionInferenceResult expressionResult =
|
||||
inferExpression(element as Expression, contextType, true);
|
||||
if (contextType is! UnknownType) {
|
||||
expressionResult =
|
||||
ensureAssignableResult(contextType, expressionResult);
|
||||
}
|
||||
Expression expression = expressionResult.expression;
|
||||
DartType type = expressionResult.inferredType;
|
||||
DartType type = expressionResult.postCoercionType ??
|
||||
expressionResult.inferredType;
|
||||
// TODO(johnniwinther): Should we use [isPureExpression] as is, make
|
||||
// it include (simple) literals, or add a new predicate?
|
||||
if (needsHoisting && !isPureExpression(expression)) {
|
||||
|
|
|
@ -529,6 +529,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
DartType expressionType = inferenceResult.inferredType;
|
||||
Expression expression = inferenceResult.expression;
|
||||
Expression result;
|
||||
DartType? postCoercionType;
|
||||
switch (assignabilityResult.kind) {
|
||||
case AssignabilityKind.assignable:
|
||||
result = expression;
|
||||
|
@ -540,6 +541,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
..isForNonNullableByDefault = isNonNullableByDefault
|
||||
..isForDynamic = expressionType is DynamicType
|
||||
..fileOffset = fileOffset;
|
||||
postCoercionType = initialContextType;
|
||||
break;
|
||||
case AssignabilityKind.unassignable:
|
||||
// Error: not assignable. Perform error recovery.
|
||||
|
@ -624,7 +626,8 @@ abstract class InferenceVisitorBase implements InferenceVisitor {
|
|||
|
||||
if (!identical(result, expression)) {
|
||||
flowAnalysis.forwardExpression(result, expression);
|
||||
return new ExpressionInferenceResult(expressionType, result);
|
||||
return new ExpressionInferenceResult(expressionType, result,
|
||||
postCoercionType: postCoercionType);
|
||||
} else {
|
||||
return inferenceResult;
|
||||
}
|
||||
|
|
|
@ -491,6 +491,9 @@ closures
|
|||
clue
|
||||
code
|
||||
coerce
|
||||
coerced
|
||||
coercing
|
||||
coercion
|
||||
coincides
|
||||
coinductively
|
||||
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() {
|
||||
(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) {
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
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 "dart:core" as core;
|
||||
|
||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
|||
} =>#t1;
|
||||
}
|
||||
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)'.
|
||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
||||
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||
}
|
||||
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?)};
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
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 "dart:core" as core;
|
||||
|
||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
|||
} =>#t1;
|
||||
}
|
||||
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)'.
|
||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
||||
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||
}
|
||||
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?)};
|
||||
|
@ -53,4 +44,5 @@ Extra constant evaluation status:
|
|||
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: 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*/;
|
||||
//
|
||||
// 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 "dart:core" as core;
|
||||
|
||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
|||
} =>#t1;
|
||||
}
|
||||
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)'.
|
||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
||||
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||
}
|
||||
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?)};
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
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 "dart:core" as core;
|
||||
|
||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
|||
} =>#t1;
|
||||
}
|
||||
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)'.
|
||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
||||
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||
}
|
||||
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?)};
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
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 "dart:core" as core;
|
||||
|
||||
|
@ -31,9 +24,7 @@ static method foo3() → dynamic {
|
|||
} =>#t1;
|
||||
}
|
||||
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)'.
|
||||
(num, num) r = (3 as dynamic, 3.5); // Error.
|
||||
^" in (3 as{ForNonNullableByDefault} dynamic, 3.5) as{TypeError,ForNonNullableByDefault} (core::num, core::num);
|
||||
(core::num, core::num) r = ((3 as{ForNonNullableByDefault} dynamic) as{TypeError,ForDynamic,ForNonNullableByDefault} core::num, 3.5);
|
||||
}
|
||||
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?)};
|
||||
|
@ -53,4 +44,5 @@ Extra constant evaluation status:
|
|||
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: 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