forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[cfe] Implement new rules around types of case expressions
Bug: http://dartbug.com/40425 Change-Id: I1f6e93bde663ab6f1a6a63e91aef4133af6e5253 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136186 Commit-Queue: Dmitry Stefantsov <dmitryas@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
- Loading branch information
Dmitry Stefantsov
authored and
commit-bot@chromium.org
committed
Feb 19, 2020
1 parent
17d8b6b
commit 0f141be
Showing
11 changed files
with
460 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Copyright (c) 2020, 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. | ||
|
||
// The test checks the constraints for types of the case expressions. The rules | ||
// can be found at the following link: | ||
// https://github.com/dart-lang/language/blob/master/accepted/future-releases/nnbd/feature-specification.md#errors-and-warnings | ||
|
||
class A { | ||
final int foo; | ||
const A(this.foo); | ||
} | ||
|
||
class B extends A { | ||
const B(int foo) : super(foo); | ||
} | ||
|
||
class C extends B { | ||
const C(int foo) : super(foo); | ||
} | ||
|
||
class D extends B { | ||
const D(int foo) : super(foo); | ||
|
||
bool operator ==(dynamic other) => identical(this, other); | ||
} | ||
|
||
bar(B b) { | ||
switch (b) { | ||
case const B(42): | ||
break; | ||
case const C(42): | ||
break; | ||
case const A(42): // Error: not a subtype of B. | ||
break; | ||
case const D(42): // Error: D has custom operator ==. | ||
break; | ||
default: | ||
} | ||
} | ||
|
||
main() {} |
31 changes: 31 additions & 0 deletions
31
pkg/front_end/testcases/nnbd/switch_redesign_types.dart.outline.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
library /*isNonNullableByDefault*/; | ||
import self as self; | ||
import "dart:core" as core; | ||
|
||
class A extends core::Object /*hasConstConstructor*/ { | ||
final field core::int foo; | ||
const constructor •(core::int foo) → self::A | ||
: self::A::foo = foo, super core::Object::•() | ||
; | ||
} | ||
class B extends self::A /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::B | ||
: super self::A::•(foo) | ||
; | ||
} | ||
class C extends self::B /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::C | ||
: super self::B::•(foo) | ||
; | ||
} | ||
class D extends self::B /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::D | ||
: super self::B::•(foo) | ||
; | ||
operator ==(dynamic other) → core::bool | ||
; | ||
} | ||
static method bar(self::B b) → dynamic | ||
; | ||
static method main() → dynamic | ||
; |
76 changes: 76 additions & 0 deletions
76
pkg/front_end/testcases/nnbd/switch_redesign_types.dart.strong.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
library /*isNonNullableByDefault*/; | ||
// | ||
// Problems in library: | ||
// | ||
// pkg/front_end/testcases/nnbd/switch_redesign_types.dart:34:16: Error: Type 'A' of the case expression is not a subtype of type 'B' of this switch expression. | ||
// - 'A' is from 'pkg/front_end/testcases/nnbd/switch_redesign_types.dart'. | ||
// - 'B' is from 'pkg/front_end/testcases/nnbd/switch_redesign_types.dart'. | ||
// case const A(42): // Error: not a subtype of B. | ||
// ^ | ||
// pkg/front_end/testcases/nnbd/switch_redesign_types.dart:29:11: Context: The switch expression is here. | ||
// switch (b) { | ||
// ^ | ||
// | ||
import self as self; | ||
import "dart:core" as core; | ||
|
||
class A extends core::Object /*hasConstConstructor*/ { | ||
final field core::int foo; | ||
const constructor •(core::int foo) → self::A | ||
: self::A::foo = foo, super core::Object::•() | ||
; | ||
} | ||
class B extends self::A /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::B | ||
: super self::A::•(foo) | ||
; | ||
} | ||
class C extends self::B /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::C | ||
: super self::B::•(foo) | ||
; | ||
} | ||
class D extends self::B /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::D | ||
: super self::B::•(foo) | ||
; | ||
operator ==(dynamic other) → core::bool | ||
return core::identical(this, other); | ||
} | ||
static method bar(self::B b) → dynamic { | ||
#L1: | ||
switch(b) { | ||
#L2: | ||
case #C2: | ||
{ | ||
break #L1; | ||
} | ||
#L3: | ||
case #C3: | ||
{ | ||
break #L1; | ||
} | ||
#L4: | ||
case #C4: | ||
{ | ||
break #L1; | ||
} | ||
#L5: | ||
case #C5: | ||
{ | ||
break #L1; | ||
} | ||
#L6: | ||
default: | ||
{} | ||
} | ||
} | ||
static method main() → dynamic {} | ||
|
||
constants { | ||
#C1 = 42 | ||
#C2 = self::B {foo:#C1} | ||
#C3 = self::C {foo:#C1} | ||
#C4 = self::A {foo:#C1} | ||
#C5 = self::D {foo:#C1} | ||
} |
76 changes: 76 additions & 0 deletions
76
pkg/front_end/testcases/nnbd/switch_redesign_types.dart.strong.transformed.expect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
library /*isNonNullableByDefault*/; | ||
// | ||
// Problems in library: | ||
// | ||
// pkg/front_end/testcases/nnbd/switch_redesign_types.dart:34:16: Error: Type 'A' of the case expression is not a subtype of type 'B' of this switch expression. | ||
// - 'A' is from 'pkg/front_end/testcases/nnbd/switch_redesign_types.dart'. | ||
// - 'B' is from 'pkg/front_end/testcases/nnbd/switch_redesign_types.dart'. | ||
// case const A(42): // Error: not a subtype of B. | ||
// ^ | ||
// pkg/front_end/testcases/nnbd/switch_redesign_types.dart:29:11: Context: The switch expression is here. | ||
// switch (b) { | ||
// ^ | ||
// | ||
import self as self; | ||
import "dart:core" as core; | ||
|
||
class A extends core::Object /*hasConstConstructor*/ { | ||
final field core::int foo; | ||
const constructor •(core::int foo) → self::A | ||
: self::A::foo = foo, super core::Object::•() | ||
; | ||
} | ||
class B extends self::A /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::B | ||
: super self::A::•(foo) | ||
; | ||
} | ||
class C extends self::B /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::C | ||
: super self::B::•(foo) | ||
; | ||
} | ||
class D extends self::B /*hasConstConstructor*/ { | ||
const constructor •(core::int foo) → self::D | ||
: super self::B::•(foo) | ||
; | ||
operator ==(dynamic other) → core::bool | ||
return core::identical(this, other); | ||
} | ||
static method bar(self::B b) → dynamic { | ||
#L1: | ||
switch(b) { | ||
#L2: | ||
case #C2: | ||
{ | ||
break #L1; | ||
} | ||
#L3: | ||
case #C3: | ||
{ | ||
break #L1; | ||
} | ||
#L4: | ||
case #C4: | ||
{ | ||
break #L1; | ||
} | ||
#L5: | ||
case #C5: | ||
{ | ||
break #L1; | ||
} | ||
#L6: | ||
default: | ||
{} | ||
} | ||
} | ||
static method main() → dynamic {} | ||
|
||
constants { | ||
#C1 = 42 | ||
#C2 = self::B {foo:#C1} | ||
#C3 = self::C {foo:#C1} | ||
#C4 = self::A {foo:#C1} | ||
#C5 = self::D {foo:#C1} | ||
} |
Oops, something went wrong.