diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart index 3cef3365212f..a896978ace2d 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart @@ -9392,7 +9392,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase parent is RelationalPattern && parent.expression == node; ExpressionInferenceResult expressionResult = - inferExpression(node, context).stopShorting(); + // TODO(johnniwinther): Handle [isVoidAllowed] through + // [dispatchExpression]. + inferExpression(node, context, isVoidAllowed: true).stopShorting(); if (needsCoercion) { expressionResult = diff --git a/pkg/front_end/testcases/patterns/issue52191.dart b/pkg/front_end/testcases/patterns/issue52191.dart new file mode 100644 index 000000000000..9dbf9a944310 --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart @@ -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. + +void printBugsSwitch(int n) => switch (n) { + 0 => print('no bugs'), + 1 => print('one bug'), + _ => print('$n bugs'), + }; + +void printBugsConditional(int n) => n == 0 + ? print('no bugs') + : n == 1 + ? print('one bug') + : print('$n bugs'); + +main() { + printBugsSwitch(0); + printBugsSwitch(1); + printBugsSwitch(2); + + printBugsConditional(0); + printBugsConditional(1); + printBugsConditional(2); +} diff --git a/pkg/front_end/testcases/patterns/issue52191.dart.strong.expect b/pkg/front_end/testcases/patterns/issue52191.dart.strong.expect new file mode 100644 index 000000000000..db6559d0810a --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart.strong.expect @@ -0,0 +1,45 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method printBugsSwitch(core::int n) → void + return block { + void #t1; + final synthesized core::int #0#0 = n; + #L1: + { + { + if(#C1 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("no bugs"); + break #L1; + } + } + { + if(#C2 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("one bug"); + break #L1; + } + } + { + if(true) { + #t1 = core::print("${n} bugs"); + break #L1; + } + } + } + } =>#t1; +static method printBugsConditional(core::int n) → void + return n =={core::num::==}{(core::Object) → core::bool} 0 ?{void} core::print("no bugs") : n =={core::num::==}{(core::Object) → core::bool} 1 ?{void} core::print("one bug") : core::print("${n} bugs"); +static method main() → dynamic { + self::printBugsSwitch(0); + self::printBugsSwitch(1); + self::printBugsSwitch(2); + self::printBugsConditional(0); + self::printBugsConditional(1); + self::printBugsConditional(2); +} + +constants { + #C1 = 0 + #C2 = 1 +} diff --git a/pkg/front_end/testcases/patterns/issue52191.dart.strong.transformed.expect b/pkg/front_end/testcases/patterns/issue52191.dart.strong.transformed.expect new file mode 100644 index 000000000000..db6559d0810a --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart.strong.transformed.expect @@ -0,0 +1,45 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method printBugsSwitch(core::int n) → void + return block { + void #t1; + final synthesized core::int #0#0 = n; + #L1: + { + { + if(#C1 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("no bugs"); + break #L1; + } + } + { + if(#C2 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("one bug"); + break #L1; + } + } + { + if(true) { + #t1 = core::print("${n} bugs"); + break #L1; + } + } + } + } =>#t1; +static method printBugsConditional(core::int n) → void + return n =={core::num::==}{(core::Object) → core::bool} 0 ?{void} core::print("no bugs") : n =={core::num::==}{(core::Object) → core::bool} 1 ?{void} core::print("one bug") : core::print("${n} bugs"); +static method main() → dynamic { + self::printBugsSwitch(0); + self::printBugsSwitch(1); + self::printBugsSwitch(2); + self::printBugsConditional(0); + self::printBugsConditional(1); + self::printBugsConditional(2); +} + +constants { + #C1 = 0 + #C2 = 1 +} diff --git a/pkg/front_end/testcases/patterns/issue52191.dart.textual_outline.expect b/pkg/front_end/testcases/patterns/issue52191.dart.textual_outline.expect new file mode 100644 index 000000000000..5ab38e9a35a5 --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart.textual_outline.expect @@ -0,0 +1,7 @@ +void printBugsSwitch(int n) => switch (n) {}; +void printBugsConditional(int n) => n == 0 + ? print('no bugs') + : n == 1 + ? print('one bug') + : print('$n bugs'); +main() {} diff --git a/pkg/front_end/testcases/patterns/issue52191.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/patterns/issue52191.dart.textual_outline_modelled.expect new file mode 100644 index 000000000000..47dfd7cdb313 --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart.textual_outline_modelled.expect @@ -0,0 +1,7 @@ +switch (n) {} +void printBugsSwitch(int n) => +---- unknown chunk starts ---- +; +---- unknown chunk ends ---- +main() {} +void printBugsConditional(int n) => n == 0 ? print('no bugs') : n == 1 ? print('one bug') : print('$n bugs'); diff --git a/pkg/front_end/testcases/patterns/issue52191.dart.weak.expect b/pkg/front_end/testcases/patterns/issue52191.dart.weak.expect new file mode 100644 index 000000000000..e26e4e8d82e7 --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart.weak.expect @@ -0,0 +1,47 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:_internal" as _in; + +static method printBugsSwitch(core::int n) → void + return block { + void #t1; + final synthesized core::int #0#0 = n; + #L1: + { + { + if(#C1 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("no bugs"); + break #L1; + } + } + { + if(#C2 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("one bug"); + break #L1; + } + } + { + if(true) { + #t1 = core::print("${n} bugs"); + break #L1; + } + } + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable type."); + } + } =>#t1; +static method printBugsConditional(core::int n) → void + return n =={core::num::==}{(core::Object) → core::bool} 0 ?{void} core::print("no bugs") : n =={core::num::==}{(core::Object) → core::bool} 1 ?{void} core::print("one bug") : core::print("${n} bugs"); +static method main() → dynamic { + self::printBugsSwitch(0); + self::printBugsSwitch(1); + self::printBugsSwitch(2); + self::printBugsConditional(0); + self::printBugsConditional(1); + self::printBugsConditional(2); +} + +constants { + #C1 = 0 + #C2 = 1 +} diff --git a/pkg/front_end/testcases/patterns/issue52191.dart.weak.modular.expect b/pkg/front_end/testcases/patterns/issue52191.dart.weak.modular.expect new file mode 100644 index 000000000000..e26e4e8d82e7 --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart.weak.modular.expect @@ -0,0 +1,47 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:_internal" as _in; + +static method printBugsSwitch(core::int n) → void + return block { + void #t1; + final synthesized core::int #0#0 = n; + #L1: + { + { + if(#C1 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("no bugs"); + break #L1; + } + } + { + if(#C2 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("one bug"); + break #L1; + } + } + { + if(true) { + #t1 = core::print("${n} bugs"); + break #L1; + } + } + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable type."); + } + } =>#t1; +static method printBugsConditional(core::int n) → void + return n =={core::num::==}{(core::Object) → core::bool} 0 ?{void} core::print("no bugs") : n =={core::num::==}{(core::Object) → core::bool} 1 ?{void} core::print("one bug") : core::print("${n} bugs"); +static method main() → dynamic { + self::printBugsSwitch(0); + self::printBugsSwitch(1); + self::printBugsSwitch(2); + self::printBugsConditional(0); + self::printBugsConditional(1); + self::printBugsConditional(2); +} + +constants { + #C1 = 0 + #C2 = 1 +} diff --git a/pkg/front_end/testcases/patterns/issue52191.dart.weak.outline.expect b/pkg/front_end/testcases/patterns/issue52191.dart.weak.outline.expect new file mode 100644 index 000000000000..e00ba2c060a5 --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart.weak.outline.expect @@ -0,0 +1,10 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +static method printBugsSwitch(core::int n) → void + ; +static method printBugsConditional(core::int n) → void + ; +static method main() → dynamic + ; diff --git a/pkg/front_end/testcases/patterns/issue52191.dart.weak.transformed.expect b/pkg/front_end/testcases/patterns/issue52191.dart.weak.transformed.expect new file mode 100644 index 000000000000..e26e4e8d82e7 --- /dev/null +++ b/pkg/front_end/testcases/patterns/issue52191.dart.weak.transformed.expect @@ -0,0 +1,47 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; +import "dart:_internal" as _in; + +static method printBugsSwitch(core::int n) → void + return block { + void #t1; + final synthesized core::int #0#0 = n; + #L1: + { + { + if(#C1 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("no bugs"); + break #L1; + } + } + { + if(#C2 =={core::num::==}{(core::Object) → core::bool} #0#0) { + #t1 = core::print("one bug"); + break #L1; + } + } + { + if(true) { + #t1 = core::print("${n} bugs"); + break #L1; + } + } + throw new _in::ReachabilityError::•("`null` encountered as case in a switch expression with a non-nullable type."); + } + } =>#t1; +static method printBugsConditional(core::int n) → void + return n =={core::num::==}{(core::Object) → core::bool} 0 ?{void} core::print("no bugs") : n =={core::num::==}{(core::Object) → core::bool} 1 ?{void} core::print("one bug") : core::print("${n} bugs"); +static method main() → dynamic { + self::printBugsSwitch(0); + self::printBugsSwitch(1); + self::printBugsSwitch(2); + self::printBugsConditional(0); + self::printBugsConditional(1); + self::printBugsConditional(2); +} + +constants { + #C1 = 0 + #C2 = 1 +}