aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-expr.h13
-rw-r--r--gcc/rust/ast/rust-item.h19
-rw-r--r--gcc/rust/ast/rust-pattern.h11
-rw-r--r--gcc/rust/backend/cscope.h160
-rw-r--r--gcc/rust/backend/rust-compile-base.h6
-rw-r--r--gcc/rust/backend/rust-compile-block.h41
-rw-r--r--gcc/rust/backend/rust-compile-context.h16
-rw-r--r--gcc/rust/backend/rust-compile-expr.h54
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.h16
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h248
-rw-r--r--gcc/rust/backend/rust-compile-item.h38
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h26
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h23
-rw-r--r--gcc/rust/backend/rust-compile.cc201
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h29
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.h100
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h29
-rw-r--r--gcc/rust/hir/tree/rust-hir-full-test.cc2
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h99
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.h2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h380
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h9
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h24
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h66
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h52
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h4
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-unused.h11
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc10
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h58
-rw-r--r--gcc/rust/rust-session-manager.cc46
-rw-r--r--gcc/rust/rust-session-manager.h17
-rw-r--r--gcc/rust/typecheck/rust-hir-method-resolve.h95
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h383
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h81
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h105
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc19
-rw-r--r--gcc/rust/typecheck/rust-tycheck-dump.h40
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h42
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc64
-rw-r--r--gcc/rust/util/rust-hir-map.cc24
-rw-r--r--gcc/rust/util/rust-hir-map.h19
-rw-r--r--gcc/testsuite/rust.test/compilable/block_expr1.rs27
-rw-r--r--gcc/testsuite/rust.test/compilable/impl_block3.rs31
-rw-r--r--gcc/testsuite/rust.test/compilable/methods1.rs39
-rw-r--r--gcc/testsuite/rust.test/compilable/methods2.rs41
-rw-r--r--gcc/testsuite/rust.test/compilable/name_resolve1.rs23
-rw-r--r--gcc/testsuite/rust.test/compilable/nested_struct1.rs17
-rw-r--r--gcc/testsuite/rust.test/compilable/self_type1.rs12
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error1.rs8
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error2.rs4
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error3.rs9
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error4.rs27
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/redef_error5.rs8
55 files changed, 2075 insertions, 867 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 74a6473..511c30d 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -2399,9 +2399,9 @@ public:
void iterate_params (std::function<bool (Expr *)> cb)
{
- for (auto it = params.begin (); it != params.end (); it++)
+ for (auto &param : params)
{
- if (!cb (it->get ()))
+ if (!cb (param.get ()))
return;
}
}
@@ -2504,6 +2504,15 @@ public:
void mark_for_strip () override { receiver = nullptr; }
bool is_marked_for_strip () const override { return receiver == nullptr; }
+ void iterate_params (std::function<bool (Expr *)> cb)
+ {
+ for (auto &param : params)
+ {
+ if (!cb (param.get ()))
+ return;
+ }
+ }
+
// TODO: this mutable getter seems really dodgy. Think up better way.
const std::vector<std::unique_ptr<Expr> > &get_params () const
{
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 9437f21..a6f5398 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -366,12 +366,14 @@ private:
// bool has_type; // only possible if not ref
std::unique_ptr<Type> type;
+ NodeId node_id;
+
Location locus;
// Unrestricted constructor used for error state
SelfParam (Lifetime lifetime, bool has_ref, bool is_mut, Type *type)
: has_ref (has_ref), is_mut (is_mut), lifetime (std::move (lifetime)),
- type (type)
+ type (type), node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
// this is ok as no outside classes can ever call this
@@ -401,20 +403,23 @@ public:
// Type-based self parameter (not ref, no lifetime)
SelfParam (std::unique_ptr<Type> type, bool is_mut, Location locus)
: has_ref (false), is_mut (is_mut), lifetime (Lifetime::error ()),
- type (std::move (type)), locus (locus)
+ type (std::move (type)),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus)
{}
// Lifetime-based self parameter (is ref, no type)
SelfParam (Lifetime lifetime, bool is_mut, Location locus)
: has_ref (true), is_mut (is_mut), lifetime (std::move (lifetime)),
- locus (locus)
+ node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus)
{}
// Copy constructor requires clone
SelfParam (SelfParam const &other)
: has_ref (other.has_ref), is_mut (other.is_mut), lifetime (other.lifetime),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ()),
locus (other.locus)
{
+ node_id = other.node_id;
if (other.type != nullptr)
type = other.type->clone_type ();
}
@@ -426,6 +431,7 @@ public:
has_ref = other.has_ref;
lifetime = other.lifetime;
locus = other.locus;
+ node_id = other.node_id;
if (other.type != nullptr)
type = other.type->clone_type ();
@@ -443,6 +449,13 @@ public:
Location get_locus () const { return locus; }
+ bool get_has_ref () const { return has_ref; };
+ bool get_is_mut () const { return is_mut; }
+
+ Lifetime get_lifetime () const { return lifetime; }
+
+ NodeId get_node_id () const { return node_id; }
+
// TODO: is this better? Or is a "vis_block" better?
std::unique_ptr<Type> &get_type ()
{
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index e89fc62..049aaf0 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -78,7 +78,7 @@ class IdentifierPattern : public Pattern
Location locus;
public:
- std::string as_string () const;
+ std::string as_string () const override;
// Returns whether the IdentifierPattern has a pattern to bind.
bool has_pattern_to_bind () const { return to_bind != nullptr; }
@@ -91,6 +91,15 @@ public:
is_mut (is_mut), to_bind (std::move (to_bind)), locus (locus)
{}
+ IdentifierPattern (NodeId node_id, Identifier ident, Location locus,
+ bool is_ref = false, bool is_mut = false,
+ std::unique_ptr<Pattern> to_bind = nullptr)
+ : Pattern (), variable_ident (std::move (ident)), is_ref (is_ref),
+ is_mut (is_mut), to_bind (std::move (to_bind)), locus (locus)
+ {
+ this->node_id = node_id;
+ }
+
// Copy constructor with clone
IdentifierPattern (IdentifierPattern const &other)
: variable_ident (other.variable_ident), is_ref (other.is_ref),
diff --git a/gcc/rust/backend/cscope.h b/gcc/rust/backend/cscope.h
deleted file mode 100644
index 3ba837c..0000000
--- a/gcc/rust/backend/cscope.h
+++ /dev/null
@@ -1,160 +0,0 @@
-// 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/>.
-
-#pragma once
-
-#include "rust-system.h"
-#include "rust-backend.h"
-#include "scope.h"
-
-namespace Rust {
-namespace Compile {
-
-class Scope
-{
-public:
- Scope (Backend *backend) : backend (backend) {}
-
- ~Scope () {}
-
- void Push ()
- {
- fndecls.Push ();
- vars.Push ();
- types.Push ();
- structDecls.Push ();
- }
-
- void Pop ()
- {
- fndecls.Pop ();
- vars.Pop ();
- types.Pop ();
- structDecls.Pop ();
- }
-
- void PushCurrentFunction (std::string name, Bfunction *fn, Btype *retType,
- Bvariable *retDecl)
- {
- fns.push_back (fn);
- fnRetType.push_back (retType);
- fnRetDecl.push_back (retDecl);
- }
-
- Bfunction *PopCurrentFunction ()
- {
- auto ret = fns.back ();
- fns.pop_back ();
- fnRetType.pop_back ();
- fnRetDecl.pop_back ();
- return ret;
- }
-
- Bfunction *GetCurrentFndecl () { return fns.back (); }
-
- Btype *GetCurrentFnRetType () { return fnRetType.back (); }
-
- Bvariable *GetCurrentFnRetDecl () { return fnRetDecl.back (); }
-
- Btype *GetFnRetType (Bfunction *fn)
- {
- auto it = fnRetTypeMapping.find (fn);
- if (it == fnRetTypeMapping.end ())
- {
- return NULL;
- }
- return it->second;
- }
-
- void PushBlock (Bblock *block)
- {
- blocks.push_back (block);
- std::vector<Bstatement *> empty;
- context.push_back (empty);
- }
-
- Bblock *PopBlock ()
- {
- auto ret = blocks.back ();
- blocks.pop_back ();
-
- auto stmts = context.back ();
- context.pop_back ();
-
- backend->block_add_statements (ret, stmts);
-
- return ret;
- }
-
- Bblock *CurBlock () { return blocks.back (); }
-
- void AddStatement (Bstatement *stmt) { context.back ().push_back (stmt); }
-
- void InsertStructDecl (std::string name, AST::StructStruct *decl)
- {
- structDecls.Insert (name, decl);
- }
-
- bool LookupStructDecl (std::string name, AST::StructStruct **decl)
- {
- return structDecls.Lookup (name, decl);
- }
-
- void InsertFunction (std::string name, Bfunction *fn, Btype *retType)
- {
- fndecls.Insert (name, fn);
- fnRetTypeMapping[fn] = retType;
- }
-
- bool LookupFunction (std::string name, Bfunction **fn)
- {
- return fndecls.Lookup (name, fn);
- }
-
- void InsertType (std::string name, Btype *type) { types.Insert (name, type); }
-
- bool LookupType (std::string name, Btype **type)
- {
- return types.Lookup (name, type);
- }
-
- void InsertVar (std::string name, Bvariable *var) { vars.Insert (name, var); }
-
- bool LookupVar (std::string name, Bvariable **var)
- {
- return vars.Lookup (name, var);
- }
-
-private:
- Backend *backend;
-
- ::std::vector<Bfunction *> fns;
- ::std::vector<Bblock *> blocks;
- ::std::vector< ::std::vector<Bstatement *> > context;
- ::std::vector< ::Btype *> fnRetType;
- ::std::vector< ::Bvariable *> fnRetDecl;
- ::std::map<Bfunction *, Btype *> fnRetTypeMapping;
-
- Analysis::Scope<Bfunction *> fndecls;
- Analysis::Scope<Bvariable *> vars;
- Analysis::Scope<Btype *> types;
- Analysis::Scope<AST::StructStruct *> structDecls;
-};
-
-} // namespace Compile
-} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index fdc5ad9..ec7c13a 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -237,9 +237,13 @@ public:
protected:
HIRCompileBase (Context *ctx) : ctx (ctx) {}
+ Context *ctx;
+
Context *get_context () { return ctx; }
- Context *ctx;
+ void compile_function_body (Bfunction *fndecl,
+ std::unique_ptr<HIR::BlockExpr> &function_body,
+ bool has_return_type);
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-block.h b/gcc/rust/backend/rust-compile-block.h
index b17fb05..879e32d 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -28,35 +28,35 @@ namespace Compile {
class CompileBlock : public HIRCompileBase
{
public:
- static Bblock *compile (HIR::BlockExpr *expr, Context *ctx)
+ static Bblock *compile (HIR::BlockExpr *expr, Context *ctx, Bvariable *result)
{
- CompileBlock compiler (ctx);
+ CompileBlock compiler (ctx, result);
expr->accept_vis (compiler);
return compiler.translated;
}
- ~CompileBlock () {}
-
void visit (HIR::BlockExpr &expr);
private:
- CompileBlock (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}
+ CompileBlock (Context *ctx, Bvariable *result)
+ : HIRCompileBase (ctx), translated (nullptr), result (result)
+ {}
Bblock *translated;
+ Bvariable *result;
};
class CompileConditionalBlocks : public HIRCompileBase
{
public:
- static Bstatement *compile (HIR::IfExpr *expr, Context *ctx)
+ static Bstatement *compile (HIR::IfExpr *expr, Context *ctx,
+ Bvariable *result)
{
- CompileConditionalBlocks resolver (ctx);
+ CompileConditionalBlocks resolver (ctx, result);
expr->accept_vis (resolver);
return resolver.translated;
}
- ~CompileConditionalBlocks () {}
-
void visit (HIR::IfExpr &expr);
void visit (HIR::IfExprConseqElse &expr);
@@ -64,46 +64,47 @@ public:
void visit (HIR::IfExprConseqIf &expr);
private:
- CompileConditionalBlocks (Context *ctx)
- : HIRCompileBase (ctx), translated (nullptr)
+ CompileConditionalBlocks (Context *ctx, Bvariable *result)
+ : HIRCompileBase (ctx), translated (nullptr), result (result)
{}
Bstatement *translated;
+ Bvariable *result;
};
class CompileExprWithBlock : public HIRCompileBase
{
public:
- static Bstatement *compile (HIR::ExprWithBlock *expr, Context *ctx)
+ static Bstatement *compile (HIR::ExprWithBlock *expr, Context *ctx,
+ Bvariable *result)
{
- CompileExprWithBlock resolver (ctx);
+ CompileExprWithBlock resolver (ctx, result);
expr->accept_vis (resolver);
return resolver.translated;
}
- ~CompileExprWithBlock () {}
-
void visit (HIR::IfExpr &expr)
{
- translated = CompileConditionalBlocks::compile (&expr, ctx);
+ translated = CompileConditionalBlocks::compile (&expr, ctx, result);
}
void visit (HIR::IfExprConseqElse &expr)
{
- translated = CompileConditionalBlocks::compile (&expr, ctx);
+ translated = CompileConditionalBlocks::compile (&expr, ctx, result);
}
void visit (HIR::IfExprConseqIf &expr)
{
- translated = CompileConditionalBlocks::compile (&expr, ctx);
+ translated = CompileConditionalBlocks::compile (&expr, ctx, result);
}
private:
- CompileExprWithBlock (Context *ctx)
- : HIRCompileBase (ctx), translated (nullptr)
+ CompileExprWithBlock (Context *ctx, Bvariable *result)
+ : HIRCompileBase (ctx), translated (nullptr), result (result)
{}
Bstatement *translated;
+ Bvariable *result;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 034568f..25c9b89 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -110,6 +110,11 @@ public:
return scope_stack.back ();
}
+ void add_statement_to_enclosing_scope (Bstatement *stmt)
+ {
+ statements.at (statements.size () - 2).push_back (stmt);
+ }
+
void add_statement (Bstatement *stmt) { statements.back ().push_back (stmt); }
void insert_var_decl (HirId id, ::Bvariable *decl)
@@ -222,11 +227,11 @@ public:
virtual ~TyTyResolveCompile () {}
- void visit (TyTy::ErrorType &type) override { gcc_unreachable (); }
+ void visit (TyTy::ErrorType &) override { gcc_unreachable (); }
- void visit (TyTy::InferType &type) override { gcc_unreachable (); }
+ void visit (TyTy::InferType &) override { gcc_unreachable (); }
- void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); }
+ void visit (TyTy::StructFieldType &) override { gcc_unreachable (); }
void visit (TyTy::FnType &type) override
{
@@ -261,7 +266,7 @@ public:
ctx->get_mappings ()->lookup_location (type.get_ref ()));
}
- void visit (TyTy::UnitType &type) override
+ void visit (TyTy::UnitType &) override
{
translated = ctx->get_backend ()->void_type ();
}
@@ -278,8 +283,7 @@ public:
{
TyTy::StructFieldType *field = type.get_field (i);
Btype *compiled_field_ty
- = TyTyCompile::compile (ctx->get_backend (),
- field->get_field_type ());
+ = TyTyResolveCompile::compile (ctx, field->get_field_type ());
Backend::Btyped_identifier f (field->get_name (), compiled_field_ty,
ctx->get_mappings ()->lookup_location (
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index ccff51a..b823d29 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -99,6 +99,8 @@ public:
void visit (HIR::CallExpr &expr);
+ void visit (HIR::MethodCallExpr &expr);
+
void visit (HIR::IdentifierExpr &expr)
{
// need to look up the reference for this identifier
@@ -409,27 +411,71 @@ public:
void visit (HIR::IfExpr &expr)
{
- auto stmt = CompileConditionalBlocks::compile (&expr, ctx);
+ auto stmt = CompileConditionalBlocks::compile (&expr, ctx, nullptr);
ctx->add_statement (stmt);
}
void visit (HIR::IfExprConseqElse &expr)
{
- auto stmt = CompileConditionalBlocks::compile (&expr, ctx);
+ // this can be a return expression
+ TyTy::TyBase *if_type = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &if_type))
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to lookup type of IfExprConseqElse");
+ return;
+ }
+
+ fncontext fnctx = ctx->peek_fn ();
+ Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
+ Btype *block_type = TyTyResolveCompile::compile (ctx, if_type);
+
+ bool is_address_taken = false;
+ Bstatement *ret_var_stmt = nullptr;
+ Bvariable *tmp = ctx->get_backend ()->temporary_variable (
+ fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
+ expr.get_locus (), &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
+
+ auto stmt = CompileConditionalBlocks::compile (&expr, ctx, tmp);
ctx->add_statement (stmt);
+
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
}
void visit (HIR::IfExprConseqIf &expr)
{
- auto stmt = CompileConditionalBlocks::compile (&expr, ctx);
+ auto stmt = CompileConditionalBlocks::compile (&expr, ctx, nullptr);
ctx->add_statement (stmt);
}
void visit (HIR::BlockExpr &expr)
{
- auto code_block = CompileBlock::compile (&expr, ctx);
+ TyTy::TyBase *block_tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &block_tyty))
+ {
+ rust_error_at (expr.get_locus (), "failed to lookup type of BlockExpr");
+ return;
+ }
+
+ fncontext fnctx = ctx->peek_fn ();
+ Bblock *enclosing_scope = ctx->peek_enclosing_scope ();
+ Btype *block_type = TyTyResolveCompile::compile (ctx, block_tyty);
+
+ bool is_address_taken = false;
+ Bstatement *ret_var_stmt = nullptr;
+ Bvariable *tmp = ctx->get_backend ()->temporary_variable (
+ fnctx.fndecl, enclosing_scope, block_type, NULL, is_address_taken,
+ expr.get_locus (), &ret_var_stmt);
+ ctx->add_statement (ret_var_stmt);
+
+ auto code_block = CompileBlock::compile (&expr, ctx, tmp);
auto block_stmt = ctx->get_backend ()->block_statement (code_block);
ctx->add_statement (block_stmt);
+
+ translated = ctx->get_backend ()->var_expression (tmp, expr.get_locus ());
}
void visit (HIR::StructExprStructFields &struct_expr)
diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index cf6e6f7..1ea0c9f 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -61,6 +61,22 @@ private:
::Bvariable *translated;
};
+class CompileSelfParam : public HIRCompileBase
+{
+public:
+ static Bvariable *compile (Context *ctx, Bfunction *fndecl,
+ HIR::SelfParam &self, Btype *decl_type,
+ Location locus)
+ {
+ if (!self.get_is_mut ())
+ decl_type = ctx->get_backend ()->immutable_type (decl_type);
+
+ return ctx->get_backend ()->parameter_variable (fndecl, "self", decl_type,
+ false /* address_taken */,
+ locus);
+ }
+};
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index fe2abf1..6d180c8 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -32,10 +32,10 @@ namespace Compile {
class CompileInherentImplItem : public HIRCompileBase
{
public:
- static void Compile (HIR::Type *base, HIR::InherentImplItem *item,
+ static void Compile (TyTy::TyBase *self, HIR::InherentImplItem *item,
Context *ctx, bool compile_fns)
{
- CompileInherentImplItem compiler (base, ctx, compile_fns);
+ CompileInherentImplItem compiler (self, ctx, compile_fns);
item->accept_vis (compiler);
}
@@ -50,7 +50,7 @@ public:
::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type);
Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx);
- std::string ident = base->as_string () + "::" + constant.get_identifier ();
+ std::string ident = self->as_string () + "::" + constant.get_identifier ();
Bexpression *const_expr = ctx->get_backend ()->named_constant_expression (
type, constant.get_identifier (), value, constant.get_locus ());
@@ -78,7 +78,8 @@ public:
if (!ctx->get_tyctx ()->lookup_type (function.get_mappings ().get_hirid (),
&fntype_tyty))
{
- rust_fatal_error (function.locus, "failed to lookup function type");
+ rust_fatal_error (function.get_locus (),
+ "failed to lookup function type");
return;
}
@@ -93,23 +94,15 @@ public:
::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;
+ = self->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 ())
+ if (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 ());
@@ -213,34 +206,219 @@ public:
ctx->push_fn (fndecl, return_address);
- // compile the block
- function_body->iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
- CompileStmt::Compile (s, ctx);
+ compile_function_body (fndecl, function.function_body,
+ function.has_function_return_type ());
+
+ 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);
+ }
+
+ void visit (HIR::Method &method)
+ {
+ 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 (method.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 (method.get_mappings ().get_hirid (),
+ &fntype_tyty))
+ {
+ rust_fatal_error (method.get_locus (),
+ "failed to lookup function type");
+ return;
+ }
+
+ if (fntype_tyty->get_kind () != TyTy::TypeKind::FNDEF)
+ {
+ rust_error_at (method.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;
+ std::string fn_identifier
+ = self->as_string () + "::" + method.get_method_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 (method.has_visibility ())
+ flags |= Backend::function_is_visible;
+
+ std::string asm_name = fn_identifier;
+ Bfunction *fndecl
+ = ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
+ asm_name, flags, method.get_locus ());
+ ctx->insert_function_decl (method.get_mappings ().get_hirid (), fndecl);
+
+ // setup the params
+ TyTy::TyBase *tyret = fntype->return_type ();
+ std::vector<Bvariable *> param_vars;
+
+ // insert self
+ TyTy::TyBase *self_tyty_lookup = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (
+ method.get_self_param ().get_mappings ().get_hirid (),
+ &self_tyty_lookup))
+ {
+ rust_error_at (method.get_self_param ().get_locus (),
+ "failed to lookup self param type");
+ return;
+ }
+
+ Btype *self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup);
+ if (self_type == nullptr)
+ {
+ rust_error_at (method.get_self_param ().get_locus (),
+ "failed to compile self param type");
+ return;
+ }
+
+ Bvariable *compiled_self_param
+ = CompileSelfParam::compile (ctx, fndecl, method.get_self_param (),
+ self_type,
+ method.get_self_param ().get_locus ());
+ if (compiled_self_param == nullptr)
+ {
+ rust_error_at (method.get_self_param ().get_locus (),
+ "failed to compile self param variable");
+ return;
+ }
+
+ param_vars.push_back (compiled_self_param);
+ ctx->insert_var_decl (method.get_self_param ().get_mappings ().get_hirid (),
+ compiled_self_param);
+
+ // offset from + 1 for the TyTy::FnType being used
+ size_t i = 1;
+ for (auto referenced_param : method.get_function_params ())
+ {
+ auto tyty_param = fntype->param_at (i);
+ auto param_tyty = tyty_param.second;
+
+ auto compiled_param_type
+ = TyTyResolveCompile::compile (ctx, param_tyty);
+ if (compiled_param_type == nullptr)
+ {
+ rust_error_at (referenced_param.get_locus (),
+ "failed to compile parameter type");
+ return;
+ }
+
+ 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 (method.get_locus (),
+ "failed to setup parameter variables");
+ return;
+ }
+
+ // lookup locals
+ auto block_expr = method.get_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 (method.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;
});
- if (function_body->has_expr () && function_body->tail_expr_reachable ())
+ bool toplevel_item
+ = method.get_mappings ().get_local_defid () != UNKNOWN_LOCAL_DEFID;
+ Bblock *enclosing_scope
+ = toplevel_item ? NULL : ctx->peek_enclosing_scope ();
+
+ HIR::BlockExpr *function_body = method.get_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 (method.has_function_return_type ())
{
- // 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);
+ 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,
+ method.get_locus (), &ret_var_stmt);
+
+ ctx->add_statement (ret_var_stmt);
}
+ ctx->push_fn (fndecl, return_address);
+
+ compile_function_body (fndecl, method.get_function_body (),
+ method.has_function_return_type ());
+
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");
+ rust_error_at (method.get_locus (), "failed to set body to function");
return;
}
@@ -250,11 +428,11 @@ public:
}
private:
- CompileInherentImplItem (HIR::Type *base, Context *ctx, bool compile_fns)
- : HIRCompileBase (ctx), base (base), compile_fns (compile_fns)
+ CompileInherentImplItem (TyTy::TyBase *self, Context *ctx, bool compile_fns)
+ : HIRCompileBase (ctx), self (self), compile_fns (compile_fns)
{}
- HIR::Type *base;
+ TyTy::TyBase *self;
bool compile_fns;
};
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 83e4451..7f93af9f 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -265,28 +265,8 @@ public:
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);
- }
+ compile_function_body (fndecl, function.function_body,
+ function.has_function_return_type ());
ctx->pop_block ();
auto body = ctx->get_backend ()->block_statement (code_block);
@@ -297,15 +277,23 @@ public:
}
ctx->pop_fn ();
-
ctx->push_function (fndecl);
}
void visit (HIR::InherentImpl &impl_block)
{
+ TyTy::TyBase *self_lookup = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (
+ impl_block.get_type ()->get_mappings ().get_hirid (), &self_lookup))
+ {
+ rust_error_at (impl_block.get_locus (),
+ "failed to resolve type of impl");
+ return;
+ }
+
for (auto &impl_item : impl_block.get_impl_items ())
- CompileInherentImplItem::Compile (impl_block.get_type ().get (),
- impl_item.get (), ctx, compile_fns);
+ CompileInherentImplItem::Compile (self_lookup, impl_item.get (), ctx,
+ compile_fns);
}
private:
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index c52f605..d021240e4 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -29,37 +29,24 @@ namespace Compile {
class CompileStmt : public HIRCompileBase
{
public:
- static void Compile (HIR::Stmt *stmt, Context *ctx)
+ static Bexpression *Compile (HIR::Stmt *stmt, Context *ctx)
{
CompileStmt compiler (ctx);
stmt->accept_vis (compiler);
rust_assert (compiler.ok);
+ return compiler.translated;
}
- virtual ~CompileStmt () {}
-
void visit (HIR::ExprStmtWithBlock &stmt)
{
ok = true;
- auto translated = CompileExpr::Compile (stmt.get_expr (), ctx);
-
- // these can be null
- if (translated == nullptr)
- return;
-
- gcc_unreachable ();
+ translated = CompileExpr::Compile (stmt.get_expr (), ctx);
}
void visit (HIR::ExprStmtWithoutBlock &stmt)
{
ok = true;
- auto translated = CompileExpr::Compile (stmt.get_expr (), ctx);
-
- // these can be null
- if (translated == nullptr)
- return;
-
- gcc_unreachable ();
+ translated = CompileExpr::Compile (stmt.get_expr (), ctx);
}
void visit (HIR::LetStmt &stmt)
@@ -99,9 +86,12 @@ public:
}
private:
- CompileStmt (Context *ctx) : HIRCompileBase (ctx), ok (false) {}
+ CompileStmt (Context *ctx)
+ : HIRCompileBase (ctx), ok (false), translated (nullptr)
+ {}
bool ok;
+ Bexpression *translated;
};
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h
index 2c54b17..0629cbe 100644
--- a/gcc/rust/backend/rust-compile-tyty.h
+++ b/gcc/rust/backend/rust-compile-tyty.h
@@ -44,22 +44,19 @@ public:
~TyTyCompile () {}
- void visit (TyTy::ErrorType &type) override { gcc_unreachable (); }
+ void visit (TyTy::ErrorType &) override { gcc_unreachable (); }
- void visit (TyTy::InferType &type) override { gcc_unreachable (); }
+ void visit (TyTy::InferType &) override { gcc_unreachable (); }
- void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); }
+ void visit (TyTy::StructFieldType &) override { gcc_unreachable (); }
- void visit (TyTy::ADTType &type) override { gcc_unreachable (); }
+ void visit (TyTy::ADTType &) override { gcc_unreachable (); }
- void visit (TyTy::TupleType &type) override { gcc_unreachable (); }
+ void visit (TyTy::TupleType &) override { gcc_unreachable (); }
- void visit (TyTy::ArrayType &type) override { gcc_unreachable (); }
+ void visit (TyTy::ArrayType &) override { gcc_unreachable (); }
- void visit (TyTy::UnitType &type) override
- {
- translated = backend->void_type ();
- }
+ void visit (TyTy::UnitType &) override { translated = backend->void_type (); }
void visit (TyTy::FnType &type) override
{
@@ -93,7 +90,7 @@ public:
mappings->lookup_location (type.get_ref ()));
}
- void visit (TyTy::BoolType &type) override
+ void visit (TyTy::BoolType &) override
{
translated = backend->named_type ("bool", backend->bool_type (),
Linemap::predeclared_location ());
@@ -190,14 +187,14 @@ public:
gcc_unreachable ();
}
- void visit (TyTy::USizeType &type) override
+ void visit (TyTy::USizeType &) override
{
translated = backend->named_type (
"usize", backend->integer_type (true, backend->get_pointer_size ()),
Linemap::predeclared_location ());
}
- void visit (TyTy::ISizeType &type) override
+ void visit (TyTy::ISizeType &) override
{
translated = backend->named_type (
"isize", backend->integer_type (false, backend->get_pointer_size ()),
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index ce6d827..0b83c72 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -95,6 +95,83 @@ CompileExpr::visit (HIR::CallExpr &expr)
}
}
+void
+CompileExpr::visit (HIR::MethodCallExpr &expr)
+{
+ // lookup the resolved name
+ NodeId resolved_node_id = UNKNOWN_NODEID;
+ if (!ctx->get_resolver ()->lookup_resolved_name (
+ expr.get_mappings ().get_nodeid (), &resolved_node_id))
+ {
+ rust_error_at (expr.get_locus (), "failed to lookup resolved MethodCall");
+ return;
+ }
+
+ // reverse lookup
+ HirId ref;
+ if (!ctx->get_mappings ()->lookup_node_to_hir (
+ expr.get_mappings ().get_crate_num (), resolved_node_id, &ref))
+ {
+ rust_fatal_error (expr.get_locus (), "reverse lookup failure");
+ return;
+ }
+
+ // lookup compiled functions
+ Bfunction *fn = nullptr;
+ if (!ctx->lookup_function_decl (ref, &fn))
+ {
+ // this might fail because its a forward decl so we can attempt to
+ // resolve it now
+ HIR::InherentImplItem *resolved_item
+ = ctx->get_mappings ()->lookup_hir_implitem (
+ expr.get_mappings ().get_crate_num (), ref);
+ if (resolved_item == nullptr)
+ {
+ rust_error_at (expr.get_locus (), "failed to lookup forward decl");
+ return;
+ }
+
+ TyTy::TyBase *self_type = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (
+ expr.get_receiver ()->get_mappings ().get_hirid (), &self_type))
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to resolve type for self param");
+ return;
+ }
+
+ CompileInherentImplItem::Compile (self_type, resolved_item, ctx, true);
+ if (!ctx->lookup_function_decl (ref, &fn))
+ {
+ rust_error_at (expr.get_locus (), "forward decl was not compiled");
+ return;
+ }
+ }
+
+ Bexpression *fn_expr
+ = ctx->get_backend ()->function_code_expression (fn, expr.get_locus ());
+
+ std::vector<Bexpression *> args;
+
+ // method receiver
+ Bexpression *self = CompileExpr::Compile (expr.get_receiver ().get (), ctx);
+ rust_assert (self != nullptr);
+ args.push_back (self);
+
+ // normal args
+ expr.iterate_params ([&] (HIR::Expr *p) mutable -> bool {
+ Bexpression *compiled_expr = CompileExpr::Compile (p, ctx);
+ rust_assert (compiled_expr != nullptr);
+ args.push_back (compiled_expr);
+ return true;
+ });
+
+ auto fncontext = ctx->peek_fn ();
+ translated
+ = ctx->get_backend ()->call_expression (fncontext.fndecl, fn_expr, args,
+ nullptr, expr.get_locus ());
+}
+
// rust-compile-block.h
void
@@ -135,10 +212,30 @@ CompileBlock::visit (HIR::BlockExpr &expr)
start_location, end_location);
ctx->push_block (new_block);
- expr.iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
- CompileStmt::Compile (s, ctx);
- return true;
- });
+ for (auto &s : expr.get_statements ())
+ {
+ auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
+ if (compiled_expr == nullptr)
+ continue;
+
+ if (result == nullptr)
+ {
+ Bstatement *final_stmt
+ = ctx->get_backend ()->expression_statement (fnctx.fndecl,
+ compiled_expr);
+ ctx->add_statement (final_stmt);
+ }
+ else
+ {
+ Bexpression *result_reference
+ = ctx->get_backend ()->var_expression (result,
+ s->get_locus_slow ());
+
+ Bstatement *assignment = ctx->get_backend ()->assignment_statement (
+ fnctx.fndecl, result_reference, compiled_expr, expr.get_locus ());
+ ctx->add_statement (assignment);
+ }
+ }
if (expr.has_expr () && expr.tail_expr_reachable ())
{
@@ -147,14 +244,22 @@ CompileBlock::visit (HIR::BlockExpr &expr)
Bexpression *compiled_expr = CompileExpr::Compile (expr.expr.get (), ctx);
rust_assert (compiled_expr != nullptr);
- auto fncontext = ctx->peek_fn ();
+ if (result == nullptr)
+ {
+ Bstatement *final_stmt
+ = ctx->get_backend ()->expression_statement (fnctx.fndecl,
+ compiled_expr);
+ ctx->add_statement (final_stmt);
+ }
+ else
+ {
+ Bexpression *result_reference = ctx->get_backend ()->var_expression (
+ result, expr.get_final_expr ()->get_locus_slow ());
- 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);
+ Bstatement *assignment = ctx->get_backend ()->assignment_statement (
+ fnctx.fndecl, result_reference, compiled_expr, expr.get_locus ());
+ ctx->add_statement (assignment);
+ }
}
ctx->pop_block ();
@@ -168,7 +273,8 @@ CompileConditionalBlocks::visit (HIR::IfExpr &expr)
Bfunction *fndecl = fnctx.fndecl;
Bexpression *condition_expr
= CompileExpr::Compile (expr.get_if_condition (), ctx);
- Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx);
+ Bblock *then_block
+ = CompileBlock::compile (expr.get_if_block (), ctx, result);
translated
= ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
@@ -182,8 +288,10 @@ CompileConditionalBlocks::visit (HIR::IfExprConseqElse &expr)
Bfunction *fndecl = fnctx.fndecl;
Bexpression *condition_expr
= CompileExpr::Compile (expr.get_if_condition (), ctx);
- Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx);
- Bblock *else_block = CompileBlock::compile (expr.get_else_block (), ctx);
+ Bblock *then_block
+ = CompileBlock::compile (expr.get_if_block (), ctx, result);
+ Bblock *else_block
+ = CompileBlock::compile (expr.get_else_block (), ctx, result);
translated
= ctx->get_backend ()->if_statement (fndecl, condition_expr, then_block,
@@ -197,7 +305,8 @@ CompileConditionalBlocks::visit (HIR::IfExprConseqIf &expr)
Bfunction *fndecl = fnctx.fndecl;
Bexpression *condition_expr
= CompileExpr::Compile (expr.get_if_condition (), ctx);
- Bblock *then_block = CompileBlock::compile (expr.get_if_block (), ctx);
+ Bblock *then_block
+ = CompileBlock::compile (expr.get_if_block (), ctx, result);
// else block
std::vector<Bvariable *> locals;
@@ -210,7 +319,8 @@ CompileConditionalBlocks::visit (HIR::IfExprConseqIf &expr)
ctx->push_block (else_block);
Bstatement *else_stmt_decl
- = CompileConditionalBlocks::compile (expr.get_conseq_if_expr (), ctx);
+ = CompileConditionalBlocks::compile (expr.get_conseq_if_expr (), ctx,
+ result);
ctx->add_statement (else_stmt_decl);
ctx->pop_block ();
@@ -244,5 +354,64 @@ CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field)
translated = CompileExpr::Compile (&expr, ctx);
}
+// Shared methods in compilation
+
+void
+HIRCompileBase::compile_function_body (
+ Bfunction *fndecl, std::unique_ptr<HIR::BlockExpr> &function_body,
+ bool has_return_type)
+{
+ for (auto &s : function_body->get_statements ())
+ {
+ auto compiled_expr = CompileStmt::Compile (s.get (), ctx);
+ if (compiled_expr != nullptr)
+ {
+ if (has_return_type)
+ {
+ std::vector<Bexpression *> retstmts;
+ retstmts.push_back (compiled_expr);
+
+ auto ret
+ = ctx->get_backend ()->return_statement (fndecl, retstmts,
+ s->get_locus_slow ());
+ ctx->add_statement (ret);
+ }
+ else
+ {
+ Bstatement *final_stmt
+ = ctx->get_backend ()->expression_statement (fndecl,
+ compiled_expr);
+ ctx->add_statement (final_stmt);
+ }
+ }
+ }
+
+ 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);
+
+ if (has_return_type)
+ {
+ std::vector<Bexpression *> retstmts;
+ retstmts.push_back (compiled_expr);
+
+ auto ret = ctx->get_backend ()->return_statement (
+ fndecl, retstmts,
+ function_body->get_final_expr ()->get_locus_slow ());
+ ctx->add_statement (ret);
+ }
+ else
+ {
+ Bstatement *final_stmt
+ = ctx->get_backend ()->expression_statement (fndecl, compiled_expr);
+ ctx->add_statement (final_stmt);
+ }
+ }
+}
+
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index fc18e27..cd1863f 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -238,6 +238,35 @@ public:
expr.get_locus ());
}
+ void visit (AST::MethodCallExpr &expr)
+ {
+ std::vector<HIR::Attribute> outer_attribs;
+
+ HIR::PathExprSegment method_path (
+ expr.get_method_name ().get_ident_segment ().as_string (),
+ expr.get_method_name ().get_locus ());
+
+ HIR::Expr *receiver
+ = ASTLoweringExpr::translate (expr.get_receiver_expr ().get ());
+
+ std::vector<std::unique_ptr<HIR::Expr> > params;
+ expr.iterate_params ([&] (AST::Expr *p) mutable -> bool {
+ auto trans = ASTLoweringExpr::translate (p);
+ params.push_back (std::unique_ptr<HIR::Expr> (trans));
+ return true;
+ });
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (
+ crate_num, UNKNOWN_NODEID /* this can map back to the AST*/,
+ mappings->get_next_hir_id (crate_num), UNKNOWN_LOCAL_DEFID);
+
+ translated
+ = new HIR::MethodCallExpr (mapping, std::unique_ptr<HIR::Expr> (receiver),
+ method_path, std::move (params),
+ std::move (outer_attribs), expr.get_locus ());
+ }
+
void visit (AST::AssignmentExpr &expr)
{
HIR::Expr *lhs = ASTLoweringExpr::translate (expr.get_left_expr ().get ());
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index dab3208..de4d55d 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -40,6 +40,21 @@ public:
return resolver.translated;
}
+ HIR::SelfParam lower_self (AST::SelfParam &self)
+ {
+ HIR::Type *type = self.has_type ()
+ ? ASTLoweringType::translate (self.get_type ().get ())
+ : nullptr;
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, self.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
+ return HIR::SelfParam (mapping, std::unique_ptr<HIR::Type> (type),
+ self.get_is_mut (), self.get_locus ());
+ }
+
void visit (AST::ConstantItem &constant)
{
std::vector<HIR::Attribute> outer_attrs;
@@ -143,6 +158,91 @@ public:
translated = fn;
}
+ void visit (AST::Method &method)
+ {
+ // 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 method_name = method.get_method_name ();
+ Location locus = method.get_locus ();
+
+ HIR::SelfParam self_param = lower_self (method.get_self_param ());
+
+ std::unique_ptr<HIR::Type> return_type
+ = method.has_return_type () ? std::unique_ptr<HIR::Type> (
+ ASTLoweringType::translate (method.get_return_type ().get ()))
+ : nullptr;
+
+ std::vector<HIR::FunctionParam> function_params;
+ for (auto &param : method.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> method_body
+ = std::unique_ptr<HIR::BlockExpr> (
+ ASTLoweringBlock::translate (method.get_definition ().get (),
+ &terminated));
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, method.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+ auto mth
+ = new HIR::Method (mapping, std::move (method_name),
+ std::move (qualifiers), std::move (generic_params),
+ std::move (self_param), std::move (function_params),
+ std::move (return_type), std::move (where_clause),
+ std::move (method_body), std::move (vis),
+ std::move (outer_attrs), locus);
+
+ mappings->insert_hir_implitem (mapping.get_crate_num (),
+ mapping.get_hirid (), mth);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ method.get_locus ());
+
+ // insert mappings for self
+ mappings->insert_hir_self_param (crate_num,
+ self_param.get_mappings ().get_hirid (),
+ &self_param);
+ mappings->insert_location (crate_num,
+ self_param.get_mappings ().get_hirid (),
+ self_param.get_locus ());
+
+ // add the mappings for the function params at the end
+ for (auto &param : mth->get_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 = mth;
+ }
+
private:
ASTLowerImplItem () : translated (nullptr) {}
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 69b680d..d4af3c2 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -2177,9 +2177,9 @@ public:
void iterate_params (std::function<bool (Expr *)> cb)
{
- for (auto it = params.begin (); it != params.end (); it++)
+ for (auto &param : params)
{
- if (!cb (it->get ()))
+ if (!cb (param.get ()))
return;
}
}
@@ -2261,6 +2261,27 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ std::unique_ptr<Expr> &get_receiver () { return receiver; }
+
+ PathExprSegment get_method_name () const { return method_name; };
+
+ std::vector<std::unique_ptr<Expr> > &get_params () { return params; }
+ const std::vector<std::unique_ptr<Expr> > &get_params () const
+ {
+ return params;
+ }
+
+ size_t num_params () const { return params.size (); }
+
+ void iterate_params (std::function<bool (Expr *)> cb)
+ {
+ for (auto &param : params)
+ {
+ if (!cb (param.get ()))
+ return;
+ }
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -2585,6 +2606,10 @@ public:
return statements[statements.size () - 1]->get_locus_slow ();
}
+ std::unique_ptr<ExprWithoutBlock> &get_final_expr () { return expr; }
+
+ std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index 8502c9c..e4fa39a 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -676,7 +676,7 @@ Method::as_string () const
}
str += "\n Block expr (body): \n ";
- str += expr->as_string ();
+ str += function_body->as_string ();
return str;
}
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index e90dbb4..4ab23e1 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -297,10 +297,13 @@ private:
Location locus;
+ Analysis::NodeMapping mappings;
+
// Unrestricted constructor used for error state
- SelfParam (Lifetime lifetime, bool has_ref, bool is_mut, Type *type)
+ SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, bool has_ref,
+ bool is_mut, Type *type)
: has_ref (has_ref), is_mut (is_mut), lifetime (std::move (lifetime)),
- type (type)
+ type (type), mappings (mappings)
{}
// this is ok as no outside classes can ever call this
@@ -319,21 +322,23 @@ public:
}
// Type-based self parameter (not ref, no lifetime)
- SelfParam (std::unique_ptr<Type> type, bool is_mut, Location locus)
+ SelfParam (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
+ bool is_mut, Location locus)
: has_ref (false), is_mut (is_mut), lifetime (Lifetime::error ()),
- type (std::move (type)), locus (locus)
+ type (std::move (type)), locus (locus), mappings (mappings)
{}
// Lifetime-based self parameter (is ref, no type)
- SelfParam (Lifetime lifetime, bool is_mut, Location locus)
+ SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, bool is_mut,
+ Location locus)
: has_ref (true), is_mut (is_mut), lifetime (std::move (lifetime)),
- locus (locus)
+ locus (locus), mappings (mappings)
{}
// Copy constructor requires clone
SelfParam (SelfParam const &other)
: has_ref (other.has_ref), is_mut (other.is_mut), lifetime (other.lifetime),
- locus (other.locus)
+ locus (other.locus), mappings (other.mappings)
{
if (other.type != nullptr)
type = other.type->clone_type ();
@@ -348,6 +353,7 @@ public:
has_ref = other.has_ref;
lifetime = other.lifetime;
locus = other.locus;
+ mappings = other.mappings;
return *this;
}
@@ -359,6 +365,18 @@ public:
std::string as_string () const;
Location get_locus () const { return locus; }
+
+ bool get_has_ref () const { return has_ref; };
+ bool get_is_mut () const { return is_mut; }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Type> &get_type ()
+ {
+ rust_assert (has_type ());
+ return type;
+ }
+
+ Analysis::NodeMapping get_mappings () { return mappings; }
};
// Qualifiers for function, i.e. const, unsafe, extern etc.
@@ -542,6 +560,8 @@ protected:
// A method (function belonging to a type)
class Method : public InherentImplItem, public TraitImplItem
{
+ Analysis::NodeMapping mappings;
+
// moved from impl items for consistency
std::vector<Attribute> outer_attrs;
Visibility vis;
@@ -566,9 +586,7 @@ class Method : public InherentImplItem, public TraitImplItem
// bool has_where_clause;
WhereClause where_clause;
- std::unique_ptr<BlockExpr> expr;
-
- Analysis::NodeMapping mappings;
+ std::unique_ptr<BlockExpr> function_body;
Location locus;
@@ -603,8 +621,8 @@ public:
self_param (std::move (self_param)),
function_params (std::move (function_params)),
return_type (std::move (return_type)),
- where_clause (std::move (where_clause)), expr (std::move (function_body)),
- locus (locus)
+ where_clause (std::move (where_clause)),
+ function_body (std::move (function_body)), locus (locus)
{}
// TODO: add constructor with less fields
@@ -616,7 +634,8 @@ public:
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 ()),
+ where_clause (other.where_clause),
+ function_body (other.function_body->clone_block_expr ()),
locus (other.locus)
{
generic_params.reserve (other.generic_params.size ());
@@ -636,7 +655,7 @@ public:
function_params = other.function_params;
return_type = other.return_type->clone_type ();
where_clause = other.where_clause;
- expr = other.expr->clone_block_expr ();
+ function_body = other.function_body->clone_block_expr ();
locus = other.locus;
generic_params.reserve (other.generic_params.size ());
@@ -661,6 +680,58 @@ public:
return get_mappings ();
};
+ // Returns whether function has return type - if not, it is void.
+ bool has_function_return_type () const { return return_type != nullptr; }
+
+ std::vector<FunctionParam> &get_function_params () { return function_params; }
+ const std::vector<FunctionParam> &get_function_params () const
+ {
+ return function_params;
+ }
+
+ std::vector<std::unique_ptr<GenericParam> > &get_generic_params ()
+ {
+ return generic_params;
+ }
+ const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const
+ {
+ return generic_params;
+ }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<BlockExpr> &get_definition ()
+ {
+ rust_assert (function_body != nullptr);
+ return function_body;
+ }
+
+ SelfParam &get_self_param () { return self_param; }
+ const SelfParam &get_self_param () const { return self_param; }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Type> &get_return_type ()
+ {
+ rust_assert (has_return_type ());
+ return return_type;
+ }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ WhereClause &get_where_clause ()
+ {
+ rust_assert (has_where_clause ());
+ return where_clause;
+ }
+
+ Identifier get_method_name () const { return method_name; }
+
+ Location get_locus () const { return locus; }
+
+ std::unique_ptr<BlockExpr> &get_function_body () { return function_body; }
+ const std::unique_ptr<BlockExpr> &get_function_body () const
+ {
+ return function_body;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index 1bba506..9a772f0 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -228,6 +228,8 @@ public:
std::string as_string () const;
Location get_locus () const { return locus; }
+
+ PathIdentSegment get_segment () const { return segment_name; }
};
// HIR node representing a pattern that involves a "path" - abstract base class
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
index cc60055..16334bd 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -21,7 +21,6 @@
#include "rust-ast-visitor.h"
#include "rust-name-resolver.h"
-
#include "rust-diagnostics.h"
#include "rust-location.h"
@@ -33,210 +32,181 @@ class ResolverBase : public AST::ASTVisitor
public:
virtual ~ResolverBase () {}
- // visitor impl
- // rust-ast.h
- // virtual void visit(AttrInput& attr_input);
- // virtual void visit(TokenTree& token_tree);
- // virtual void visit(MacroMatch& macro_match);
- virtual void visit (AST::Token &tok) {}
- virtual void visit (AST::DelimTokenTree &delim_tok_tree) {}
- virtual void visit (AST::AttrInputMetaItemContainer &input) {}
- // virtual void visit(MetaItem& meta_item) {}
- // void vsit(Stmt& stmt) {}
- // virtual void visit(Expr& expr) {}
- virtual void visit (AST::IdentifierExpr &ident_expr) {}
- // virtual void visit(Pattern& pattern) {}
- // virtual void visit(Type& type) {}
- // virtual void visit(TypeParamBound& type_param_bound) {}
- virtual void visit (AST::Lifetime &lifetime) {}
- // virtual void visit(GenericParam& generic_param) {}
- virtual void visit (AST::LifetimeParam &lifetime_param) {}
- // virtual void visit(TraitItem& trait_item) {}
- // virtual void visit(InherentImplItem& inherent_impl_item) {}
- // virtual void visit(TraitImplItem& trait_impl_item) {}
- virtual void visit (AST::MacroInvocationSemi &macro) {}
-
- // rust-path.h
- virtual void visit (AST::PathInExpression &path) {}
- virtual void visit (AST::TypePathSegment &segment) {}
- virtual void visit (AST::TypePathSegmentGeneric &segment) {}
- virtual void visit (AST::TypePathSegmentFunction &segment) {}
- virtual void visit (AST::TypePath &path) {}
- virtual void visit (AST::QualifiedPathInExpression &path) {}
- virtual void visit (AST::QualifiedPathInType &path) {}
-
- // rust-expr.h
- virtual void visit (AST::LiteralExpr &expr) {}
- virtual void visit (AST::AttrInputLiteral &attr_input) {}
- virtual void visit (AST::MetaItemLitExpr &meta_item) {}
- virtual void visit (AST::MetaItemPathLit &meta_item) {}
- virtual void visit (AST::BorrowExpr &expr) {}
- virtual void visit (AST::DereferenceExpr &expr) {}
- virtual void visit (AST::ErrorPropagationExpr &expr) {}
- virtual void visit (AST::NegationExpr &expr) {}
- virtual void visit (AST::ArithmeticOrLogicalExpr &expr) {}
- virtual void visit (AST::ComparisonExpr &expr) {}
- virtual void visit (AST::LazyBooleanExpr &expr) {}
- virtual void visit (AST::TypeCastExpr &expr) {}
- virtual void visit (AST::AssignmentExpr &expr) {}
- virtual void visit (AST::CompoundAssignmentExpr &expr) {}
- virtual void visit (AST::GroupedExpr &expr) {}
- // virtual void visit(ArrayElems& elems) {}
- virtual void visit (AST::ArrayElemsValues &elems) {}
- virtual void visit (AST::ArrayElemsCopied &elems) {}
- virtual void visit (AST::ArrayExpr &expr) {}
- virtual void visit (AST::ArrayIndexExpr &expr) {}
- virtual void visit (AST::TupleExpr &expr) {}
- virtual void visit (AST::TupleIndexExpr &expr) {}
- virtual void visit (AST::StructExprStruct &expr) {}
- // virtual void visit(StructExprField& field) {}
- virtual void visit (AST::StructExprFieldIdentifier &field) {}
- virtual void visit (AST::StructExprFieldIdentifierValue &field) {}
- virtual void visit (AST::StructExprFieldIndexValue &field) {}
- virtual void visit (AST::StructExprStructFields &expr) {}
- virtual void visit (AST::StructExprStructBase &expr) {}
- virtual void visit (AST::StructExprTuple &expr) {}
- virtual void visit (AST::StructExprUnit &expr) {}
- // virtual void visit(EnumExprField& field) {}
- virtual void visit (AST::EnumExprFieldIdentifier &field) {}
- virtual void visit (AST::EnumExprFieldIdentifierValue &field) {}
- virtual void visit (AST::EnumExprFieldIndexValue &field) {}
- virtual void visit (AST::EnumExprStruct &expr) {}
- virtual void visit (AST::EnumExprTuple &expr) {}
- virtual void visit (AST::EnumExprFieldless &expr) {}
- virtual void visit (AST::CallExpr &expr) {}
- virtual void visit (AST::MethodCallExpr &expr) {}
- virtual void visit (AST::FieldAccessExpr &expr) {}
- virtual void visit (AST::ClosureExprInner &expr) {}
- virtual void visit (AST::BlockExpr &expr) {}
- virtual void visit (AST::ClosureExprInnerTyped &expr) {}
- virtual void visit (AST::ContinueExpr &expr) {}
- virtual void visit (AST::BreakExpr &expr) {}
- virtual void visit (AST::RangeFromToExpr &expr) {}
- virtual void visit (AST::RangeFromExpr &expr) {}
- virtual void visit (AST::RangeToExpr &expr) {}
- virtual void visit (AST::RangeFullExpr &expr) {}
- virtual void visit (AST::RangeFromToInclExpr &expr) {}
- virtual void visit (AST::RangeToInclExpr &expr) {}
- virtual void visit (AST::ReturnExpr &expr) {}
- virtual void visit (AST::UnsafeBlockExpr &expr) {}
- virtual void visit (AST::LoopExpr &expr) {}
- virtual void visit (AST::WhileLoopExpr &expr) {}
- virtual void visit (AST::WhileLetLoopExpr &expr) {}
- virtual void visit (AST::ForLoopExpr &expr) {}
- virtual void visit (AST::IfExpr &expr) {}
- virtual void visit (AST::IfExprConseqElse &expr) {}
- virtual void visit (AST::IfExprConseqIf &expr) {}
- virtual void visit (AST::IfExprConseqIfLet &expr) {}
- virtual void visit (AST::IfLetExpr &expr) {}
- virtual void visit (AST::IfLetExprConseqElse &expr) {}
- virtual void visit (AST::IfLetExprConseqIf &expr) {}
- virtual void visit (AST::IfLetExprConseqIfLet &expr) {}
- // virtual void visit(MatchCase& match_case) {}
- // virtual void visit (AST::MatchCaseBlockExpr &match_case) {}
- // virtual void visit (AST::MatchCaseExpr &match_case) {}
- virtual void visit (AST::MatchExpr &expr) {}
- virtual void visit (AST::AwaitExpr &expr) {}
- virtual void visit (AST::AsyncBlockExpr &expr) {}
-
- // rust-item.h
- virtual void visit (AST::TypeParam &param) {}
- // virtual void visit(WhereClauseItem& item) {}
- virtual void visit (AST::LifetimeWhereClauseItem &item) {}
- virtual void visit (AST::TypeBoundWhereClauseItem &item) {}
- virtual void visit (AST::Method &method) {}
- virtual void visit (AST::ModuleBodied &module) {}
- virtual void visit (AST::ModuleNoBody &module) {}
- virtual void visit (AST::ExternCrate &crate) {}
- // virtual void visit(UseTree& use_tree) {}
- virtual void visit (AST::UseTreeGlob &use_tree) {}
- virtual void visit (AST::UseTreeList &use_tree) {}
- virtual void visit (AST::UseTreeRebind &use_tree) {}
- virtual void visit (AST::UseDeclaration &use_decl) {}
- virtual void visit (AST::Function &function) {}
- virtual void visit (AST::TypeAlias &type_alias) {}
- virtual void visit (AST::StructStruct &struct_item) {}
- virtual void visit (AST::TupleStruct &tuple_struct) {}
- virtual void visit (AST::EnumItem &item) {}
- virtual void visit (AST::EnumItemTuple &item) {}
- virtual void visit (AST::EnumItemStruct &item) {}
- virtual void visit (AST::EnumItemDiscriminant &item) {}
- virtual void visit (AST::Enum &enum_item) {}
- virtual void visit (AST::Union &union_item) {}
- virtual void visit (AST::ConstantItem &const_item) {}
- virtual void visit (AST::StaticItem &static_item) {}
- virtual void visit (AST::TraitItemFunc &item) {}
- virtual void visit (AST::TraitItemMethod &item) {}
- virtual void visit (AST::TraitItemConst &item) {}
- virtual void visit (AST::TraitItemType &item) {}
- virtual void visit (AST::Trait &trait) {}
- virtual void visit (AST::InherentImpl &impl) {}
- virtual void visit (AST::TraitImpl &impl) {}
- // virtual void visit(ExternalItem& item) {}
- virtual void visit (AST::ExternalStaticItem &item) {}
- virtual void visit (AST::ExternalFunctionItem &item) {}
- virtual void visit (AST::ExternBlock &block) {}
-
- // rust-macro.h
- virtual void visit (AST::MacroMatchFragment &match) {}
- virtual void visit (AST::MacroMatchRepetition &match) {}
- virtual void visit (AST::MacroMatcher &matcher) {}
- virtual void visit (AST::MacroRulesDefinition &rules_def) {}
- virtual void visit (AST::MacroInvocation &macro_invoc) {}
- virtual void visit (AST::MetaItemPath &meta_item) {}
- virtual void visit (AST::MetaItemSeq &meta_item) {}
- virtual void visit (AST::MetaWord &meta_item) {}
- virtual void visit (AST::MetaNameValueStr &meta_item) {}
- virtual void visit (AST::MetaListPaths &meta_item) {}
- virtual void visit (AST::MetaListNameValueStr &meta_item) {}
-
- // rust-pattern.h
- virtual void visit (AST::LiteralPattern &pattern) {}
- virtual void visit (AST::IdentifierPattern &pattern) {}
- virtual void visit (AST::WildcardPattern &pattern) {}
- // virtual void visit(RangePatternBound& bound) {}
- virtual void visit (AST::RangePatternBoundLiteral &bound) {}
- virtual void visit (AST::RangePatternBoundPath &bound) {}
- virtual void visit (AST::RangePatternBoundQualPath &bound) {}
- virtual void visit (AST::RangePattern &pattern) {}
- virtual void visit (AST::ReferencePattern &pattern) {}
- // virtual void visit(StructPatternField& field) {}
- virtual void visit (AST::StructPatternFieldTuplePat &field) {}
- virtual void visit (AST::StructPatternFieldIdentPat &field) {}
- virtual void visit (AST::StructPatternFieldIdent &field) {}
- virtual void visit (AST::StructPattern &pattern) {}
- // virtual void visit(TupleStructItems& tuple_items) {}
- virtual void visit (AST::TupleStructItemsNoRange &tuple_items) {}
- virtual void visit (AST::TupleStructItemsRange &tuple_items) {}
- virtual void visit (AST::TupleStructPattern &pattern) {}
- // virtual void visit(TuplePatternItems& tuple_items) {}
- virtual void visit (AST::TuplePatternItemsMultiple &tuple_items) {}
- virtual void visit (AST::TuplePatternItemsRanged &tuple_items) {}
- virtual void visit (AST::TuplePattern &pattern) {}
- virtual void visit (AST::GroupedPattern &pattern) {}
- virtual void visit (AST::SlicePattern &pattern) {}
-
- // rust-stmt.h
- virtual void visit (AST::EmptyStmt &stmt) {}
- virtual void visit (AST::LetStmt &stmt) {}
- virtual void visit (AST::ExprStmtWithoutBlock &stmt) {}
- virtual void visit (AST::ExprStmtWithBlock &stmt) {}
-
- // rust-type.h
- virtual void visit (AST::TraitBound &bound) {}
- virtual void visit (AST::ImplTraitType &type) {}
- virtual void visit (AST::TraitObjectType &type) {}
- virtual void visit (AST::ParenthesisedType &type) {}
- virtual void visit (AST::ImplTraitTypeOneBound &type) {}
- virtual void visit (AST::TraitObjectTypeOneBound &type) {}
- virtual void visit (AST::TupleType &type) {}
- virtual void visit (AST::NeverType &type) {}
- virtual void visit (AST::RawPointerType &type) {}
- virtual void visit (AST::ReferenceType &type) {}
- virtual void visit (AST::ArrayType &type) {}
- virtual void visit (AST::SliceType &type) {}
- virtual void visit (AST::InferredType &type) {}
- virtual void visit (AST::BareFunctionType &type) {}
+ void visit (AST::Token &) {}
+ void visit (AST::DelimTokenTree &) {}
+ void visit (AST::AttrInputMetaItemContainer &) {}
+ void visit (AST::IdentifierExpr &) {}
+ void visit (AST::Lifetime &) {}
+ void visit (AST::LifetimeParam &) {}
+ void visit (AST::MacroInvocationSemi &) {}
+ void visit (AST::PathInExpression &) {}
+ void visit (AST::TypePathSegment &) {}
+ void visit (AST::TypePathSegmentGeneric &) {}
+ void visit (AST::TypePathSegmentFunction &) {}
+ void visit (AST::TypePath &) {}
+ void visit (AST::QualifiedPathInExpression &) {}
+ void visit (AST::QualifiedPathInType &) {}
+ void visit (AST::LiteralExpr &) {}
+ void visit (AST::AttrInputLiteral &) {}
+ void visit (AST::MetaItemLitExpr &) {}
+ void visit (AST::MetaItemPathLit &) {}
+ void visit (AST::BorrowExpr &) {}
+ void visit (AST::DereferenceExpr &) {}
+ void visit (AST::ErrorPropagationExpr &) {}
+ void visit (AST::NegationExpr &) {}
+ void visit (AST::ArithmeticOrLogicalExpr &) {}
+ void visit (AST::ComparisonExpr &) {}
+ void visit (AST::LazyBooleanExpr &) {}
+ void visit (AST::TypeCastExpr &) {}
+ void visit (AST::AssignmentExpr &) {}
+ void visit (AST::CompoundAssignmentExpr &) {}
+ void visit (AST::GroupedExpr &) {}
+ void visit (AST::ArrayElemsValues &) {}
+ void visit (AST::ArrayElemsCopied &) {}
+ void visit (AST::ArrayExpr &) {}
+ void visit (AST::ArrayIndexExpr &) {}
+ void visit (AST::TupleExpr &) {}
+ void visit (AST::TupleIndexExpr &) {}
+ void visit (AST::StructExprStruct &) {}
+ void visit (AST::StructExprFieldIdentifier &) {}
+ void visit (AST::StructExprFieldIdentifierValue &) {}
+ void visit (AST::StructExprFieldIndexValue &) {}
+ void visit (AST::StructExprStructFields &) {}
+ void visit (AST::StructExprStructBase &) {}
+ void visit (AST::StructExprTuple &) {}
+ void visit (AST::StructExprUnit &) {}
+ void visit (AST::EnumExprFieldIdentifier &) {}
+ void visit (AST::EnumExprFieldIdentifierValue &) {}
+ void visit (AST::EnumExprFieldIndexValue &) {}
+ void visit (AST::EnumExprStruct &) {}
+ void visit (AST::EnumExprTuple &) {}
+ void visit (AST::EnumExprFieldless &) {}
+ void visit (AST::CallExpr &) {}
+ void visit (AST::MethodCallExpr &) {}
+ void visit (AST::FieldAccessExpr &) {}
+ void visit (AST::ClosureExprInner &) {}
+ void visit (AST::BlockExpr &) {}
+ void visit (AST::ClosureExprInnerTyped &) {}
+ void visit (AST::ContinueExpr &) {}
+ void visit (AST::BreakExpr &) {}
+ void visit (AST::RangeFromToExpr &) {}
+ void visit (AST::RangeFromExpr &) {}
+ void visit (AST::RangeToExpr &) {}
+ void visit (AST::RangeFullExpr &) {}
+ void visit (AST::RangeFromToInclExpr &) {}
+ void visit (AST::RangeToInclExpr &) {}
+ void visit (AST::ReturnExpr &) {}
+ void visit (AST::UnsafeBlockExpr &) {}
+ void visit (AST::LoopExpr &) {}
+ void visit (AST::WhileLoopExpr &) {}
+ void visit (AST::WhileLetLoopExpr &) {}
+ void visit (AST::ForLoopExpr &) {}
+ void visit (AST::IfExpr &) {}
+ void visit (AST::IfExprConseqElse &) {}
+ void visit (AST::IfExprConseqIf &) {}
+ void visit (AST::IfExprConseqIfLet &) {}
+ void visit (AST::IfLetExpr &) {}
+ void visit (AST::IfLetExprConseqElse &) {}
+ void visit (AST::IfLetExprConseqIf &) {}
+ void visit (AST::IfLetExprConseqIfLet &) {}
+
+ void visit (AST::MatchExpr &) {}
+ void visit (AST::AwaitExpr &) {}
+ void visit (AST::AsyncBlockExpr &) {}
+
+ void visit (AST::TypeParam &) {}
+
+ void visit (AST::LifetimeWhereClauseItem &) {}
+ void visit (AST::TypeBoundWhereClauseItem &) {}
+ void visit (AST::Method &) {}
+ void visit (AST::ModuleBodied &) {}
+ void visit (AST::ModuleNoBody &) {}
+ void visit (AST::ExternCrate &) {}
+
+ void visit (AST::UseTreeGlob &) {}
+ void visit (AST::UseTreeList &) {}
+ void visit (AST::UseTreeRebind &) {}
+ void visit (AST::UseDeclaration &) {}
+ void visit (AST::Function &) {}
+ void visit (AST::TypeAlias &) {}
+ void visit (AST::StructStruct &) {}
+ void visit (AST::TupleStruct &) {}
+ void visit (AST::EnumItem &) {}
+ void visit (AST::EnumItemTuple &) {}
+ void visit (AST::EnumItemStruct &) {}
+ void visit (AST::EnumItemDiscriminant &) {}
+ void visit (AST::Enum &) {}
+ void visit (AST::Union &) {}
+ void visit (AST::ConstantItem &) {}
+ void visit (AST::StaticItem &) {}
+ void visit (AST::TraitItemFunc &) {}
+ void visit (AST::TraitItemMethod &) {}
+ void visit (AST::TraitItemConst &) {}
+ void visit (AST::TraitItemType &) {}
+ void visit (AST::Trait &) {}
+ void visit (AST::InherentImpl &) {}
+ void visit (AST::TraitImpl &) {}
+
+ void visit (AST::ExternalStaticItem &) {}
+ void visit (AST::ExternalFunctionItem &) {}
+ void visit (AST::ExternBlock &) {}
+
+ void visit (AST::MacroMatchFragment &) {}
+ void visit (AST::MacroMatchRepetition &) {}
+ void visit (AST::MacroMatcher &) {}
+ void visit (AST::MacroRulesDefinition &) {}
+ void visit (AST::MacroInvocation &) {}
+ void visit (AST::MetaItemPath &) {}
+ void visit (AST::MetaItemSeq &) {}
+ void visit (AST::MetaWord &) {}
+ void visit (AST::MetaNameValueStr &) {}
+ void visit (AST::MetaListPaths &) {}
+ void visit (AST::MetaListNameValueStr &) {}
+
+ void visit (AST::LiteralPattern &) {}
+ void visit (AST::IdentifierPattern &) {}
+ void visit (AST::WildcardPattern &) {}
+
+ void visit (AST::RangePatternBoundLiteral &) {}
+ void visit (AST::RangePatternBoundPath &) {}
+ void visit (AST::RangePatternBoundQualPath &) {}
+ void visit (AST::RangePattern &) {}
+ void visit (AST::ReferencePattern &) {}
+
+ void visit (AST::StructPatternFieldTuplePat &) {}
+ void visit (AST::StructPatternFieldIdentPat &) {}
+ void visit (AST::StructPatternFieldIdent &) {}
+ void visit (AST::StructPattern &) {}
+
+ void visit (AST::TupleStructItemsNoRange &) {}
+ void visit (AST::TupleStructItemsRange &) {}
+ void visit (AST::TupleStructPattern &) {}
+
+ void visit (AST::TuplePatternItemsMultiple &) {}
+ void visit (AST::TuplePatternItemsRanged &) {}
+ void visit (AST::TuplePattern &) {}
+ void visit (AST::GroupedPattern &) {}
+ void visit (AST::SlicePattern &) {}
+
+ void visit (AST::EmptyStmt &) {}
+ void visit (AST::LetStmt &) {}
+ void visit (AST::ExprStmtWithoutBlock &) {}
+ void visit (AST::ExprStmtWithBlock &) {}
+
+ void visit (AST::TraitBound &) {}
+ void visit (AST::ImplTraitType &) {}
+ void visit (AST::TraitObjectType &) {}
+ void visit (AST::ParenthesisedType &) {}
+ void visit (AST::ImplTraitTypeOneBound &) {}
+ void visit (AST::TraitObjectTypeOneBound &) {}
+ void visit (AST::TupleType &) {}
+ void visit (AST::NeverType &) {}
+ void visit (AST::RawPointerType &) {}
+ void visit (AST::ReferenceType &) {}
+ void visit (AST::ArrayType &) {}
+ void visit (AST::SliceType &) {}
+ void visit (AST::InferredType &) {}
+ void visit (AST::BareFunctionType &) {}
protected:
ResolverBase (NodeId parent)
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index f62f17c..d563f93 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -91,6 +91,15 @@ public:
});
}
+ void visit (AST::MethodCallExpr &expr)
+ {
+ ResolveExpr::go (expr.get_receiver_expr ().get (), expr.get_node_id ());
+ expr.iterate_params ([&] (AST::Expr *p) mutable -> bool {
+ ResolveExpr::go (p, expr.get_node_id ());
+ return true;
+ });
+ }
+
void visit (AST::AssignmentExpr &expr)
{
ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index 74f2cdc..9cbef53 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -39,8 +39,12 @@ public:
{
std::string identifier
= base->as_string () + "::" + constant.get_identifier ();
- resolver->get_name_scope ().insert (identifier, constant.get_node_id (),
- constant.get_locus ());
+ resolver->get_name_scope ().insert (
+ identifier, constant.get_node_id (), constant.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (constant.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (constant.get_node_id (),
Definition{constant.get_node_id (),
constant.get_node_id ()});
@@ -50,8 +54,12 @@ public:
{
std::string identifier
= base->as_string () + "::" + function.get_function_name ();
- resolver->get_name_scope ().insert (identifier, function.get_node_id (),
- function.get_locus ());
+ resolver->get_name_scope ().insert (
+ identifier, function.get_node_id (), function.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (function.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (function.get_node_id (),
Definition{function.get_node_id (),
function.get_node_id ()});
@@ -61,8 +69,12 @@ public:
{
std::string identifier
= base->as_string () + "::" + method.get_method_name ();
- resolver->get_name_scope ().insert (identifier, method.get_node_id (),
- method.get_locus ());
+ resolver->get_name_scope ().insert (
+ identifier, method.get_node_id (), method.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (method.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (method.get_node_id (),
Definition{method.get_node_id (),
method.get_node_id ()});
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 74b5f8d..8b6227e 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -24,7 +24,6 @@
#include "rust-ast-resolve-type.h"
#include "rust-ast-resolve-pattern.h"
#include "rust-ast-resolve-stmt.h"
-#include "rust-ast-resolve-unused.h"
namespace Rust {
namespace Resolver {
@@ -110,17 +109,76 @@ public:
ResolveExpr::go (function.get_definition ().get (),
function.get_node_id ());
- ScanUnused::Scan (resolver->get_name_scope ().peek ());
- ScanUnused::Scan (resolver->get_type_scope ().peek ());
-
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
}
void visit (AST::InherentImpl &impl_block)
{
+ NodeId resolved_node = ResolveType::go (impl_block.get_type ().get (),
+ impl_block.get_node_id ());
+ if (resolved_node == UNKNOWN_NODEID)
+ return;
+
+ resolver->get_type_scope ().insert (
+ "Self", resolved_node, impl_block.get_type ()->get_locus_slow ());
+
for (auto &impl_item : impl_block.get_impl_items ())
impl_item->accept_vis (*this);
+
+ resolver->get_type_scope ().peek ()->clear_name ("Self", resolved_node);
+ }
+
+ void visit (AST::Method &method)
+ {
+ if (method.has_return_type ())
+ ResolveType::go (method.get_return_type ().get (), method.get_node_id ());
+
+ NodeId scope_node_id = method.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 ());
+
+ // self turns into self: Self as a function param
+ AST::SelfParam &self_param = method.get_self_param ();
+ AST::IdentifierPattern self_pattern (
+ self_param.get_node_id (), "self", self_param.get_locus (),
+ self_param.get_has_ref (), self_param.get_is_mut (),
+ std::unique_ptr<AST::Pattern> (nullptr));
+
+ std::vector<std::unique_ptr<AST::TypePathSegment> > segments;
+ segments.push_back (std::unique_ptr<AST::TypePathSegment> (
+ new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
+
+ AST::TypePath self_type_path (std::move (segments),
+ self_param.get_locus ());
+
+ ResolveType::go (&self_type_path, self_param.get_node_id ());
+ PatternDeclaration::go (&self_pattern, self_param.get_node_id ());
+
+ resolver->mark_assignment_to_decl (self_pattern.get_node_id (),
+ self_pattern.get_node_id ());
+
+ // we make a new scope so the names of parameters are resolved and shadowed
+ // correctly
+ for (auto &param : method.get_function_params ())
+ {
+ ResolveType::go (param.get_type ().get (), param.get_node_id ());
+ PatternDeclaration::go (param.get_pattern ().get (),
+ param.get_node_id ());
+
+ // the mutability checker needs to verify for immutable decls the number
+ // of assignments are <1. This marks an implicit assignment
+ resolver->mark_assignment_to_decl (param.get_pattern ()->get_node_id (),
+ param.get_node_id ());
+ }
+
+ // resolve the function body
+ ResolveExpr::go (method.get_definition ().get (), method.get_node_id ());
+
+ resolver->get_name_scope ().pop ();
+ resolver->get_type_scope ().pop ();
}
private:
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 7ca8275..2e4e8e7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -38,22 +38,34 @@ public:
void visit (AST::TupleStruct &struct_decl)
{
- resolver->get_type_scope ().insert (struct_decl.get_identifier (),
- struct_decl.get_node_id (),
- struct_decl.get_locus ());
+ resolver->get_type_scope ().insert (
+ struct_decl.get_identifier (), struct_decl.get_node_id (),
+ struct_decl.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (struct_decl.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
}
void visit (AST::StructStruct &struct_decl)
{
- resolver->get_type_scope ().insert (struct_decl.get_identifier (),
- struct_decl.get_node_id (),
- struct_decl.get_locus ());
+ resolver->get_type_scope ().insert (
+ struct_decl.get_identifier (), struct_decl.get_node_id (),
+ struct_decl.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (struct_decl.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
}
void visit (AST::StaticItem &var)
{
- resolver->get_name_scope ().insert (var.get_identifier (),
- var.get_node_id (), var.get_locus ());
+ resolver->get_name_scope ().insert (
+ var.get_identifier (), var.get_node_id (), var.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (var.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (var.get_node_id (),
Definition{var.get_node_id (),
var.get_node_id ()});
@@ -62,9 +74,13 @@ public:
void visit (AST::ConstantItem &constant)
{
- resolver->get_name_scope ().insert (constant.get_identifier (),
- constant.get_node_id (),
- constant.get_locus ());
+ resolver->get_name_scope ().insert (
+ constant.get_identifier (), constant.get_node_id (),
+ constant.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (constant.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (constant.get_node_id (),
Definition{constant.get_node_id (),
constant.get_node_id ()});
@@ -72,9 +88,13 @@ public:
void visit (AST::Function &function)
{
- resolver->get_name_scope ().insert (function.get_function_name (),
- function.get_node_id (),
- function.get_locus ());
+ resolver->get_name_scope ().insert (
+ function.get_function_name (), function.get_node_id (),
+ function.get_locus (), false,
+ [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (function.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
resolver->insert_new_definition (function.get_node_id (),
Definition{function.get_node_id (),
function.get_node_id ()});
@@ -90,10 +110,6 @@ 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 ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 258524b..ec8ee87 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -28,14 +28,14 @@ namespace Resolver {
class ResolveType : public ResolverBase
{
public:
- static bool go (AST::Type *type, NodeId parent)
+ static NodeId 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;
+ return resolver.resolved_node;
};
void visit (AST::BareFunctionType &fntype)
diff --git a/gcc/rust/resolve/rust-ast-resolve-unused.h b/gcc/rust/resolve/rust-ast-resolve-unused.h
index 08b2db1..928cf11 100644
--- a/gcc/rust/resolve/rust-ast-resolve-unused.h
+++ b/gcc/rust/resolve/rust-ast-resolve-unused.h
@@ -24,10 +24,10 @@
namespace Rust {
namespace Resolver {
-class ScanUnused : public ResolverBase
+class ScanUnused
{
public:
- static void Scan (Rib *r)
+ static void ScanRib (Rib *r)
{
r->iterate_decls ([&] (NodeId decl_node_id, Location locus) -> bool {
if (!r->have_references_for_node (decl_node_id))
@@ -37,6 +37,13 @@ public:
return true;
});
}
+
+ static void Scan ()
+ {
+ auto resolver = Resolver::get ();
+ resolver->iterate_name_ribs ([&] (Rib *r) -> void { ScanRib (r); });
+ resolver->iterate_type_ribs ([&] (Rib *r) -> void { ScanRib (r); });
+ }
};
} // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 6731f13..d514132 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -22,7 +22,6 @@
#include "rust-ast-resolve-toplevel.h"
#include "rust-ast-resolve-item.h"
#include "rust-ast-resolve-expr.h"
-#include "rust-ast-resolve-unused.h"
#define MKBUILTIN_TYPE(_X, _R, _TY) \
do \
@@ -110,7 +109,8 @@ Resolver::insert_builtin_types (Rib *r)
auto builtins = get_builtin_types ();
for (auto &builtin : builtins)
r->insert_name (builtin->as_string (), builtin->get_node_id (),
- Linemap::predeclared_location ());
+ Linemap::predeclared_location (), false,
+ [] (std::string, NodeId, Location) -> void {});
}
std::vector<AST::Type *> &
@@ -283,9 +283,6 @@ NameResolution::go (AST::Crate &crate)
// next we can drill down into the items and their scopes
for (auto it = crate.items.begin (); it != crate.items.end (); it++)
ResolveItem::go (it->get ());
-
- ScanUnused::Scan (resolver->get_name_scope ().peek ());
- ScanUnused::Scan (resolver->get_type_scope ().peek ());
}
// rust-ast-resolve-expr.h
@@ -307,9 +304,6 @@ ResolveExpr::visit (AST::BlockExpr &expr)
if (expr.has_tail_expr ())
ResolveExpr::go (expr.get_tail_expr ().get (), expr.get_node_id ());
- ScanUnused::Scan (resolver->get_name_scope ().peek ());
- ScanUnused::Scan (resolver->get_type_scope ().peek ());
-
resolver->get_name_scope ().pop ();
resolver->get_type_scope ().pop ();
}
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 5bc6aba..ea0e4f5 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -37,8 +37,25 @@ public:
~Rib () {}
- void insert_name (std::string ident, NodeId id, Location locus)
+ void insert_name (std::string ident, NodeId id, Location locus, bool shadow,
+ std::function<void (std::string, NodeId, Location)> dup_cb)
{
+ auto it = mappings.find (ident);
+ bool already_exists = it != mappings.end ();
+ if (already_exists && !shadow)
+ {
+ for (auto &decl : decls_within_rib)
+ {
+ if (decl.first == it->second)
+ {
+ dup_cb (ident, it->second, decl.second);
+ return;
+ }
+ }
+ dup_cb (ident, it->second, locus);
+ return;
+ }
+
mappings[ident] = id;
decls_within_rib.insert (std::pair<NodeId, Location> (id, locus));
references[id] = {};
@@ -54,6 +71,19 @@ public:
return true;
}
+ void clear_name (std::string ident, NodeId id)
+ {
+ mappings.erase (ident);
+ for (auto &it : decls_within_rib)
+ {
+ if (it.first == id)
+ {
+ decls_within_rib.erase (it);
+ break;
+ }
+ }
+ }
+
CrateNum get_crate_num () const { return crate_num; }
NodeId get_node_id () const { return node_id; }
@@ -117,9 +147,16 @@ public:
Scope (CrateNum crate_num) : crate_num (crate_num) {}
~Scope () {}
+ void insert (std::string ident, NodeId id, Location locus, bool shadow,
+ std::function<void (std::string, NodeId, Location)> dup_cb)
+ {
+ peek ()->insert_name (ident, id, locus, shadow, dup_cb);
+ }
+
void insert (std::string ident, NodeId id, Location locus)
{
- peek ()->insert_name (ident, id, locus);
+ peek ()->insert_name (ident, id, locus, true,
+ [] (std::string, NodeId, Location) -> void {});
}
bool lookup (std::string ident, NodeId *id)
@@ -266,6 +303,23 @@ public:
return it->second.size ();
}
+ void iterate_name_ribs (std::function<void (Rib *)> cb)
+ {
+ for (auto it = name_ribs.begin (); it != name_ribs.end (); it++)
+ cb (it->second);
+ }
+
+ void iterate_type_ribs (std::function<void (Rib *)> cb)
+ {
+ for (auto it = type_ribs.begin (); it != type_ribs.end (); it++)
+ {
+ if (it->first == global_type_node_id)
+ continue;
+
+ cb (it->second);
+ }
+ }
+
private:
Resolver ();
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index dcdbd49..1d31135 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -35,6 +35,7 @@
#include "rust-ast-lower.h"
#include "rust-hir-type-check.h"
#include "rust-tycheck-dump.h"
+#include "rust-ast-resolve-unused.h"
#include "rust-compile.h"
extern Linemap *
@@ -527,9 +528,7 @@ Session::parse_file (const char *filename)
}
// resolution pipeline stage
- resolution (parsed_crate);
- fprintf (stderr, "\033[0;31mSUCCESSFULLY FINISHED RESOLUTION \n\033[0m");
-
+ Resolver::NameResolution::Resolve (parsed_crate);
if (options.dump_option == CompileOptions::RESOLUTION_DUMP)
{
// TODO: what do I dump here? resolved names? AST with resolved names?
@@ -539,7 +538,7 @@ Session::parse_file (const char *filename)
return;
// lower AST to HIR
- HIR::Crate hir = lower_ast (parsed_crate);
+ HIR::Crate hir = HIR::ASTLowering::Resolve (parsed_crate);
if (options.dump_option == CompileOptions::HIR_DUMP)
{
fprintf (stderr, "%s", hir.as_string ().c_str ());
@@ -550,11 +549,17 @@ Session::parse_file (const char *filename)
return;
// type resolve
- type_resolution (hir);
+ Resolver::TypeResolution::Resolve (hir);
+ if (options.dump_option == CompileOptions::TYPE_RESOLUTION_DUMP)
+ {
+ auto buf = Resolver::TypeResolverDump::go (hir);
+ fprintf (stderr, "%s\n", buf.c_str ());
+ return;
+ }
- // FIXME this needs an option of itself
- // auto buf = Resolver::TypeResolverDump::go (hir);
- // fprintf (stderr, "%s\n", buf.c_str ());
+ // scan unused has to be done after type resolution since methods are resolved
+ // at that point
+ Resolver::ScanUnused::Scan ();
if (saw_errors ())
return;
@@ -792,31 +797,6 @@ Session::expansion (AST::Crate &crate)
}
void
-Session::resolution (AST::Crate &crate)
-{
- fprintf (stderr, "started name resolution\n");
- Resolver::NameResolution::Resolve (crate);
- fprintf (stderr, "finished name resolution\n");
-}
-
-HIR::Crate
-Session::lower_ast (AST::Crate &crate)
-{
- fprintf (stderr, "started lowering AST\n");
- auto hir = HIR::ASTLowering::Resolve (crate);
- fprintf (stderr, "finished lowering AST\n");
- return hir;
-}
-
-void
-Session::type_resolution (HIR::Crate &crate)
-{
- fprintf (stderr, "started type resolution\n");
- Resolver::TypeResolution::Resolve (crate);
- fprintf (stderr, "finished type resolution\n");
-}
-
-void
TargetOptions::dump_target_options () const
{
fprintf (stderr,
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 4836cc8..07d5461 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -177,7 +177,8 @@ struct CompileOptions
RESOLUTION_DUMP,
TARGET_OPTION_DUMP,
HIR_DUMP,
- // TODO: add more?
+ TYPE_RESOLUTION_DUMP,
+
} dump_option;
/* configuration options - actually useful for conditional compilation and
@@ -204,8 +205,6 @@ struct Session
// backend linemap
Linemap *linemap;
- // TODO: replace raw pointers with smart pointers?
-
public:
/* Initialise compiler session. Corresponds to langhook grs_langhook_init().
* Note that this is called after option handling. */
@@ -217,7 +216,6 @@ public:
void init_options ();
private:
- // TODO: should this be private or public?
void parse_file (const char *filename);
bool enable_dump (std::string arg);
@@ -232,23 +230,16 @@ private:
* (top-level inner attribute creation from command line arguments), setting
* options maybe, registering lints maybe, loading plugins maybe. */
void register_plugins (AST::Crate &crate);
+
/* Injection pipeline stage. TODO maybe move to another object? Maybe have
* some lint checks (in future, obviously), register builtin macros, crate
* injection. */
void injection (AST::Crate &crate);
+
/* Expansion pipeline stage. TODO maybe move to another object? Expands all
* macros, maybe build test harness in future, AST validation, maybe create
* macro crate (if not rustdoc).*/
void expansion (AST::Crate &crate);
- /* Resolution pipeline stage. TODO maybe move to another object.
- * Performs name resolution and type resolution, maybe complete gated
- * feature checking, maybe create buffered lints in future. */
- void resolution (AST::Crate &crate);
- /* This lowers the AST down to HIR and assigns all mappings from AST
- * NodeIds back to HirIds */
- HIR::Crate lower_ast (AST::Crate &crate);
- /* This adds the type resolution process */
- void type_resolution (HIR::Crate &crate);
};
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-method-resolve.h b/gcc/rust/typecheck/rust-hir-method-resolve.h
new file mode 100644
index 0000000..9a6c76f
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-method-resolve.h
@@ -0,0 +1,95 @@
+// 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_METHOD_RESOLVE_H
+#define RUST_HIR_METHOD_RESOLVE_H
+
+#include "rust-hir-type-check-base.h"
+#include "rust-hir-full.h"
+#include "rust-tyty.h"
+
+namespace Rust {
+namespace Resolver {
+
+class MethodResolution : public TypeCheckBase
+{
+public:
+ static std::vector<HIR::Method *> Probe (TyTy::TyBase *receiver,
+ HIR::PathExprSegment method_name)
+ {
+ MethodResolution probe (receiver, method_name);
+
+ // lookup impl items for this crate and find all methods that can resolve to
+ // this receiver
+ probe.mappings->iterate_impl_items (
+ [&] (HirId id, HIR::InherentImplItem *item) mutable -> bool {
+ item->accept_vis (probe);
+ return true;
+ });
+
+ return probe.probed;
+ }
+
+ void visit (HIR::Method &method)
+ {
+ TyTy::TyBase *self_lookup = nullptr;
+ if (!context->lookup_type (
+ method.get_self_param ().get_mappings ().get_hirid (), &self_lookup))
+ {
+ rust_error_at (method.get_self_param ().get_locus (),
+ "failed to lookup lookup self type in MethodProbe");
+ return;
+ }
+
+ // are the names the same
+ HIR::PathIdentSegment seg = method_name.get_segment ();
+ if (seg.as_string ().compare (method.get_method_name ()) != 0)
+ {
+ // if the method name does not match then this is not a valid match
+ return;
+ }
+
+ // FIXME this can be simplified with
+ // https://github.com/Rust-GCC/gccrs/issues/187
+ auto combined = receiver->combine (self_lookup);
+ if (combined == nullptr)
+ {
+ // incompatible self argument then this is not a valid method for this
+ // receiver
+ return;
+ }
+ delete combined;
+
+ probed.push_back (&method);
+ }
+
+private:
+ MethodResolution (TyTy::TyBase *receiver, HIR::PathExprSegment method_name)
+ : TypeCheckBase (), receiver (receiver), method_name (method_name)
+ {}
+
+ TyTy::TyBase *receiver;
+ HIR::PathExprSegment method_name;
+
+ std::vector<HIR::Method *> probed;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_METHOD_RESOLVE_H
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index 8de1474..6906878 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -34,209 +34,186 @@ class TypeCheckBase : public HIR::HIRVisitor
public:
virtual ~TypeCheckBase () {}
- // visitor impl
- // rust-ast.h
- // virtual void visit(AttrInput& attr_input);
- // virtual void visit(TokenTree& token_tree);
- // virtual void visit(MacroMatch& macro_match);
- virtual void visit (HIR::Token &tok) {}
- virtual void visit (HIR::DelimTokenTree &delim_tok_tree) {}
- virtual void visit (HIR::AttrInputMetaItemContainer &input) {}
- // virtual void visit(MetaItem& meta_item) {}
- // void vsit(Stmt& stmt) {}
- // virtual void visit(Expr& expr) {}
- virtual void visit (HIR::IdentifierExpr &ident_expr) {}
- // virtual void visit(Pattern& pattern) {}
- // virtual void visit(Type& type) {}
- // virtual void visit(TypeParamBound& type_param_bound) {}
- virtual void visit (HIR::Lifetime &lifetime) {}
- // virtual void visit(GenericParam& generic_param) {}
- virtual void visit (HIR::LifetimeParam &lifetime_param) {}
- // virtual void visit(TraitItem& trait_item) {}
- // virtual void visit(InherentImplItem& inherent_impl_item) {}
- // virtual void visit(TraitImplItem& trait_impl_item) {}
-
- // rust-path.h
- virtual void visit (HIR::PathInExpression &path) {}
- virtual void visit (HIR::TypePathSegment &segment) {}
- virtual void visit (HIR::TypePathSegmentGeneric &segment) {}
- virtual void visit (HIR::TypePathSegmentFunction &segment) {}
- virtual void visit (HIR::TypePath &path) {}
- virtual void visit (HIR::QualifiedPathInExpression &path) {}
- virtual void visit (HIR::QualifiedPathInType &path) {}
-
- // rust-expr.h
- virtual void visit (HIR::LiteralExpr &expr) {}
- virtual void visit (HIR::AttrInputLiteral &attr_input) {}
- virtual void visit (HIR::MetaItemLitExpr &meta_item) {}
- virtual void visit (HIR::MetaItemPathLit &meta_item) {}
- virtual void visit (HIR::BorrowExpr &expr) {}
- virtual void visit (HIR::DereferenceExpr &expr) {}
- virtual void visit (HIR::ErrorPropagationExpr &expr) {}
- virtual void visit (HIR::NegationExpr &expr) {}
- virtual void visit (HIR::ArithmeticOrLogicalExpr &expr) {}
- virtual void visit (HIR::ComparisonExpr &expr) {}
- virtual void visit (HIR::LazyBooleanExpr &expr) {}
- virtual void visit (HIR::TypeCastExpr &expr) {}
- virtual void visit (HIR::AssignmentExpr &expr) {}
- virtual void visit (HIR::CompoundAssignmentExpr &expr) {}
- virtual void visit (HIR::GroupedExpr &expr) {}
- // virtual void visit(ArrayElems& elems) {}
- virtual void visit (HIR::ArrayElemsValues &elems) {}
- virtual void visit (HIR::ArrayElemsCopied &elems) {}
- virtual void visit (HIR::ArrayExpr &expr) {}
- virtual void visit (HIR::ArrayIndexExpr &expr) {}
- virtual void visit (HIR::TupleExpr &expr) {}
- virtual void visit (HIR::TupleIndexExpr &expr) {}
- virtual void visit (HIR::StructExprStruct &expr) {}
- // virtual void visit(StructExprField& field) {}
- virtual void visit (HIR::StructExprFieldIdentifier &field) {}
- virtual void visit (HIR::StructExprFieldIdentifierValue &field) {}
- virtual void visit (HIR::StructExprFieldIndexValue &field) {}
- virtual void visit (HIR::StructExprStructFields &expr) {}
- virtual void visit (HIR::StructExprStructBase &expr) {}
- virtual void visit (HIR::StructExprTuple &expr) {}
- virtual void visit (HIR::StructExprUnit &expr) {}
- // virtual void visit(EnumExprField& field) {}
- virtual void visit (HIR::EnumExprFieldIdentifier &field) {}
- virtual void visit (HIR::EnumExprFieldIdentifierValue &field) {}
- virtual void visit (HIR::EnumExprFieldIndexValue &field) {}
- virtual void visit (HIR::EnumExprStruct &expr) {}
- virtual void visit (HIR::EnumExprTuple &expr) {}
- virtual void visit (HIR::EnumExprFieldless &expr) {}
- virtual void visit (HIR::CallExpr &expr) {}
- virtual void visit (HIR::MethodCallExpr &expr) {}
- virtual void visit (HIR::FieldAccessExpr &expr) {}
- virtual void visit (HIR::ClosureExprInner &expr) {}
- virtual void visit (HIR::BlockExpr &expr) {}
- virtual void visit (HIR::ClosureExprInnerTyped &expr) {}
- virtual void visit (HIR::ContinueExpr &expr) {}
- virtual void visit (HIR::BreakExpr &expr) {}
- virtual void visit (HIR::RangeFromToExpr &expr) {}
- virtual void visit (HIR::RangeFromExpr &expr) {}
- virtual void visit (HIR::RangeToExpr &expr) {}
- virtual void visit (HIR::RangeFullExpr &expr) {}
- virtual void visit (HIR::RangeFromToInclExpr &expr) {}
- virtual void visit (HIR::RangeToInclExpr &expr) {}
- virtual void visit (HIR::ReturnExpr &expr) {}
- virtual void visit (HIR::UnsafeBlockExpr &expr) {}
- virtual void visit (HIR::LoopExpr &expr) {}
- virtual void visit (HIR::WhileLoopExpr &expr) {}
- virtual void visit (HIR::WhileLetLoopExpr &expr) {}
- virtual void visit (HIR::ForLoopExpr &expr) {}
- virtual void visit (HIR::IfExpr &expr) {}
- virtual void visit (HIR::IfExprConseqElse &expr) {}
- virtual void visit (HIR::IfExprConseqIf &expr) {}
- virtual void visit (HIR::IfExprConseqIfLet &expr) {}
- virtual void visit (HIR::IfLetExpr &expr) {}
- virtual void visit (HIR::IfLetExprConseqElse &expr) {}
- virtual void visit (HIR::IfLetExprConseqIf &expr) {}
- virtual void visit (HIR::IfLetExprConseqIfLet &expr) {}
- // virtual void visit(MatchCase& match_case) {}
- // virtual void visit (HIR::MatchCaseBlockExpr &match_case) {}
- // virtual void visit (HIR::MatchCaseExpr &match_case) {}
- virtual void visit (HIR::MatchExpr &expr) {}
- virtual void visit (HIR::AwaitExpr &expr) {}
- virtual void visit (HIR::AsyncBlockExpr &expr) {}
-
- // rust-item.h
- virtual void visit (HIR::TypeParam &param) {}
- // virtual void visit(WhereClauseItem& item) {}
- virtual void visit (HIR::LifetimeWhereClauseItem &item) {}
- virtual void visit (HIR::TypeBoundWhereClauseItem &item) {}
- virtual void visit (HIR::Method &method) {}
- virtual void visit (HIR::ModuleBodied &module) {}
- virtual void visit (HIR::ModuleNoBody &module) {}
- virtual void visit (HIR::ExternCrate &crate) {}
- // virtual void visit(UseTree& use_tree) {}
- virtual void visit (HIR::UseTreeGlob &use_tree) {}
- virtual void visit (HIR::UseTreeList &use_tree) {}
- virtual void visit (HIR::UseTreeRebind &use_tree) {}
- virtual void visit (HIR::UseDeclaration &use_decl) {}
- virtual void visit (HIR::Function &function) {}
- virtual void visit (HIR::TypeAlias &type_alias) {}
- virtual void visit (HIR::StructStruct &struct_item) {}
- virtual void visit (HIR::TupleStruct &tuple_struct) {}
- virtual void visit (HIR::EnumItem &item) {}
- virtual void visit (HIR::EnumItemTuple &item) {}
- virtual void visit (HIR::EnumItemStruct &item) {}
- virtual void visit (HIR::EnumItemDiscriminant &item) {}
- virtual void visit (HIR::Enum &enum_item) {}
- virtual void visit (HIR::Union &union_item) {}
- virtual void visit (HIR::ConstantItem &const_item) {}
- virtual void visit (HIR::StaticItem &static_item) {}
- virtual void visit (HIR::TraitItemFunc &item) {}
- virtual void visit (HIR::TraitItemMethod &item) {}
- virtual void visit (HIR::TraitItemConst &item) {}
- virtual void visit (HIR::TraitItemType &item) {}
- virtual void visit (HIR::Trait &trait) {}
- virtual void visit (HIR::InherentImpl &impl) {}
- virtual void visit (HIR::TraitImpl &impl) {}
- // virtual void visit(ExternalItem& item) {}
- virtual void visit (HIR::ExternalStaticItem &item) {}
- virtual void visit (HIR::ExternalFunctionItem &item) {}
- virtual void visit (HIR::ExternBlock &block) {}
-
- // rust-macro.h
- virtual void visit (HIR::MacroMatchFragment &match) {}
- virtual void visit (HIR::MacroMatchRepetition &match) {}
- virtual void visit (HIR::MacroMatcher &matcher) {}
- virtual void visit (HIR::MacroRulesDefinition &rules_def) {}
- virtual void visit (HIR::MacroInvocation &macro_invoc) {}
- virtual void visit (HIR::MetaItemPath &meta_item) {}
- virtual void visit (HIR::MetaItemSeq &meta_item) {}
- virtual void visit (HIR::MetaWord &meta_item) {}
- virtual void visit (HIR::MetaNameValueStr &meta_item) {}
- virtual void visit (HIR::MetaListPaths &meta_item) {}
- virtual void visit (HIR::MetaListNameValueStr &meta_item) {}
-
- // rust-pattern.h
- virtual void visit (HIR::LiteralPattern &pattern) {}
- virtual void visit (HIR::IdentifierPattern &pattern) {}
- virtual void visit (HIR::WildcardPattern &pattern) {}
- // virtual void visit(RangePatternBound& bound) {}
- virtual void visit (HIR::RangePatternBoundLiteral &bound) {}
- virtual void visit (HIR::RangePatternBoundPath &bound) {}
- virtual void visit (HIR::RangePatternBoundQualPath &bound) {}
- virtual void visit (HIR::RangePattern &pattern) {}
- virtual void visit (HIR::ReferencePattern &pattern) {}
- // virtual void visit(StructPatternField& field) {}
- virtual void visit (HIR::StructPatternFieldTuplePat &field) {}
- virtual void visit (HIR::StructPatternFieldIdentPat &field) {}
- virtual void visit (HIR::StructPatternFieldIdent &field) {}
- virtual void visit (HIR::StructPattern &pattern) {}
- // virtual void visit(TupleStructItems& tuple_items) {}
- virtual void visit (HIR::TupleStructItemsNoRange &tuple_items) {}
- virtual void visit (HIR::TupleStructItemsRange &tuple_items) {}
- virtual void visit (HIR::TupleStructPattern &pattern) {}
- // virtual void visit(TuplePatternItems& tuple_items) {}
- virtual void visit (HIR::TuplePatternItemsMultiple &tuple_items) {}
- virtual void visit (HIR::TuplePatternItemsRanged &tuple_items) {}
- virtual void visit (HIR::TuplePattern &pattern) {}
- virtual void visit (HIR::GroupedPattern &pattern) {}
- virtual void visit (HIR::SlicePattern &pattern) {}
-
- // rust-stmt.h
- virtual void visit (HIR::EmptyStmt &stmt) {}
- virtual void visit (HIR::LetStmt &stmt) {}
- virtual void visit (HIR::ExprStmtWithoutBlock &stmt) {}
- virtual void visit (HIR::ExprStmtWithBlock &stmt) {}
-
- // rust-type.h
- virtual void visit (HIR::TraitBound &bound) {}
- virtual void visit (HIR::ImplTraitType &type) {}
- virtual void visit (HIR::TraitObjectType &type) {}
- virtual void visit (HIR::ParenthesisedType &type) {}
- virtual void visit (HIR::ImplTraitTypeOneBound &type) {}
- virtual void visit (HIR::TraitObjectTypeOneBound &type) {}
- virtual void visit (HIR::TupleType &type) {}
- virtual void visit (HIR::NeverType &type) {}
- virtual void visit (HIR::RawPointerType &type) {}
- virtual void visit (HIR::ReferenceType &type) {}
- virtual void visit (HIR::ArrayType &type) {}
- virtual void visit (HIR::SliceType &type) {}
- virtual void visit (HIR::InferredType &type) {}
- virtual void visit (HIR::BareFunctionType &type) {}
+ virtual void visit (HIR::Token &) override {}
+ virtual void visit (HIR::DelimTokenTree &) override {}
+ virtual void visit (HIR::AttrInputMetaItemContainer &) override {}
+ virtual void visit (HIR::IdentifierExpr &) override {}
+ virtual void visit (HIR::Lifetime &) override {}
+ virtual void visit (HIR::LifetimeParam &) override {}
+ virtual void visit (HIR::PathInExpression &) override {}
+ virtual void visit (HIR::TypePathSegment &) override {}
+ virtual void visit (HIR::TypePathSegmentGeneric &) override {}
+ virtual void visit (HIR::TypePathSegmentFunction &) override {}
+ virtual void visit (HIR::TypePath &) override {}
+ virtual void visit (HIR::QualifiedPathInExpression &) override {}
+ virtual void visit (HIR::QualifiedPathInType &) override {}
+
+ virtual void visit (HIR::LiteralExpr &) override {}
+ virtual void visit (HIR::AttrInputLiteral &) override {}
+ virtual void visit (HIR::MetaItemLitExpr &) override {}
+ virtual void visit (HIR::MetaItemPathLit &) override {}
+ virtual void visit (HIR::BorrowExpr &) override {}
+ virtual void visit (HIR::DereferenceExpr &) override {}
+ virtual void visit (HIR::ErrorPropagationExpr &) override {}
+ virtual void visit (HIR::NegationExpr &) override {}
+ virtual void visit (HIR::ArithmeticOrLogicalExpr &) override {}
+ virtual void visit (HIR::ComparisonExpr &) override {}
+ virtual void visit (HIR::LazyBooleanExpr &) override {}
+ virtual void visit (HIR::TypeCastExpr &) override {}
+ virtual void visit (HIR::AssignmentExpr &) override {}
+
+ virtual void visit (HIR::GroupedExpr &) override {}
+
+ virtual void visit (HIR::ArrayElemsValues &) override {}
+ virtual void visit (HIR::ArrayElemsCopied &) override {}
+ virtual void visit (HIR::ArrayExpr &) override {}
+ virtual void visit (HIR::ArrayIndexExpr &) override {}
+ virtual void visit (HIR::TupleExpr &) override {}
+ virtual void visit (HIR::TupleIndexExpr &) override {}
+ virtual void visit (HIR::StructExprStruct &) override {}
+
+ virtual void visit (HIR::StructExprFieldIdentifier &) override {}
+ virtual void visit (HIR::StructExprFieldIdentifierValue &) override {}
+
+ virtual void visit (HIR::StructExprFieldIndexValue &) override {}
+ virtual void visit (HIR::StructExprStructFields &) override {}
+ virtual void visit (HIR::StructExprStructBase &) override {}
+ virtual void visit (HIR::StructExprTuple &) override {}
+ virtual void visit (HIR::StructExprUnit &) override {}
+
+ virtual void visit (HIR::EnumExprFieldIdentifier &) override {}
+ virtual void visit (HIR::EnumExprFieldIdentifierValue &) override {}
+
+ virtual void visit (HIR::EnumExprFieldIndexValue &) override {}
+ virtual void visit (HIR::EnumExprStruct &) override {}
+ virtual void visit (HIR::EnumExprTuple &) override {}
+ virtual void visit (HIR::EnumExprFieldless &) override {}
+ virtual void visit (HIR::CallExpr &) override {}
+ virtual void visit (HIR::MethodCallExpr &) override {}
+ virtual void visit (HIR::FieldAccessExpr &) override {}
+ virtual void visit (HIR::ClosureExprInner &) override {}
+ virtual void visit (HIR::BlockExpr &) override {}
+ virtual void visit (HIR::ClosureExprInnerTyped &) override {}
+ virtual void visit (HIR::ContinueExpr &) override {}
+ virtual void visit (HIR::BreakExpr &) override {}
+ virtual void visit (HIR::RangeFromToExpr &) override {}
+ virtual void visit (HIR::RangeFromExpr &) override {}
+ virtual void visit (HIR::RangeToExpr &) override {}
+ virtual void visit (HIR::RangeFullExpr &) override {}
+ virtual void visit (HIR::RangeFromToInclExpr &) override {}
+ virtual void visit (HIR::RangeToInclExpr &) override {}
+ virtual void visit (HIR::ReturnExpr &) override {}
+ virtual void visit (HIR::UnsafeBlockExpr &) override {}
+ virtual void visit (HIR::LoopExpr &) override {}
+ virtual void visit (HIR::WhileLoopExpr &) override {}
+ virtual void visit (HIR::WhileLetLoopExpr &) override {}
+ virtual void visit (HIR::ForLoopExpr &) override {}
+ virtual void visit (HIR::IfExpr &) override {}
+ virtual void visit (HIR::IfExprConseqElse &) override {}
+ virtual void visit (HIR::IfExprConseqIf &) override {}
+ virtual void visit (HIR::IfExprConseqIfLet &) override {}
+ virtual void visit (HIR::IfLetExpr &) override {}
+ virtual void visit (HIR::IfLetExprConseqElse &) override {}
+ virtual void visit (HIR::IfLetExprConseqIf &) override {}
+ virtual void visit (HIR::IfLetExprConseqIfLet &) override {}
+
+ virtual void visit (HIR::MatchExpr &) override {}
+ virtual void visit (HIR::AwaitExpr &) override {}
+ virtual void visit (HIR::AsyncBlockExpr &) override {}
+
+ virtual void visit (HIR::TypeParam &) override {}
+
+ virtual void visit (HIR::LifetimeWhereClauseItem &) override {}
+ virtual void visit (HIR::TypeBoundWhereClauseItem &) override {}
+ virtual void visit (HIR::Method &) override {}
+ virtual void visit (HIR::ModuleBodied &) override {}
+ virtual void visit (HIR::ModuleNoBody &) override {}
+ virtual void visit (HIR::ExternCrate &) override {}
+
+ virtual void visit (HIR::UseTreeGlob &) override {}
+ virtual void visit (HIR::UseTreeList &) override {}
+ virtual void visit (HIR::UseTreeRebind &) override {}
+ virtual void visit (HIR::UseDeclaration &) override {}
+ virtual void visit (HIR::Function &) override {}
+ virtual void visit (HIR::TypeAlias &) override {}
+ virtual void visit (HIR::StructStruct &) override {}
+ virtual void visit (HIR::TupleStruct &) override {}
+ virtual void visit (HIR::EnumItem &) override {}
+ virtual void visit (HIR::EnumItemTuple &) override {}
+ virtual void visit (HIR::EnumItemStruct &) override {}
+ virtual void visit (HIR::EnumItemDiscriminant &) override {}
+ virtual void visit (HIR::Enum &) override {}
+ virtual void visit (HIR::Union &) override {}
+ virtual void visit (HIR::ConstantItem &) override {}
+ virtual void visit (HIR::StaticItem &) override {}
+ virtual void visit (HIR::TraitItemFunc &) override {}
+ virtual void visit (HIR::TraitItemMethod &) override {}
+ virtual void visit (HIR::TraitItemConst &) override {}
+ virtual void visit (HIR::TraitItemType &) override {}
+ virtual void visit (HIR::Trait &) override {}
+ virtual void visit (HIR::InherentImpl &) override {}
+ virtual void visit (HIR::TraitImpl &) override {}
+
+ virtual void visit (HIR::ExternalStaticItem &) override {}
+ virtual void visit (HIR::ExternalFunctionItem &) override {}
+ virtual void visit (HIR::ExternBlock &) override {}
+
+ virtual void visit (HIR::MacroMatchFragment &) override {}
+ virtual void visit (HIR::MacroMatchRepetition &) override {}
+ virtual void visit (HIR::MacroMatcher &) override {}
+ virtual void visit (HIR::MacroRulesDefinition &) override {}
+ virtual void visit (HIR::MacroInvocation &) override {}
+ virtual void visit (HIR::MetaItemPath &) override {}
+ virtual void visit (HIR::MetaItemSeq &) override {}
+ virtual void visit (HIR::MetaWord &) override {}
+ virtual void visit (HIR::MetaNameValueStr &) override {}
+ virtual void visit (HIR::MetaListPaths &) override {}
+ virtual void visit (HIR::MetaListNameValueStr &) override {}
+
+ virtual void visit (HIR::LiteralPattern &) override {}
+ virtual void visit (HIR::IdentifierPattern &) override {}
+ virtual void visit (HIR::WildcardPattern &) override {}
+
+ virtual void visit (HIR::RangePatternBoundLiteral &) override {}
+ virtual void visit (HIR::RangePatternBoundPath &) override {}
+ virtual void visit (HIR::RangePatternBoundQualPath &) override {}
+ virtual void visit (HIR::RangePattern &) override {}
+ virtual void visit (HIR::ReferencePattern &) override {}
+
+ virtual void visit (HIR::StructPatternFieldTuplePat &) override {}
+ virtual void visit (HIR::StructPatternFieldIdentPat &) override {}
+ virtual void visit (HIR::StructPatternFieldIdent &) override {}
+ virtual void visit (HIR::StructPattern &) override {}
+
+ virtual void visit (HIR::TupleStructItemsNoRange &) override {}
+ virtual void visit (HIR::TupleStructItemsRange &) override {}
+ virtual void visit (HIR::TupleStructPattern &) override {}
+
+ virtual void visit (HIR::TuplePatternItemsMultiple &) override {}
+ virtual void visit (HIR::TuplePatternItemsRanged &) override {}
+ virtual void visit (HIR::TuplePattern &) override {}
+ virtual void visit (HIR::GroupedPattern &) override {}
+ virtual void visit (HIR::SlicePattern &) override {}
+
+ virtual void visit (HIR::EmptyStmt &) override {}
+ virtual void visit (HIR::LetStmt &) override {}
+ virtual void visit (HIR::ExprStmtWithoutBlock &) override {}
+ virtual void visit (HIR::ExprStmtWithBlock &) override {}
+
+ virtual void visit (HIR::TraitBound &) override {}
+ virtual void visit (HIR::ImplTraitType &) override {}
+ virtual void visit (HIR::TraitObjectType &) override {}
+ virtual void visit (HIR::ParenthesisedType &) override {}
+ virtual void visit (HIR::ImplTraitTypeOneBound &) override {}
+ virtual void visit (HIR::TraitObjectTypeOneBound &) override {}
+ virtual void visit (HIR::TupleType &) override {}
+ virtual void visit (HIR::NeverType &) override {}
+ virtual void visit (HIR::RawPointerType &) override {}
+ virtual void visit (HIR::ReferenceType &) override {}
+ virtual void visit (HIR::ArrayType &) override {}
+ virtual void visit (HIR::SliceType &) override {}
+ virtual void visit (HIR::InferredType &) override {}
+ virtual void visit (HIR::BareFunctionType &) override {}
protected:
TypeCheckBase ()
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 82977e4..e6cca19 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -24,6 +24,7 @@
#include "rust-tyty.h"
#include "rust-tyty-call.h"
#include "rust-hir-type-check-struct-field.h"
+#include "rust-hir-method-resolve.h"
namespace Rust {
namespace Resolver {
@@ -37,7 +38,10 @@ public:
expr->accept_vis (resolver);
if (resolver.infered == nullptr)
- return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
+ {
+ rust_error_at (expr->get_locus_slow (), "failed to resolve expression");
+ return new TyTy::ErrorType (expr->get_mappings ().get_hirid ());
+ }
auto ref = expr->get_mappings ().get_hirid ();
resolver.infered->set_ref (ref);
@@ -196,9 +200,8 @@ public:
TyTy::TyBase *lookup;
if (!context->lookup_type (ref, &lookup))
{
- // FIXME we need to be able to lookup the location info for the
- // reference here
- rust_error_at (expr.get_locus (), "consider giving this a type: %s",
+ rust_error_at (mappings->lookup_location (ref),
+ "failed to lookup type for CallExpr: %s",
expr.as_string ().c_str ());
return;
}
@@ -213,6 +216,65 @@ public:
infered->set_ref (expr.get_mappings ().get_hirid ());
}
+ void visit (HIR::MethodCallExpr &expr)
+ {
+ auto receiver_tyty = TypeCheckExpr::Resolve (expr.get_receiver ().get ());
+ if (receiver_tyty == nullptr)
+ {
+ rust_error_at (expr.get_receiver ()->get_locus_slow (),
+ "failed to resolve receiver in MethodCallExpr");
+ return;
+ }
+
+ // https://doc.rust-lang.org/reference/expressions/method-call-expr.html
+ // method resolution is complex in rust once we start handling generics and
+ // traits. For now we only support looking up the valid name in impl blocks
+ // which is simple. There will need to be adjustments to ensure we can turn
+ // the receiver into borrowed references etc
+
+ auto probes
+ = MethodResolution::Probe (receiver_tyty, expr.get_method_name ());
+ if (probes.size () == 0)
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to resolve the PathExprSegment to any Method");
+ return;
+ }
+ else if (probes.size () > 1)
+ {
+ rust_error_at (
+ expr.get_locus (),
+ "Generics and Traits are not implemented yet for MethodCall");
+ return;
+ }
+
+ auto resolved_method = probes.at (0);
+ TyTy::TyBase *lookup;
+ if (!context->lookup_type (resolved_method->get_mappings ().get_hirid (),
+ &lookup))
+ {
+ rust_error_at (resolved_method->get_locus (),
+ "failed to lookup type for CallExpr: %s",
+ expr.as_string ().c_str ());
+ return;
+ }
+
+ infered = TyTy::TypeCheckMethodCallExpr::go (lookup, expr, context);
+ if (infered == nullptr)
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to lookup type to MethodCallExpr");
+ return;
+ }
+
+ infered->set_ref (expr.get_mappings ().get_hirid ());
+
+ // set up the resolved name on the path
+ resolver->insert_resolved_name (
+ expr.get_mappings ().get_nodeid (),
+ resolved_method->get_mappings ().get_nodeid ());
+ }
+
void visit (HIR::AssignmentExpr &expr)
{
auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
@@ -313,7 +375,7 @@ public:
if (!context->lookup_type (ref, &lookup))
{
rust_error_at (mappings->lookup_location (ref),
- "consider giving this a type: %s",
+ "Failed to resolve IdentifierExpr type: %s",
expr.as_string ().c_str ());
return;
}
@@ -703,7 +765,7 @@ public:
if (!is_valid_type)
{
rust_error_at (expr.get_locus (),
- "expected ADT or Tuple Type got: [%s]",
+ "expected algebraic data type got: [%s]",
struct_base->as_string ().c_str ());
return;
}
@@ -747,7 +809,11 @@ public:
return;
}
- context->lookup_type (ref, &infered);
+ if (!context->lookup_type (ref, &infered))
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to resolve PathInExpression type");
+ }
}
private:
@@ -799,6 +865,7 @@ private:
&& (((TyTy::InferType *) type)->get_infer_kind ()
== TyTy::InferType::INTEGRAL));
}
+ gcc_unreachable ();
}
TyTy::TyBase *infered;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index abaee73..c8d161a 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -31,9 +31,9 @@ namespace Resolver {
class TypeCheckTopLevelImplItem : public TypeCheckBase
{
public:
- static void Resolve (HIR::InherentImplItem *item)
+ static void Resolve (HIR::InherentImplItem *item, TyTy::TyBase *self)
{
- TypeCheckTopLevelImplItem resolver;
+ TypeCheckTopLevelImplItem resolver (self);
item->accept_vis (resolver);
}
@@ -81,8 +81,62 @@ public:
context->insert_type (function.get_mappings (), fnType);
}
+ void visit (HIR::Method &method)
+ {
+ TyTy::TyBase *ret_type = nullptr;
+ if (!method.has_function_return_type ())
+ ret_type = new TyTy::UnitType (method.get_mappings ().get_hirid ());
+ else
+ {
+ auto resolved
+ = TypeCheckType::Resolve (method.get_return_type ().get ());
+ if (resolved == nullptr)
+ {
+ rust_error_at (method.get_locus (),
+ "failed to resolve return type");
+ return;
+ }
+
+ ret_type = resolved->clone ();
+ ret_type->set_ref (
+ method.get_return_type ()->get_mappings ().get_hirid ());
+ }
+
+ // hold all the params to the fndef
+ std::vector<std::pair<HIR::Pattern *, TyTy::TyBase *> > params;
+
+ // add the self param at the front
+ HIR::SelfParam &self_param = method.get_self_param ();
+ HIR::IdentifierPattern *self_pattern
+ = new HIR::IdentifierPattern ("self", self_param.get_locus (),
+ self_param.get_has_ref (),
+ self_param.get_is_mut (),
+ std::unique_ptr<HIR::Pattern> (nullptr));
+ context->insert_type (self_param.get_mappings (), self->clone ());
+ params.push_back (
+ std::pair<HIR::Pattern *, TyTy::TyBase *> (self_pattern, self->clone ()));
+
+ for (auto &param : method.get_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 (method.get_mappings ().get_hirid (), params,
+ ret_type);
+ context->insert_type (method.get_mappings (), fnType);
+ }
+
private:
- TypeCheckTopLevelImplItem () : TypeCheckBase () {}
+ TypeCheckTopLevelImplItem (TyTy::TyBase *self) : TypeCheckBase (), self (self)
+ {}
+
+ TyTy::TyBase *self;
};
class TypeCheckImplItem : public TypeCheckBase
@@ -99,7 +153,7 @@ public:
TyTy::TyBase *lookup;
if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup))
{
- rust_error_at (function.locus, "failed to lookup function type");
+ rust_error_at (function.get_locus (), "failed to lookup function type");
return;
}
@@ -137,6 +191,49 @@ public:
context->pop_return_type ();
}
+ void visit (HIR::Method &method)
+ {
+ TyTy::TyBase *lookup;
+ if (!context->lookup_type (method.get_mappings ().get_hirid (), &lookup))
+ {
+ rust_error_at (method.get_locus (), "failed to lookup function type");
+ return;
+ }
+
+ if (lookup->get_kind () != TyTy::TypeKind::FNDEF)
+ {
+ rust_error_at (method.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 (method.get_function_body ().get ());
+ if (method.get_function_body ()->has_expr ())
+ {
+ auto resolved
+ = TypeCheckExpr::Resolve (method.get_function_body ()->expr.get ());
+
+ auto ret_resolved = expected_ret_tyty->combine (resolved);
+ if (ret_resolved == nullptr)
+ {
+ rust_error_at (method.get_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) {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 571d998..06be1ac 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -38,7 +38,7 @@ public:
item->accept_vis (resolver);
}
- void visit (HIR::InherentImpl &impl_block)
+ void visit (HIR::InherentImpl &impl_block) override
{
TyTy::TyBase *self = nullptr;
if (!context->lookup_type (
@@ -53,7 +53,7 @@ public:
TypeCheckImplItem::Resolve (impl_item.get (), self);
}
- void visit (HIR::Function &function)
+ void visit (HIR::Function &function) override
{
TyTy::TyBase *lookup;
if (!context->lookup_type (function.get_mappings ().get_hirid (), &lookup))
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index 46b3b0f..61823bf 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -137,11 +137,15 @@ public:
void visit (HIR::InherentImpl &impl_block)
{
- TypeCheckType::Resolve (impl_block.get_type ().get ());
- for (auto &impl_item : impl_block.get_impl_items ())
+ auto self = TypeCheckType::Resolve (impl_block.get_type ().get ());
+ if (self == nullptr)
{
- TypeCheckTopLevelImplItem::Resolve (impl_item.get ());
+ rust_error_at (impl_block.get_locus (), "failed to resolve impl type");
+ return;
}
+
+ for (auto &impl_item : impl_block.get_impl_items ())
+ TypeCheckTopLevelImplItem::Resolve (impl_item.get (), self);
}
private:
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 416cd89..681d023 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -127,19 +127,12 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
return true;
});
- // tail expression must be checked as part of the caller since
- // the result of this is very dependant on what we expect it to be
-
- // 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);
+ if (expr.has_expr ())
+ {
+ delete block_tyty;
+
+ block_tyty = TypeCheckExpr::Resolve (expr.get_final_expr ().get (), true);
+ }
infered = block_tyty->clone ();
}
diff --git a/gcc/rust/typecheck/rust-tycheck-dump.h b/gcc/rust/typecheck/rust-tycheck-dump.h
index 0d8fffc..9d882fb 100644
--- a/gcc/rust/typecheck/rust-tycheck-dump.h
+++ b/gcc/rust/typecheck/rust-tycheck-dump.h
@@ -37,7 +37,7 @@ public:
return dumper.dump;
}
- void visit (HIR::InherentImpl &impl_block)
+ void visit (HIR::InherentImpl &impl_block) override
{
dump += indent () + "impl "
+ type_string (impl_block.get_type ()->get_mappings ()) + " {\n";
@@ -53,7 +53,7 @@ public:
dump += indent () + "}\n";
}
- void visit (HIR::ConstantItem &constant)
+ void visit (HIR::ConstantItem &constant) override
{
dump += indent () + "constant " + constant.get_identifier () + ":"
+ type_string (constant.get_mappings ()) + " = ";
@@ -61,7 +61,7 @@ public:
dump += ";\n";
}
- void visit (HIR::Function &function)
+ void visit (HIR::Function &function) override
{
dump += indent () + "fn " + function.function_name + " "
+ type_string (function.get_mappings ()) + "\n";
@@ -73,7 +73,19 @@ public:
dump += indent () + "}\n";
}
- void visit (HIR::BlockExpr &expr)
+ void visit (HIR::Method &method) override
+ {
+ dump += indent () + "fn " + method.get_method_name () + " "
+ + type_string (method.get_mappings ()) + "\n";
+ dump += indent () + "{\n";
+
+ HIR::BlockExpr *function_body = method.get_function_body ().get ();
+ function_body->accept_vis (*this);
+
+ dump += indent () + "}\n";
+ }
+
+ void visit (HIR::BlockExpr &expr) override
{
indentation_level++;
@@ -94,7 +106,7 @@ public:
indentation_level--;
}
- void visit (HIR::LetStmt &stmt)
+ void visit (HIR::LetStmt &stmt) override
{
dump += "let " + stmt.get_pattern ()->as_string () + ":"
+ type_string (stmt.get_mappings ());
@@ -105,35 +117,35 @@ public:
}
}
- void visit (HIR::ExprStmtWithBlock &stmt)
+ void visit (HIR::ExprStmtWithBlock &stmt) override
{
stmt.get_expr ()->accept_vis (*this);
}
- void visit (HIR::ExprStmtWithoutBlock &stmt)
+ void visit (HIR::ExprStmtWithoutBlock &stmt) override
{
stmt.get_expr ()->accept_vis (*this);
}
- void visit (HIR::AssignmentExpr &expr)
+ void visit (HIR::AssignmentExpr &expr) override
{
expr.get_lhs ()->accept_vis (*this);
dump += " = ";
expr.get_rhs ()->accept_vis (*this);
}
- void visit (HIR::LiteralExpr &expr)
+ void visit (HIR::LiteralExpr &expr) override
{
dump += expr.get_literal ()->as_string () + ":"
+ type_string (expr.get_mappings ());
}
- void visit (HIR::IdentifierExpr &expr)
+ void visit (HIR::IdentifierExpr &expr) override
{
dump += expr.get_identifier () + ":" + type_string (expr.get_mappings ());
}
- void visit (HIR::ArrayExpr &expr)
+ void visit (HIR::ArrayExpr &expr) override
{
dump += type_string (expr.get_mappings ()) + ":[";
@@ -143,7 +155,7 @@ public:
dump += "]";
}
- void visit (HIR::ArrayElemsValues &elems)
+ void visit (HIR::ArrayElemsValues &elems) override
{
elems.iterate ([&] (HIR::Expr *e) mutable -> bool {
e->accept_vis (*this);
@@ -152,7 +164,7 @@ public:
});
}
- void visit (HIR::GroupedExpr &expr)
+ void visit (HIR::GroupedExpr &expr) override
{
HIR::Expr *paren_expr = expr.get_expr_in_parens ().get ();
dump += "(";
@@ -160,7 +172,7 @@ public:
dump += ")";
}
- void visit (HIR::PathInExpression &expr)
+ void visit (HIR::PathInExpression &expr) override
{
dump += type_string (expr.get_mappings ());
}
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index 2b3cfb6..82b070f 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -38,7 +38,6 @@ public:
ref->accept_vis (checker);
return checker.resolved;
}
- ~TypeCheckCallExpr () {}
void visit (UnitType &type) override { gcc_unreachable (); }
void visit (InferType &type) override { gcc_unreachable (); }
@@ -71,6 +70,47 @@ private:
Analysis::Mappings *mappings;
};
+class TypeCheckMethodCallExpr : private TyVisitor
+{
+public:
+ static TyBase *go (TyBase *ref, HIR::MethodCallExpr &call,
+ Resolver::TypeCheckContext *context)
+ {
+ TypeCheckMethodCallExpr checker (call, context);
+ ref->accept_vis (checker);
+ return checker.resolved;
+ }
+
+ void visit (UnitType &type) override { gcc_unreachable (); }
+ void visit (InferType &type) override { gcc_unreachable (); }
+ void visit (TupleType &type) override { gcc_unreachable (); }
+ void visit (StructFieldType &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 (USizeType &type) override { gcc_unreachable (); }
+ void visit (ISizeType &type) override { gcc_unreachable (); }
+ void visit (ErrorType &type) override { gcc_unreachable (); }
+ void visit (ADTType &type) override { gcc_unreachable (); };
+
+ // call fns
+ void visit (FnType &type) override;
+
+private:
+ TypeCheckMethodCallExpr (HIR::MethodCallExpr &c,
+ Resolver::TypeCheckContext *context)
+ : resolved (nullptr), call (c), context (context),
+ mappings (Analysis::Mappings::get ())
+ {}
+
+ TyBase *resolved;
+ HIR::MethodCallExpr &call;
+ Resolver::TypeCheckContext *context;
+ Analysis::Mappings *mappings;
+};
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index d506415..8b04209 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -147,14 +147,15 @@ ADTType::accept_vis (TyVisitor &vis)
std::string
ADTType::as_string () const
{
- if (num_fields () == 0)
- return identifier;
+ // if (num_fields () == 0)
+ // return identifier;
- std::string fields_buffer;
- for (auto &field : fields)
- fields_buffer += field->as_string () + ", ";
+ // std::string fields_buffer;
+ // for (auto &field : fields)
+ // fields_buffer += field->as_string () + ", ";
- return identifier + "{" + fields_buffer + "}";
+ // return identifier + "{" + fields_buffer + "}";
+ return identifier;
}
TyBase *
@@ -574,5 +575,56 @@ TypeCheckCallExpr::visit (FnType &type)
resolved = type.get_return_type ()->clone ();
}
+// method call checker
+
+void
+TypeCheckMethodCallExpr::visit (FnType &type)
+{
+ // +1 for the receiver self
+ size_t num_args_to_call = call.num_params () + 1;
+ if (num_args_to_call != type.num_params ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ call.num_params (), type.num_params ());
+ return;
+ }
+
+ size_t i = 1;
+ call.iterate_params ([&] (HIR::Expr *param) mutable -> bool {
+ auto fnparam = type.param_at (i);
+ auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (param);
+ if (argument_expr_tyty == nullptr)
+ {
+ rust_error_at (param->get_locus_slow (),
+ "failed to resolve type for argument expr in CallExpr");
+ return false;
+ }
+
+ auto resolved_argument_type = fnparam.second->combine (argument_expr_tyty);
+ if (resolved_argument_type == nullptr)
+ {
+ rust_error_at (param->get_locus_slow (),
+ "Type Resolution failure on parameter");
+ return false;
+ }
+
+ context->insert_type (param->get_mappings (), resolved_argument_type);
+
+ i++;
+ return true;
+ });
+
+ if (i != num_args_to_call)
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu", i,
+ call.num_params ());
+ return;
+ }
+
+ resolved = type.get_return_type ()->clone ();
+}
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index eb55581..8a15631 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -375,6 +375,30 @@ Mappings::lookup_hir_param (CrateNum crateNum, HirId id)
}
void
+Mappings::insert_hir_self_param (CrateNum crateNum, HirId id,
+ HIR::SelfParam *param)
+{
+ rust_assert (lookup_hir_stmt (crateNum, id) == nullptr);
+
+ hirSelfParamMappings[crateNum][id] = param;
+ nodeIdToHirMappings[crateNum][param->get_mappings ().get_nodeid ()] = id;
+}
+
+HIR::SelfParam *
+Mappings::lookup_hir_self_param (CrateNum crateNum, HirId id)
+{
+ auto it = hirSelfParamMappings.find (crateNum);
+ if (it == hirSelfParamMappings.end ())
+ return nullptr;
+
+ auto iy = it->second.find (id);
+ if (iy == it->second.end ())
+ return nullptr;
+
+ return iy->second;
+}
+
+void
Mappings::insert_hir_struct_field (CrateNum crateNum, HirId id,
HIR::StructExprField *field)
{
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index f81cee6..0d625f6 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -125,6 +125,10 @@ public:
void insert_hir_param (CrateNum crateNum, HirId id, HIR::FunctionParam *type);
HIR::FunctionParam *lookup_hir_param (CrateNum crateNum, HirId id);
+ void insert_hir_self_param (CrateNum crateNum, HirId id,
+ HIR::SelfParam *type);
+ HIR::SelfParam *lookup_hir_self_param (CrateNum crateNum, HirId id);
+
void insert_hir_struct_field (CrateNum crateNum, HirId id,
HIR::StructExprField *type);
HIR::StructExprField *lookup_hir_struct_field (CrateNum crateNum, HirId id);
@@ -152,6 +156,20 @@ public:
return hirNodesWithinCrate[crate];
}
+ void
+ iterate_impl_items (std::function<bool (HirId, HIR::InherentImplItem *)> cb)
+ {
+ for (auto it = hirImplItemMappings.begin ();
+ it != hirImplItemMappings.end (); it++)
+ {
+ for (auto iy = it->second.begin (); iy != it->second.end (); iy++)
+ {
+ if (!cb (iy->first, iy->second))
+ return;
+ }
+ }
+ }
+
private:
Mappings ();
@@ -176,6 +194,7 @@ private:
hirStructFieldMappings;
std::map<CrateNum, std::map<HirId, HIR::InherentImplItem *> >
hirImplItemMappings;
+ std::map<CrateNum, std::map<HirId, HIR::SelfParam *> > hirSelfParamMappings;
// location info
std::map<CrateNum, std::map<NodeId, Location> > locations;
diff --git a/gcc/testsuite/rust.test/compilable/block_expr1.rs b/gcc/testsuite/rust.test/compilable/block_expr1.rs
new file mode 100644
index 0000000..fe63252
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/block_expr1.rs
@@ -0,0 +1,27 @@
+fn test3(x: i32) -> i32 {
+ if x > 1 {
+ 5
+ } else {
+ 0
+ }
+}
+
+fn test5(x: i32) -> i32 {
+ if x > 1 {
+ if x == 5 {
+ 7
+ } else {
+ 9
+ }
+ } else {
+ 0
+ }
+}
+
+fn main() {
+ let call3: i32 = { test3(3) + 2 };
+ let call5 = {
+ let a = test5(5);
+ a + 1
+ };
+}
diff --git a/gcc/testsuite/rust.test/compilable/impl_block3.rs b/gcc/testsuite/rust.test/compilable/impl_block3.rs
new file mode 100644
index 0000000..3093a6c
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/impl_block3.rs
@@ -0,0 +1,31 @@
+struct Point {
+ x: f64,
+ y: f64,
+}
+
+impl Point {
+ fn origin() -> Point {
+ Point { x: 0.0, y: 0.0 }
+ }
+
+ fn new(x: f64, y: f64) -> Point {
+ Point { x: x, y: y }
+ }
+}
+
+struct Rectangle {
+ p1: Point,
+ p2: Point,
+}
+
+impl Rectangle {
+ fn from(p1: Point, p2: Point) -> Self {
+ Self { p1, p2 }
+ }
+}
+
+fn main() {
+ let p1 = Point::origin();
+ let p2 = Point::new(3.0, 4.0);
+ let rect = Rectangle::from(p1, p2);
+}
diff --git a/gcc/testsuite/rust.test/compilable/methods1.rs b/gcc/testsuite/rust.test/compilable/methods1.rs
new file mode 100644
index 0000000..cffa02e
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/methods1.rs
@@ -0,0 +1,39 @@
+struct Point {
+ x: f64,
+ y: f64,
+}
+
+impl Point {
+ fn origin() -> Point {
+ Point { x: 0.0, y: 0.0 }
+ }
+
+ fn new(x: f64, y: f64) -> Point {
+ Point { x: x, y: y }
+ }
+}
+
+struct Rectangle {
+ p1: Point,
+ p2: Point,
+}
+
+impl Rectangle {
+ fn from(p1: Point, p2: Point) -> Self {
+ Self { p1, p2 }
+ }
+
+ fn sum_x(self) -> f64 {
+ let p1 = self.p1;
+ let p2 = self.p2;
+ p1.x + p2.x
+ }
+}
+
+fn main() {
+ let p1 = Point::origin();
+ let p2 = Point::new(3.0, 4.0);
+ let rect = Rectangle::from(p1, p2);
+
+ let sum = rect.sum_x();
+}
diff --git a/gcc/testsuite/rust.test/compilable/methods2.rs b/gcc/testsuite/rust.test/compilable/methods2.rs
new file mode 100644
index 0000000..96a3211
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/methods2.rs
@@ -0,0 +1,41 @@
+struct Point {
+ x: f64,
+ y: f64,
+}
+
+impl Point {
+ fn origin() -> Point {
+ Point { x: 0.0, y: 0.0 }
+ }
+
+ fn new(x: f64, y: f64) -> Point {
+ Point { x: x, y: y }
+ }
+}
+
+struct Rectangle {
+ p1: Point,
+ p2: Point,
+}
+
+impl Rectangle {
+ fn from(p1: Point, p2: Point) -> Self {
+ Self { p1, p2 }
+ }
+}
+
+fn main() {
+ let p1 = Point::origin();
+ let p2 = Point::new(3.0, 4.0);
+ let rect = Rectangle::from(p1, p2);
+
+ let sum = rect.sum_x();
+}
+
+impl Rectangle {
+ fn sum_x(self) -> f64 {
+ let p1 = self.p1;
+ let p2 = self.p2;
+ p1.x + p2.x
+ }
+}
diff --git a/gcc/testsuite/rust.test/compilable/name_resolve1.rs b/gcc/testsuite/rust.test/compilable/name_resolve1.rs
new file mode 100644
index 0000000..817f48b
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/name_resolve1.rs
@@ -0,0 +1,23 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ fn new(a: i32, b: bool) -> Foo {
+ Foo(a, b)
+ }
+
+ fn test() -> i32 {
+ test()
+ }
+}
+
+fn test() -> i32 {
+ 123
+}
+
+fn main() {
+ let a;
+ a = Foo::new(1, true);
+
+ let b;
+ b = Foo::test();
+}
diff --git a/gcc/testsuite/rust.test/compilable/nested_struct1.rs b/gcc/testsuite/rust.test/compilable/nested_struct1.rs
new file mode 100644
index 0000000..3880be0
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/nested_struct1.rs
@@ -0,0 +1,17 @@
+struct Point {
+ x: f64,
+ y: f64,
+}
+
+struct Rectangle {
+ p1: Point,
+ p2: Point,
+}
+
+fn main() {
+ let p1 = Point { x: 0.0, y: 0.0 };
+ let p2 = Point { x: 2.0, y: 4.0 };
+ let rect = Rectangle { p1, p2 };
+
+ let a = rect.p1.x;
+}
diff --git a/gcc/testsuite/rust.test/compilable/self_type1.rs b/gcc/testsuite/rust.test/compilable/self_type1.rs
new file mode 100644
index 0000000..373d6dd
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/self_type1.rs
@@ -0,0 +1,12 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ fn new(a: i32, b: bool) -> Self {
+ Self(a, b)
+ }
+}
+
+fn main() {
+ let a;
+ a = Foo::new(1, true);
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error1.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error1.rs
new file mode 100644
index 0000000..9acdf5f
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error1.rs
@@ -0,0 +1,8 @@
+struct S1 {
+ x: f64,
+ y: f64,
+}
+
+struct S1(i32, bool);
+
+fn main() {}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error2.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error2.rs
new file mode 100644
index 0000000..c04d2cf
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error2.rs
@@ -0,0 +1,4 @@
+const TEST: i32 = 2;
+const TEST: f32 = 3.0;
+
+fn main() {}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error3.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error3.rs
new file mode 100644
index 0000000..9ffa4e5
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error3.rs
@@ -0,0 +1,9 @@
+fn test() -> bool {
+ true
+}
+
+fn test() -> i32 {
+ 123
+}
+
+fn main() {}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error4.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error4.rs
new file mode 100644
index 0000000..5b20e1b
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error4.rs
@@ -0,0 +1,27 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ fn new(a: i32, b: bool) -> Foo {
+ Foo(a, b)
+ }
+
+ fn test() -> i32 {
+ test()
+ }
+
+ fn test() -> bool {
+ true
+ }
+}
+
+fn test() -> i32 {
+ 123
+}
+
+fn main() {
+ let a;
+ a = Foo::new(1, true);
+
+ let b;
+ b = Foo::test();
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/redef_error5.rs b/gcc/testsuite/rust.test/fail_compilation/redef_error5.rs
new file mode 100644
index 0000000..342a67e
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/redef_error5.rs
@@ -0,0 +1,8 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ const TEST: i32 = 123;
+ const TEST: bool = false;
+}
+
+fn main() {}