diff options
author | Owen Avery <powerboat9.gamer@gmail.com> | 2023-03-18 01:41:01 -0400 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-01-16 18:34:08 +0100 |
commit | 197962cb062edb41538af9f5e9b4c02f090c4ba8 (patch) | |
tree | 536c925e94418bf49faf12e7518d2acd0f7048f5 /gcc | |
parent | 694063d84e47f57c99d4558e789932c31a7bf6dd (diff) | |
download | gcc-197962cb062edb41538af9f5e9b4c02f090c4ba8.zip gcc-197962cb062edb41538af9f5e9b4c02f090c4ba8.tar.gz gcc-197962cb062edb41538af9f5e9b4c02f090c4ba8.tar.bz2 |
gccrs: Add lowering for if-let expressions
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-expr.cc
(TypeCheckExpr::visit): Add implementation for IfLetExprConseqElse.
* typecheck/rust-hir-type-check-expr.h:
(TypeCheckExpr::visit): Remove stub implementation for IfLetExprConseqElse.
* hir/rust-ast-lower-expr.cc
(ASTLoweringExpr::visit): Lower IfLetExpr{,ConseqElse}.
* hir/rust-ast-lower-expr.h:
(ASTLoweringExpr::visit): Likewise.
* hir/rust-ast-lower-block.h
(ASTLoweringIfLetBlock::visit): Lower IfLetExprConseqElse.
(ASTLoweringExprWithBlock::visit): Likewise.
* hir/rust-ast-lower.cc
(ASTLoweringIfLetBlock::visit): Lower IfLetExprConseqElse.
* hir/tree/rust-hir-expr.h
(IfLetExprConseqElse::IfLetExprConseqElse): Make constructor more general.
(IfLetExprConseqElse::vis_else_block): Add.
(IfLetExprConseqElse::get_else_block): Add.
* resolve/rust-ast-resolve-expr.cc
(ResolveExpr::visit): Add IfLetExprConseqElse visitor.
* resolve/rust-ast-resolve-expr.h
(ResolveExpr::visit): Add IfLetExprConseqElse visitor.
gcc/testsuite/ChangeLog:
* rust/compile/if_let_expr.rs: Increase test coverage.
Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-block.h | 7 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.cc | 12 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.cc | 34 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 6 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.cc | 31 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.h | 1 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.cc | 36 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/if_let_expr.rs | 4 |
10 files changed, 130 insertions, 5 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h index a12fd87..a4d6069 100644 --- a/gcc/rust/hir/rust-ast-lower-block.h +++ b/gcc/rust/hir/rust-ast-lower-block.h @@ -130,6 +130,8 @@ public: void visit (AST::IfLetExpr &expr) override; + void visit (AST::IfLetExprConseqElse &expr) override; + private: ASTLoweringIfLetBlock () : ASTLoweringBase (), translated (nullptr) {} @@ -172,6 +174,11 @@ public: translated = ASTLoweringIfLetBlock::translate (&expr); } + void visit (AST::IfLetExprConseqElse &expr) override + { + translated = ASTLoweringIfLetBlock::translate (&expr); + } + void visit (AST::BlockExpr &expr) override { translated = ASTLoweringBlock::translate (&expr, &terminated); diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index c65b08e..31b7f0f 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -104,6 +104,18 @@ ASTLoweringExpr::visit (AST::IfExprConseqElse &expr) } void +ASTLoweringExpr::visit (AST::IfLetExpr &expr) +{ + translated = ASTLoweringIfLetBlock::translate (&expr); +} + +void +ASTLoweringExpr::visit (AST::IfLetExprConseqElse &expr) +{ + translated = ASTLoweringIfLetBlock::translate (&expr); +} + +void ASTLoweringExpr::visit (AST::BlockExpr &expr) { translated = ASTLoweringBlock::translate (&expr, &terminated); diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index d3e9532414..5b86ea2 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -78,6 +78,8 @@ public: void visit (AST::TupleExpr &expr) override; void visit (AST::IfExpr &expr) override; void visit (AST::IfExprConseqElse &expr) override; + void visit (AST::IfLetExpr &expr) override; + void visit (AST::IfLetExprConseqElse &expr) override; void visit (AST::BlockExpr &expr) override; void visit (AST::UnsafeBlockExpr &expr) override; void visit (AST::PathInExpression &expr) override; diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index c9d5d01..cf5b75a 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -227,6 +227,40 @@ ASTLoweringIfLetBlock::visit (AST::IfLetExpr &expr) expr.get_locus ()); } +void +ASTLoweringIfLetBlock::visit (AST::IfLetExprConseqElse &expr) +{ + std::vector<std::unique_ptr<HIR::Pattern>> patterns; + for (auto &pattern : expr.get_patterns ()) + { + HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ()); + patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn)); + } + HIR::Expr *value_ptr + = ASTLoweringExpr::translate (expr.get_value_expr ().get ()); + + bool ignored_terminated = false; + HIR::BlockExpr *block + = ASTLoweringBlock::translate (expr.get_if_block ().get (), + &ignored_terminated); + + HIR::ExprWithBlock *else_block + = ASTLoweringExprWithBlock::translate (expr.get_else_block ().get (), + &ignored_terminated); + + rust_assert (else_block); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated = new HIR::IfLetExprConseqElse ( + mapping, std::move (patterns), std::unique_ptr<HIR::Expr> (value_ptr), + std::unique_ptr<HIR::BlockExpr> (block), + std::unique_ptr<HIR::ExprWithBlock> (else_block), expr.get_locus ()); +} + // rust-ast-lower-struct-field-expr.h void diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index 3c9db9f..47b9897 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -3457,7 +3457,7 @@ public: Analysis::NodeMapping mappings, std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block, - std::unique_ptr<BlockExpr> else_block, Location locus) + std::unique_ptr<ExprWithBlock> else_block, Location locus) : IfLetExpr (std::move (mappings), std::move (match_arm_patterns), std::move (value), std::move (if_block), locus), else_block (std::move (else_block)) @@ -3489,6 +3489,10 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; + void vis_else_block (HIRFullVisitor &vis) { else_block->accept_vis (vis); } + + ExprWithBlock *get_else_block () { return else_block.get (); } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc index 339fd8a..41ce9c9 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc @@ -217,6 +217,37 @@ ResolveExpr::visit (AST::IfLetExpr &expr) } void +ResolveExpr::visit (AST::IfLetExprConseqElse &expr) +{ + ResolveExpr::go (expr.get_value_expr ().get (), prefix, canonical_prefix); + + NodeId scope_node_id = expr.get_node_id (); + resolver->get_name_scope ().push (scope_node_id); + resolver->get_type_scope ().push (scope_node_id); + resolver->get_label_scope ().push (scope_node_id); + resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); + resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); + resolver->push_new_label_rib (resolver->get_type_scope ().peek ()); + + // We know expr.get_patterns () has one pattern at most + // so there's no reason to handle it like an AltPattern. + std::vector<PatternBinding> bindings + = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())}; + + for (auto &pattern : expr.get_patterns ()) + { + PatternDeclaration::go (pattern.get (), Rib::ItemType::Var, bindings); + } + + ResolveExpr::go (expr.get_if_block ().get (), prefix, canonical_prefix); + ResolveExpr::go (expr.get_else_block ().get (), prefix, canonical_prefix); + + resolver->get_name_scope ().pop (); + resolver->get_type_scope ().pop (); + resolver->get_label_scope ().pop (); +} + +void ResolveExpr::visit (AST::BlockExpr &expr) { NodeId scope_node_id = expr.get_node_id (); diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 7b0beaf..896617cc 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -51,6 +51,7 @@ public: void visit (AST::IfExpr &expr) override; void visit (AST::IfExprConseqElse &expr) override; void visit (AST::IfLetExpr &expr) override; + void visit (AST::IfLetExprConseqElse &expr) override; void visit (AST::BlockExpr &expr) override; void visit (AST::UnsafeBlockExpr &expr) override; void visit (AST::ArrayElemsValues &elems) override; diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index 4352dc9..6594068 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -494,6 +494,42 @@ TypeCheckExpr::visit (HIR::IfLetExpr &expr) } void +TypeCheckExpr::visit (HIR::IfLetExprConseqElse &expr) +{ + TyTy::BaseType *scrutinee_tyty + = TypeCheckExpr::Resolve (expr.get_scrutinee_expr ().get ()); + + for (auto &pattern : expr.get_patterns ()) + { + TyTy::BaseType *kase_arm_ty + = TypeCheckPattern::Resolve (pattern.get (), scrutinee_tyty); + + unify_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (scrutinee_tyty), + TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()), + expr.get_locus ()); + } + + auto if_blk_resolved = TypeCheckExpr::Resolve (expr.get_if_block ()); + auto else_blk_resolved = TypeCheckExpr::Resolve (expr.get_else_block ()); + + if (if_blk_resolved->get_kind () == TyTy::NEVER) + infered = else_blk_resolved; + else if (else_blk_resolved->get_kind () == TyTy::NEVER) + infered = if_blk_resolved; + else + { + infered = unify_site ( + expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (if_blk_resolved, + expr.get_if_block ()->get_locus ()), + TyTy::TyWithLocation (else_blk_resolved, + expr.get_else_block ()->get_locus ()), + expr.get_locus ()); + } +} + +void TypeCheckExpr::visit (HIR::UnsafeBlockExpr &expr) { infered = TypeCheckExpr::Resolve (expr.get_block_expr ().get ()); diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 68c09c7..2ff320d 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -45,6 +45,7 @@ public: void visit (HIR::IfExpr &expr) override; void visit (HIR::IfExprConseqElse &expr) override; void visit (HIR::IfLetExpr &expr) override; + void visit (HIR::IfLetExprConseqElse &) override; void visit (HIR::BlockExpr &expr) override; void visit (HIR::UnsafeBlockExpr &expr) override; void visit (HIR::ArrayIndexExpr &expr) override; @@ -75,7 +76,6 @@ public: void visit (HIR::RangeToInclExpr &) override {} void visit (HIR::WhileLetLoopExpr &) override {} void visit (HIR::ForLoopExpr &) override {} - void visit (HIR::IfLetExprConseqElse &) override {} void visit (HIR::AwaitExpr &) override {} void visit (HIR::AsyncBlockExpr &) override {} diff --git a/gcc/testsuite/rust/compile/if_let_expr.rs b/gcc/testsuite/rust/compile/if_let_expr.rs index 31e301f..ffa367b 100644 --- a/gcc/testsuite/rust/compile/if_let_expr.rs +++ b/gcc/testsuite/rust/compile/if_let_expr.rs @@ -1,12 +1,10 @@ -// { dg-options "-fsyntax-only" } - pub enum Option<T> { None, Some(T), } fn main() { - let x = Option::Some(3); + let x = Option::Some(3); // { dg-warning "unused name" } let a = if let Option::Some(1) = x { 1 } else if x == Option::Some(2) { |