aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSimplyTheOther <simplytheother@gmail.com>2021-01-10 14:30:39 +0800
committerSimplyTheOther <simplytheother@gmail.com>2021-01-10 14:30:39 +0800
commitb247c0d5aadf6eb7323641ffbcf7cc67bedd2c52 (patch)
tree3a4d3a0b0569d28f679ecbc74928125034d50f4f /gcc
parentee85db852a5a819e559ab00e7a382a34e925447a (diff)
parent0f42a240e53e932de0ae4799d54fe0bd15d06047 (diff)
downloadgcc-b247c0d5aadf6eb7323641ffbcf7cc67bedd2c52.zip
gcc-b247c0d5aadf6eb7323641ffbcf7cc67bedd2c52.tar.gz
gcc-b247c0d5aadf6eb7323641ffbcf7cc67bedd2c52.tar.bz2
Merge branch 'master' of https://github.com/redbrain/gccrs
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-expr.h2
-rw-r--r--gcc/rust/ast/rust-stmt.h2
-rw-r--r--gcc/rust/backend/rust-compile-context.h6
-rw-r--r--gcc/rust/backend/rust-compile-expr.h4
-rw-r--r--gcc/rust/backend/rust-compile-item.h17
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h62
-rw-r--r--gcc/rust/backend/rust-compile.cc17
-rw-r--r--gcc/rust/hir/rust-ast-lower-block.h37
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h23
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h7
-rw-r--r--gcc/rust/hir/rust-ast-lower-stmt.h18
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc67
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h2
-rw-r--r--gcc/rust/hir/tree/rust-hir.h2
-rw-r--r--gcc/rust/lex/rust-lex.cc10
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h23
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h73
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h32
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h19
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc36
-rw-r--r--gcc/rust/typecheck/rust-tyctx.cc5
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h12
-rw-r--r--gcc/rust/typecheck/rust-tyty-resolver.h20
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h173
-rw-r--r--gcc/rust/typecheck/rust-tyty-visitor.h23
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc19
-rw-r--r--gcc/rust/typecheck/rust-tyty.h17
-rw-r--r--gcc/testsuite/rust.test/compilable/deadcode1.rs18
-rw-r--r--gcc/testsuite/rust.test/compilable/float_types.rs11
-rw-r--r--gcc/testsuite/rust.test/compilable/implicit_returns1.rs65
-rw-r--r--gcc/testsuite/rust.test/compilable/literals1.rs9
-rw-r--r--gcc/testsuite/rust.test/compilable/scoping1.rs10
-rw-r--r--gcc/testsuite/rust.test/compilable/shadow2.rs4
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/missing_return1.rs5
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 &param : 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();
+}