summaryrefslogtreecommitdiffstats
path: root/src/test/ui/never_type/diverging-fallback-control-flow.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/never_type/diverging-fallback-control-flow.rs')
-rw-r--r--src/test/ui/never_type/diverging-fallback-control-flow.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/test/ui/never_type/diverging-fallback-control-flow.rs b/src/test/ui/never_type/diverging-fallback-control-flow.rs
new file mode 100644
index 000000000..45a3362fa
--- /dev/null
+++ b/src/test/ui/never_type/diverging-fallback-control-flow.rs
@@ -0,0 +1,100 @@
+// revisions: nofallback fallback
+// run-pass
+
+#![allow(dead_code)]
+#![allow(unused_assignments)]
+#![allow(unused_variables)]
+#![allow(unreachable_code)]
+// Test various cases where we permit an unconstrained variable
+// to fallback based on control-flow. In all of these cases,
+// the type variable winds up being the target of both a `!` coercion
+// and a coercion from a non-`!` variable, and hence falls back to `()`.
+#![cfg_attr(fallback, feature(never_type, never_type_fallback))]
+
+trait UnitDefault {
+ fn default() -> Self;
+}
+
+impl UnitDefault for u32 {
+ fn default() -> Self {
+ 0
+ }
+}
+
+impl UnitDefault for () {
+ fn default() -> () {
+ panic!()
+ }
+}
+
+fn assignment() {
+ let x;
+
+ if true {
+ x = UnitDefault::default();
+ } else {
+ x = return;
+ }
+}
+
+fn assignment_rev() {
+ let x;
+
+ if true {
+ x = return;
+ } else {
+ x = UnitDefault::default();
+ }
+}
+
+fn if_then_else() {
+ let _x = if true {
+ UnitDefault::default()
+ } else {
+ return;
+ };
+}
+
+fn if_then_else_rev() {
+ let _x = if true {
+ return;
+ } else {
+ UnitDefault::default()
+ };
+}
+
+fn match_arm() {
+ let _x = match Ok(UnitDefault::default()) {
+ Ok(v) => v,
+ Err(()) => return,
+ };
+}
+
+fn match_arm_rev() {
+ let _x = match Ok(UnitDefault::default()) {
+ Err(()) => return,
+ Ok(v) => v,
+ };
+}
+
+fn loop_break() {
+ let _x = loop {
+ if false {
+ break return;
+ } else {
+ break UnitDefault::default();
+ }
+ };
+}
+
+fn loop_break_rev() {
+ let _x = loop {
+ if false {
+ break return;
+ } else {
+ break UnitDefault::default();
+ }
+ };
+}
+
+fn main() {}