diff options
author | SimplyTheOther <simplytheother@gmail.com> | 2021-01-10 14:30:39 +0800 |
---|---|---|
committer | SimplyTheOther <simplytheother@gmail.com> | 2021-01-10 14:30:39 +0800 |
commit | b247c0d5aadf6eb7323641ffbcf7cc67bedd2c52 (patch) | |
tree | 3a4d3a0b0569d28f679ecbc74928125034d50f4f /gcc | |
parent | ee85db852a5a819e559ab00e7a382a34e925447a (diff) | |
parent | 0f42a240e53e932de0ae4799d54fe0bd15d06047 (diff) | |
download | gcc-b247c0d5aadf6eb7323641ffbcf7cc67bedd2c52.zip gcc-b247c0d5aadf6eb7323641ffbcf7cc67bedd2c52.tar.gz gcc-b247c0d5aadf6eb7323641ffbcf7cc67bedd2c52.tar.bz2 |
Merge branch 'master' of https://github.com/redbrain/gccrs
Diffstat (limited to 'gcc')
36 files changed, 651 insertions, 208 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index eee654b..cfb4228 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -2839,6 +2839,8 @@ public: } } + size_t num_statements () const { return statements.size (); } + // TODO: this mutable getter seems really dodgy. Think up better way. const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h index c2ce387..c840112 100644 --- a/gcc/rust/ast/rust-stmt.h +++ b/gcc/rust/ast/rust-stmt.h @@ -184,6 +184,8 @@ class ExprStmt : public Stmt Location locus; public: + Location get_locus_slow () const final override { return get_locus (); } + Location get_locus () const { return locus; } protected: diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index d241921..298ff50 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -221,12 +221,18 @@ public: virtual ~TyTyResolveCompile () {} + void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } + void visit (TyTy::UnitType &type) override { gcc_unreachable (); } void visit (TyTy::InferType &type) override { gcc_unreachable (); } void visit (TyTy::FnType &type) override { gcc_unreachable (); } + void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } + + void visit (TyTy::ParamType &type) override { gcc_unreachable (); } + void visit (TyTy::ADTType &type) override { ::Btype *compiled_type = nullptr; diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index 9081000..0370129 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -156,8 +156,6 @@ public: return; case HIR::Literal::FLOAT: { - printf ("FLOATY BOYO: [%s]\n", expr.as_string ().c_str ()); - mpfr_t fval; if (mpfr_init_set_str (fval, expr.as_string ().c_str (), 10, MPFR_RNDN) @@ -177,8 +175,6 @@ public: return; } - printf ("tyty float is [%s]\n", tyty->as_string ().c_str ()); - Btype *type = TyTyResolveCompile::compile (ctx, tyty); translated = ctx->get_backend ()->float_constant_expression (type, fval); diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index 90630bb..f1b39da 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -232,6 +232,23 @@ public: return true; }); + if (function_body->has_expr ()) + { + // the previous passes will ensure this is a valid return + // dead code elimination should remove any bad trailing expressions + Bexpression *compiled_expr + = CompileExpr::Compile (function_body->expr.get (), ctx); + rust_assert (compiled_expr != nullptr); + + auto fncontext = ctx->peek_fn (); + + std::vector<Bexpression *> retstmts; + retstmts.push_back (compiled_expr); + auto s = ctx->get_backend ()->return_statement ( + fncontext.fndecl, retstmts, function_body->expr->get_locus_slow ()); + ctx->add_statement (s); + } + ctx->pop_block (); auto body = ctx->get_backend ()->block_statement (code_block); if (!ctx->get_backend ()->function_set_body (fndecl, body)) diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index 528f90e..137b74b 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -43,13 +43,19 @@ public: ~TyTyCompile () {} - void visit (TyTy::InferType &type) override - { - // there shouldn't be any of these left - gcc_unreachable (); - } + void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } + + void visit (TyTy::UnitType &type) override { gcc_unreachable (); } + + void visit (TyTy::InferType &type) override { gcc_unreachable (); } + + void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } - void visit (TyTy::UnitType &type) override {} + void visit (TyTy::ParamType &type) override { gcc_unreachable (); } + + void visit (TyTy::ADTType &type) override { gcc_unreachable (); } + + void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } void visit (TyTy::FnType &type) override { @@ -82,8 +88,6 @@ public: mappings->lookup_location (type.get_ref ())); } - void visit (TyTy::ParamType &type) override {} - void visit (TyTy::BoolType &type) override { translated = backend->named_type ("bool", backend->bool_type (), @@ -132,19 +136,19 @@ public: switch (type.get_kind ()) { case TyTy::UintType::U8: - translated = backend->named_type ("i8", backend->integer_type (true, 8), + translated = backend->named_type ("u8", backend->integer_type (true, 8), Linemap::predeclared_location ()); return; case TyTy::UintType::U16: translated - = backend->named_type ("i16", backend->integer_type (true, 16), + = backend->named_type ("u16", backend->integer_type (true, 16), Linemap::predeclared_location ()); return; case TyTy::UintType::U32: translated - = backend->named_type ("i32", backend->integer_type (true, 32), + = backend->named_type ("u32", backend->integer_type (true, 32), Linemap::predeclared_location ()); return; @@ -205,6 +209,18 @@ public: ~TyTyExtractParamsFromFnType () {} + void visit (TyTy::UnitType &type) override { gcc_unreachable (); } + void visit (TyTy::InferType &type) override { gcc_unreachable (); } + void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } + void visit (TyTy::ADTType &type) override { gcc_unreachable (); } + void visit (TyTy::ParamType &type) override { gcc_unreachable (); } + void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } + void visit (TyTy::BoolType &type) override { gcc_unreachable (); } + void visit (TyTy::IntType &type) override { gcc_unreachable (); } + void visit (TyTy::UintType &type) override { gcc_unreachable (); } + void visit (TyTy::FloatType &type) override { gcc_unreachable (); } + void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } + void visit (TyTy::FnType &type) override { ok = true; @@ -234,6 +250,18 @@ public: ~TyTyExtractRetFromFnType () {} + void visit (TyTy::UnitType &type) override { gcc_unreachable (); } + void visit (TyTy::InferType &type) override { gcc_unreachable (); } + void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } + void visit (TyTy::ADTType &type) override { gcc_unreachable (); } + void visit (TyTy::ParamType &type) override { gcc_unreachable (); } + void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } + void visit (TyTy::BoolType &type) override { gcc_unreachable (); } + void visit (TyTy::IntType &type) override { gcc_unreachable (); } + void visit (TyTy::UintType &type) override { gcc_unreachable (); } + void visit (TyTy::FloatType &type) override { gcc_unreachable (); } + void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } + void visit (TyTy::FnType &type) override { ok = true; @@ -261,6 +289,18 @@ public: ~TyTyCompileParam () {} + void visit (TyTy::UnitType &type) override { gcc_unreachable (); } + void visit (TyTy::InferType &type) override { gcc_unreachable (); } + void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } + void visit (TyTy::ADTType &type) override { gcc_unreachable (); } + void visit (TyTy::FnType &type) override { gcc_unreachable (); } + void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } + void visit (TyTy::BoolType &type) override { gcc_unreachable (); } + void visit (TyTy::IntType &type) override { gcc_unreachable (); } + void visit (TyTy::UintType &type) override { gcc_unreachable (); } + void visit (TyTy::FloatType &type) override { gcc_unreachable (); } + void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } + void visit (TyTy::ParamType &type) override { auto btype = TyTyCompile::compile (backend, type.get_base_type ()); diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 24b45ee..a52f183 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -90,6 +90,23 @@ CompileBlock::visit (HIR::BlockExpr &expr) return true; }); + if (expr.has_expr ()) + { + // the previous passes will ensure this is a valid return + // dead code elimination should remove any bad trailing expressions + Bexpression *compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx); + rust_assert (compiled_expr != nullptr); + + auto fncontext = ctx->peek_fn (); + + std::vector<Bexpression *> retstmts; + retstmts.push_back (compiled_expr); + auto s + = ctx->get_backend ()->return_statement (fncontext.fndecl, retstmts, + expr.expr->get_locus_slow ()); + ctx->add_statement (s); + } + ctx->pop_block (); translated = new_block; } diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h index 11f1ab8..f81a242 100644 --- a/gcc/rust/hir/rust-ast-lower-block.h +++ b/gcc/rust/hir/rust-ast-lower-block.h @@ -28,7 +28,7 @@ namespace HIR { class ASTLoweringBlock : public ASTLoweringBase { public: - static HIR::BlockExpr *translate (AST::BlockExpr *expr) + static HIR::BlockExpr *translate (AST::BlockExpr *expr, bool *terminated) { ASTLoweringBlock resolver; expr->accept_vis (resolver); @@ -40,6 +40,7 @@ public: resolver.translated); } + *terminated = resolver.terminated; return resolver.translated; } @@ -48,15 +49,18 @@ public: void visit (AST::BlockExpr &expr); private: - ASTLoweringBlock () : ASTLoweringBase (), translated (nullptr) {} + ASTLoweringBlock () + : ASTLoweringBase (), translated (nullptr), terminated (false) + {} HIR::BlockExpr *translated; + bool terminated; }; class ASTLoweringIfBlock : public ASTLoweringBase { public: - static HIR::IfExpr *translate (AST::IfExpr *expr) + static HIR::IfExpr *translate (AST::IfExpr *expr, bool *terminated) { ASTLoweringIfBlock resolver; expr->accept_vis (resolver); @@ -67,7 +71,7 @@ public: resolver.translated->get_mappings ().get_hirid (), resolver.translated); } - + *terminated = resolver.terminated; return resolver.translated; } @@ -80,15 +84,19 @@ public: void visit (AST::IfExprConseqIf &expr); private: - ASTLoweringIfBlock () : ASTLoweringBase (), translated (nullptr) {} + ASTLoweringIfBlock () + : ASTLoweringBase (), translated (nullptr), terminated (false) + {} HIR::IfExpr *translated; + bool terminated; }; class ASTLoweringExprWithBlock : public ASTLoweringBase { public: - static HIR::ExprWithBlock *translate (AST::ExprWithBlock *expr) + static HIR::ExprWithBlock *translate (AST::ExprWithBlock *expr, + bool *terminated) { ASTLoweringExprWithBlock resolver; expr->accept_vis (resolver); @@ -100,6 +108,7 @@ public: resolver.translated); } + *terminated = resolver.terminated; return resolver.translated; } @@ -107,23 +116,31 @@ public: void visit (AST::IfExpr &expr) { - translated = ASTLoweringIfBlock::translate (&expr); + translated = ASTLoweringIfBlock::translate (&expr, &terminated); } void visit (AST::IfExprConseqElse &expr) { - translated = ASTLoweringIfBlock::translate (&expr); + translated = ASTLoweringIfBlock::translate (&expr, &terminated); } void visit (AST::IfExprConseqIf &expr) { - translated = ASTLoweringIfBlock::translate (&expr); + translated = ASTLoweringIfBlock::translate (&expr, &terminated); + } + + void visit (AST::BlockExpr &expr) + { + translated = ASTLoweringBlock::translate (&expr, &terminated); } private: - ASTLoweringExprWithBlock () : ASTLoweringBase (), translated (nullptr) {} + ASTLoweringExprWithBlock () + : ASTLoweringBase (), translated (nullptr), terminated (false) + {} HIR::ExprWithBlock *translated; + bool terminated; }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 87ba0dc..51bf108 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -107,7 +107,7 @@ private: class ASTLoweringExpr : public ASTLoweringBase { public: - static HIR::Expr *translate (AST::Expr *expr) + static HIR::Expr *translate (AST::Expr *expr, bool *terminated = nullptr) { ASTLoweringExpr resolver; expr->accept_vis (resolver); @@ -121,6 +121,13 @@ public: resolver.mappings->insert_hir_expr ( resolver.translated->get_mappings ().get_crate_num (), resolver.translated->get_mappings ().get_hirid (), resolver.translated); + resolver.mappings->insert_location ( + resolver.translated->get_mappings ().get_crate_num (), + resolver.translated->get_mappings ().get_hirid (), + expr->get_locus_slow ()); + + if (terminated != nullptr) + *terminated = resolver.terminated; return resolver.translated; } @@ -129,22 +136,22 @@ public: void visit (AST::IfExpr &expr) { - translated = ASTLoweringIfBlock::translate (&expr); + translated = ASTLoweringIfBlock::translate (&expr, &terminated); } void visit (AST::IfExprConseqElse &expr) { - translated = ASTLoweringIfBlock::translate (&expr); + translated = ASTLoweringIfBlock::translate (&expr, &terminated); } void visit (AST::IfExprConseqIf &expr) { - translated = ASTLoweringIfBlock::translate (&expr); + translated = ASTLoweringIfBlock::translate (&expr, &terminated); } void visit (AST::BlockExpr &expr) { - translated = ASTLoweringBlock::translate (&expr); + translated = ASTLoweringBlock::translate (&expr, &terminated); } void visit (AST::PathInExpression &expr) @@ -154,6 +161,7 @@ public: void visit (AST::ReturnExpr &expr) { + terminated = true; HIR::Expr *return_expr = expr.has_returned_expr () ? ASTLoweringExpr::translate (expr.get_returned_expr ().get ()) @@ -498,10 +506,13 @@ public: } private: - ASTLoweringExpr () : translated (nullptr), translated_array_elems (nullptr) {} + ASTLoweringExpr () + : translated (nullptr), translated_array_elems (nullptr), terminated (false) + {} HIR::Expr *translated; HIR::ArrayElems *translated_array_elems; + bool terminated; }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h index 2a17880..4a5a3fe 100644 --- a/gcc/rust/hir/rust-ast-lower-item.h +++ b/gcc/rust/hir/rust-ast-lower-item.h @@ -185,9 +185,14 @@ public: function_params.push_back (hir_param); } + bool terminated = false; std::unique_ptr<HIR::BlockExpr> function_body = std::unique_ptr<HIR::BlockExpr> ( - ASTLoweringBlock::translate (function.get_definition ().get ())); + ASTLoweringBlock::translate (function.get_definition ().get (), + &terminated)); + if (!terminated && function.has_return_type ()) + rust_error_at (function.get_definition ()->get_locus (), + "missing return"); auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, function.get_node_id (), diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h index f4ecd8e..b672456 100644 --- a/gcc/rust/hir/rust-ast-lower-stmt.h +++ b/gcc/rust/hir/rust-ast-lower-stmt.h @@ -33,15 +33,12 @@ namespace HIR { class ASTLoweringStmt : public ASTLoweringBase { public: - static HIR::Stmt *translate (AST::Stmt *stmt) + static HIR::Stmt *translate (AST::Stmt *stmt, bool *terminated) { ASTLoweringStmt resolver; stmt->accept_vis (resolver); - if (resolver.translated == nullptr) - { - printf ("Failing translating: %s\n", stmt->as_string ().c_str ()); - rust_assert (resolver.translated != nullptr); - } + rust_assert (resolver.translated != nullptr); + *terminated = resolver.terminated; return resolver.translated; } @@ -50,7 +47,8 @@ public: void visit (AST::ExprStmtWithBlock &stmt) { HIR::ExprWithBlock *expr - = ASTLoweringExprWithBlock::translate (stmt.get_expr ().get ()); + = ASTLoweringExprWithBlock::translate (stmt.get_expr ().get (), + &terminated); auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (), @@ -67,7 +65,8 @@ public: void visit (AST::ExprStmtWithoutBlock &stmt) { - HIR::Expr *expr = ASTLoweringExpr::translate (stmt.get_expr ().get ()); + HIR::Expr *expr + = ASTLoweringExpr::translate (stmt.get_expr ().get (), &terminated); auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (), @@ -110,9 +109,10 @@ public: } private: - ASTLoweringStmt () : translated (nullptr) {} + ASTLoweringStmt () : translated (nullptr), terminated (false) {} HIR::Stmt *translated; + bool terminated; }; } // namespace HIR diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index 8dd8800..4f0d0d0 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -64,17 +64,44 @@ ASTLowering::go () void ASTLoweringBlock::visit (AST::BlockExpr &expr) { - std::vector<std::unique_ptr<HIR::Stmt> > block_stmts; - std::unique_ptr<HIR::ExprWithoutBlock> block_expr; std::vector<HIR::Attribute> inner_attribs; std::vector<HIR::Attribute> outer_attribs; + std::vector<std::unique_ptr<HIR::Stmt> > block_stmts; + bool block_did_terminate = false; expr.iterate_stmts ([&] (AST::Stmt *s) mutable -> bool { - auto translated_stmt = ASTLoweringStmt::translate (s); + bool terminated = false; + auto translated_stmt = ASTLoweringStmt::translate (s, &terminated); block_stmts.push_back (std::unique_ptr<HIR::Stmt> (translated_stmt)); + block_did_terminate = terminated; + return !block_did_terminate; + }); + + // if there was a return expression everything after that becomes + // unreachable code. This can be detected for any AST NodeIDs that have no + // associated HIR Mappings + expr.iterate_stmts ([&] (AST::Stmt *s) -> bool { + HirId ref; + if (!mappings->lookup_node_to_hir (mappings->get_current_crate (), + s->get_node_id (), &ref)) + rust_warning_at (s->get_locus_slow (), 0, "unreachable statement"); + return true; }); + HIR::ExprWithoutBlock *tail_expr = nullptr; + if (expr.has_tail_expr () && !block_did_terminate) + { + tail_expr = (HIR::ExprWithoutBlock *) ASTLoweringExpr::translate ( + expr.get_tail_expr ().get ()); + } + else if (expr.has_tail_expr () && block_did_terminate) + { + // warning unreachable tail expressions + rust_warning_at (expr.get_tail_expr ()->get_locus_slow (), 0, + "unreachable expression"); + } + auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), mappings->get_next_hir_id (crate_num), @@ -82,17 +109,23 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr) translated = new HIR::BlockExpr (mapping, std::move (block_stmts), - std::move (block_expr), std::move (inner_attribs), - std::move (outer_attribs), expr.get_locus ()); + std::unique_ptr<HIR::ExprWithoutBlock> (tail_expr), + std::move (inner_attribs), std::move (outer_attribs), + expr.get_locus ()); + + terminated = block_did_terminate || expr.has_tail_expr (); } void ASTLoweringIfBlock::visit (AST::IfExpr &expr) { + bool ignored_terminated = false; HIR::Expr *condition - = ASTLoweringExpr::translate (expr.get_condition_expr ().get ()); + = ASTLoweringExpr::translate (expr.get_condition_expr ().get (), + &ignored_terminated); HIR::BlockExpr *block - = ASTLoweringBlock::translate (expr.get_if_block ().get ()); + = ASTLoweringBlock::translate (expr.get_if_block ().get (), + &ignored_terminated); auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), @@ -109,10 +142,18 @@ ASTLoweringIfBlock::visit (AST::IfExprConseqElse &expr) { HIR::Expr *condition = ASTLoweringExpr::translate (expr.get_condition_expr ().get ()); + + bool if_block_terminated = false; + bool else_block_termianted = false; + HIR::BlockExpr *if_block - = ASTLoweringBlock::translate (expr.get_if_block ().get ()); + = ASTLoweringBlock::translate (expr.get_if_block ().get (), + &if_block_terminated); HIR::BlockExpr *else_block - = ASTLoweringBlock::translate (expr.get_else_block ().get ()); + = ASTLoweringBlock::translate (expr.get_else_block ().get (), + &else_block_termianted); + + terminated = if_block_terminated && else_block_termianted; auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), @@ -132,10 +173,14 @@ ASTLoweringIfBlock::visit (AST::IfExprConseqIf &expr) { HIR::Expr *condition = ASTLoweringExpr::translate (expr.get_condition_expr ().get ()); + + bool ignored_terminated = false; HIR::BlockExpr *block - = ASTLoweringBlock::translate (expr.get_if_block ().get ()); + = ASTLoweringBlock::translate (expr.get_if_block ().get (), + &ignored_terminated); HIR::IfExpr *conseq_if_expr - = ASTLoweringIfBlock::translate (expr.get_conseq_if_expr ().get ()); + = ASTLoweringIfBlock::translate (expr.get_conseq_if_expr ().get (), + &ignored_terminated); auto crate_num = mappings->get_current_crate (); Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index dc7ab5a..11be8b6 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -2594,6 +2594,8 @@ public: } } + bool is_final_stmt (Stmt *stmt) { return statements.back ().get () == stmt; } + Location get_closing_locus () { if (statements.size () == 0) diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h index 7417a32..5d758ee 100644 --- a/gcc/rust/hir/tree/rust-hir.h +++ b/gcc/rust/hir/tree/rust-hir.h @@ -257,6 +257,8 @@ public: return Literal ("", CHAR, PrimitiveCoreType::CORETYPE_UNKNOWN); } + void set_lit_type (LitType lt) { type = lt; } + // Returns whether literal is in an invalid state. bool is_error () const { return value_as_string == ""; } }; diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc index b97eea1..4606a6c 100644 --- a/gcc/rust/lex/rust-lex.cc +++ b/gcc/rust/lex/rust-lex.cc @@ -1938,16 +1938,6 @@ Lexer::parse_decimal_int_or_float (Location loc) PrimitiveCoreType type_hint = type_suffix_pair.first; length += type_suffix_pair.second; - if (type_hint == CORETYPE_F32 || type_hint == CORETYPE_F64) - { - rust_error_at ( - get_current_location (), - "invalid type suffix %qs for integer (decimal) literal", - get_type_hint_string (type_hint)); - // ignore invalid type suffix as everything else seems fine - type_hint = CORETYPE_UNKNOWN; - } - current_column += length; str.shrink_to_fit (); diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index c3b2312..310d296 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -65,6 +65,14 @@ public: ResolveType::go (function.get_return_type ().get (), function.get_node_id ()); + NodeId scope_node_id = function.get_node_id (); + resolver->get_name_scope ().push (scope_node_id); + resolver->get_type_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 ()); + + // we make a new scope so the names of parameters are resolved and shadowed + // correctly for (auto ¶m : function.get_function_params ()) { ResolveType::go (param.get_type ().get (), param.get_node_id ()); @@ -72,18 +80,9 @@ public: param.get_node_id ()); } - // setup parent scoping for names - NodeId scope_node_id = function.get_definition ()->get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_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 ()); - - function.get_definition ()->iterate_stmts ( - [&] (AST::Stmt *s) mutable -> bool { - ResolveStmt::go (s, s->get_node_id ()); - return true; - }); + // resolve the function body + ResolveExpr::go (function.get_definition ().get (), + function.get_node_id ()); resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index 87b3cf3..6d751e6 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -51,12 +51,12 @@ public: void visit (AST::LetStmt &stmt) { + if (stmt.has_init_expr ()) + ResolveExpr::go (stmt.get_init_expr ().get (), stmt.get_node_id ()); + PatternDeclaration::go (stmt.get_pattern ().get (), stmt.get_node_id ()); if (stmt.has_type ()) ResolveType::go (stmt.get_type ().get (), stmt.get_node_id ()); - - if (stmt.has_init_expr ()) - ResolveExpr::go (stmt.get_init_expr ().get (), stmt.get_node_id ()); } private: diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index fe8d7e0..e5b0942 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -285,6 +285,9 @@ ResolveExpr::visit (AST::BlockExpr &expr) return true; }); + if (expr.has_tail_expr ()) + ResolveExpr::go (expr.get_tail_expr ().get (), expr.get_node_id ()); + resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); } diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index a5440c0..f2014a1 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -32,9 +32,9 @@ namespace Resolver { class TypeCheckExpr : public TypeCheckBase { public: - static TyTy::TyBase *Resolve (HIR::Expr *expr) + static TyTy::TyBase *Resolve (HIR::Expr *expr, bool is_final_expr = false) { - TypeCheckExpr resolver; + TypeCheckExpr resolver (is_final_expr); expr->accept_vis (resolver); if (resolver.infered != nullptr) resolver.context->insert_type (expr->get_mappings ().get_hirid (), @@ -188,6 +188,15 @@ public: ok = context->lookup_builtin ("u128", &infered); break; + case CORETYPE_F32: + expr.get_literal ()->set_lit_type (HIR::Literal::LitType::FLOAT); + ok = context->lookup_builtin ("f32", &infered); + break; + case CORETYPE_F64: + expr.get_literal ()->set_lit_type (HIR::Literal::LitType::FLOAT); + ok = context->lookup_builtin ("f64", &infered); + break; + default: ok = context->lookup_builtin ("i32", &infered); break; @@ -197,8 +206,20 @@ public: break; case HIR::Literal::LitType::FLOAT: { - // FIXME need to respect the suffix if applicable - auto ok = context->lookup_builtin ("f32", &infered); + bool ok = false; + + switch (expr.get_literal ()->get_type_hint ()) + { + case CORETYPE_F32: + ok = context->lookup_builtin ("f32", &infered); + break; + case CORETYPE_F64: + ok = context->lookup_builtin ("f64", &infered); + break; + default: + ok = context->lookup_builtin ("f32", &infered); + break; + } rust_assert (ok); } break; @@ -245,13 +266,30 @@ public: { TypeCheckExpr::Resolve (expr.get_if_condition ()); TypeCheckExpr::Resolve (expr.get_if_block ()); + + // if without else always resolves to unit type + infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ()); } void visit (HIR::IfExprConseqElse &expr) { - TypeCheckExpr::Resolve (expr.get_if_condition ()); - TypeCheckExpr::Resolve (expr.get_if_block ()); - TypeCheckExpr::Resolve (expr.get_else_block ()); + // this must combine to what the type is expected + // this might be a parameter or the last expr in an if + else in a BlockExpr + // then it must resolve to fn return type + // else its a unit-type + infered = is_final_expr + ? context->peek_return_type () + : new TyTy::UnitType (expr.get_mappings ().get_hirid ()); + + TypeCheckExpr::Resolve (expr.get_if_condition (), is_final_expr); + auto if_blk_ty = TypeCheckExpr::Resolve (expr.get_if_block ()); + auto else_blk_ty = TypeCheckExpr::Resolve (expr.get_else_block ()); + + if (is_final_expr) + { + infered = infered->combine (if_blk_ty); + infered = infered->combine (else_blk_ty); + } } void visit (HIR::IfExprConseqIf &expr) @@ -259,22 +297,28 @@ public: TypeCheckExpr::Resolve (expr.get_if_condition ()); TypeCheckExpr::Resolve (expr.get_if_block ()); TypeCheckExpr::Resolve (expr.get_conseq_if_expr ()); + + infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ()); } void visit (HIR::BlockExpr &expr); void visit (HIR::ArrayIndexExpr &expr) { - // check the index + // FIXME this should be size type TyTy::IntType size_ty (expr.get_index_expr ()->get_mappings ().get_hirid (), TyTy::IntType::I32); auto resolved = size_ty.combine (TypeCheckExpr::Resolve (expr.get_index_expr ())); - context->insert_type (expr.get_index_expr ()->get_mappings ().get_hirid (), - resolved); + rust_assert (resolved != nullptr); expr.get_array_expr ()->accept_vis (*this); - rust_assert (infered != nullptr); + if (infered->get_kind () != TyTy::TypeKind::ARRAY) + { + rust_fatal_error (expr.get_array_expr ()->get_locus_slow (), + "expected an ArrayType for index expression"); + return; + } // extract the element type out now from the base type infered = TyTyExtractorArray::ExtractElementTypeFromArray (infered); @@ -318,12 +362,15 @@ public: } private: - TypeCheckExpr () - : TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr) + TypeCheckExpr (bool is_final_expr) + : TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr), + is_final_expr (is_final_expr) {} TyTy::TyBase *infered; TyTy::TyBase *infered_array_elems; + + bool is_final_expr; }; } // namespace Resolver diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h index c90af13..62320a6 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.h +++ b/gcc/rust/typecheck/rust-hir-type-check-item.h @@ -43,6 +43,18 @@ public: return state; } + void visit (TyTy::UnitType &type) override { gcc_unreachable (); } + void visit (TyTy::InferType &type) override { gcc_unreachable (); } + void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } + void visit (TyTy::ADTType &type) override { gcc_unreachable (); } + void visit (TyTy::ParamType &type) override { gcc_unreachable (); } + void visit (TyTy::ArrayType &type) override { gcc_unreachable (); } + void visit (TyTy::BoolType &type) override { gcc_unreachable (); } + void visit (TyTy::IntType &type) override { gcc_unreachable (); } + void visit (TyTy::UintType &type) override { gcc_unreachable (); } + void visit (TyTy::FloatType &type) override { gcc_unreachable (); } + void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } + void visit (TyTy::FnType &type) override { state = type.return_type (); } private: @@ -72,25 +84,7 @@ public: ResolveFnType resolve_fn_type (fnType); context->push_return_type (resolve_fn_type.go ()); - // walk statements to make sure they are all typed correctly and they match - // up - function.function_body->iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool { - TypeCheckStmt::Resolve (s); - return true; - }); - - // now that the stmts have been resolved we must resolve the block of locals - // and make sure the variables have been resolved - auto body_mappings = function.function_body->get_mappings (); - Rib *rib = nullptr; - if (!resolver->find_name_rib (body_mappings.get_nodeid (), &rib)) - { - rust_fatal_error (function.get_locus (), - "failed to lookup locals per block"); - return; - } - - TyTyResolver::Resolve (rib, mappings, resolver, context); + TypeCheckExpr::Resolve (function.function_body.get ()); context->pop_return_type (); } diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h index dbf6583..bf754db 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h @@ -30,27 +30,29 @@ namespace Resolver { class TypeCheckStmt : public TypeCheckBase { public: - static void Resolve (HIR::Stmt *stmt) + static TyTy::TyBase *Resolve (HIR::Stmt *stmt, bool is_final_stmt) { - TypeCheckStmt resolver; + TypeCheckStmt resolver (is_final_stmt); stmt->accept_vis (resolver); + return resolver.infered; } void visit (HIR::ExprStmtWithBlock &stmt) { - TypeCheckExpr::Resolve (stmt.get_expr ()); + infered = TypeCheckExpr::Resolve (stmt.get_expr (), is_final_stmt); } void visit (HIR::ExprStmtWithoutBlock &stmt) { - TypeCheckExpr::Resolve (stmt.get_expr ()); + infered = TypeCheckExpr::Resolve (stmt.get_expr (), is_final_stmt); } void visit (HIR::LetStmt &stmt) { TyTy::TyBase *init_expr_ty = nullptr; if (stmt.has_init_expr ()) - init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ()); + init_expr_ty + = TypeCheckExpr::Resolve (stmt.get_init_expr (), is_final_stmt); TyTy::TyBase *specified_ty = nullptr; if (stmt.has_type ()) @@ -94,7 +96,12 @@ public: } private: - TypeCheckStmt () : TypeCheckBase () {} + TypeCheckStmt (bool is_final_stmt) + : TypeCheckBase (), is_final_stmt (is_final_stmt) + {} + + TyTy::TyBase *infered; + bool is_final_stmt; }; // namespace Resolver } // namespace Resolver diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index e7d3366..e68ba9a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -40,10 +40,44 @@ TypeResolution::Resolve (HIR::Crate &crate) void TypeCheckExpr::visit (HIR::BlockExpr &expr) { + TyTy::TyBase *block_tyty + = new TyTy::UnitType (expr.get_mappings ().get_hirid ()); + expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool { - TypeCheckStmt::Resolve (s); + bool is_final_stmt = expr.is_final_stmt (s); + bool is_final_expr = is_final_stmt && !expr.has_expr (); + + auto infered = TypeCheckStmt::Resolve (s, is_final_stmt); + if (is_final_expr) + { + delete block_tyty; + block_tyty = infered; + } + return true; }); + + if (expr.has_expr ()) + { + auto tail_tyty = TypeCheckExpr::Resolve (expr.expr.get (), true); + + delete block_tyty; + block_tyty = tail_tyty; + } + + // now that the stmts have been resolved we must resolve the block of locals + // and make sure the variables have been resolved + auto body_mappings = expr.get_mappings (); + Rib *rib = nullptr; + if (!resolver->find_name_rib (body_mappings.get_nodeid (), &rib)) + { + rust_fatal_error (expr.get_locus (), "failed to lookup locals per block"); + return; + } + + TyTyResolver::Resolve (rib, mappings, resolver, context); + + infered = block_tyty; } // RUST_HIR_TYPE_CHECK_STRUCT_FIELD diff --git a/gcc/rust/typecheck/rust-tyctx.cc b/gcc/rust/typecheck/rust-tyctx.cc index 6eb46ff..cd171d1 100644 --- a/gcc/rust/typecheck/rust-tyctx.cc +++ b/gcc/rust/typecheck/rust-tyctx.cc @@ -69,7 +69,10 @@ TypeCheckContext::lookup_type (HirId id, TyTy::TyBase **type) { auto it = resolved.find (id); if (it == resolved.end ()) - return false; + { + *type = new TyTy::ErrorType (id); + return false; + } *type = it->second; return true; diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h index d1341df..c3fcb1a 100644 --- a/gcc/rust/typecheck/rust-tyty-call.h +++ b/gcc/rust/typecheck/rust-tyty-call.h @@ -38,6 +38,18 @@ public: } ~TypeCheckCallExpr () {} + void visit (UnitType &type) override { gcc_unreachable (); } + void visit (InferType &type) override { gcc_unreachable (); } + void visit (StructFieldType &type) override { gcc_unreachable (); } + void visit (ADTType &type) override { gcc_unreachable (); } + void visit (ParamType &type) override { gcc_unreachable (); } + void visit (ArrayType &type) override { gcc_unreachable (); } + void visit (BoolType &type) override { gcc_unreachable (); } + void visit (IntType &type) override { gcc_unreachable (); } + void visit (UintType &type) override { gcc_unreachable (); } + void visit (FloatType &type) override { gcc_unreachable (); } + void visit (ErrorType &type) override { gcc_unreachable (); } + void visit (FnType &type) override; private: diff --git a/gcc/rust/typecheck/rust-tyty-resolver.h b/gcc/rust/typecheck/rust-tyty-resolver.h index 2851a1e..3d2196a 100644 --- a/gcc/rust/typecheck/rust-tyty-resolver.h +++ b/gcc/rust/typecheck/rust-tyty-resolver.h @@ -73,8 +73,6 @@ public: d.parent, &hir_node_ref); rust_assert (ok); - printf ("failed lets try [%u]\n", hir_node_ref); - if (!context->lookup_type (hir_node_ref, &resolved)) { rust_fatal_error ( @@ -102,10 +100,8 @@ public: &resolved_type); rust_assert (ok); - if (!resolved_type->is_unit ()) - { - return true; - } + if (resolved_type->get_kind () != TyTy::TypeKind::INFER) + return true; auto resolved_tyty = resolved_type; for (auto it : gathered_types) @@ -155,6 +151,18 @@ public: virtual ~TyTyExtractorArray () {} + void visit (TyTy::UnitType &type) override { gcc_unreachable (); } + void visit (TyTy::InferType &type) override { gcc_unreachable (); } + void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); } + void visit (TyTy::ADTType &type) override { gcc_unreachable (); } + void visit (TyTy::ParamType &type) override { gcc_unreachable (); } + void visit (TyTy::FnType &type) override { gcc_unreachable (); } + void visit (TyTy::BoolType &type) override { gcc_unreachable (); } + void visit (TyTy::IntType &type) override { gcc_unreachable (); } + void visit (TyTy::UintType &type) override { gcc_unreachable (); } + void visit (TyTy::FloatType &type) override { gcc_unreachable (); } + void visit (TyTy::ErrorType &type) override { gcc_unreachable (); } + void visit (TyTy::ArrayType &type) override { extracted = type.get_type (); } private: diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index 615ef80..677013f 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -34,77 +34,127 @@ public: virtual void visit (UnitType &type) override { - Location locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), - type.as_string ().c_str ()); + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); + } + + virtual void visit (ADTType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); } virtual void visit (InferType &type) override { - Location locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), - type.as_string ().c_str ()); + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); } virtual void visit (FnType &type) override { - Location locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), - type.as_string ().c_str ()); + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); } virtual void visit (ParamType &type) override { - Location locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), - type.as_string ().c_str ()); + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); } virtual void visit (ArrayType &type) override { - Location locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), - type.as_string ().c_str ()); + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); } virtual void visit (BoolType &type) override { - Location locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), - type.as_string ().c_str ()); + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); } virtual void visit (IntType &type) override { - Location locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), - type.as_string ().c_str ()); + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); } virtual void visit (UintType &type) override { - Location locus = mappings->lookup_location (type.get_ref ()); - rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (), - type.as_string ().c_str ()); + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); + } + + virtual void visit (FloatType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); + } + + virtual void visit (ErrorType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); + } + + virtual void visit (StructFieldType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + Location def_locus = mappings->lookup_location (base->get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + rust_fatal_error (def_locus, "declared here"); } protected: - BaseRules (TyBase *base) : mappings (Analysis::Mappings::get ()), base (base) + BaseRules (TyBase *base) + : mappings (Analysis::Mappings::get ()), base (base), + resolved (new ErrorType (base->get_ref ())) {} Analysis::Mappings *mappings; - -private: TyBase *base; + TyBase *resolved; }; class InferRules : protected BaseRules { public: - InferRules (InferType *base) - : BaseRules (base), base (base), resolved (nullptr) - {} - ~InferRules () {} + InferRules (InferType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -114,31 +164,34 @@ public: // we are an inference variable so this means we can take the other as the // type - virtual void visit (BoolType &type) override + void visit (UnitType &type) override + { + resolved = new UnitType (type.get_ref ()); + } + + void visit (BoolType &type) override { resolved = new BoolType (type.get_ref ()); } - virtual void visit (IntType &type) override + void visit (IntType &type) override { resolved = new IntType (type.get_ref (), type.get_kind ()); } - virtual void visit (UintType &type) override + void visit (UintType &type) override { resolved = new UintType (type.get_ref (), type.get_kind ()); } private: InferType *base; - TyBase *resolved; }; class StructFieldTypeRules : protected BaseRules { public: - StructFieldTypeRules (StructFieldType *base) - : BaseRules (base), base (base), resolved (nullptr) + StructFieldTypeRules (StructFieldType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) @@ -149,15 +202,12 @@ public: private: StructFieldType *base; - TyBase *resolved; }; class UnitRules : protected BaseRules { public: - UnitRules (UnitType *base) : BaseRules (base), base (base), resolved (nullptr) - {} - ~UnitRules () {} + UnitRules (UnitType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -165,16 +215,16 @@ public: return resolved; } + void visit (IntType &type) override { rust_assert (false); } + private: UnitType *base; - TyBase *resolved; }; class FnRules : protected BaseRules { public: - FnRules (FnType *base) : BaseRules (base), base (base), resolved (nullptr) {} - ~FnRules () {} + FnRules (FnType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -184,16 +234,12 @@ public: private: FnType *base; - TyBase *resolved; }; class ParamRules : protected BaseRules { public: - ParamRules (ParamType *base) - : BaseRules (base), base (base), resolved (nullptr) - {} - ~ParamRules () {} + ParamRules (ParamType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -203,17 +249,12 @@ public: private: ParamType *base; - TyBase *resolved; }; class ArrayRules : protected BaseRules { public: - ArrayRules (ArrayType *base) - : BaseRules (base), base (base), resolved (nullptr) - {} - - ~ArrayRules () {} + ArrayRules (ArrayType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -242,15 +283,12 @@ public: private: ArrayType *base; - TyBase *resolved; }; class BoolRules : protected BaseRules { public: - BoolRules (BoolType *base) : BaseRules (base), base (base), resolved (nullptr) - {} - ~BoolRules () {} + BoolRules (BoolType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -265,15 +303,12 @@ public: private: BoolType *base; - TyBase *resolved; }; class IntRules : protected BaseRules { public: - IntRules (IntType *base) : BaseRules (base), base (base), resolved (nullptr) - {} - ~IntRules () {} + IntRules (IntType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -289,15 +324,12 @@ public: private: IntType *base; - TyBase *resolved; }; class UintRules : protected BaseRules { public: - UintRules (UintType *base) : BaseRules (base), base (base), resolved (nullptr) - {} - ~UintRules () {} + UintRules (UintType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -313,16 +345,12 @@ public: private: UintType *base; - TyBase *resolved; }; class FloatRules : protected BaseRules { public: - FloatRules (FloatType *base) - : BaseRules (base), base (base), resolved (nullptr) - {} - ~FloatRules () {} + FloatRules (FloatType *base) : BaseRules (base), base (base) {} TyBase *combine (TyBase *other) { @@ -338,7 +366,6 @@ public: private: FloatType *base; - TyBase *resolved; }; } // namespace TyTy diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index 40998ca..def43cd 100644 --- a/gcc/rust/typecheck/rust-tyty-visitor.h +++ b/gcc/rust/typecheck/rust-tyty-visitor.h @@ -27,17 +27,18 @@ namespace TyTy { class TyVisitor { public: - virtual void visit (UnitType &type) {} - virtual void visit (InferType &type) {} - virtual void visit (StructFieldType &type) {} - virtual void visit (ADTType &type) {} - virtual void visit (FnType &type) {} - virtual void visit (ParamType &type) {} - virtual void visit (ArrayType &type) {} - virtual void visit (BoolType &type) {} - virtual void visit (IntType &type) {} - virtual void visit (UintType &type) {} - virtual void visit (FloatType &type) {} + virtual void visit (UnitType &type) = 0; + virtual void visit (InferType &type) = 0; + virtual void visit (StructFieldType &type) = 0; + virtual void visit (ADTType &type) = 0; + virtual void visit (FnType &type) = 0; + virtual void visit (ParamType &type) = 0; + virtual void visit (ArrayType &type) = 0; + virtual void visit (BoolType &type) = 0; + virtual void visit (IntType &type) = 0; + virtual void visit (UintType &type) = 0; + virtual void visit (FloatType &type) = 0; + virtual void visit (ErrorType &type) = 0; }; } // namespace TyTy diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 0cefab6..033f839 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -64,6 +64,25 @@ InferType::combine (TyBase *other) } void +ErrorType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +std::string +ErrorType::as_string () const +{ + return "<tyty::error>"; +} + +TyBase * +ErrorType::combine (TyBase *other) +{ + // rust_error_at (); + return this; +} + +void StructFieldType::accept_vis (TyVisitor &vis) { vis.visit (*this); diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 59c4bcb..be7ec0c 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -43,13 +43,14 @@ enum TypeKind UNIT, FIELD, // there are more to add... + ERROR }; class TyVisitor; class TyBase { public: - ~TyBase () {} + virtual ~TyBase () {} HirId get_ref () const { return ref; } @@ -84,6 +85,20 @@ public: TyBase *combine (TyBase *other) override; }; +class ErrorType : public TyBase +{ +public: + ErrorType (HirId ref) : TyBase (ref, TypeKind::ERROR) {} + + void accept_vis (TyVisitor &vis) override; + + bool is_unit () const override { return true; } + + std::string as_string () const override; + + TyBase *combine (TyBase *other) override; +}; + class UnitType : public TyBase { public: diff --git a/gcc/testsuite/rust.test/compilable/deadcode1.rs b/gcc/testsuite/rust.test/compilable/deadcode1.rs new file mode 100644 index 0000000..ec6e240 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/deadcode1.rs @@ -0,0 +1,18 @@ +fn test1() -> i32 { + return 2; + 1 +} + +fn test2(x: i32) -> i32 { + if x > 1 { + return 5; + } else { + return 0; + } + return 1; +} + +fn main() { + let call1 = test1(); + let call2 = test2(2); +} diff --git a/gcc/testsuite/rust.test/compilable/float_types.rs b/gcc/testsuite/rust.test/compilable/float_types.rs new file mode 100644 index 0000000..50b392e --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/float_types.rs @@ -0,0 +1,11 @@ +fn main() { + let a1: f32 = 1.0f32; + let a2: f64 = 2.0f64; + let a3: f32 = 3f32; + let a4: f64 = 4f64; + + let b1 = 1.0f32; + let b2 = 2.0f64; + let b3 = 3f32; + let b4 = 4f64; +} diff --git a/gcc/testsuite/rust.test/compilable/implicit_returns1.rs b/gcc/testsuite/rust.test/compilable/implicit_returns1.rs new file mode 100644 index 0000000..49457c6 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/implicit_returns1.rs @@ -0,0 +1,65 @@ +fn test1() -> i32 { + 1 +} + +fn test2() -> i32 { + return 2; +} + +fn test3(x: i32) -> i32 { + if x > 1 { + 5 + } else { + 0 + } +} + +fn test4(x: i32) -> i32 { + if x > 1 { + return 1; + } + 0 +} + +fn test5(x: i32) -> i32 { + if x > 1 { + if x == 5 { + 7 + } else { + 9 + } + } else { + 0 + } +} + +fn test6(x: i32) -> i32 { + if x > 1 { + return 5; + } else { + return 0; + } +} + +fn test7(x: i32) -> i32 { + if x > 1 { + return 5; + } else { + return 0; + } +} + +fn test8() -> i32 { + return 1; +} + +fn main() { + let call1 = test1(); + let call2 = test2(); + let call3 = test3(3); + let call4 = test4(4); + let call5 = test5(5); + let call6 = test6(6); + let call7 = test7(7); + let call8 = test8(); +} diff --git a/gcc/testsuite/rust.test/compilable/literals1.rs b/gcc/testsuite/rust.test/compilable/literals1.rs new file mode 100644 index 0000000..cd48e83 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/literals1.rs @@ -0,0 +1,9 @@ +fn main() { + let hex: i32 = 0xFF; + let binary: i32 = 0b11110000; + let oct: i32 = 0o70; + + let hex_u8: u8 = 0xFF_u8; + let bin_u16: u16 = 0b1111000011110000_u16; + let oct: u32 = 0o70_u32; +} diff --git a/gcc/testsuite/rust.test/compilable/scoping1.rs b/gcc/testsuite/rust.test/compilable/scoping1.rs new file mode 100644 index 0000000..02b5f93 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/scoping1.rs @@ -0,0 +1,10 @@ +fn main() { + let x = 1; + { + let x = true; + { + x = false; + } + } + let x = x + 1; +} diff --git a/gcc/testsuite/rust.test/compilable/shadow2.rs b/gcc/testsuite/rust.test/compilable/shadow2.rs new file mode 100644 index 0000000..fbac8c0 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/shadow2.rs @@ -0,0 +1,4 @@ +fn main() { + let x = 1; + let x = x + 1; +} diff --git a/gcc/testsuite/rust.test/fail_compilation/missing_return1.rs b/gcc/testsuite/rust.test/fail_compilation/missing_return1.rs new file mode 100644 index 0000000..500d007 --- /dev/null +++ b/gcc/testsuite/rust.test/fail_compilation/missing_return1.rs @@ -0,0 +1,5 @@ +fn test1() -> i32 {} + +fn main() { + let call1 = test1(); +} |