Record Type checking

44 views
Skip to first unread message

Frank Pepermans

unread,
Feb 16, 2023, 6:06:28 AM2/16/23
to mi...@dartlang.org
I was playing around with the new Record feature in Dart 3 alpha, basically trying out some things with Records when used as generic types,

Doing so, some unexpected failing Record Type checks were failing, so I made a little test to reproduce this.

The first test is the one which fails for me, (int, int) and T also have different hash codes, regardless if that is intentional or not, there is then no way to do something like T is (int, int) for example.

So the question is, is this behavior expected? And if so, would there be any way to properly cast a Record Type, like T is (int, int)?

void main() {
Test1<(int, int)>(); // false??
print(identical((int, int), (int, int))); // true
Test2<int>(); // true
Test3<Test<Name>>(); // true
}

class Test1<T> {
Test1() {
print(identical((int, int), T));
}
}

class Test2<T> {
Test2() {
print(identical(int, T));
}
}

class Test3<T> {
Test3() {
final t = Test<Name>;
print(identical(Test<Name>, T));
}
}

class Test<T> {
final T test;

Test(this.test);
}

class Name {
final String value;

const Name(this.value);

@override
String toString() => value;
}

Erik Ernst

unread,
Feb 16, 2023, 7:33:01 AM2/16/23
to mi...@dartlang.org
On Thu, Feb 16, 2023 at 12:06 PM Frank Pepermans <fr...@igindo.com> wrote:
I was playing around with the new Record feature in Dart 3 alpha, basically trying out some things with Records when used as generic types,

Doing so, some unexpected failing Record Type checks were failing, so I made a little test to reproduce this.

The first test is the one which fails for me, (int, int) and T also have different hash codes, regardless if that is intentional or not, there is then no way to do something like T is (int, int) for example.

So the question is, is this behavior expected? And if so, would there be any way to properly cast a Record Type, like T is (int, int)?

void main() {
Test1<(int, int)>(); // false??
The test fails because `(int, int)` occurs as an expression in the Test1 constructor, and that's a record of type `(Type, Type)` with the value of `int` as an expression in both fields, and that's a different thing than the `Type` for the type `(int, int)`. There is no syntax for type literals denoting record types, but you can use

Type typeOf<X>() => X;

If you use `typeOf<(int, int)>()` rather than `(int, int)` as an expression, you get `true` in the first line of output.

The other cases involve types where we _do_ have a type literal, so there's no need to use `typeOf`.
  print(identical((int, int), (int, int))); // true
Test2<int>(); // true
Test3<Test<Name>>(); // true
}

class Test1<T> {
Test1() {
print(identical((int, int), T));
}
}

class Test2<T> {
Test2() {
print(identical(int, T));
}
}

class Test3<T> {
Test3() {
final t = Test<Name>;
print(identical(Test<Name>, T));
}
}

class Test<T> {
final T test;

Test(this.test);
}

class Name {
final String value;

const Name(this.value);

@override
String toString() => value;
}

--
For more ways to connect visit https://dart.dev/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/CAFBTw7i2pTZR9esuvP11mq58%2BSeZvS9g1Zm_sYVy-jpAS8JMgw%40mail.gmail.com.


--
Erik Ernst  -  Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984

Bob Nystrom

unread,
Feb 16, 2023, 1:42:57 PM2/16/23
to mi...@dartlang.org
Erik has it. More specifically, if you write:

var x = (int, int);

Then x does not hold a type literal for a record type with two int fields. It holds a record object whose two fields are the type literal int. Those are different things.

– bob

Reply all
Reply to author
Forward
0 new messages