mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[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 <johnniwinther@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
parent
9b9a8cf042
commit
911b376f7e
|
@ -10429,6 +10429,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
case ObjectAccessTargetKind.nullableCallFunction:
|
||||
case ObjectAccessTargetKind.missing:
|
||||
case ObjectAccessTargetKind.ambiguous:
|
||||
case ObjectAccessTargetKind.nullableInlineClassRepresentation:
|
||||
field.pattern = new InvalidPattern(
|
||||
createMissingPropertyGet(
|
||||
field.fileOffset, node.requiredType, field.fieldName),
|
||||
|
@ -10443,9 +10444,10 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
case ObjectAccessTargetKind.callFunction:
|
||||
field.accessKind = ObjectAccessKind.FunctionTearOff;
|
||||
break;
|
||||
case ObjectAccessTargetKind.superMember:
|
||||
case ObjectAccessTargetKind.inlineClassRepresentation:
|
||||
case ObjectAccessTargetKind.nullableInlineClassRepresentation:
|
||||
field.accessKind = ObjectAccessKind.Direct;
|
||||
field.resultType = fieldTarget.getGetterType(this);
|
||||
case ObjectAccessTargetKind.superMember:
|
||||
problems.unsupported(
|
||||
'Object field target $fieldTarget', node.fileOffset, helper.uri);
|
||||
case ObjectAccessTargetKind.extensionMember:
|
||||
|
|
|
@ -423,6 +423,10 @@ class MatchingExpressionVisitor
|
|||
typedMatchedExpression, field.target!, field.resultType!,
|
||||
isObjectAccess: false, fileOffset: field.fileOffset);
|
||||
break;
|
||||
case ObjectAccessKind.Direct:
|
||||
expression = new DelayedAsExpression(
|
||||
typedMatchedExpression, field.resultType!,
|
||||
isUnchecked: true, fileOffset: field.fileOffset);
|
||||
case ObjectAccessKind.Static:
|
||||
expression = new DelayedExtensionInvocation(field.target as Procedure,
|
||||
[typedMatchedExpression], field.typeArguments!, field.resultType!,
|
||||
|
|
25
pkg/front_end/testcases/inline_class/issue52667.dart
Normal file
25
pkg/front_end/testcases/inline_class/issue52667.dart
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2023, 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.
|
||||
|
||||
abstract class Foo {}
|
||||
|
||||
inline class FooBar implements Foo {
|
||||
final int i;
|
||||
|
||||
const FooBar(this.i);
|
||||
}
|
||||
|
||||
inline class FooBaz implements Foo {
|
||||
final int i;
|
||||
|
||||
const FooBaz(this.i);
|
||||
}
|
||||
|
||||
void main() {
|
||||
final a = FooBar(0);
|
||||
switch (a) {
|
||||
case FooBar(i: final a):
|
||||
print("FooBar $a");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class Foo extends core::Object {
|
||||
synthetic constructor •() → self::Foo
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
inline class FooBar /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBar|;
|
||||
tearoff • = self::FooBar|_#new#tearOff;
|
||||
}
|
||||
inline class FooBaz /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBaz|;
|
||||
tearoff • = self::FooBaz|_#new#tearOff;
|
||||
}
|
||||
static inline-class-member method FooBar|(core::int i) → self::FooBar {
|
||||
lowered final self::FooBar #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
|
||||
return self::FooBar|(i);
|
||||
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
|
||||
lowered final self::FooBaz #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
|
||||
return self::FooBaz|(i);
|
||||
static method main() → void {
|
||||
final self::FooBar a = self::FooBar|(0);
|
||||
#L1:
|
||||
{
|
||||
final synthesized self::FooBar #0#0 = a;
|
||||
{
|
||||
final hoisted core::int a;
|
||||
if(let final dynamic #t1 = a = #0#0 as{Unchecked} core::int in true) {
|
||||
{
|
||||
core::print("FooBar ${a}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class Foo extends core::Object {
|
||||
synthetic constructor •() → self::Foo
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
inline class FooBar /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBar|;
|
||||
tearoff • = self::FooBar|_#new#tearOff;
|
||||
}
|
||||
inline class FooBaz /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBaz|;
|
||||
tearoff • = self::FooBaz|_#new#tearOff;
|
||||
}
|
||||
static inline-class-member method FooBar|(core::int i) → self::FooBar {
|
||||
lowered final self::FooBar #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
|
||||
return self::FooBar|(i);
|
||||
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
|
||||
lowered final self::FooBaz #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
|
||||
return self::FooBaz|(i);
|
||||
static method main() → void {
|
||||
final self::FooBar a = self::FooBar|(0);
|
||||
#L1:
|
||||
{
|
||||
final synthesized self::FooBar #0#0 = a;
|
||||
{
|
||||
final hoisted core::int a;
|
||||
if(let final core::int #t1 = a = #0#0 as{Unchecked} core::int in true) {
|
||||
{
|
||||
core::print("FooBar ${a}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated: FactoryConstructorInvocation @ org-dartlang-testcase:///issue52667.dart:20:13 -> IntConstant(0)
|
||||
Extra constant evaluation: evaluated: 17, effectively constant: 1
|
|
@ -0,0 +1,13 @@
|
|||
abstract class Foo {}
|
||||
|
||||
inline class FooBar implements Foo {
|
||||
final int i;
|
||||
const FooBar(this.i);
|
||||
}
|
||||
|
||||
inline class FooBaz implements Foo {
|
||||
final int i;
|
||||
const FooBaz(this.i);
|
||||
}
|
||||
|
||||
void main() {}
|
|
@ -0,0 +1,13 @@
|
|||
abstract class Foo {}
|
||||
|
||||
inline class FooBar implements Foo {
|
||||
const FooBar(this.i);
|
||||
final int i;
|
||||
}
|
||||
|
||||
inline class FooBaz implements Foo {
|
||||
const FooBaz(this.i);
|
||||
final int i;
|
||||
}
|
||||
|
||||
void main() {}
|
|
@ -0,0 +1,44 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class Foo extends core::Object {
|
||||
synthetic constructor •() → self::Foo
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
inline class FooBar /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBar|;
|
||||
tearoff • = self::FooBar|_#new#tearOff;
|
||||
}
|
||||
inline class FooBaz /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBaz|;
|
||||
tearoff • = self::FooBaz|_#new#tearOff;
|
||||
}
|
||||
static inline-class-member method FooBar|(core::int i) → self::FooBar {
|
||||
lowered final self::FooBar #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
|
||||
return self::FooBar|(i);
|
||||
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
|
||||
lowered final self::FooBaz #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
|
||||
return self::FooBaz|(i);
|
||||
static method main() → void {
|
||||
final self::FooBar a = self::FooBar|(0);
|
||||
#L1:
|
||||
{
|
||||
final synthesized self::FooBar #0#0 = a;
|
||||
{
|
||||
final hoisted core::int a;
|
||||
if(let final dynamic #t1 = a = #0#0 as{Unchecked} core::int in true) {
|
||||
{
|
||||
core::print("FooBar ${a}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class Foo extends core::Object {
|
||||
synthetic constructor •() → self::Foo
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
inline class FooBar /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBar|;
|
||||
tearoff • = self::FooBar|_#new#tearOff;
|
||||
}
|
||||
inline class FooBaz /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBaz|;
|
||||
tearoff • = self::FooBaz|_#new#tearOff;
|
||||
}
|
||||
static inline-class-member method FooBar|(core::int i) → self::FooBar {
|
||||
lowered final self::FooBar #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
|
||||
return self::FooBar|(i);
|
||||
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
|
||||
lowered final self::FooBaz #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
|
||||
return self::FooBaz|(i);
|
||||
static method main() → void {
|
||||
final self::FooBar a = self::FooBar|(0);
|
||||
#L1:
|
||||
{
|
||||
final synthesized self::FooBar #0#0 = a;
|
||||
{
|
||||
final hoisted core::int a;
|
||||
if(let final dynamic #t1 = a = #0#0 as{Unchecked} core::int in true) {
|
||||
{
|
||||
core::print("FooBar ${a}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class Foo extends core::Object {
|
||||
synthetic constructor •() → self::Foo
|
||||
;
|
||||
}
|
||||
inline class FooBar /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBar|;
|
||||
tearoff • = self::FooBar|_#new#tearOff;
|
||||
}
|
||||
inline class FooBaz /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBaz|;
|
||||
tearoff • = self::FooBaz|_#new#tearOff;
|
||||
}
|
||||
static inline-class-member method FooBar|(core::int i) → self::FooBar
|
||||
;
|
||||
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
|
||||
return self::FooBar|(i);
|
||||
static inline-class-member method FooBaz|(core::int i) → self::FooBaz
|
||||
;
|
||||
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
|
||||
return self::FooBaz|(i);
|
||||
static method main() → void
|
||||
;
|
|
@ -0,0 +1,49 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
abstract class Foo extends core::Object {
|
||||
synthetic constructor •() → self::Foo
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
inline class FooBar /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBar|;
|
||||
tearoff • = self::FooBar|_#new#tearOff;
|
||||
}
|
||||
inline class FooBaz /* declaredRepresentationType = core::int */ {
|
||||
constructor • = self::FooBaz|;
|
||||
tearoff • = self::FooBaz|_#new#tearOff;
|
||||
}
|
||||
static inline-class-member method FooBar|(core::int i) → self::FooBar {
|
||||
lowered final self::FooBar #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBar|_#new#tearOff(core::int i) → self::FooBar
|
||||
return self::FooBar|(i);
|
||||
static inline-class-member method FooBaz|(core::int i) → self::FooBaz {
|
||||
lowered final self::FooBaz #this = i;
|
||||
return #this;
|
||||
}
|
||||
static inline-class-member method FooBaz|_#new#tearOff(core::int i) → self::FooBaz
|
||||
return self::FooBaz|(i);
|
||||
static method main() → void {
|
||||
final self::FooBar a = self::FooBar|(0);
|
||||
#L1:
|
||||
{
|
||||
final synthesized self::FooBar #0#0 = a;
|
||||
{
|
||||
final hoisted core::int a;
|
||||
if(let final core::int #t1 = a = #0#0 as{Unchecked} core::int in true) {
|
||||
{
|
||||
core::print("FooBar ${a}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated: FactoryConstructorInvocation @ org-dartlang-testcase:///issue52667.dart:20:13 -> IntConstant(0)
|
||||
Extra constant evaluation: evaluated: 17, effectively constant: 1
|
|
@ -1604,6 +1604,9 @@ enum ObjectAccessKind {
|
|||
|
||||
/// Erroneous property access.
|
||||
Error,
|
||||
|
||||
/// Access of an inline class representation field.
|
||||
Direct,
|
||||
}
|
||||
|
||||
/// A [Pattern] with an optional guard [Expression].
|
||||
|
|
Loading…
Reference in a new issue