aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimplyTheOther <simplytheother@gmail.com>2021-02-04 12:43:59 +0800
committerSimplyTheOther <simplytheother@gmail.com>2021-02-04 12:43:59 +0800
commit7c7c76f27f6ab999ec8fa299bde8911911fa7d90 (patch)
treee432cd20f59552da34313060fbcbd87e0ef9728a
parent877e7ac6c72608950fbe2ffde04142bbfb01b29d (diff)
parent9abf0733814c5e4131b96afb1c0abad68f4cf4ef (diff)
downloadgcc-7c7c76f27f6ab999ec8fa299bde8911911fa7d90.zip
gcc-7c7c76f27f6ab999ec8fa299bde8911911fa7d90.tar.gz
gcc-7c7c76f27f6ab999ec8fa299bde8911911fa7d90.tar.bz2
Merge branch 'master' of https://github.com/redbrain/gccrs
-rw-r--r--gcc/rust/ast/rust-ast.h6
-rw-r--r--gcc/rust/ast/rust-item.h21
-rw-r--r--gcc/rust/backend/rust-compile-base.h1
-rw-r--r--gcc/rust/backend/rust-compile-expr.h5
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h264
-rw-r--r--gcc/rust/backend/rust-compile-item.h8
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc4
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h2
-rw-r--r--gcc/rust/hir/README.md40
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.h156
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h41
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc1
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-decls.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc47
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h48
-rw-r--r--gcc/rust/hir/tree/rust-hir-macro.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir-stmt.h3
-rw-r--r--gcc/rust/hir/tree/rust-hir-visitor.h1
-rw-r--r--gcc/rust/hir/tree/rust-hir.h118
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h82
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h15
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h14
-rw-r--r--gcc/rust/rust-session-manager.cc4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h1
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h160
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h149
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h16
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc16
-rw-r--r--gcc/rust/typecheck/rust-tycheck-dump.h36
-rw-r--r--gcc/rust/util/rust-hir-map.cc24
-rw-r--r--gcc/rust/util/rust-hir-map.h6
-rw-r--r--gcc/testsuite/rust.test/compilable/impl_block1.rs23
-rw-r--r--gcc/testsuite/rust.test/compilable/impl_block2.rs28
-rw-r--r--gcc/testsuite/rust.test/compilable/integer_inference_var1.rs6
-rw-r--r--gcc/testsuite/rust.test/compilable/integer_inference_var2.rs6
-rw-r--r--gcc/testsuite/rust.test/compilable/integer_inference_var3.rs10
-rw-r--r--gcc/testsuite/rust.test/compilable/integer_inference_var4.rs4
-rw-r--r--gcc/testsuite/rust.test/compilable/integer_inference_var5.rs23
-rw-r--r--gcc/testsuite/rust.test/compilable/ints_infer1.rs18
42 files changed, 1111 insertions, 316 deletions
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index ddeb176..faecfba 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1323,6 +1323,8 @@ public:
virtual void mark_for_strip () = 0;
virtual bool is_marked_for_strip () const = 0;
+
+ virtual Location get_locus_slow () const = 0;
};
// Abstract base class for items used in a trait impl
@@ -1547,6 +1549,10 @@ public:
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const override { return get_locus (); }
+
protected:
MacroInvocationSemi *clone_macro_invocation_semi_impl () const
{
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 6de37f6..9437f21 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -698,6 +698,8 @@ class Method : public InherentImplItem, public TraitImplItem
Location locus;
+ NodeId node_id;
+
public:
// Returns whether the method is in an error state.
bool is_error () const
@@ -746,7 +748,8 @@ public:
function_params (std::move (function_params)),
return_type (std::move (return_type)),
where_clause (std::move (where_clause)),
- function_body (std::move (function_body)), locus (locus)
+ function_body (std::move (function_body)), locus (locus),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
// TODO: add constructor with less fields
@@ -769,6 +772,8 @@ public:
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
+
+ node_id = other.node_id;
}
// Overloaded assignment operator to clone
@@ -799,6 +804,8 @@ public:
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
+ node_id = other.node_id;
+
return *this;
}
@@ -860,6 +867,14 @@ public:
return where_clause;
}
+ Identifier get_method_name () const { return method_name; }
+
+ NodeId get_node_id () const { return node_id; }
+
+ Location get_locus () const { return locus; }
+
+ Location get_locus_slow () const override { return get_locus (); }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1505,6 +1520,8 @@ public:
Location get_locus () const { return locus; }
+ Location get_locus_slow () const override { return get_locus (); }
+
void accept_vis (ASTVisitor &vis) override;
// Invalid if block is null, so base stripping on that.
@@ -2538,6 +2555,8 @@ public:
Location get_locus () const { return locus; }
+ Location get_locus_slow () const override { return get_locus (); }
+
void accept_vis (ASTVisitor &vis) override;
// Invalid if type or expression are null, so base stripping on that.
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 6410fd4..fdc5ad9 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -51,7 +51,6 @@ public:
// virtual void visit(TraitItem& trait_item) {}
// virtual void visit(InherentImplItem& inherent_impl_item) {}
// virtual void visit(TraitImplItem& trait_impl_item) {}
- virtual void visit (HIR::MacroInvocationSemi &macro) {}
// rust-path.h
virtual void visit (HIR::PathInExpression &path) {}
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 81d7786..ccff51a 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -481,6 +481,11 @@ public:
expr.get_locus ());
}
+ void visit (HIR::PathInExpression &expr)
+ {
+ translated = ResolvePathRef::Compile (&expr, ctx);
+ }
+
private:
CompileExpr (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
new file mode 100644
index 0000000..fe2abf1
--- /dev/null
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -0,0 +1,264 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_COMPILE_IMPLITEM_H
+#define RUST_COMPILE_IMPLITEM_H
+
+#include "rust-compile-base.h"
+#include "rust-compile-tyty.h"
+#include "rust-compile-var-decl.h"
+#include "rust-compile-stmt.h"
+#include "rust-compile-expr.h"
+#include "rust-compile-fnparam.h"
+
+namespace Rust {
+namespace Compile {
+
+class CompileInherentImplItem : public HIRCompileBase
+{
+public:
+ static void Compile (HIR::Type *base, HIR::InherentImplItem *item,
+ Context *ctx, bool compile_fns)
+ {
+ CompileInherentImplItem compiler (base, ctx, compile_fns);
+ item->accept_vis (compiler);
+ }
+
+ void visit (HIR::ConstantItem &constant)
+ {
+ TyTy::TyBase *resolved_type = nullptr;
+ bool ok
+ = ctx->get_tyctx ()->lookup_type (constant.get_mappings ().get_hirid (),
+ &resolved_type);
+ rust_assert (ok);
+
+ ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
+ Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx);
+
+ std::string ident = base->as_string () + "::" + constant.get_identifier ();
+ Bexpression *const_expr = ctx->get_backend ()->named_constant_expression (
+ type, constant.get_identifier (), value, constant.get_locus ());
+
+ ctx->push_const (const_expr);
+ ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr);
+ }
+
+ void visit (HIR::Function &function)
+ {
+ if (!compile_fns)
+ return;
+
+ // items can be forward compiled which means we may not need to invoke this
+ // code
+ Bfunction *lookup = nullptr;
+ if (ctx->lookup_function_decl (function.get_mappings ().get_hirid (),
+ &lookup))
+ {
+ // has this been added to the list then it must be finished
+ if (ctx->function_completed (lookup))
+ return;
+ }
+
+ TyTy::TyBase *fntype_tyty;
+ if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
+ &fntype_tyty))
+ {
+ rust_fatal_error (function.locus, "failed to lookup function type");
+ return;
+ }
+
+ if (fntype_tyty->get_kind () != TyTy::TypeKind::FNDEF)
+ {
+ rust_error_at (function.get_locus (), "invalid TyTy for function item");
+ return;
+ }
+
+ TyTy::FnType *fntype = (TyTy::FnType *) fntype_tyty;
+ // convert to the actual function type
+ ::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
+
+ unsigned int flags = 0;
+ bool is_main_fn = function.function_name.compare ("main") == 0;
+
+ std::string fn_identifier
+ = base->as_string () + "::" + function.function_name;
+
+ // if its the main fn or pub visibility mark its as DECL_PUBLIC
+ // please see https://github.com/Rust-GCC/gccrs/pull/137
+ if (is_main_fn || function.has_visibility ())
+ flags |= Backend::function_is_visible;
+
+ std::string asm_name = fn_identifier;
+ if (!is_main_fn)
+ {
+ // FIXME need name mangling
+ asm_name = "__" + function.function_name;
+ }
+
+ Bfunction *fndecl
+ = ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
+ asm_name, flags, function.get_locus ());
+ ctx->insert_function_decl (function.get_mappings ().get_hirid (), fndecl);
+
+ // setup the params
+
+ TyTy::TyBase *tyret = fntype->return_type ();
+ std::vector<Bvariable *> param_vars;
+
+ size_t i = 0;
+ for (auto &it : fntype->get_params ())
+ {
+ HIR::FunctionParam &referenced_param = function.function_params.at (i);
+ auto param_tyty = it.second;
+ auto compiled_param_type
+ = TyTyResolveCompile::compile (ctx, param_tyty);
+
+ Location param_locus
+ = ctx->get_mappings ()->lookup_location (param_tyty->get_ref ());
+ Bvariable *compiled_param_var
+ = CompileFnParam::compile (ctx, fndecl, &referenced_param,
+ compiled_param_type, param_locus);
+ if (compiled_param_var == nullptr)
+ {
+ rust_error_at (param_locus, "failed to compile parameter variable");
+ return;
+ }
+
+ param_vars.push_back (compiled_param_var);
+
+ ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (),
+ compiled_param_var);
+ i++;
+ }
+
+ if (!ctx->get_backend ()->function_set_parameters (fndecl, param_vars))
+ {
+ rust_fatal_error (function.get_locus (),
+ "failed to setup parameter variables");
+ return;
+ }
+
+ // lookup locals
+ auto block_expr = function.function_body.get ();
+ auto body_mappings = block_expr->get_mappings ();
+
+ Resolver::Rib *rib = nullptr;
+ if (!ctx->get_resolver ()->find_name_rib (body_mappings.get_nodeid (),
+ &rib))
+ {
+ rust_fatal_error (function.get_locus (),
+ "failed to setup locals per block");
+ return;
+ }
+
+ std::vector<Bvariable *> locals;
+ rib->iterate_decls ([&] (NodeId n, Location) mutable -> bool {
+ Resolver::Definition d;
+ bool ok = ctx->get_resolver ()->lookup_definition (n, &d);
+ rust_assert (ok);
+
+ HIR::Stmt *decl = nullptr;
+ ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl);
+ rust_assert (ok);
+
+ Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
+ locals.push_back (compiled);
+
+ return true;
+ });
+
+ bool toplevel_item
+ = function.get_mappings ().get_local_defid () != UNKNOWN_LOCAL_DEFID;
+ Bblock *enclosing_scope
+ = toplevel_item ? NULL : ctx->peek_enclosing_scope ();
+
+ HIR::BlockExpr *function_body = function.function_body.get ();
+ Location start_location = function_body->get_locus ();
+ Location end_location = function_body->get_closing_locus ();
+
+ Bblock *code_block
+ = ctx->get_backend ()->block (fndecl, enclosing_scope, locals,
+ start_location, end_location);
+ ctx->push_block (code_block);
+
+ Bvariable *return_address = nullptr;
+ if (function.has_function_return_type ())
+ {
+ Btype *return_type = TyTyResolveCompile::compile (ctx, tyret);
+
+ bool address_is_taken = false;
+ Bstatement *ret_var_stmt = nullptr;
+
+ return_address = ctx->get_backend ()->temporary_variable (
+ fndecl, code_block, return_type, NULL, address_is_taken,
+ function.get_locus (), &ret_var_stmt);
+
+ ctx->add_statement (ret_var_stmt);
+ }
+
+ ctx->push_fn (fndecl, return_address);
+
+ // compile the block
+ function_body->iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
+ CompileStmt::Compile (s, ctx);
+ return true;
+ });
+
+ if (function_body->has_expr () && function_body->tail_expr_reachable ())
+ {
+ // 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))
+ {
+ rust_error_at (function.get_locus (), "failed to set body to function");
+ return;
+ }
+
+ ctx->pop_fn ();
+
+ ctx->push_function (fndecl);
+ }
+
+private:
+ CompileInherentImplItem (HIR::Type *base, Context *ctx, bool compile_fns)
+ : HIRCompileBase (ctx), base (base), compile_fns (compile_fns)
+ {}
+
+ HIR::Type *base;
+ bool compile_fns;
+};
+
+} // namespace Compile
+} // namespace Rust
+
+#endif // RUST_COMPILE_IMPLITEM_H
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 1bb7c91..83e4451 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -21,6 +21,7 @@
#include "rust-compile-base.h"
#include "rust-compile-tyty.h"
+#include "rust-compile-implitem.h"
#include "rust-compile-var-decl.h"
#include "rust-compile-stmt.h"
#include "rust-compile-expr.h"
@@ -300,6 +301,13 @@ public:
ctx->push_function (fndecl);
}
+ void visit (HIR::InherentImpl &impl_block)
+ {
+ for (auto &impl_item : impl_block.get_impl_items ())
+ CompileInherentImplItem::Compile (impl_block.get_type ().get (),
+ impl_item.get (), ctx, compile_fns);
+ }
+
private:
CompileItem (Context *ctx, bool compile_fns)
: HIRCompileBase (ctx), compile_fns (compile_fns)
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 818d5cb..de325fa 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -55,6 +55,10 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
return;
}
+ // might be a constant
+ if (ctx->lookup_const_decl (ref, &resolved))
+ return;
+
// this might be a variable reference or a function reference
Bvariable *var = nullptr;
if (ctx->lookup_var_decl (ref, &var))
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 06ea5a9..e701b15 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -38,8 +38,6 @@ public:
return compiler.translated;
}
- virtual ~CompileVarDecl () {}
-
void visit (HIR::LetStmt &stmt)
{
locus = stmt.get_locus ();
diff --git a/gcc/rust/hir/README.md b/gcc/rust/hir/README.md
deleted file mode 100644
index 550d104..0000000
--- a/gcc/rust/hir/README.md
+++ /dev/null
@@ -1,40 +0,0 @@
-# GCCRS HIR
-
-Working with the AST has proved to become difficult. To overcome non lexical scoping
-a toplevel scan pass was added to provide lookups for functioins. To get ready for the
-gimple conversion pass, type resolution scanned blocks to create the list of locals per
-block. Type Conversion had to create awkward getters/setters on LetStmts to have a Type or
-InferedType which was more of a hack that what should really be there. ArrayExprs get checked
-and create their own type to be checked against a possible LetStmt type. All of these things
-started to become hard to manage.
-
-HIR from the RFC defines how they create lookups and IDs for all the nodes which solves the toplevel
-scan pass. The lowering to HIR allows for cleanup in how types are resolved. Without using
-the HIR and IDs implementing the shadowing rules was going to become very difficult.
-
-
-## IMPL:
-
-* AST-lower - move down to HIR classes - generate mappings and IDs
-
-* Name Resolution - Check for path segments naming and map to HirIDS
- This should in theory map for example a call expression to already have the HirID to the function ready
- Dyn dispatch may need some help here if its a method the receiver could be bound the local name hirid
- the resoltion would need to be fixed up in type resolution pass
-
-* Expand - Gather locals per block and fix up returns is it possible to generate return expressions
- at this pass?
-
-* Type Resolution - Port over work from AST Type resolver
- generate mir from this pass?
-
-
-For now this can then port over to the existing GIMPLE conversion faily easily. But after more
-of the core data structures work MIR will be needed for all the glue that will need to be generated.
-
-
-## Returns
-
-looks like its implemented by an implicit mutable return variable for the function. If were processing
-a block expression and the last element on the block is an expression we can try to bind it to the mutable
-return variable.
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
new file mode 100644
index 0000000..dab3208
--- /dev/null
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -0,0 +1,156 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_AST_LOWER_IMPLITEM_H
+#define RUST_AST_LOWER_IMPLITEM_H
+
+#include "rust-diagnostics.h"
+#include "rust-ast-lower-type.h"
+#include "rust-ast-lower-stmt.h"
+#include "rust-ast-lower-expr.h"
+#include "rust-ast-lower-pattern.h"
+#include "rust-ast-lower-block.h"
+
+namespace Rust {
+namespace HIR {
+
+class ASTLowerImplItem : public ASTLoweringBase
+{
+public:
+ static HIR::InherentImplItem *translate (AST::InherentImplItem *item)
+ {
+ ASTLowerImplItem resolver;
+ item->accept_vis (resolver);
+ rust_assert (resolver.translated != nullptr);
+ return resolver.translated;
+ }
+
+ void visit (AST::ConstantItem &constant)
+ {
+ std::vector<HIR::Attribute> outer_attrs;
+ HIR::Visibility vis = HIR::Visibility::create_public ();
+
+ HIR::Type *type = ASTLoweringType::translate (constant.get_type ().get ());
+ HIR::Expr *expr = ASTLoweringExpr::translate (constant.get_expr ().get ());
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, constant.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
+ translated = new HIR::ConstantItem (mapping, constant.get_identifier (),
+ vis, std::unique_ptr<HIR::Type> (type),
+ std::unique_ptr<HIR::Expr> (expr),
+ outer_attrs, constant.get_locus ());
+
+ mappings->insert_hir_implitem (mapping.get_crate_num (),
+ mapping.get_hirid (), translated);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ constant.get_locus ());
+ }
+
+ void visit (AST::Function &function)
+ {
+ // ignore for now and leave empty
+ std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+ std::vector<HIR::Attribute> outer_attrs;
+ std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+ HIR::WhereClause where_clause (std::move (where_clause_items));
+ HIR::FunctionQualifiers qualifiers (
+ HIR::FunctionQualifiers::AsyncConstStatus::NONE, false);
+ HIR::Visibility vis = HIR::Visibility::create_public ();
+
+ // need
+ Identifier function_name = function.get_function_name ();
+ Location locus = function.get_locus ();
+
+ std::unique_ptr<HIR::Type> return_type
+ = function.has_return_type () ? std::unique_ptr<HIR::Type> (
+ ASTLoweringType::translate (function.get_return_type ().get ()))
+ : nullptr;
+
+ std::vector<HIR::FunctionParam> function_params;
+ for (auto &param : function.get_function_params ())
+ {
+ auto translated_pattern = std::unique_ptr<HIR::Pattern> (
+ ASTLoweringPattern::translate (param.get_pattern ().get ()));
+ auto translated_type = std::unique_ptr<HIR::Type> (
+ ASTLoweringType::translate (param.get_type ().get ()));
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ auto hir_param
+ = HIR::FunctionParam (mapping, std::move (translated_pattern),
+ std::move (translated_type),
+ param.get_locus ());
+ 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 (),
+ &terminated));
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
+ mappings->insert_location (crate_num,
+ function_body->get_mappings ().get_hirid (),
+ function.get_locus ());
+
+ auto fn
+ = new HIR::Function (mapping, std::move (function_name),
+ std::move (qualifiers), std::move (generic_params),
+ std::move (function_params), std::move (return_type),
+ std::move (where_clause), std::move (function_body),
+ std::move (vis), std::move (outer_attrs), locus);
+
+ mappings->insert_hir_implitem (mapping.get_crate_num (),
+ mapping.get_hirid (), fn);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ function.get_locus ());
+
+ // add the mappings for the function params at the end
+ for (auto &param : fn->function_params)
+ {
+ mappings->insert_hir_param (mapping.get_crate_num (),
+ param.get_mappings ().get_hirid (), &param);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ param.get_locus ());
+ }
+
+ translated = fn;
+ }
+
+private:
+ ASTLowerImplItem () : translated (nullptr) {}
+
+ HIR::InherentImplItem *translated;
+};
+
+} // namespace HIR
+
+} // namespace Rust
+
+#endif // RUST_AST_LOWER_IMPLITEM_H
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index ec4ef6b..1e48e82 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -23,6 +23,7 @@
#include "rust-ast-lower-base.h"
#include "rust-ast-lower-type.h"
+#include "rust-ast-lower-implitem.h"
#include "rust-ast-lower-stmt.h"
#include "rust-ast-lower-expr.h"
#include "rust-ast-lower-pattern.h"
@@ -282,6 +283,46 @@ public:
translated = fn;
}
+ void visit (AST::InherentImpl &impl_block)
+ {
+ std::vector<HIR::Attribute> inner_attrs;
+ std::vector<HIR::Attribute> outer_attrs;
+ std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+ std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+
+ HIR::WhereClause where_clause (std::move (where_clause_items));
+ HIR::Visibility vis = HIR::Visibility::create_public ();
+ HIR::Type *trait_type
+ = ASTLoweringType::translate (impl_block.get_type ().get ());
+
+ std::vector<std::unique_ptr<HIR::InherentImplItem> > impl_items;
+ for (auto &impl_item : impl_block.get_impl_items ())
+ {
+ HIR::InherentImplItem *lowered
+ = ASTLowerImplItem::translate (impl_item.get ());
+ impl_items.push_back (std::unique_ptr<HIR::InherentImplItem> (lowered));
+ }
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, impl_block.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
+ translated
+ = new HIR::InherentImpl (mapping, std::move (impl_items),
+ std::move (generic_params),
+ std::unique_ptr<HIR::Type> (trait_type),
+ where_clause, vis, std::move (inner_attrs),
+ std::move (outer_attrs),
+ impl_block.get_locus ());
+
+ mappings->insert_defid_mapping (mapping.get_defid (), translated);
+ mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (),
+ translated);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ impl_block.get_locus ());
+ }
+
private:
ASTLoweringItem () : translated (nullptr) {}
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index dac2320..c1ea01a 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -18,6 +18,7 @@
#include "rust-ast-lower.h"
#include "rust-ast-lower-item.h"
+#include "rust-ast-lower-implitem.h"
#include "rust-ast-lower-expr.h"
#include "rust-ast-lower-block.h"
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 02b9f03..8295e89 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -53,7 +53,6 @@ class MacroItem;
class TraitItem;
class InherentImplItem;
class TraitImplItem;
-class MacroInvocationSemi;
struct Crate;
class PathExpr;
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index b727917..8502c9c 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -1377,47 +1377,6 @@ TypeAlias::as_string () const
}
std::string
-MacroInvocationSemi::as_string () const
-{
- // get outer attrs
- std::string str = MacroItem::as_string ();
-
- str += "\n" + path.as_string () + "!";
-
- std::string tok_trees;
- if (token_trees.empty ())
- {
- tok_trees = "none";
- }
- else
- {
- auto i = token_trees.begin ();
- auto e = token_trees.end ();
-
- // DEBUG: null pointer check
- if (i == e)
- {
- fprintf (stderr,
- "something really terrible has gone wrong - null pointer "
- "token tree in macro invocation semi.");
- return "nullptr_POINTER_MARK";
- }
-
- std::string s;
- for (; i != e; i++)
- {
- s += (*i)->as_string ();
- if (e != i + 1)
- s += ", ";
- }
-
- tok_trees += get_string_in_delims (s, delim_type);
- }
-
- return str;
-}
-
-std::string
ExternBlock::as_string () const
{
std::string str = VisItem::as_string ();
@@ -5046,12 +5005,6 @@ LifetimeParam::accept_vis (HIRVisitor &vis)
}
void
-MacroInvocationSemi::accept_vis (HIRVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
PathInExpression::accept_vis (HIRVisitor &vis)
{
vis.visit (*this);
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index e99dd38..e90dbb4 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -27,7 +27,6 @@ namespace HIR {
// forward decls
class BlockExpr;
class TypePath;
-class MacroInvocationSemi;
// A type generic parameter (as opposed to a lifetime generic parameter)
class TypeParam : public GenericParam
@@ -569,6 +568,8 @@ class Method : public InherentImplItem, public TraitImplItem
std::unique_ptr<BlockExpr> expr;
+ Analysis::NodeMapping mappings;
+
Location locus;
public:
@@ -588,14 +589,15 @@ public:
bool has_visibility () const { return !vis.is_error (); }
// Mega-constructor with all possible fields
- Method (Identifier method_name, FunctionQualifiers qualifiers,
+ Method (Analysis::NodeMapping mappings, Identifier method_name,
+ FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam> > generic_params,
SelfParam self_param, std::vector<FunctionParam> function_params,
std::unique_ptr<Type> return_type, WhereClause where_clause,
std::unique_ptr<BlockExpr> function_body, Visibility vis,
std::vector<Attribute> outer_attrs, Location locus = Location ())
- : outer_attrs (std::move (outer_attrs)), vis (std::move (vis)),
- qualifiers (std::move (qualifiers)),
+ : mappings (mappings), outer_attrs (std::move (outer_attrs)),
+ vis (std::move (vis)), qualifiers (std::move (qualifiers)),
method_name (std::move (method_name)),
generic_params (std::move (generic_params)),
self_param (std::move (self_param)),
@@ -609,9 +611,10 @@ public:
// Copy constructor with clone
Method (Method const &other)
- : outer_attrs (other.outer_attrs), vis (other.vis),
- qualifiers (other.qualifiers), method_name (other.method_name),
- self_param (other.self_param), function_params (other.function_params),
+ : mappings (other.mappings), outer_attrs (other.outer_attrs),
+ vis (other.vis), qualifiers (other.qualifiers),
+ method_name (other.method_name), self_param (other.self_param),
+ function_params (other.function_params),
return_type (other.return_type->clone_type ()),
where_clause (other.where_clause), expr (other.expr->clone_block_expr ()),
locus (other.locus)
@@ -624,6 +627,7 @@ public:
// Overloaded assignment operator to clone
Method &operator= (Method const &other)
{
+ mappings = other.mappings;
method_name = other.method_name;
outer_attrs = other.outer_attrs;
vis = other.vis;
@@ -650,6 +654,13 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ Analysis::NodeMapping get_mappings () const { return mappings; };
+
+ Analysis::NodeMapping get_impl_mappings () const override
+ {
+ return get_mappings ();
+ };
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -1267,6 +1278,11 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ Analysis::NodeMapping get_impl_mappings () const override
+ {
+ return get_mappings ();
+ };
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2096,6 +2112,11 @@ public:
std::string get_identifier () { return identifier; }
+ Analysis::NodeMapping get_impl_mappings () const override
+ {
+ return get_mappings ();
+ };
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -2767,6 +2788,8 @@ public:
Location get_locus () const { return locus; }
+ std::unique_ptr<Type> &get_type () { return trait_type; };
+
protected:
// Mega-constructor
Impl (Analysis::NodeMapping mappings,
@@ -2864,6 +2887,16 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ std::vector<std::unique_ptr<InherentImplItem> > &get_impl_items ()
+ {
+ return impl_items;
+ };
+
+ const std::vector<std::unique_ptr<InherentImplItem> > &get_impl_items () const
+ {
+ return impl_items;
+ };
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
@@ -3300,7 +3333,6 @@ protected:
// Replaced with forward decls - defined in "rust-macro.h"
class MacroItem;
-class MacroInvocationSemi;
class MacroRulesDefinition;
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-macro.h b/gcc/rust/hir/tree/rust-hir-macro.h
index 84b4914..13f0d22 100644
--- a/gcc/rust/hir/tree/rust-hir-macro.h
+++ b/gcc/rust/hir/tree/rust-hir-macro.h
@@ -25,7 +25,6 @@ namespace Rust {
namespace HIR {
// Decls as definitions moved to rust-ast.h
class MacroItem;
-class MacroInvocationSemi;
enum MacroFragSpec
{
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
index be4ff7d..3384aaa 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -233,9 +233,6 @@ protected:
}
};
-/* Replaced definition of MacroInvocationSemi with forward decl - defined in
- * rust-macro.h */
-class MacroInvocationSemi;
} // namespace HIR
} // namespace Rust
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 7fefb69..a7b9791 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -52,7 +52,6 @@ public:
// virtual void visit(TraitItem& trait_item) = 0;
// virtual void visit(InherentImplItem& inherent_impl_item) = 0;
// virtual void visit(TraitImplItem& trait_impl_item) = 0;
- virtual void visit (MacroInvocationSemi &macro) = 0;
// rust-path.h
virtual void visit (PathInExpression &path) = 0;
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index e4a81c5..6fd6297 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -1256,6 +1256,8 @@ public:
virtual std::string as_string () const = 0;
virtual void accept_vis (HIRVisitor &vis) = 0;
+
+ virtual Analysis::NodeMapping get_impl_mappings () const = 0;
};
// Abstract base class for items used in a trait impl
@@ -1278,122 +1280,6 @@ public:
virtual void accept_vis (HIRVisitor &vis) = 0;
};
-/* A macro invocation item (or statement) HIR node (i.e. semi-coloned macro
- * invocation) */
-class MacroInvocationSemi : public MacroItem,
- public TraitItem,
- public InherentImplItem,
- public TraitImplItem
-{
- SimplePath path;
- // all delim types except curly must have invocation end with a semicolon
- DelimType delim_type;
- std::vector<std::unique_ptr<TokenTree> > token_trees;
- Location locus;
-
-public:
- std::string as_string () const override;
-
- MacroInvocationSemi (Analysis::NodeMapping mappings, SimplePath macro_path,
- DelimType delim_type,
- std::vector<std::unique_ptr<TokenTree> > token_trees,
- std::vector<Attribute> outer_attribs, Location locus)
- : MacroItem (std::move (mappings), std::move (outer_attribs)),
- path (std::move (macro_path)), delim_type (delim_type),
- token_trees (std::move (token_trees)), locus (locus)
- {}
- /* TODO: possible issue with Item and TraitItem hierarchies both having outer
- * attributes
- * - storage inefficiency at least.
- * Best current idea is to make Item preferred and have TraitItem get virtual
- * functions for attributes or something. Or just redo the "composition"
- * approach, but then this prevents polymorphism and would entail redoing
- * quite a bit of the parser. */
-
- // Move constructors
- MacroInvocationSemi (MacroInvocationSemi &&other) = default;
- MacroInvocationSemi &operator= (MacroInvocationSemi &&other) = default;
-
- void accept_vis (HIRVisitor &vis) override;
-
- // Clones this macro invocation semi.
- std::unique_ptr<MacroInvocationSemi> clone_macro_invocation_semi () const
- {
- return std::unique_ptr<MacroInvocationSemi> (
- clone_macro_invocation_semi_impl ());
- }
-
-protected:
- // Copy constructor with vector clone
- MacroInvocationSemi (MacroInvocationSemi const &other)
- : MacroItem (other), TraitItem (other), InherentImplItem (other),
- TraitImplItem (other), path (other.path), delim_type (other.delim_type),
- locus (other.locus)
- {
- token_trees.reserve (other.token_trees.size ());
- for (const auto &e : other.token_trees)
- token_trees.push_back (e->clone_token_tree ());
- }
-
- // Overloaded assignment operator to vector clone
- MacroInvocationSemi &operator= (MacroInvocationSemi const &other)
- {
- MacroItem::operator= (other);
- TraitItem::operator= (other);
- InherentImplItem::operator= (other);
- TraitImplItem::operator= (other);
- path = other.path;
- delim_type = other.delim_type;
- locus = other.locus;
-
- token_trees.reserve (other.token_trees.size ());
- for (const auto &e : other.token_trees)
- token_trees.push_back (e->clone_token_tree ());
-
- return *this;
- }
-
- MacroInvocationSemi *clone_macro_invocation_semi_impl () const
- {
- return new MacroInvocationSemi (*this);
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- MacroInvocationSemi *clone_item_impl () const override
- {
- return clone_macro_invocation_semi_impl ();
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- MacroInvocationSemi *clone_inherent_impl_item_impl () const override
- {
- return clone_macro_invocation_semi_impl ();
- }
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- MacroInvocationSemi *clone_trait_impl_item_impl () const override
- {
- return clone_macro_invocation_semi_impl ();
- }
-
- // FIXME: remove if item impl virtual override works properly
- // Use covariance to implement clone function as returning this object rather
- // than base
- /*MacroInvocationSemi* clone_statement_impl() const override {
- return clone_macro_invocation_semi_impl ();
- }*/
-
- /* Use covariance to implement clone function as returning this object rather
- * than base */
- MacroInvocationSemi *clone_trait_item_impl () const override
- {
- return clone_macro_invocation_semi_impl ();
- }
-};
-
// A crate HIR object - holds all the data for a single compilation unit
struct Crate
{
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
new file mode 100644
index 0000000..74f2cdc
--- /dev/null
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -0,0 +1,82 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_AST_RESOLVE_IMPLITEM_H
+#define RUST_AST_RESOLVE_IMPLITEM_H
+
+#include "rust-ast-resolve-base.h"
+#include "rust-ast-resolve-type.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolveToplevelImplItem : public ResolverBase
+{
+public:
+ static void go (AST::InherentImplItem *item, AST::Type *base)
+ {
+ ResolveToplevelImplItem resolver (base);
+ item->accept_vis (resolver);
+ };
+
+ void visit (AST::ConstantItem &constant)
+ {
+ std::string identifier
+ = base->as_string () + "::" + constant.get_identifier ();
+ resolver->get_name_scope ().insert (identifier, constant.get_node_id (),
+ constant.get_locus ());
+ resolver->insert_new_definition (constant.get_node_id (),
+ Definition{constant.get_node_id (),
+ constant.get_node_id ()});
+ }
+
+ void visit (AST::Function &function)
+ {
+ std::string identifier
+ = base->as_string () + "::" + function.get_function_name ();
+ resolver->get_name_scope ().insert (identifier, function.get_node_id (),
+ function.get_locus ());
+ resolver->insert_new_definition (function.get_node_id (),
+ Definition{function.get_node_id (),
+ function.get_node_id ()});
+ }
+
+ void visit (AST::Method &method)
+ {
+ std::string identifier
+ = base->as_string () + "::" + method.get_method_name ();
+ resolver->get_name_scope ().insert (identifier, method.get_node_id (),
+ method.get_locus ());
+ resolver->insert_new_definition (method.get_node_id (),
+ Definition{method.get_node_id (),
+ method.get_node_id ()});
+ }
+
+private:
+ ResolveToplevelImplItem (AST::Type *base)
+ : ResolverBase (UNKNOWN_NODEID), base (base)
+ {}
+
+ AST::Type *base;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_AST_RESOLVE_IMPLITEM_H
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 0f45ba0..74b5f8d 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -117,6 +117,12 @@ public:
resolver->get_type_scope ().pop ();
}
+ void visit (AST::InherentImpl &impl_block)
+ {
+ for (auto &impl_item : impl_block.get_impl_items ())
+ impl_item->accept_vis (*this);
+ }
+
private:
ResolveItem () : ResolverBase (UNKNOWN_NODEID) {}
};
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index c3f5e4c..7ca8275 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -20,6 +20,8 @@
#define RUST_AST_RESOLVE_TOPLEVEL_H
#include "rust-ast-resolve-base.h"
+#include "rust-ast-resolve-type.h"
+#include "rust-ast-resolve-implitem.h"
#include "rust-ast-full.h"
namespace Rust {
@@ -34,8 +36,6 @@ public:
item->accept_vis (resolver);
};
- ~ResolveTopLevel () {}
-
void visit (AST::TupleStruct &struct_decl)
{
resolver->get_type_scope ().insert (struct_decl.get_identifier (),
@@ -88,6 +88,17 @@ public:
}
}
+ void visit (AST::InherentImpl &impl_block)
+ {
+ if (!ResolveType::go (impl_block.get_type ().get (),
+ impl_block.get_node_id ()))
+ return;
+
+ for (auto &impl_item : impl_block.get_impl_items ())
+ ResolveToplevelImplItem::go (impl_item.get (),
+ impl_block.get_type ().get ());
+ }
+
private:
ResolveTopLevel () : ResolverBase (UNKNOWN_NODEID) {}
};
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index b303ee9..258524b 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -28,14 +28,19 @@ namespace Resolver {
class ResolveType : public ResolverBase
{
public:
- static void go (AST::Type *type, NodeId parent)
+ static bool go (AST::Type *type, NodeId parent)
{
ResolveType resolver (parent);
type->accept_vis (resolver);
+ if (!resolver.ok)
+ rust_error_at (type->get_locus_slow (), "unresolved type");
+
+ return resolver.ok;
};
void visit (AST::BareFunctionType &fntype)
{
+ ok = true;
for (auto &param : fntype.get_function_params ())
ResolveType::go (param.get_type ().get (), fntype.get_node_id ());
@@ -45,6 +50,7 @@ public:
void visit (AST::TupleType &tuple)
{
+ ok = true;
if (tuple.is_unit_type ())
{
resolved_node = resolver->get_unit_type_node_id ();
@@ -65,6 +71,8 @@ public:
path.as_string ().c_str ());
return;
}
+
+ ok = true;
resolver->insert_resolved_type (path.get_node_id (), resolved_node);
resolver->insert_new_definition (path.get_node_id (),
Definition{path.get_node_id (), parent});
@@ -76,7 +84,9 @@ public:
}
private:
- ResolveType (NodeId parent) : ResolverBase (parent) {}
+ ResolveType (NodeId parent) : ResolverBase (parent), ok (false) {}
+
+ bool ok;
};
} // namespace Resolver
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index afc238b..281049d 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -550,8 +550,8 @@ Session::parse_file (const char *filename)
type_resolution (hir);
// FIXME this needs an option of itself
- auto buf = Resolver::TypeResolverDump::go (hir);
- fprintf (stderr, "%s\n", buf.c_str ());
+ // auto buf = Resolver::TypeResolverDump::go (hir);
+ // fprintf (stderr, "%s\n", buf.c_str ());
if (saw_errors ())
return;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index 78afff9..8de1474 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -55,7 +55,6 @@ public:
// virtual void visit(TraitItem& trait_item) {}
// virtual void visit(InherentImplItem& inherent_impl_item) {}
// virtual void visit(TraitImplItem& trait_impl_item) {}
- virtual void visit (HIR::MacroInvocationSemi &macro) {}
// rust-path.h
virtual void visit (HIR::PathInExpression &path) {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 78f0d0d..82977e4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -37,10 +37,7 @@ public:
expr->accept_vis (resolver);
if (resolver.infered == nullptr)
- {
- resolver.infered
- = new TyTy::UnitType (expr->get_mappings ().get_hirid ());
- }
+ return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
auto ref = expr->get_mappings ().get_hirid ();
resolver.infered->set_ref (ref);
@@ -428,73 +425,19 @@ public:
{
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
- auto combined = lhs->combine (rhs);
- // https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators
- switch (expr.get_expr_type ())
+ bool valid_lhs = validate_arithmetic_type (lhs, expr.get_expr_type ());
+ bool valid_rhs = validate_arithmetic_type (rhs, expr.get_expr_type ());
+ bool valid = valid_lhs && valid_rhs;
+ if (!valid)
{
- // integers or floats
- case HIR::ArithmeticOrLogicalExpr::ADD:
- case HIR::ArithmeticOrLogicalExpr::SUBTRACT:
- case HIR::ArithmeticOrLogicalExpr::MULTIPLY:
- case HIR::ArithmeticOrLogicalExpr::DIVIDE:
- case HIR::ArithmeticOrLogicalExpr::MODULUS: {
- bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
- || (combined->get_kind () == TyTy::TypeKind::UINT)
- || (combined->get_kind () == TyTy::TypeKind::FLOAT)
- || (combined->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) combined)->get_infer_kind ()
- == TyTy::InferType::INTEGRAL))
- || (combined->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) combined)->get_infer_kind ()
- == TyTy::InferType::FLOAT));
- if (!valid)
- {
- rust_error_at (expr.get_locus (), "cannot apply operator to %s",
- combined->as_string ().c_str ());
- return;
- }
- }
- break;
-
- // integers or bools
- case HIR::ArithmeticOrLogicalExpr::BITWISE_AND:
- case HIR::ArithmeticOrLogicalExpr::BITWISE_OR:
- case HIR::ArithmeticOrLogicalExpr::BITWISE_XOR: {
- bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
- || (combined->get_kind () == TyTy::TypeKind::UINT)
- || (combined->get_kind () == TyTy::TypeKind::BOOL)
- || (combined->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) combined)->get_infer_kind ()
- == TyTy::InferType::INTEGRAL));
- if (!valid)
- {
- rust_error_at (expr.get_locus (), "cannot apply operator to %s",
- combined->as_string ().c_str ());
- return;
- }
- }
- break;
-
- // integers only
- case HIR::ArithmeticOrLogicalExpr::LEFT_SHIFT:
- case HIR::ArithmeticOrLogicalExpr::RIGHT_SHIFT: {
- bool valid = (combined->get_kind () == TyTy::TypeKind::INT)
- || (combined->get_kind () == TyTy::TypeKind::UINT)
- || (combined->get_kind () == TyTy::TypeKind::INFER
- && (((TyTy::InferType *) combined)->get_infer_kind ()
- == TyTy::InferType::INTEGRAL));
- if (!valid)
- {
- rust_error_at (expr.get_locus (), "cannot apply operator to %s",
- combined->as_string ().c_str ());
- return;
- }
- }
- break;
+ rust_error_at (expr.get_locus (),
+ "cannot apply this operator to types %s and %s",
+ lhs->as_string ().c_str (), rhs->as_string ().c_str ());
+ return;
}
- infered = combined;
+ infered = lhs->combine (rhs);
infered->append_reference (lhs->get_ref ());
infered->append_reference (rhs->get_ref ());
}
@@ -594,7 +537,10 @@ public:
{
auto expected_ty = context->peek_return_type ();
infered = expected_ty->combine (blk_expr);
+ return;
}
+
+ infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ());
}
void visit (HIR::IfExprConseqElse &expr)
@@ -633,7 +579,10 @@ public:
auto else_blk_combined = expected_ty->combine (else_block_tyty);
infered = if_blk_combined->combine (else_blk_combined);
+ return;
}
+
+ infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ());
}
void visit (HIR::IfExprConseqIf &expr)
@@ -649,7 +598,10 @@ public:
infered = expected_ty->combine (if_blk);
infered = infered->combine (elif_blk);
+ return;
}
+
+ infered = new TyTy::UnitType (expr.get_mappings ().get_hirid ());
}
void visit (HIR::BlockExpr &expr);
@@ -769,12 +721,86 @@ public:
infered = resolved->get_field_type ();
}
+ void visit (HIR::PathInExpression &expr)
+ {
+ NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
+
+ // then lookup the reference_node_id
+ NodeId ref_node_id;
+ if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
+ {
+ if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+ {
+ rust_error_at (expr.get_locus (),
+ "Failed to lookup reference for node: %s",
+ expr.as_string ().c_str ());
+ return;
+ }
+ }
+
+ // node back to HIR
+ HirId ref;
+ if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
+ ref_node_id, &ref))
+ {
+ rust_error_at (expr.get_locus (), "reverse lookup failure");
+ return;
+ }
+
+ context->lookup_type (ref, &infered);
+ }
+
private:
TypeCheckExpr (bool is_final_expr)
: TypeCheckBase (), infered (nullptr), infered_array_elems (nullptr),
is_final_expr (is_final_expr)
{}
+ bool
+ validate_arithmetic_type (TyTy::TyBase *type,
+ HIR::ArithmeticOrLogicalExpr::ExprType expr_type)
+ {
+ // https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators
+ // this will change later when traits are added
+ switch (expr_type)
+ {
+ case HIR::ArithmeticOrLogicalExpr::ADD:
+ case HIR::ArithmeticOrLogicalExpr::SUBTRACT:
+ case HIR::ArithmeticOrLogicalExpr::MULTIPLY:
+ case HIR::ArithmeticOrLogicalExpr::DIVIDE:
+ case HIR::ArithmeticOrLogicalExpr::MODULUS:
+ return (type->get_kind () == TyTy::TypeKind::INT)
+ || (type->get_kind () == TyTy::TypeKind::UINT)
+ || (type->get_kind () == TyTy::TypeKind::FLOAT)
+ || (type->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) type)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL))
+ || (type->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) type)->get_infer_kind ()
+ == TyTy::InferType::FLOAT));
+
+ // integers or bools
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_AND:
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_OR:
+ case HIR::ArithmeticOrLogicalExpr::BITWISE_XOR:
+ return (type->get_kind () == TyTy::TypeKind::INT)
+ || (type->get_kind () == TyTy::TypeKind::UINT)
+ || (type->get_kind () == TyTy::TypeKind::BOOL)
+ || (type->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) type)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL));
+
+ // integers only
+ case HIR::ArithmeticOrLogicalExpr::LEFT_SHIFT:
+ case HIR::ArithmeticOrLogicalExpr::RIGHT_SHIFT:
+ return (type->get_kind () == TyTy::TypeKind::INT)
+ || (type->get_kind () == TyTy::TypeKind::UINT)
+ || (type->get_kind () == TyTy::TypeKind::INFER
+ && (((TyTy::InferType *) type)->get_infer_kind ()
+ == TyTy::InferType::INTEGRAL));
+ }
+ }
+
TyTy::TyBase *infered;
TyTy::TyBase *infered_array_elems;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
new file mode 100644
index 0000000..abaee73
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -0,0 +1,149 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK_IMPLITEM_H
+#define RUST_HIR_TYPE_CHECK_IMPLITEM_H
+
+#include "rust-hir-type-check-base.h"
+#include "rust-hir-full.h"
+#include "rust-hir-type-check-type.h"
+#include "rust-hir-type-check-expr.h"
+#include "rust-tyty.h"
+
+namespace Rust {
+namespace Resolver {
+
+class TypeCheckTopLevelImplItem : public TypeCheckBase
+{
+public:
+ static void Resolve (HIR::InherentImplItem *item)
+ {
+ TypeCheckTopLevelImplItem resolver;
+ item->accept_vis (resolver);
+ }
+
+ void visit (HIR::ConstantItem &constant)
+ {
+ TyTy::TyBase *type = TypeCheckType::Resolve (constant.get_type ());
+ TyTy::TyBase *expr_type = TypeCheckExpr::Resolve (constant.get_expr ());
+
+ context->insert_type (constant.get_mappings (), type->combine (expr_type));
+ }
+
+ void visit (HIR::Function &function)
+ {
+ TyTy::TyBase *ret_type = nullptr;
+ if (!function.has_function_return_type ())
+ ret_type = new TyTy::UnitType (function.get_mappings ().get_hirid ());
+ else
+ {
+ auto resolved = TypeCheckType::Resolve (function.return_type.get ());
+ if (resolved == nullptr)
+ {
+ rust_error_at (function.get_locus (),
+ "failed to resolve return type");
+ return;
+ }
+
+ ret_type = resolved->clone ();
+ ret_type->set_ref (function.return_type->get_mappings ().get_hirid ());
+ }
+
+ std::vector<std::pair<HIR::Pattern *, TyTy::TyBase *> > params;
+ for (auto &param : function.function_params)
+ {
+ // get the name as well required for later on
+ auto param_tyty = TypeCheckType::Resolve (param.get_type ());
+ params.push_back (
+ std::pair<HIR::Pattern *, TyTy::TyBase *> (param.get_param_name (),
+ param_tyty));
+
+ context->insert_type (param.get_mappings (), param_tyty);
+ }
+
+ auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
+ params, ret_type);
+ context->insert_type (function.get_mappings (), fnType);
+ }
+
+private:
+ TypeCheckTopLevelImplItem () : TypeCheckBase () {}
+};
+
+class TypeCheckImplItem : public TypeCheckBase
+{
+public:
+ static void Resolve (HIR::InherentImplItem *item, TyTy::TyBase *self)
+ {
+ TypeCheckImplItem resolver (self);
+ item->accept_vis (resolver);
+ }
+
+ void visit (HIR::Function &function)
+ {
+ TyTy::TyBase *lookup;
+ if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup))
+ {
+ rust_error_at (function.locus, "failed to lookup function type");
+ return;
+ }
+
+ if (lookup->get_kind () != TyTy::TypeKind::FNDEF)
+ {
+ rust_error_at (function.get_locus (),
+ "found invalid type for function [%s]",
+ lookup->as_string ().c_str ());
+ return;
+ }
+
+ // need to get the return type from this
+ TyTy::FnType *resolve_fn_type = (TyTy::FnType *) lookup;
+ auto expected_ret_tyty = resolve_fn_type->return_type ();
+ context->push_return_type (expected_ret_tyty);
+
+ TypeCheckExpr::Resolve (function.function_body.get ());
+ if (function.function_body->has_expr ())
+ {
+ auto resolved
+ = TypeCheckExpr::Resolve (function.function_body->expr.get ());
+
+ auto ret_resolved = expected_ret_tyty->combine (resolved);
+ if (ret_resolved == nullptr)
+ {
+ rust_error_at (function.function_body->expr->get_locus_slow (),
+ "failed to resolve final expression");
+ return;
+ }
+
+ context->peek_return_type ()->append_reference (
+ ret_resolved->get_ref ());
+ }
+
+ context->pop_return_type ();
+ }
+
+private:
+ TypeCheckImplItem (TyTy::TyBase *self) : TypeCheckBase (), self (self) {}
+
+ TyTy::TyBase *self;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK_IMPLITEM_H
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index d7f9af1..571d998 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -21,6 +21,7 @@
#include "rust-hir-type-check-base.h"
#include "rust-hir-full.h"
+#include "rust-hir-type-check-implitem.h"
#include "rust-hir-type-check-type.h"
#include "rust-hir-type-check-stmt.h"
#include "rust-tyty-visitor.h"
@@ -37,6 +38,21 @@ public:
item->accept_vis (resolver);
}
+ void visit (HIR::InherentImpl &impl_block)
+ {
+ TyTy::TyBase *self = nullptr;
+ if (!context->lookup_type (
+ impl_block.get_type ()->get_mappings ().get_hirid (), &self))
+ {
+ rust_error_at (impl_block.get_locus (),
+ "failed to resolve Self for InherentImpl");
+ return;
+ }
+
+ for (auto &impl_item : impl_block.get_impl_items ())
+ TypeCheckImplItem::Resolve (impl_item.get (), self);
+ }
+
void visit (HIR::Function &function)
{
TyTy::TyBase *lookup;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 99be0b7..e04284e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -56,6 +56,8 @@ public:
{
init_expr_ty
= TypeCheckExpr::Resolve (stmt.get_init_expr (), is_final_stmt);
+ if (init_expr_ty == nullptr)
+ return;
init_expr_ty = init_expr_ty->clone ();
auto ref = init_expr_ty->get_ref ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index 52b6cde..46b3b0f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -21,6 +21,7 @@
#include "rust-hir-type-check-base.h"
#include "rust-hir-full.h"
+#include "rust-hir-type-check-implitem.h"
#include "rust-hir-type-check-type.h"
#include "rust-hir-type-check-expr.h"
#include "rust-tyty.h"
@@ -134,6 +135,15 @@ public:
context->insert_type (function.get_mappings (), fnType);
}
+ void visit (HIR::InherentImpl &impl_block)
+ {
+ TypeCheckType::Resolve (impl_block.get_type ().get ());
+ for (auto &impl_item : impl_block.get_impl_items ())
+ {
+ TypeCheckTopLevelImplItem::Resolve (impl_item.get ());
+ }
+ }
+
private:
TypeCheckTopLevel () : TypeCheckBase () {}
};
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index cf3a846..416cd89 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -23,6 +23,9 @@
#include "rust-hir-type-check-expr.h"
#include "rust-hir-type-check-struct-field.h"
+extern bool
+saw_errors (void);
+
namespace Rust {
namespace Resolver {
@@ -32,13 +35,26 @@ TypeResolution::Resolve (HIR::Crate &crate)
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
TypeCheckTopLevel::Resolve (it->get ());
+ if (saw_errors ())
+ return;
+
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
TypeCheckItem::Resolve (it->get ());
+ if (saw_errors ())
+ return;
+
auto mappings = Analysis::Mappings::get ();
auto context = TypeCheckContext::get ();
context->iterate ([&] (HirId id, TyTy::TyBase *ty) mutable -> bool {
+ if (ty->get_kind () == TyTy::TypeKind::ERROR)
+ {
+ rust_error_at (mappings->lookup_location (id),
+ "failure in type resolution");
+ return false;
+ }
+
// nothing to do
if (ty->get_kind () != TyTy::TypeKind::INFER)
return true;
diff --git a/gcc/rust/typecheck/rust-tycheck-dump.h b/gcc/rust/typecheck/rust-tycheck-dump.h
index 863c2eb..0d8fffc 100644
--- a/gcc/rust/typecheck/rust-tycheck-dump.h
+++ b/gcc/rust/typecheck/rust-tycheck-dump.h
@@ -37,6 +37,30 @@ public:
return dumper.dump;
}
+ void visit (HIR::InherentImpl &impl_block)
+ {
+ dump += indent () + "impl "
+ + type_string (impl_block.get_type ()->get_mappings ()) + " {\n";
+ indentation_level++;
+
+ for (auto &impl_item : impl_block.get_impl_items ())
+ {
+ impl_item->accept_vis (*this);
+ dump += "\n";
+ }
+
+ indentation_level--;
+ dump += indent () + "}\n";
+ }
+
+ void visit (HIR::ConstantItem &constant)
+ {
+ dump += indent () + "constant " + constant.get_identifier () + ":"
+ + type_string (constant.get_mappings ()) + " = ";
+ constant.get_expr ()->accept_vis (*this);
+ dump += ";\n";
+ }
+
void visit (HIR::Function &function)
{
dump += indent () + "fn " + function.function_name + " "
@@ -54,6 +78,7 @@ public:
indentation_level++;
expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
+ dump += indent ();
s->accept_vis (*this);
dump += ";\n";
return true;
@@ -61,6 +86,7 @@ public:
if (expr.has_expr () && expr.tail_expr_reachable ())
{
+ dump += indent ();
expr.expr->accept_vis (*this);
dump += ";\n";
}
@@ -70,7 +96,7 @@ public:
void visit (HIR::LetStmt &stmt)
{
- dump += indent () + "let " + stmt.get_pattern ()->as_string () + ":"
+ dump += "let " + stmt.get_pattern ()->as_string () + ":"
+ type_string (stmt.get_mappings ());
if (stmt.has_init_expr ())
{
@@ -81,13 +107,11 @@ public:
void visit (HIR::ExprStmtWithBlock &stmt)
{
- dump += indent ();
stmt.get_expr ()->accept_vis (*this);
}
void visit (HIR::ExprStmtWithoutBlock &stmt)
{
- dump += indent ();
stmt.get_expr ()->accept_vis (*this);
}
@@ -136,6 +160,11 @@ public:
dump += ")";
}
+ void visit (HIR::PathInExpression &expr)
+ {
+ dump += type_string (expr.get_mappings ());
+ }
+
protected:
std::string type_string (const Analysis::NodeMapping &mappings)
{
@@ -152,6 +181,7 @@ protected:
buf += "]";
return "<" + lookup->as_string ()
+ + " HIRID: " + std::to_string (mappings.get_hirid ())
+ " RF:" + std::to_string (lookup->get_ref ()) + " TF:"
+ std::to_string (lookup->get_ty_ref ()) + +" - " + buf + ">";
}
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 925130f..eb55581 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -259,6 +259,30 @@ Mappings::lookup_hir_item (CrateNum crateNum, HirId id)
}
void
+Mappings::insert_hir_implitem (CrateNum crateNum, HirId id,
+ HIR::InherentImplItem *item)
+{
+ rust_assert (lookup_hir_implitem (crateNum, id) == nullptr);
+
+ hirImplItemMappings[crateNum][id] = item;
+ nodeIdToHirMappings[crateNum][item->get_impl_mappings ().get_nodeid ()] = id;
+}
+
+HIR::InherentImplItem *
+Mappings::lookup_hir_implitem (CrateNum crateNum, HirId id)
+{
+ auto it = hirImplItemMappings.find (crateNum);
+ if (it == hirImplItemMappings.end ())
+ return nullptr;
+
+ auto iy = it->second.find (id);
+ if (iy == it->second.end ())
+ return nullptr;
+
+ return iy->second;
+}
+
+void
Mappings::insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr)
{
hirExprMappings[crateNum][id] = expr;
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 4859d1e..f81cee6 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -109,6 +109,10 @@ public:
void insert_hir_item (CrateNum crateNum, HirId id, HIR::Item *item);
HIR::Item *lookup_hir_item (CrateNum crateNum, HirId id);
+ void insert_hir_implitem (CrateNum crateNum, HirId id,
+ HIR::InherentImplItem *item);
+ HIR::InherentImplItem *lookup_hir_implitem (CrateNum crateNum, HirId id);
+
void insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr);
HIR::Expr *lookup_hir_expr (CrateNum crateNum, HirId id);
@@ -170,6 +174,8 @@ private:
std::map<CrateNum, std::map<HirId, HIR::FunctionParam *> > hirParamMappings;
std::map<CrateNum, std::map<HirId, HIR::StructExprField *> >
hirStructFieldMappings;
+ std::map<CrateNum, std::map<HirId, HIR::InherentImplItem *> >
+ hirImplItemMappings;
// location info
std::map<CrateNum, std::map<NodeId, Location> > locations;
diff --git a/gcc/testsuite/rust.test/compilable/impl_block1.rs b/gcc/testsuite/rust.test/compilable/impl_block1.rs
new file mode 100644
index 0000000..d67afa1
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/impl_block1.rs
@@ -0,0 +1,23 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ fn new(a: i32, b: bool) -> Foo {
+ Foo(a, b)
+ }
+
+ fn test2() -> i32 {
+ test_forward_decl()
+ }
+}
+
+fn test_forward_decl() -> i32 {
+ 123
+}
+
+fn main() {
+ let a;
+ a = Foo::new(1, true);
+
+ let b;
+ b = Foo::test2();
+}
diff --git a/gcc/testsuite/rust.test/compilable/impl_block2.rs b/gcc/testsuite/rust.test/compilable/impl_block2.rs
new file mode 100644
index 0000000..0ed592d
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/impl_block2.rs
@@ -0,0 +1,28 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ const number: i32 = 456;
+
+ fn new(a: i32, b: bool) -> Foo {
+ Foo(a, b)
+ }
+
+ fn test2() -> i32 {
+ test_forward_decl()
+ }
+}
+
+fn test_forward_decl() -> i32 {
+ 123
+}
+
+fn main() {
+ let a;
+ a = Foo::new(1, true);
+
+ let b;
+ b = Foo::test2();
+
+ let c;
+ c = Foo::new(Foo::number, true);
+}
diff --git a/gcc/testsuite/rust.test/compilable/integer_inference_var1.rs b/gcc/testsuite/rust.test/compilable/integer_inference_var1.rs
new file mode 100644
index 0000000..ccee06a
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/integer_inference_var1.rs
@@ -0,0 +1,6 @@
+const TEST_CONST: i32 = 10;
+
+fn main() {
+ let a;
+ a = TEST_CONST;
+}
diff --git a/gcc/testsuite/rust.test/compilable/integer_inference_var2.rs b/gcc/testsuite/rust.test/compilable/integer_inference_var2.rs
new file mode 100644
index 0000000..2209e93
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/integer_inference_var2.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let a = 1u32;
+
+ let b;
+ b = a;
+}
diff --git a/gcc/testsuite/rust.test/compilable/integer_inference_var3.rs b/gcc/testsuite/rust.test/compilable/integer_inference_var3.rs
new file mode 100644
index 0000000..858c5d3
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/integer_inference_var3.rs
@@ -0,0 +1,10 @@
+fn test(a: u32) -> u32 {
+ a + 1
+}
+
+fn main() {
+ let param;
+ param = 123;
+
+ let a = test(param);
+}
diff --git a/gcc/testsuite/rust.test/compilable/integer_inference_var4.rs b/gcc/testsuite/rust.test/compilable/integer_inference_var4.rs
new file mode 100644
index 0000000..136d818
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/integer_inference_var4.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let a;
+ a = 1;
+}
diff --git a/gcc/testsuite/rust.test/compilable/integer_inference_var5.rs b/gcc/testsuite/rust.test/compilable/integer_inference_var5.rs
new file mode 100644
index 0000000..6b97de5
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/integer_inference_var5.rs
@@ -0,0 +1,23 @@
+const TEST_CONST: i32 = 10;
+
+fn test(x: u32) -> u32 {
+ x + 1
+}
+
+fn main() {
+ let x = TEST_CONST;
+
+ let a = 1u32;
+ let b = a;
+
+ let c;
+ c = 1;
+
+ let d;
+ d = b;
+
+ let param;
+ param = 123;
+
+ let test_call = test(param);
+}
diff --git a/gcc/testsuite/rust.test/compilable/ints_infer1.rs b/gcc/testsuite/rust.test/compilable/ints_infer1.rs
deleted file mode 100644
index 3170c7c..0000000
--- a/gcc/testsuite/rust.test/compilable/ints_infer1.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-const TEST_CONST: i32 = 10;
-
-fn main() {
- let mut x = TEST_CONST;
- x = x + 1;
-
- let mut y = x + TEST_CONST;
-
- let z = 1u32;
-
- let a = z;
-
- let b;
- b = 1;
-
- let c;
- c = a;
-}