From: Benjamin Thos <[email protected]>
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 <[email protected]>
---
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