diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-05-25 11:21:26 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-25 11:21:26 +0000 |
commit | 79d977e759b073a0a4d422b9a1032427ddc05295 (patch) | |
tree | 5241cceab618ab0bb6bfc00d344980f1aa87cf57 /gcc | |
parent | d09b135116f2bd56fbab054a9a0122cc6b59e06e (diff) | |
parent | ec9a03a03b512e268dd31571df18e2c37e1ee372 (diff) | |
download | gcc-79d977e759b073a0a4d422b9a1032427ddc05295.zip gcc-79d977e759b073a0a4d422b9a1032427ddc05295.tar.gz gcc-79d977e759b073a0a4d422b9a1032427ddc05295.tar.bz2 |
Merge #1279
1279: Implement type checking for the `IfLet` expression. r=philberty a=antego
Addresses #1177.
This change implements the type check for the `IfLet` expression. This is the adapted type checking code from the `MatchExpr`.
Tested on this code
```
enum E {
X(u8),
}
fn main() -> i32 {
let mut res = 0;
let v = E::X(4);
if let E::X(n) = v {
res = n;
}
0
}
```
Compilation finishes without errors.
Next is the implementation of the code generation but I'll need help to find where it's located.
Co-authored-by: antego <antego@users.noreply.github.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 13 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 23 |
2 files changed, 36 insertions, 0 deletions
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index f6f035e..789ad78 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -3477,6 +3477,19 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; + std::unique_ptr<Expr> &get_scrutinee_expr () + { + rust_assert (value != nullptr); + return value; + } + + std::vector<std::unique_ptr<Pattern> > &get_patterns () + { + return match_arm_patterns; + } + + BlockExpr *get_if_block () { return if_block.get (); } + ExprType get_expression_type () const final override { return ExprType::IfLet; diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index b20a048..411d45d 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -703,6 +703,29 @@ public: infered = if_blk_resolved->unify (else_blk_resolved); } + void visit (HIR::IfLetExpr &expr) override + { + // this needs to perform a least upper bound coercion on the blocks and then + // unify the scruintee and arms + TyTy::BaseType *scrutinee_tyty + = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ().get (), false); + + for (auto &pattern : expr.get_patterns ()) + { + TyTy::BaseType *kase_arm_ty + = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty); + + TyTy::BaseType *checked_kase = scrutinee_tyty->unify (kase_arm_ty); + if (checked_kase->get_kind () == TyTy::TypeKind::ERROR) + return; + } + + TypeCheckExpr::Resolve (expr.get_if_block (), inside_loop); + + infered + = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ()); + } + void visit (HIR::BlockExpr &expr) override; void visit (HIR::UnsafeBlockExpr &expr) override |