Skip to content

Commit 911b376

Browse files
johnniwintherCommit Queue
authored and
Commit Queue
committed
[cfe] Handle inline class representation field in object pattern
Closes #52667 Change-Id: I9c6d51597ff27ae3a7cdeed29d75755c18a2d530 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311742 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]>
1 parent 9b9a8cf commit 911b376

12 files changed

+318
-2
lines changed

pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10429,6 +10429,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
1042910429
case ObjectAccessTargetKind.nullableCallFunction:
1043010430
case ObjectAccessTargetKind.missing:
1043110431
case ObjectAccessTargetKind.ambiguous:
10432+
case ObjectAccessTargetKind.nullableInlineClassRepresentation:
1043210433
field.pattern = new InvalidPattern(
1043310434
createMissingPropertyGet(
1043410435
field.fileOffset, node.requiredType, field.fieldName),
@@ -10443,9 +10444,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
1044310444
case ObjectAccessTargetKind.callFunction:
1044410445
field.accessKind = ObjectAccessKind.FunctionTearOff;
1044510446
break;
10446-
case ObjectAccessTargetKind.superMember:
1044710447
case ObjectAccessTargetKind.inlineClassRepresentation:
10448-
case ObjectAccessTargetKind.nullableInlineClassRepresentation:
10448+
field.accessKind = ObjectAccessKind.Direct;
10449+
field.resultType = fieldTarget.getGetterType(this);
10450+
case ObjectAccessTargetKind.superMember:
1044910451
problems.unsupported(
1045010452
'Object field target $fieldTarget', node.fileOffset, helper.uri);
1045110453
case ObjectAccessTargetKind.extensionMember:

pkg/front_end/lib/src/fasta/type_inference/matching_expressions.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ class MatchingExpressionVisitor
423423
typedMatchedExpression, field.target!, field.resultType!,
424424
isObjectAccess: false, fileOffset: field.fileOffset);
425425
break;
426+
case ObjectAccessKind.Direct:
427+
expression = new DelayedAsExpression(
428+
typedMatchedExpression, field.resultType!,
429+
isUnchecked: true, fileOffset: field.fileOffset);
426430
case ObjectAccessKind.Static:
427431
expression = new DelayedExtensionInvocation(field.target as Procedure,
428432
[typedMatchedExpression], field.typeArguments!, field.resultType!,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
abstract class Foo {}
6+
7+
inline class FooBar implements Foo {
8+
final int i;
9+
10+
const FooBar(this.i);
11+
}
12+
13+
inline class FooBaz implements Foo {
14+
final int i;
15+
16+
const FooBaz(this.i);
17+
}
18+
19+
void main() {
20+
final a = FooBar(0);
21+
switch (a) {
22+
case FooBar(i: final a):
23+
print("FooBar $a");
24+
}
25+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class Foo extends core::Object {
6+
synthetic constructor •() → self::Foo
7+
: super core::Object::•()
8+
;
9+
}
10+
inline class FooBar /* declaredRepresentationType = core::int */ {
11+
constructor • = self::FooBar|;
12+
tearoff • = self::FooBar|_#new#tearOff;
13+
}
14+
inline class FooBaz /* declaredRepresentationType = core::int */ {
15+
constructor • = self::FooBaz|;
16+
tearoff • = self::FooBaz|_#new#tearOff;
17+
}
18+
static inline-class-member method FooBar|(core::int i) → self::FooBar {
19+
lowered final self::FooBar #this = i;
20+
return #this;
21+
}
22+
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
23+
return self::FooBar|(i);
24+
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
25+
lowered final self::FooBaz #this = i;
26+
return #this;
27+
}
28+
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
29+
return self::FooBaz|(i);
30+
static method main() → void {
31+
final self::FooBar a = self::FooBar|(0);
32+
#L1:
33+
{
34+
final synthesized self::FooBar #0#0 = a;
35+
{
36+
final hoisted core::int a;
37+
if(let final dynamic #t1 = a = #0#0 as{Unchecked} core::int in true) {
38+
{
39+
core::print("FooBar ${a}");
40+
}
41+
}
42+
}
43+
}
44+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class Foo extends core::Object {
6+
synthetic constructor •() → self::Foo
7+
: super core::Object::•()
8+
;
9+
}
10+
inline class FooBar /* declaredRepresentationType = core::int */ {
11+
constructor • = self::FooBar|;
12+
tearoff • = self::FooBar|_#new#tearOff;
13+
}
14+
inline class FooBaz /* declaredRepresentationType = core::int */ {
15+
constructor • = self::FooBaz|;
16+
tearoff • = self::FooBaz|_#new#tearOff;
17+
}
18+
static inline-class-member method FooBar|(core::int i) → self::FooBar {
19+
lowered final self::FooBar #this = i;
20+
return #this;
21+
}
22+
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
23+
return self::FooBar|(i);
24+
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
25+
lowered final self::FooBaz #this = i;
26+
return #this;
27+
}
28+
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
29+
return self::FooBaz|(i);
30+
static method main() → void {
31+
final self::FooBar a = self::FooBar|(0);
32+
#L1:
33+
{
34+
final synthesized self::FooBar #0#0 = a;
35+
{
36+
final hoisted core::int a;
37+
if(let final core::int #t1 = a = #0#0 as{Unchecked} core::int in true) {
38+
{
39+
core::print("FooBar ${a}");
40+
}
41+
}
42+
}
43+
}
44+
}
45+
46+
47+
Extra constant evaluation status:
48+
Evaluated: FactoryConstructorInvocation @ org-dartlang-testcase:///issue52667.dart:20:13 -> IntConstant(0)
49+
Extra constant evaluation: evaluated: 17, effectively constant: 1
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
abstract class Foo {}
2+
3+
inline class FooBar implements Foo {
4+
final int i;
5+
const FooBar(this.i);
6+
}
7+
8+
inline class FooBaz implements Foo {
9+
final int i;
10+
const FooBaz(this.i);
11+
}
12+
13+
void main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
abstract class Foo {}
2+
3+
inline class FooBar implements Foo {
4+
const FooBar(this.i);
5+
final int i;
6+
}
7+
8+
inline class FooBaz implements Foo {
9+
const FooBaz(this.i);
10+
final int i;
11+
}
12+
13+
void main() {}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class Foo extends core::Object {
6+
synthetic constructor •() → self::Foo
7+
: super core::Object::•()
8+
;
9+
}
10+
inline class FooBar /* declaredRepresentationType = core::int */ {
11+
constructor • = self::FooBar|;
12+
tearoff • = self::FooBar|_#new#tearOff;
13+
}
14+
inline class FooBaz /* declaredRepresentationType = core::int */ {
15+
constructor • = self::FooBaz|;
16+
tearoff • = self::FooBaz|_#new#tearOff;
17+
}
18+
static inline-class-member method FooBar|(core::int i) → self::FooBar {
19+
lowered final self::FooBar #this = i;
20+
return #this;
21+
}
22+
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
23+
return self::FooBar|(i);
24+
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
25+
lowered final self::FooBaz #this = i;
26+
return #this;
27+
}
28+
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
29+
return self::FooBaz|(i);
30+
static method main() → void {
31+
final self::FooBar a = self::FooBar|(0);
32+
#L1:
33+
{
34+
final synthesized self::FooBar #0#0 = a;
35+
{
36+
final hoisted core::int a;
37+
if(let final dynamic #t1 = a = #0#0 as{Unchecked} core::int in true) {
38+
{
39+
core::print("FooBar ${a}");
40+
}
41+
}
42+
}
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class Foo extends core::Object {
6+
synthetic constructor •() → self::Foo
7+
: super core::Object::•()
8+
;
9+
}
10+
inline class FooBar /* declaredRepresentationType = core::int */ {
11+
constructor • = self::FooBar|;
12+
tearoff • = self::FooBar|_#new#tearOff;
13+
}
14+
inline class FooBaz /* declaredRepresentationType = core::int */ {
15+
constructor • = self::FooBaz|;
16+
tearoff • = self::FooBaz|_#new#tearOff;
17+
}
18+
static inline-class-member method FooBar|(core::int i) → self::FooBar {
19+
lowered final self::FooBar #this = i;
20+
return #this;
21+
}
22+
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
23+
return self::FooBar|(i);
24+
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
25+
lowered final self::FooBaz #this = i;
26+
return #this;
27+
}
28+
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
29+
return self::FooBaz|(i);
30+
static method main() → void {
31+
final self::FooBar a = self::FooBar|(0);
32+
#L1:
33+
{
34+
final synthesized self::FooBar #0#0 = a;
35+
{
36+
final hoisted core::int a;
37+
if(let final dynamic #t1 = a = #0#0 as{Unchecked} core::int in true) {
38+
{
39+
core::print("FooBar ${a}");
40+
}
41+
}
42+
}
43+
}
44+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class Foo extends core::Object {
6+
synthetic constructor •() → self::Foo
7+
;
8+
}
9+
inline class FooBar /* declaredRepresentationType = core::int */ {
10+
constructor • = self::FooBar|;
11+
tearoff • = self::FooBar|_#new#tearOff;
12+
}
13+
inline class FooBaz /* declaredRepresentationType = core::int */ {
14+
constructor • = self::FooBaz|;
15+
tearoff • = self::FooBaz|_#new#tearOff;
16+
}
17+
static inline-class-member method FooBar|(core::int i) → self::FooBar
18+
;
19+
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
20+
return self::FooBar|(i);
21+
static inline-class-member method FooBaz|(core::int i) → self::FooBaz
22+
;
23+
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
24+
return self::FooBaz|(i);
25+
static method main() → void
26+
;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
abstract class Foo extends core::Object {
6+
synthetic constructor •() → self::Foo
7+
: super core::Object::•()
8+
;
9+
}
10+
inline class FooBar /* declaredRepresentationType = core::int */ {
11+
constructor • = self::FooBar|;
12+
tearoff • = self::FooBar|_#new#tearOff;
13+
}
14+
inline class FooBaz /* declaredRepresentationType = core::int */ {
15+
constructor • = self::FooBaz|;
16+
tearoff • = self::FooBaz|_#new#tearOff;
17+
}
18+
static inline-class-member method FooBar|(core::int i) → self::FooBar {
19+
lowered final self::FooBar #this = i;
20+
return #this;
21+
}
22+
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
23+
return self::FooBar|(i);
24+
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
25+
lowered final self::FooBaz #this = i;
26+
return #this;
27+
}
28+
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
29+
return self::FooBaz|(i);
30+
static method main() → void {
31+
final self::FooBar a = self::FooBar|(0);
32+
#L1:
33+
{
34+
final synthesized self::FooBar #0#0 = a;
35+
{
36+
final hoisted core::int a;
37+
if(let final core::int #t1 = a = #0#0 as{Unchecked} core::int in true) {
38+
{
39+
core::print("FooBar ${a}");
40+
}
41+
}
42+
}
43+
}
44+
}
45+
46+
47+
Extra constant evaluation status:
48+
Evaluated: FactoryConstructorInvocation @ org-dartlang-testcase:///issue52667.dart:20:13 -> IntConstant(0)
49+
Extra constant evaluation: evaluated: 17, effectively constant: 1

pkg/kernel/lib/src/ast/patterns.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,9 @@ enum ObjectAccessKind {
16041604

16051605
/// Erroneous property access.
16061606
Error,
1607+
1608+
/// Access of an inline class representation field.
1609+
Direct,
16071610
}
16081611

16091612
/// A [Pattern] with an optional guard [Expression].

0 commit comments

Comments
 (0)