Skip to content

Commit

Permalink
Language test of record demotion behavior.
Browse files Browse the repository at this point in the history
When a local variable is promoted to a record type, and then an
assignment statement is used to assign a record literal to that local
variable, if the fields of the new record literal are not assignable
to the fields of the promoted record type, that's not a problem; both
the analyzer and front end agree that the local variable is simply
demoted.

But the spec implies that if the old and new record _shapes_ are the
same, then a compile-time error will occur instead of a demotion. I've
created dart-lang/language#3613 to bring the
spec in line with the implementations. This test demonstrates the
current behavior of the implementations, and makes sure that it
doesn't regress.

Change-Id: I0eacd7ca7f6579a35dbc34687113a2112418f368
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352462
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
  • Loading branch information
stereotype441 authored and Commit Queue committed Feb 13, 2024
1 parent c9e2b01 commit 0ae2ac1
Showing 1 changed file with 72 additions and 0 deletions.
72 changes: 72 additions & 0 deletions tests/language/records/assign_to_promoted_record_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (c) 2024, 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.

/// Test that if an assignment is made to a local variable that's been promoted
/// to a record type, and the newly assigned value doesn't match the previously
/// promoted type, no error occurs (the variable is simply demoted).
import '../static_type_helper.dart';

void testPositionalFieldTypeMismatch(Object o) {
if (o is (int,)) {
o.expectStaticType<Exactly<(int,)>>();
// Note: prior to https://github.com/dart-lang/language/pull/3613 this would
// have been a compile-time error, since there is no coercion from `String`
// to `int`.
o = ('',)..expectStaticType<Exactly<(String,)>>();
o.expectStaticType<Exactly<Object>>();
}
}

void testNamedFieldTypeMismatch(Object o) {
if (o is ({int f1})) {
o.expectStaticType<Exactly<({int f1})>>();
// Note: prior to https://github.com/dart-lang/language/pull/3613 this would
// have been a compile-time error, since there is no coercion from `String`
// to `int`.
o = (f1: '')..expectStaticType<Exactly<({String f1})>>();
o.expectStaticType<Exactly<Object>>();
}
}

void testAdditionalPositionalField(Object o) {
if (o is (int,)) {
o.expectStaticType<Exactly<(int,)>>();
o = (1, 2)..expectStaticType<Exactly<(int, int)>>();
o.expectStaticType<Exactly<Object>>();
}
}

void testAdditionalNamedField(Object o) {
if (o is ({int f1})) {
o.expectStaticType<Exactly<({int f1})>>();
o = (f1: 1, f2: 2)..expectStaticType<Exactly<({int f1, int f2})>>();
o.expectStaticType<Exactly<Object>>();
}
}

void testMissingPositionalField(Object o) {
if (o is (int, int)) {
o.expectStaticType<Exactly<(int, int)>>();
o = (1,);
o.expectStaticType<Exactly<Object>>();
}
}

void testMissingNamedField(Object o) {
if (o is ({int f1, int f2})) {
o.expectStaticType<Exactly<({int f1, int f2})>>();
o = (f1: 1);
o.expectStaticType<Exactly<Object>>();
}
}

main() {
testPositionalFieldTypeMismatch((1,));
testNamedFieldTypeMismatch((f1: 1));
testAdditionalPositionalField((1,));
testAdditionalNamedField((f1: 1));
testMissingPositionalField((1, 2));
testMissingNamedField((f1: 1, f2: 2));
}

0 comments on commit 0ae2ac1

Please sign in to comment.