From: Benjamin Thos <benjamin.t...@epita.fr>

Check if an if-expr returns void type or a coercible type like an early return.

gcc/rust/ChangeLog:

        * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
        Add check on if-expr.

gcc/testsuite/ChangeLog:

        * rust/compile/implicit_returns_err3.rs: Change test to be valid.
        * rust/compile/torture/if.rs: Likewise.
        * rust/compile/if-without-else.rs: New test.

Signed-off-by: Benjamin Thos <benjamin.t...@epita.fr>
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc      | 13 +++++++++++--
 gcc/testsuite/rust/compile/if-without-else.rs       |  9 +++++++++
 gcc/testsuite/rust/compile/implicit_returns_err3.rs |  2 +-
 gcc/testsuite/rust/compile/torture/if.rs            |  8 ++++++--
 4 files changed, 27 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/if-without-else.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 85d717535ed..4e57d6a8ffb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -526,9 +526,18 @@ TypeCheckExpr::visit (HIR::IfExpr &expr)
                                    expr.get_if_condition ().get_locus ()),
              expr.get_locus ());
 
-  TypeCheckExpr::Resolve (expr.get_if_block ());
+  TyTy::BaseType *block_type = TypeCheckExpr::Resolve (expr.get_if_block ());
 
-  infered = TyTy::TupleType::get_unit_type ();
+  TyTy::BaseType *unit_ty = nullptr;
+  ok = context->lookup_builtin ("()", &unit_ty);
+  rust_assert (ok);
+
+  infered
+    = coercion_site (expr.get_mappings ().get_hirid (),
+                    TyTy::TyWithLocation (unit_ty),
+                    TyTy::TyWithLocation (block_type,
+                                          expr.get_if_block ().get_locus ()),
+                    expr.get_locus ());
 }
 
 void
diff --git a/gcc/testsuite/rust/compile/if-without-else.rs 
b/gcc/testsuite/rust/compile/if-without-else.rs
new file mode 100644
index 00000000000..1a0f6449d70
--- /dev/null
+++ b/gcc/testsuite/rust/compile/if-without-else.rs
@@ -0,0 +1,9 @@
+fn foo(pred: bool) -> u8 {
+    if pred { // { dg-error "mismatched types" }
+        1
+    }
+    3
+}
+
+fn main(){
+}
diff --git a/gcc/testsuite/rust/compile/implicit_returns_err3.rs 
b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
index ac982137798..f0330aca9c0 100644
--- a/gcc/testsuite/rust/compile/implicit_returns_err3.rs
+++ b/gcc/testsuite/rust/compile/implicit_returns_err3.rs
@@ -1,6 +1,6 @@
 fn test(x: i32) -> i32 { // { dg-error "mismatched types, expected .i32. but 
got ...." }
     if x > 1 {
-        1
+        return 1;
     }
 }
 
diff --git a/gcc/testsuite/rust/compile/torture/if.rs 
b/gcc/testsuite/rust/compile/torture/if.rs
index bcd520f66a9..3b753a71eb2 100644
--- a/gcc/testsuite/rust/compile/torture/if.rs
+++ b/gcc/testsuite/rust/compile/torture/if.rs
@@ -4,6 +4,10 @@ fn foo() -> bool {
 
 fn bar() {}
 
+fn baz(a: i32) {
+    a;
+}
+
 struct Foo1 {
     one: i32
 }
@@ -13,7 +17,7 @@ fn main() {
     if foo() {
         bar();
         let a = Foo1{one: 1};
-        a.one
+        baz (a.one);
     }
 
-}
\ No newline at end of file
+}
-- 
2.45.2

Reply via email to