]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add type check on if-expr
authorBenjamin Thos <benjamin.thos@epita.fr>
Mon, 16 Dec 2024 13:11:38 +0000 (14:11 +0100)
committerCohenArthur <arthur.cohen@embecosm.com>
Mon, 17 Feb 2025 09:40:03 +0000 (09:40 +0000)
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.thos@epita.fr>
gcc/rust/typecheck/rust-hir-type-check-expr.cc
gcc/testsuite/rust/compile/if-without-else.rs [new file with mode: 0644]
gcc/testsuite/rust/compile/implicit_returns_err3.rs
gcc/testsuite/rust/compile/torture/if.rs

index 99edcc3ec67e2eb331205973eac04665d4833e99..8d000113c082aa31c72227626e5723f3680ffaae 100644 (file)
@@ -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 (file)
index 0000000..1a0f644
--- /dev/null
@@ -0,0 +1,9 @@
+fn foo(pred: bool) -> u8 {
+    if pred { // { dg-error "mismatched types" }
+        1
+    }
+    3
+}
+
+fn main(){
+}
index ac9821377989581209c05ce67bbf43fecd5d0ad2..f0330aca9c09e53f6197160583825635fd4774aa 100644 (file)
@@ -1,6 +1,6 @@
 fn test(x: i32) -> i32 { // { dg-error "mismatched types, expected .i32. but got ...." }
     if x > 1 {
-        1
+        return 1;
     }
 }
 
index bcd520f66a93ac2c0c697792cbc3437137e0ffc2..3b753a71eb2f025a455538b83dbda2ca7eef41c2 100644 (file)
@@ -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
+}