aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2020-12-12 12:56:02 +0000
committerPhilip Herron <herron.philip@googlemail.com>2020-12-17 17:23:46 +0000
commit44d10d9547612b5fda3d27bb628d5d6ee79108af (patch)
treeee39563bec035ad3882c1e655a49ba55df12d47c /gcc
parent4fb0ab7e635c65318aadf958e0e1303f3435c4e5 (diff)
downloadgcc-44d10d9547612b5fda3d27bb628d5d6ee79108af.zip
gcc-44d10d9547612b5fda3d27bb628d5d6ee79108af.tar.gz
gcc-44d10d9547612b5fda3d27bb628d5d6ee79108af.tar.bz2
TypeResolution pass now with a TyTy module
Resolution must implement the Gathering specified in the rust-dev guide. We need to be able to handle cases such as: let mut x; x = 1; or let mut x = vec!{} x.push(1) Now the TyTy module has a combine abstract method to allow the combination of types to condense down from their integral parts.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in13
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-stmt.h4
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.h9
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h13
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h29
-rw-r--r--gcc/rust/hir/tree/rust-hir-macro.h3
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.h31
-rw-r--r--gcc/rust/hir/tree/rust-hir-stmt.h4
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.h105
-rw-r--r--gcc/rust/hir/tree/rust-hir.h8
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h15
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h13
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h1
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h8
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc43
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h11
-rw-r--r--gcc/rust/rust-session-manager.cc30
-rw-r--r--gcc/rust/rust-session-manager.h9
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h256
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h173
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h90
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h86
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h63
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h81
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc38
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h66
-rw-r--r--gcc/rust/typecheck/rust-tyctx.cc104
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h53
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h241
-rw-r--r--gcc/rust/typecheck/rust-tyty-visitor.h42
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc223
-rw-r--r--gcc/rust/typecheck/rust-tyty.h208
-rw-r--r--gcc/rust/util/rust-hir-map.cc65
-rw-r--r--gcc/rust/util/rust-hir-map.h30
-rw-r--r--gcc/rust/util/rust-inference-var.h112
36 files changed, 2039 insertions, 243 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index aa81813..96457ed 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -78,6 +78,9 @@ GRS_OBJS = \
rust/rust-hir-map.o \
rust/rust-ast-lower.o \
rust/rust-ast-resolve.o \
+ rust/rust-hir-type-check.o \
+ rust/rust-tyty.o \
+ rust/rust-tyctx.o \
$(END)
# removed object files from here
@@ -231,7 +234,8 @@ RUST_INCLUDES = -I $(srcdir)/rust \
-I $(srcdir)/rust/hir/tree \
-I $(srcdir)/rust/hir \
-I $(srcdir)/rust/resolve \
- -I $(srcdir)/rust/util
+ -I $(srcdir)/rust/util \
+ -I $(srcdir)/rust/typecheck
# add files that require cross-folder includes - currently rust-lang.o, rust-lex.o
CFLAGS-rust/rust-lang.o += $(RUST_INCLUDES)
@@ -287,8 +291,13 @@ rust/%.o: rust/hir/tree/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
-# build rust/hir/tree files in rust folder
+# build rust/resolve files in rust folder
rust/%.o: rust/resolve/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
+# build rust/typecheck files in rust folder
+rust/%.o: rust/typecheck/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index 71e465e..e0ce862 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -93,6 +93,8 @@ public:
mappings->insert_defid_mapping (mapping.get_defid (), translated);
mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (),
translated);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ function.get_locus ());
}
// Helpers
diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h
index d18dc19..c813639 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.h
+++ b/gcc/rust/hir/rust-ast-lower-stmt.h
@@ -58,6 +58,8 @@ public:
= new HIR::ExprStmtWithoutBlock (mapping,
std::unique_ptr<HIR::Expr> (expr),
stmt.get_locus ());
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ stmt.get_locus ());
}
void visit (AST::LetStmt &stmt)
@@ -82,6 +84,8 @@ public:
std::unique_ptr<HIR::Expr> (init_expression),
std::unique_ptr<HIR::Type> (type),
std::move (outer_attrs), stmt.get_locus ());
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ stmt.get_locus ());
}
private:
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index 9611ca0..4193415 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -65,9 +65,16 @@ public:
return true;
});
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, path.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
translated
- = new HIR::TypePath (std::move (translated_segments), path.get_locus (),
+ = new HIR::TypePath (std::move (mapping), std::move (translated_segments),
+ path.get_locus (),
path.has_opening_scope_resolution_op ());
+ mappings->insert_hir_type (mapping.get_crate_num (), mapping.get_hirid (),
+ translated);
}
private:
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 5f5bbf9..b08aa91 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -2169,6 +2169,8 @@ public:
Expr *get_fnexpr () { return function.get (); }
+ size_t num_params () const { return params.size (); }
+
void iterate_params (std::function<bool (Expr *)> cb)
{
for (auto it = params.begin (); it != params.end (); it++)
@@ -2551,6 +2553,15 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ void iterate_stmts (std::function<bool (Stmt *)> cb)
+ {
+ for (auto it = statements.begin (); it != statements.end (); it++)
+ {
+ if (!cb (it->get ()))
+ return;
+ }
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
@@ -3118,6 +3129,8 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ Expr *get_expr () { return return_expr.get (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 774e407..cf24bae 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -319,19 +319,6 @@ public:
// not having either is not an error
}
- // Creates an error state self-param.
- static SelfParam create_error ()
- {
- /* HACK: creates a dummy type. Since it's a unique pointer, it should
- * clean it up, but it still allocates memory, which is not ideal. */
- return SelfParam (Lifetime (Lifetime::STATIC), false, false,
- new QualifiedPathInType (
- QualifiedPathInType::create_error ()));
- /* FIXME: is there a reason why I didn't just create a null pointer? Is it
- * due to error being having both a type and a lifetime? If it is, wouldn't
- * something like "not has_ref and has lifetime" for error be better? */
- }
-
// 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 ()),
@@ -588,22 +575,6 @@ class Method : public InherentImplItem, public TraitImplItem
Location locus;
public:
- // Returns whether the method is in an error state.
- bool is_error () const
- {
- return expr == nullptr || method_name.empty () || self_param.is_error ();
- }
-
- // Creates an error state method.
- static Method create_error ()
- {
- return Method ("", FunctionQualifiers (FunctionQualifiers::NONE, true),
- std::vector<std::unique_ptr<GenericParam> > (),
- SelfParam::create_error (), std::vector<FunctionParam> (),
- nullptr, WhereClause::create_empty (), nullptr,
- Visibility::create_error (), std::vector<Attribute> ());
- }
-
// Returns whether the method has generic parameters.
bool has_generics () const { return !generic_params.empty (); }
diff --git a/gcc/rust/hir/tree/rust-hir-macro.h b/gcc/rust/hir/tree/rust-hir-macro.h
index 0a38134..84b4914 100644
--- a/gcc/rust/hir/tree/rust-hir-macro.h
+++ b/gcc/rust/hir/tree/rust-hir-macro.h
@@ -345,7 +345,8 @@ public:
MacroInvocation (Analysis::NodeMapping mappings, SimplePath path,
DelimTokenTree token_tree,
std::vector<Attribute> outer_attrs, Location locus)
- : ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
+ : TypeNoBounds (mappings),
+ ExprWithoutBlock (std::move (mappings), std::move (outer_attrs)),
path (std::move (path)), token_tree (std::move (token_tree)),
locus (locus)
{}
diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h
index 06d31aa..1bba506 100644
--- a/gcc/rust/hir/tree/rust-hir-path.h
+++ b/gcc/rust/hir/tree/rust-hir-path.h
@@ -591,20 +591,24 @@ public:
// Creates an error state TypePath.
static TypePath create_error ()
{
- return TypePath (std::vector<std::unique_ptr<TypePathSegment> > (),
+ return TypePath (Analysis::NodeMapping::get_error (),
+ std::vector<std::unique_ptr<TypePathSegment> > (),
Location ());
}
// Constructor
- TypePath (std::vector<std::unique_ptr<TypePathSegment> > segments,
+ TypePath (Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<TypePathSegment> > segments,
Location locus, bool has_opening_scope_resolution = false)
- : has_opening_scope_resolution (has_opening_scope_resolution),
+ : TypeNoBounds (mappings),
+ has_opening_scope_resolution (has_opening_scope_resolution),
segments (std::move (segments)), locus (locus)
{}
// Copy constructor with vector clone
TypePath (TypePath const &other)
- : has_opening_scope_resolution (other.has_opening_scope_resolution),
+ : TypeNoBounds (other.mappings),
+ has_opening_scope_resolution (other.has_opening_scope_resolution),
locus (other.locus)
{
segments.reserve (other.segments.size ());
@@ -617,6 +621,7 @@ public:
{
has_opening_scope_resolution = other.has_opening_scope_resolution;
locus = other.locus;
+ mappings = other.mappings;
segments.reserve (other.segments.size ());
for (const auto &e : other.segments)
@@ -793,10 +798,10 @@ protected:
public:
QualifiedPathInType (
- QualifiedPathType qual_path_type,
+ Analysis::NodeMapping mappings, QualifiedPathType qual_path_type,
std::vector<std::unique_ptr<TypePathSegment> > path_segments,
Location locus = Location ())
- : path_type (std::move (qual_path_type)),
+ : TypeNoBounds (mappings), path_type (std::move (qual_path_type)),
segments (std::move (path_segments)), locus (locus)
{}
@@ -805,7 +810,7 @@ public:
// Copy constructor with vector clone
QualifiedPathInType (QualifiedPathInType const &other)
- : path_type (other.path_type), locus (other.locus)
+ : TypeNoBounds (mappings), path_type (other.path_type), locus (other.locus)
{
segments.reserve (other.segments.size ());
for (const auto &e : other.segments)
@@ -817,6 +822,7 @@ public:
{
path_type = other.path_type;
locus = other.locus;
+ mappings = other.mappings;
segments.reserve (other.segments.size ());
for (const auto &e : other.segments)
@@ -829,17 +835,6 @@ public:
QualifiedPathInType (QualifiedPathInType &&other) = default;
QualifiedPathInType &operator= (QualifiedPathInType &&other) = default;
- // Returns whether qualified path in type is in an error state.
- bool is_error () const { return path_type.is_error (); }
-
- // Creates an error state qualified path in type.
- static QualifiedPathInType create_error ()
- {
- return QualifiedPathInType (
- QualifiedPathType::create_error (),
- std::vector<std::unique_ptr<TypePathSegment> > ());
- }
-
std::string as_string () const override;
void accept_vis (HIRVisitor &vis) override;
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h b/gcc/rust/hir/tree/rust-hir-stmt.h
index 61d9dcb..31d55b6 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -113,6 +113,10 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ HIR::Type *get_type () { return type.get (); }
+
+ HIR::Expr *get_init_expr () { return init_expr.get (); }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index 0a446bd..f8c851c 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -92,13 +92,16 @@ protected:
public:
ImplTraitType (
+ Analysis::NodeMapping mappings,
std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds,
Location locus)
- : type_param_bounds (std::move (type_param_bounds)), locus (locus)
+ : Type (mappings), type_param_bounds (std::move (type_param_bounds)),
+ locus (locus)
{}
// copy constructor with vector clone
- ImplTraitType (ImplTraitType const &other) : locus (other.locus)
+ ImplTraitType (ImplTraitType const &other)
+ : Type (other.mappings), locus (other.locus)
{
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
@@ -109,6 +112,7 @@ public:
ImplTraitType &operator= (ImplTraitType const &other)
{
locus = other.locus;
+ mappings = other.mappings;
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
@@ -148,15 +152,16 @@ protected:
public:
TraitObjectType (
+ Analysis::NodeMapping mappings,
std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds,
Location locus, bool is_dyn_dispatch = false)
- : has_dyn (is_dyn_dispatch),
+ : Type (mappings), has_dyn (is_dyn_dispatch),
type_param_bounds (std::move (type_param_bounds)), locus (locus)
{}
// copy constructor with vector clone
TraitObjectType (TraitObjectType const &other)
- : has_dyn (other.has_dyn), locus (other.locus)
+ : Type (other.mappings), has_dyn (other.has_dyn), locus (other.locus)
{
type_param_bounds.reserve (other.type_param_bounds.size ());
for (const auto &e : other.type_param_bounds)
@@ -166,6 +171,7 @@ public:
// overloaded assignment operator to clone
TraitObjectType &operator= (TraitObjectType const &other)
{
+ mappings = other.mappings;
has_dyn = other.has_dyn;
locus = other.locus;
type_param_bounds.reserve (other.type_param_bounds.size ());
@@ -209,19 +215,23 @@ protected:
public:
// Constructor uses Type pointer for polymorphism
- ParenthesisedType (std::unique_ptr<Type> type_inside_parens, Location locus)
- : type_in_parens (std::move (type_inside_parens)), locus (locus)
+ ParenthesisedType (Analysis::NodeMapping mappings,
+ std::unique_ptr<Type> type_inside_parens, Location locus)
+ : TypeNoBounds (mappings), type_in_parens (std::move (type_inside_parens)),
+ locus (locus)
{}
/* Copy constructor uses custom deep copy method for type to preserve
* polymorphism */
ParenthesisedType (ParenthesisedType const &other)
- : type_in_parens (other.type_in_parens->clone_type ()), locus (other.locus)
+ : TypeNoBounds (other.mappings),
+ type_in_parens (other.type_in_parens->clone_type ()), locus (other.locus)
{}
// overload assignment operator to use custom clone method
ParenthesisedType &operator= (ParenthesisedType const &other)
{
+ mappings = other.mappings;
type_in_parens = other.type_in_parens->clone_type ();
locus = other.locus;
return *this;
@@ -273,8 +283,10 @@ protected:
}
public:
- ImplTraitTypeOneBound (TraitBound trait_bound, Location locus)
- : trait_bound (std::move (trait_bound)), locus (locus)
+ ImplTraitTypeOneBound (Analysis::NodeMapping mappings, TraitBound trait_bound,
+ Location locus)
+ : TypeNoBounds (mappings), trait_bound (std::move (trait_bound)),
+ locus (locus)
{}
std::string as_string () const override;
@@ -309,10 +321,11 @@ protected:
}
public:
- TraitObjectTypeOneBound (TraitBound trait_bound, Location locus,
+ TraitObjectTypeOneBound (Analysis::NodeMapping mappings,
+ TraitBound trait_bound, Location locus,
bool is_dyn_dispatch = false)
- : has_dyn (is_dyn_dispatch), trait_bound (std::move (trait_bound)),
- locus (locus)
+ : TypeNoBounds (mappings), has_dyn (is_dyn_dispatch),
+ trait_bound (std::move (trait_bound)), locus (locus)
{}
std::string as_string () const override;
@@ -343,13 +356,16 @@ public:
// Returns whether the tuple type is the unit type, i.e. has no elements.
bool is_unit_type () const { return elems.empty (); }
- TupleType (std::vector<std::unique_ptr<Type> > elems, Location locus)
- : elems (std::move (elems)), locus (locus)
+ TupleType (Analysis::NodeMapping mappings,
+ std::vector<std::unique_ptr<Type> > elems, Location locus)
+ : TypeNoBounds (mappings), elems (std::move (elems)), locus (locus)
{}
// copy constructor with vector clone
- TupleType (TupleType const &other) : locus (other.locus)
+ TupleType (TupleType const &other)
+ : TypeNoBounds (other.mappings), locus (other.locus)
{
+ mappings = other.mappings;
elems.reserve (other.elems.size ());
for (const auto &e : other.elems)
elems.push_back (e->clone_type ());
@@ -410,7 +426,9 @@ protected:
}
public:
- NeverType (Location locus) : locus (locus) {}
+ NeverType (Analysis::NodeMapping mappings, Location locus)
+ : TypeNoBounds (mappings), locus (locus)
+ {}
std::string as_string () const override { return "! (never type)"; }
@@ -439,21 +457,22 @@ public:
PointerType get_pointer_type () const { return pointer_type; }
// Constructor requires pointer for polymorphism reasons
- RawPointerType (PointerType pointer_type,
+ RawPointerType (Analysis::NodeMapping mappings, PointerType pointer_type,
std::unique_ptr<TypeNoBounds> type_no_bounds, Location locus)
- : pointer_type (pointer_type), type (std::move (type_no_bounds)),
- locus (locus)
+ : TypeNoBounds (mappings), pointer_type (pointer_type),
+ type (std::move (type_no_bounds)), locus (locus)
{}
// Copy constructor calls custom polymorphic clone function
RawPointerType (RawPointerType const &other)
- : pointer_type (other.pointer_type),
+ : TypeNoBounds (other.mappings), pointer_type (other.pointer_type),
type (other.type->clone_type_no_bounds ()), locus (other.locus)
{}
// overload assignment operator to use custom clone method
RawPointerType &operator= (RawPointerType const &other)
{
+ mappings = other.mappings;
pointer_type = other.pointer_type;
type = other.type->clone_type_no_bounds ();
locus = other.locus;
@@ -504,21 +523,24 @@ public:
bool has_lifetime () const { return !lifetime.is_error (); }
// Constructor
- ReferenceType (bool is_mut, std::unique_ptr<TypeNoBounds> type_no_bounds,
- Location locus, Lifetime lifetime = Lifetime::error ())
- : lifetime (std::move (lifetime)), has_mut (is_mut),
- type (std::move (type_no_bounds)), locus (locus)
+ ReferenceType (Analysis::NodeMapping mappings, bool is_mut,
+ std::unique_ptr<TypeNoBounds> type_no_bounds, Location locus,
+ Lifetime lifetime = Lifetime::error ())
+ : TypeNoBounds (mappings), lifetime (std::move (lifetime)),
+ has_mut (is_mut), type (std::move (type_no_bounds)), locus (locus)
{}
// Copy constructor with custom clone method
ReferenceType (ReferenceType const &other)
- : lifetime (other.lifetime), has_mut (other.has_mut),
- type (other.type->clone_type_no_bounds ()), locus (other.locus)
+ : TypeNoBounds (other.mappings), lifetime (other.lifetime),
+ has_mut (other.has_mut), type (other.type->clone_type_no_bounds ()),
+ locus (other.locus)
{}
// Operator overload assignment operator to custom clone the unique pointer
ReferenceType &operator= (ReferenceType const &other)
{
+ mappings = other.mappings;
lifetime = other.lifetime;
has_mut = other.has_mut;
type = other.type->clone_type_no_bounds ();
@@ -562,20 +584,22 @@ class ArrayType : public TypeNoBounds
public:
// Constructor requires pointers for polymorphism
- ArrayType (std::unique_ptr<Type> type, std::unique_ptr<Expr> array_size,
- Location locus)
- : elem_type (std::move (type)), size (std::move (array_size)), locus (locus)
+ ArrayType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
+ std::unique_ptr<Expr> array_size, Location locus)
+ : TypeNoBounds (mappings), elem_type (std::move (type)),
+ size (std::move (array_size)), locus (locus)
{}
// Copy constructor requires deep copies of both unique pointers
ArrayType (ArrayType const &other)
- : elem_type (other.elem_type->clone_type ()),
+ : TypeNoBounds (mappings), elem_type (other.elem_type->clone_type ()),
size (other.size->clone_expr ()), locus (other.locus)
{}
// Overload assignment operator to deep copy pointers
ArrayType &operator= (ArrayType const &other)
{
+ mappings = other.mappings;
elem_type = other.elem_type->clone_type ();
size = other.size->clone_expr ();
locus = other.locus;
@@ -620,18 +644,21 @@ class SliceType : public TypeNoBounds
public:
// Constructor requires pointer for polymorphism
- SliceType (std::unique_ptr<Type> type, Location locus)
- : elem_type (std::move (type)), locus (locus)
+ SliceType (Analysis::NodeMapping mappings, std::unique_ptr<Type> type,
+ Location locus)
+ : TypeNoBounds (mappings), elem_type (std::move (type)), locus (locus)
{}
// Copy constructor requires deep copy of Type smart pointer
SliceType (SliceType const &other)
- : elem_type (other.elem_type->clone_type ()), locus (other.locus)
+ : TypeNoBounds (other.mappings), elem_type (other.elem_type->clone_type ()),
+ locus (other.locus)
{}
// Overload assignment operator to deep copy
SliceType &operator= (SliceType const &other)
{
+ mappings = other.mappings;
elem_type = other.elem_type->clone_type ();
locus = other.locus;
@@ -684,7 +711,9 @@ protected:
}
public:
- InferredType (Location locus) : locus (locus) {}
+ InferredType (Analysis::NodeMapping mappings, Location locus)
+ : TypeNoBounds (mappings), locus (locus)
+ {}
std::string as_string () const override;
@@ -783,11 +812,12 @@ public:
// Whether the function has ForLifetimes.
bool has_for_lifetimes () const { return !for_lifetimes.empty (); }
- BareFunctionType (std::vector<LifetimeParam> lifetime_params,
+ BareFunctionType (Analysis::NodeMapping mappings,
+ std::vector<LifetimeParam> lifetime_params,
FunctionQualifiers qualifiers,
std::vector<MaybeNamedParam> named_params, bool is_variadic,
std::unique_ptr<TypeNoBounds> type, Location locus)
- : for_lifetimes (std::move (lifetime_params)),
+ : TypeNoBounds (mappings), for_lifetimes (std::move (lifetime_params)),
function_qualifiers (std::move (qualifiers)),
params (std::move (named_params)), is_variadic (is_variadic),
return_type (std::move (type)), locus (locus)
@@ -795,7 +825,7 @@ public:
// Copy constructor with clone
BareFunctionType (BareFunctionType const &other)
- : for_lifetimes (other.for_lifetimes),
+ : TypeNoBounds (other.mappings), for_lifetimes (other.for_lifetimes),
function_qualifiers (other.function_qualifiers), params (other.params),
is_variadic (other.is_variadic),
return_type (other.return_type->clone_type_no_bounds ()),
@@ -805,6 +835,7 @@ public:
// Overload assignment operator to deep copy
BareFunctionType &operator= (BareFunctionType const &other)
{
+ mappings = other.mappings;
for_lifetimes = other.for_lifetimes;
function_qualifiers = other.function_qualifiers;
params = other.params;
diff --git a/gcc/rust/hir/tree/rust-hir.h b/gcc/rust/hir/tree/rust-hir.h
index b7feb59..cbaa2e9 100644
--- a/gcc/rust/hir/tree/rust-hir.h
+++ b/gcc/rust/hir/tree/rust-hir.h
@@ -968,9 +968,15 @@ public:
virtual void accept_vis (HIRVisitor &vis) = 0;
+ virtual Analysis::NodeMapping get_mappings () { return mappings; }
+
protected:
+ Type (Analysis::NodeMapping mappings) : mappings (mappings) {}
+
// Clone function implementation as pure virtual method
virtual Type *clone_type_impl () const = 0;
+
+ Analysis::NodeMapping mappings;
};
// A type without parentheses? - abstract
@@ -984,6 +990,8 @@ public:
}
protected:
+ TypeNoBounds (Analysis::NodeMapping mappings) : Type (mappings) {}
+
// Clone function implementation as pure virtual method
virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0;
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 9ca763d..b9e7f6a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -49,23 +49,24 @@ public:
void visit (AST::ReturnExpr &expr)
{
- if (expr.has_return_expr ())
- ResolveExpr::go (expr.get_expr (), expr.get_node_id ());
+ if (expr.has_returned_expr ())
+ ResolveExpr::go (expr.get_returned_expr ().get (), expr.get_node_id ());
}
void visit (AST::CallExpr &expr)
{
- ResolveExpr::go (expr.function.get (), expr.get_node_id ());
+ ResolveExpr::go (expr.get_function_expr ().get (), expr.get_node_id ());
expr.iterate_params ([&] (AST::Expr *p) mutable -> bool {
ResolveExpr::go (p, expr.get_node_id ());
return true;
});
+ /// resolver->insert_resolved_name(NodeId refId,NodeId defId)
}
void visit (AST::AssignmentExpr &expr)
{
- ResolveExpr::go (expr.get_lhs (), expr.get_node_id ());
- ResolveExpr::go (expr.get_rhs (), expr.get_node_id ());
+ ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ());
+ ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ());
}
void visit (AST::IdentifierExpr &expr)
@@ -84,8 +85,8 @@ public:
void visit (AST::ArithmeticOrLogicalExpr &expr)
{
- ResolveExpr::go (expr.get_lhs (), expr.get_node_id ());
- ResolveExpr::go (expr.right_expr.get (), expr.get_node_id ());
+ ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ());
+ ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ());
}
private:
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index ea79fc0..2c21a52 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -23,6 +23,7 @@
#include "rust-ast-full.h"
#include "rust-ast-resolve-type.h"
#include "rust-ast-resolve-pattern.h"
+#include "rust-ast-resolve-stmt.h"
namespace Rust {
namespace Resolver {
@@ -51,11 +52,21 @@ public:
param.get_node_id ());
}
+ // setup parent scoping for names
+ NodeId scope_node_id = function.get_definition ()->get_node_id ();
+ resolver->get_name_scope ().push (scope_node_id);
+ resolver->get_type_scope ().push (scope_node_id);
+ resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
+ resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
+
function.get_definition ()->iterate_stmts (
[&] (AST::Stmt *s) mutable -> bool {
- // TODO
+ ResolveStmt::go (s, s->get_node_id ());
return true;
});
+
+ resolver->get_name_scope ().pop ();
+ resolver->get_type_scope ().pop ();
}
private:
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
index fc2da70..a393d31 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -78,6 +78,7 @@ public:
void visit (AST::IdentifierPattern &pattern)
{
+ printf ("declaration for: %s\n", pattern.as_string ().c_str ());
// if we have a duplicate id this then allows for shadowing correctly
// as new refs to this decl will match back here so it is ok to overwrite
resolver->get_name_scope ().insert (pattern.get_ident (),
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index 42fb097..623fbd4 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -41,16 +41,16 @@ public:
void visit (AST::LetStmt &stmt)
{
- PatternDeclaration::go (stmt.variables_pattern.get (), stmt.get_node_id ());
+ PatternDeclaration::go (stmt.get_pattern ().get (), stmt.get_node_id ());
if (stmt.has_type ())
- ResolveType::go (stmt.type.get (), stmt.get_node_id ());
+ ResolveType::go (stmt.get_type ().get (), stmt.get_node_id ());
if (stmt.has_init_expr ())
- ResolveExpr::go (stmt.init_expr.get (), stmt.get_node_id ());
+ ResolveExpr::go (stmt.get_init_expr ().get (), stmt.get_node_id ());
}
private:
- ResolveStmt () : ResolverBase (UNKNOWN_NODEID) {}
+ ResolveStmt (NodeId parent) : ResolverBase (parent) {}
};
} // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 664af12..57bd0f3 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -20,8 +20,9 @@
#include "rust-ast-resolve-toplevel.h"
#include "rust-ast-resolve-item.h"
#include "rust-ast-full.h"
+#include "rust-tyty.h"
-#define MKBUILTIN_TYPE(_X, _R) \
+#define MKBUILTIN_TYPE(_X, _R, _TY) \
do \
{ \
AST::PathIdentSegment seg (_X); \
@@ -34,6 +35,8 @@
= new AST::TypePath (::std::move (segs), \
Linemap::predeclared_location (), false); \
_R.push_back (builtin_type); \
+ tyctx->insert_builtin (_TY->get_ref (), builtin_type->get_node_id (), \
+ _TY); \
} \
while (0)
@@ -43,7 +46,7 @@ namespace Resolver {
// Resolver
Resolver::Resolver ()
- : mappings (Analysis::Mappings::get ()),
+ : mappings (Analysis::Mappings::get ()), tyctx (TypeCheckContext::get ()),
name_scope (Scope (mappings->get_current_crate ())),
type_scope (Scope (mappings->get_current_crate ()))
{
@@ -116,22 +119,26 @@ Resolver::get_builtin_types ()
void
Resolver::generate_builtins ()
{
- MKBUILTIN_TYPE ("u8", builtins);
- MKBUILTIN_TYPE ("u16", builtins);
- MKBUILTIN_TYPE ("u32", builtins);
- MKBUILTIN_TYPE ("u64", builtins);
-
- MKBUILTIN_TYPE ("i8", builtins);
- MKBUILTIN_TYPE ("i16", builtins);
- MKBUILTIN_TYPE ("i32", builtins);
- MKBUILTIN_TYPE ("i64", builtins);
-
- MKBUILTIN_TYPE ("f32", builtins);
- MKBUILTIN_TYPE ("f64", builtins);
-
- MKBUILTIN_TYPE ("char", builtins);
- MKBUILTIN_TYPE ("str", builtins);
- MKBUILTIN_TYPE ("bool", builtins);
+ auto u8
+ = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U8);
+ auto u16
+ = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U16);
+ auto u32
+ = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U32);
+ auto i8 = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I8);
+ auto i16
+ = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I16);
+ auto i32
+ = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I32);
+ auto rbool = new TyTy::BoolType (mappings->get_next_hir_id ());
+
+ MKBUILTIN_TYPE ("u8", builtins, u8);
+ MKBUILTIN_TYPE ("u16", builtins, u16);
+ MKBUILTIN_TYPE ("u32", builtins, u32);
+ MKBUILTIN_TYPE ("i8", builtins, i8);
+ MKBUILTIN_TYPE ("i16", builtins, i16);
+ MKBUILTIN_TYPE ("i32", builtins, i32);
+ MKBUILTIN_TYPE ("bool", builtins, rbool);
}
void
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 4aac7d5..2aa592c 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -21,6 +21,7 @@
#include "rust-system.h"
#include "rust-hir-map.h"
+#include "rust-hir-type-check.h"
namespace Rust {
namespace Resolver {
@@ -55,6 +56,15 @@ public:
CrateNum get_crate_num () const { return crate_num; }
NodeId get_node_id () const { return node_id; }
+ void iterate_decls (std::function<bool (NodeId)> cb)
+ {
+ for (auto it : decls_within_rib)
+ {
+ if (!cb (it))
+ return;
+ }
+ }
+
private:
CrateNum crate_num;
NodeId node_id;
@@ -174,6 +184,7 @@ private:
void generate_builtins ();
Analysis::Mappings *mappings;
+ TypeCheckContext *tyctx;
std::vector<AST::TypePath *> builtins;
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 3131af0..fc64994 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -26,16 +26,15 @@
#include "tm.h"
#include "tm_p.h"
+#include "rust-target.h"
+
#include "rust-lex.h"
#include "rust-parse.h"
#include "rust-scan.h"
#include "rust-macro-expand.h"
-#include "rust-compile.h"
-#include "rust-target.h"
-
-// hir passes wip
#include "rust-ast-resolve.h"
#include "rust-ast-lower.h"
+#include "rust-hir-type-check.h"
extern Linemap *
rust_get_linemap ();
@@ -531,7 +530,7 @@ Session::parse_file (const char *filename)
}
// lower AST to HIR
- HIR::Crate hir = HIR::ASTLowering::Resolve (parsed_crate);
+ HIR::Crate hir = lower_ast (parsed_crate);
if (options.dump_option == CompileOptions::HIR_DUMP)
{
fprintf (stderr, "%s", hir.as_string ().c_str ());
@@ -539,13 +538,13 @@ Session::parse_file (const char *filename)
}
// type resolve
- // TODO
+ type_resolution (hir);
if (saw_errors ())
return;
// do compile
- Compile::Compilation::Compile (parsed_crate, backend);
+ // Compile::Compilation::Compile (parsed_crate, backend);
}
// TODO: actually implement method
@@ -777,6 +776,23 @@ Session::resolution (AST::Crate &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
{
diff --git a/gcc/rust/rust-session-manager.h b/gcc/rust/rust-session-manager.h
index 2bb1dfb..4836cc8 100644
--- a/gcc/rust/rust-session-manager.h
+++ b/gcc/rust/rust-session-manager.h
@@ -37,6 +37,10 @@ class Lexer;
namespace AST {
struct Crate;
}
+// crate forward decl
+namespace HIR {
+struct Crate;
+}
/* Data related to target, most useful for conditional compilation and
* whatever. */
@@ -240,6 +244,11 @@ private:
* 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-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
new file mode 100644
index 0000000..78afff9
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -0,0 +1,256 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK_BASE
+#define RUST_HIR_TYPE_CHECK_BASE
+
+#include "rust-diagnostics.h"
+#include "rust-hir-type-check.h"
+#include "rust-name-resolver.h"
+#include "rust-hir-visitor.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace Resolver {
+
+// base class to allow derivatives to overload as needed
+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) {}
+ virtual void visit (HIR::MacroInvocationSemi &macro) {}
+
+ // 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) {}
+
+protected:
+ TypeCheckBase ()
+ : mappings (Analysis::Mappings::get ()), resolver (Resolver::get ()),
+ context (TypeCheckContext::get ())
+ {}
+
+ Analysis::Mappings *mappings;
+ Resolver *resolver;
+ TypeCheckContext *context;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK_BASE
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
new file mode 100644
index 0000000..2e715e9
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -0,0 +1,173 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK_EXPR
+#define RUST_HIR_TYPE_CHECK_EXPR
+
+#include "rust-hir-type-check-base.h"
+#include "rust-hir-full.h"
+#include "rust-tyty.h"
+#include "rust-tyty-call.h"
+
+namespace Rust {
+namespace Resolver {
+
+class TypeCheckExpr : public TypeCheckBase
+{
+public:
+ static TyTy::TyBase *Resolve (HIR::Expr *expr)
+ {
+ TypeCheckExpr resolver;
+ expr->accept_vis (resolver);
+ if (resolver.infered != nullptr)
+ resolver.context->insert_type (expr->get_mappings ().get_hirid (),
+ resolver.infered);
+
+ return resolver.infered;
+ }
+
+ void visit (HIR::ReturnExpr &expr)
+ {
+ auto ret = context->peek_return_type ();
+ rust_assert (ret != nullptr);
+
+ auto expr_ty = TypeCheckExpr::Resolve (expr.get_expr ());
+ infered = ret->combine (expr_ty);
+ }
+
+ void visit (HIR::CallExpr &expr)
+ {
+ auto fn = expr.get_fnexpr ();
+ auto fn_node_id = fn->get_mappings ().get_nodeid ();
+
+ // then lookup the reference_node_id
+ NodeId ref_node_id;
+ if (!resolver->lookup_resolved_name (fn_node_id, &ref_node_id))
+ {
+ rust_error_at (expr.get_locus (),
+ "Failed to lookup reference for node: %s",
+ expr.as_string ().c_str ());
+ return;
+ }
+
+ // node back to HIR
+ HirId ref;
+ if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
+ ref_node_id, &ref))
+ {
+ rust_error_at (expr.get_locus (), "reverse lookup failure");
+ return;
+ }
+
+ // check if this has a type
+ 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",
+ expr.as_string ().c_str ());
+ return;
+ }
+
+ infered = TyTy::TypeCheckCallExpr::go (lookup, expr);
+ }
+
+ void visit (HIR::AssignmentExpr &expr)
+ {
+ auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+ auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
+
+ infered = lhs->combine (rhs);
+ }
+
+ void visit (HIR::IdentifierExpr &expr)
+ {
+ NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
+
+ // then lookup the reference_node_id
+ NodeId ref_node_id;
+ if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
+ {
+ rust_error_at (expr.get_locus (),
+ "Failed to lookup reference for node: %s",
+ expr.as_string ().c_str ());
+ return;
+ }
+
+ // node back to HIR
+ HirId ref;
+ if (!mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
+ ref_node_id, &ref))
+ {
+ rust_error_at (expr.get_locus (), "reverse lookup failure");
+ return;
+ }
+
+ // check if this has a type
+ 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",
+ expr.as_string ().c_str ());
+ return;
+ }
+
+ // FIXME this needs to be cloned for memory management later on
+ infered = lookup;
+ }
+
+ void visit (HIR::LiteralExpr &expr)
+ {
+ switch (expr.get_lit_type ())
+ {
+ case HIR::Literal::LitType::INT:
+ infered = new TyTy::IntType (expr.get_mappings ().get_hirid (),
+ TyTy::IntType::IntKind::I32);
+ break;
+
+ case HIR::Literal::LitType::BOOL:
+ infered = new TyTy::BoolType (expr.get_mappings ().get_hirid ());
+ break;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+ }
+
+ void visit (HIR::ArithmeticOrLogicalExpr &expr)
+ {
+ auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ());
+ auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ());
+
+ infered = lhs->combine (rhs);
+ }
+
+private:
+ TypeCheckExpr () : TypeCheckBase (), infered (nullptr) {}
+
+ TyTy::TyBase *infered;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK_EXPR
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
new file mode 100644
index 0000000..29d6db6
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -0,0 +1,90 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK_ITEM
+#define RUST_HIR_TYPE_CHECK_ITEM
+
+#include "rust-hir-type-check-base.h"
+#include "rust-hir-full.h"
+#include "rust-hir-type-check-type.h"
+#include "rust-hir-type-check-stmt.h"
+#include "rust-tyty-visitor.h"
+
+namespace Rust {
+namespace Resolver {
+
+class ResolveFnType : public TyTy::TyVisitor
+{
+public:
+ ResolveFnType (TyTy::TyBase *base) : base (base), state (nullptr) {}
+
+ TyTy::TyBase *go ()
+ {
+ base->accept_vis (*this);
+ if (state == nullptr)
+ gcc_unreachable ();
+
+ return state;
+ }
+
+ void visit (TyTy::FnType &type) override { state = type.return_type (); }
+
+private:
+ TyTy::TyBase *base;
+ TyTy::TyBase *state;
+};
+
+class TypeCheckItem : public TypeCheckBase
+{
+public:
+ static void Resolve (HIR::Item *item)
+ {
+ TypeCheckItem resolver;
+ item->accept_vis (resolver);
+ }
+
+ void visit (HIR::Function &function)
+ {
+ TyTy::TyBase *fnType;
+ if (!context->lookup_type (function.get_mappings ().get_hirid (), &fnType))
+ {
+ rust_error_at (function.locus, "failed to lookup function type");
+ return;
+ }
+ // need to get the return type from this
+ ResolveFnType resolve_fn_type (fnType);
+ context->push_return_type (resolve_fn_type.go ());
+
+ // walk statements to make sure they are all typed correctly and they match
+ // up
+ function.function_body->iterate_stmts ([&] (HIR::Stmt *s) mutable -> bool {
+ TypeCheckStmt::Resolve (s);
+ return true;
+ });
+
+ context->pop_return_type ();
+ }
+
+private:
+ TypeCheckItem () : TypeCheckBase () {}
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK_ITEM
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
new file mode 100644
index 0000000..39c48f0
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -0,0 +1,86 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK_STMT
+#define RUST_HIR_TYPE_CHECK_STMT
+
+#include "rust-hir-type-check-base.h"
+#include "rust-hir-full.h"
+#include "rust-hir-type-check-type.h"
+#include "rust-hir-type-check-expr.h"
+
+namespace Rust {
+namespace Resolver {
+
+class TypeCheckStmt : public TypeCheckBase
+{
+public:
+ static void Resolve (HIR::Stmt *stmt)
+ {
+ TypeCheckStmt resolver;
+ stmt->accept_vis (resolver);
+ }
+
+ void visit (HIR::LetStmt &stmt)
+ {
+ TyTy::TyBase *init_expr_ty = nullptr;
+ if (stmt.has_init_expr ())
+ init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ());
+
+ TyTy::TyBase *specified_ty = nullptr;
+ if (stmt.has_type ())
+ specified_ty = TypeCheckType::Resolve (stmt.get_type ());
+
+ // let x:i32 = 123;
+ if (specified_ty != nullptr && init_expr_ty != nullptr)
+ {
+ context->insert_type (stmt.get_mappings ().get_hirid (),
+ specified_ty->combine (init_expr_ty));
+ }
+ else
+ {
+ // let x:i32;
+ if (specified_ty != nullptr)
+ {
+ context->insert_type (stmt.get_mappings ().get_hirid (),
+ specified_ty);
+ }
+ // let x = 123;
+ else if (init_expr_ty != nullptr)
+ {
+ context->insert_type (stmt.get_mappings ().get_hirid (),
+ init_expr_ty);
+ }
+ // let x;
+ else
+ {
+ context->insert_type (stmt.get_mappings ().get_hirid (),
+ new TyTy::InferType (
+ stmt.get_mappings ().get_hirid ()));
+ }
+ }
+ }
+
+private:
+ TypeCheckStmt () : TypeCheckBase () {}
+}; // namespace Resolver
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK_STMT
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
new file mode 100644
index 0000000..c15aaef
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -0,0 +1,63 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK_TOPLEVEL
+#define RUST_HIR_TYPE_CHECK_TOPLEVEL
+
+#include "rust-hir-type-check-base.h"
+#include "rust-hir-full.h"
+#include "rust-hir-type-check-type.h"
+#include "rust-tyty.h"
+
+namespace Rust {
+namespace Resolver {
+
+class TypeCheckTopLevel : public TypeCheckBase
+{
+public:
+ static void Resolve (HIR::Item *item)
+ {
+ TypeCheckTopLevel resolver;
+ item->accept_vis (resolver);
+ }
+
+ void visit (HIR::Function &function)
+ {
+ TyTy::TyBase *ret_type = nullptr;
+ if (!function.has_function_return_type ())
+ ret_type = new TyTy::UnitType (function.get_mappings ().get_hirid ());
+ else
+ ret_type = TypeCheckType::Resolve (function.return_type.get ());
+
+ std::vector<TyTy::TyBase *> params;
+ for (auto &param : function.function_params)
+ params.push_back (TypeCheckType::Resolve (param.type.get ()));
+
+ auto fnType = new TyTy::FnType (function.get_mappings ().get_hirid (),
+ params, ret_type);
+ context->insert_type (function.get_mappings ().get_hirid (), fnType);
+ }
+
+private:
+ TypeCheckTopLevel () : TypeCheckBase () {}
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK_TOPLEVEL
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
new file mode 100644
index 0000000..d8721a3
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -0,0 +1,81 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK_TYPE
+#define RUST_HIR_TYPE_CHECK_TYPE
+
+#include "rust-hir-type-check-base.h"
+#include "rust-hir-full.h"
+
+namespace Rust {
+namespace Resolver {
+
+class TypeCheckType : public TypeCheckBase
+{
+public:
+ static TyTy::TyBase *Resolve (HIR::Type *type)
+ {
+ TypeCheckType resolver;
+ type->accept_vis (resolver);
+
+ if (resolver.translated != nullptr)
+ resolver.context->insert_type (type->get_mappings ().get_hirid (),
+ resolver.translated);
+
+ return resolver.translated;
+ }
+
+ virtual void visit (HIR::TypePath &path)
+ {
+ // check if this is already defined or not
+ if (context->lookup_type (path.get_mappings ().get_hirid (), &translated))
+ return;
+
+ // lookup the Node this resolves to
+ NodeId ref;
+ if (!resolver->lookup_resolved_type (path.get_mappings ().get_nodeid (),
+ &ref))
+ {
+ rust_error_at (path.get_locus (), "Type was not resolved");
+ return;
+ }
+
+ HirId hir_lookup;
+ if (context->lookup_type_by_node_id (ref, &hir_lookup))
+ {
+ // we got an HIR node
+ if (context->lookup_type (hir_lookup, &translated))
+ return;
+ }
+
+ // this might be a struct type reference
+ // TODO
+ printf ("UNREACHABLE %s\n", path.as_string ().c_str ());
+ gcc_unreachable ();
+ }
+
+private:
+ TypeCheckType () : TypeCheckBase (), translated (nullptr) {}
+
+ TyTy::TyBase *translated;
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK_TYPE
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
new file mode 100644
index 0000000..f9dbe49
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -0,0 +1,38 @@
+// 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/>.
+
+#include "rust-hir-type-check.h"
+#include "rust-hir-full.h"
+#include "rust-hir-type-check-toplevel.h"
+#include "rust-hir-type-check-item.h"
+
+namespace Rust {
+namespace Resolver {
+
+void
+TypeResolution::Resolve (HIR::Crate &crate)
+{
+ for (auto it = crate.items.begin (); it != crate.items.end (); it++)
+ TypeCheckTopLevel::Resolve (it->get ());
+
+ for (auto it = crate.items.begin (); it != crate.items.end (); it++)
+ TypeCheckItem::Resolve (it->get ());
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
new file mode 100644
index 0000000..5a8abe1
--- /dev/null
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -0,0 +1,66 @@
+// Copyright (C) 2020 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_HIR_TYPE_CHECK
+#define RUST_HIR_TYPE_CHECK
+
+#include "rust-hir-full-decls.h"
+#include "rust-hir-map.h"
+#include "rust-tyty.h"
+
+namespace Rust {
+namespace Resolver {
+
+class TypeCheckContext
+{
+public:
+ static TypeCheckContext *get ();
+
+ ~TypeCheckContext ();
+
+ void insert_builtin (HirId id, NodeId ref, TyTy::TyBase *type);
+
+ void insert_type (HirId id, TyTy::TyBase *type);
+ bool lookup_type (HirId id, TyTy::TyBase **type);
+
+ void insert_type_by_node_id (NodeId ref, HirId id);
+ bool lookup_type_by_node_id (NodeId ref, HirId *id);
+
+ TyTy::TyBase *peek_return_type ();
+ void push_return_type (TyTy::TyBase *return_type);
+ void pop_return_type ();
+
+private:
+ TypeCheckContext ();
+
+ std::map<NodeId, HirId> node_id_refs;
+ std::map<HirId, TyTy::TyBase *> resolved;
+ std::vector<std::unique_ptr<TyTy::TyBase> > builtins;
+ std::vector<TyTy::TyBase *> return_type_stack;
+};
+
+class TypeResolution
+{
+public:
+ static void Resolve (HIR::Crate &crate);
+};
+
+} // namespace Resolver
+} // namespace Rust
+
+#endif // RUST_HIR_TYPE_CHECK
diff --git a/gcc/rust/typecheck/rust-tyctx.cc b/gcc/rust/typecheck/rust-tyctx.cc
new file mode 100644
index 0000000..195291e
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyctx.cc
@@ -0,0 +1,104 @@
+// 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/>.
+
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver {
+
+TypeCheckContext *
+TypeCheckContext::get ()
+{
+ static TypeCheckContext *instance;
+ if (instance == nullptr)
+ instance = new TypeCheckContext ();
+
+ return instance;
+}
+
+TypeCheckContext::TypeCheckContext () {}
+
+TypeCheckContext::~TypeCheckContext () {}
+
+void
+TypeCheckContext::insert_builtin (HirId id, NodeId ref, TyTy::TyBase *type)
+{
+ printf ("inserting builtin: hir %u node %u -> %s\n", id, ref,
+ type->as_string ().c_str ());
+ node_id_refs[ref] = id;
+ resolved[id] = type;
+ builtins.push_back (std::unique_ptr<TyTy::TyBase> (type));
+}
+
+void
+TypeCheckContext::insert_type (HirId id, TyTy::TyBase *type)
+{
+ rust_assert (resolved.find (id) == resolved.end ());
+ rust_assert (type != nullptr);
+ resolved[id] = type;
+}
+
+bool
+TypeCheckContext::lookup_type (HirId id, TyTy::TyBase **type)
+{
+ auto it = resolved.find (id);
+ if (it == resolved.end ())
+ return false;
+
+ *type = it->second;
+ return true;
+}
+
+void
+TypeCheckContext::insert_type_by_node_id (NodeId ref, HirId id)
+{
+ rust_assert (node_id_refs.find (ref) == node_id_refs.end ());
+ node_id_refs[ref] = id;
+}
+
+bool
+TypeCheckContext::lookup_type_by_node_id (NodeId ref, HirId *id)
+{
+ auto it = node_id_refs.find (ref);
+ if (it == node_id_refs.end ())
+ return false;
+
+ *id = it->second;
+ return true;
+}
+
+TyTy::TyBase *
+TypeCheckContext::peek_return_type ()
+{
+ return return_type_stack.back ();
+}
+
+void
+TypeCheckContext::push_return_type (TyTy::TyBase *return_type)
+{
+ return_type_stack.push_back (return_type);
+}
+
+void
+TypeCheckContext::pop_return_type ()
+{
+ return_type_stack.pop_back ();
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
new file mode 100644
index 0000000..d1341df
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -0,0 +1,53 @@
+// 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_TYTY_CALL
+#define RUST_TYTY_CALL
+
+#include "rust-diagnostics.h"
+#include "rust-hir-full.h"
+#include "rust-tyty-visitor.h"
+#include "rust-tyty.h"
+
+namespace Rust {
+namespace TyTy {
+
+class TypeCheckCallExpr : private TyVisitor
+{
+public:
+ static TyBase *go (TyBase *ref, HIR::CallExpr &call)
+ {
+ TypeCheckCallExpr checker (call);
+ ref->accept_vis (checker);
+ return checker.resolved;
+ }
+ ~TypeCheckCallExpr () {}
+
+ void visit (FnType &type) override;
+
+private:
+ TypeCheckCallExpr (HIR::CallExpr &c) : resolved (nullptr), call (c) {}
+
+ TyBase *resolved;
+ HIR::CallExpr &call;
+};
+
+} // namespace TyTy
+} // namespace Rust
+
+#endif // RUST_TYTY_CALL
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
new file mode 100644
index 0000000..375d909
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -0,0 +1,241 @@
+// 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_TYTY_RULES
+#define RUST_TYTY_RULES
+
+#include "rust-diagnostics.h"
+#include "rust-tyty.h"
+#include "rust-tyty-visitor.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace TyTy {
+
+class BaseRules : public TyVisitor
+{
+public:
+ virtual ~BaseRules () {}
+
+ virtual void visit (UnitType &type) override
+ {
+ Location locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+
+ virtual void visit (InferType &type) override
+ {
+ Location locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+
+ virtual void visit (FnType &type) override
+ {
+ Location locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+
+ virtual void visit (ParamType &type) override
+ {
+ Location locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+
+ virtual void visit (BoolType &type) override
+ {
+ Location locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+
+ virtual void visit (IntType &type) override
+ {
+ Location locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+
+ virtual void visit (UintType &type) override
+ {
+ Location locus = mappings->lookup_location (type.get_ref ());
+ rust_error_at (locus, "expected [%s] got [%s]", base->as_string ().c_str (),
+ type.as_string ().c_str ());
+ }
+
+protected:
+ BaseRules (TyBase *base) : mappings (Analysis::Mappings::get ()), base (base)
+ {}
+
+ Analysis::Mappings *mappings;
+
+private:
+ TyBase *base;
+};
+
+class InferRules : protected BaseRules
+{
+public:
+ InferRules (InferType *base)
+ : BaseRules (base), base (base), resolved (nullptr)
+ {}
+ ~InferRules () {}
+
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ return resolved;
+ }
+
+private:
+ InferType *base;
+ TyBase *resolved;
+};
+
+class UnitRules : protected BaseRules
+{
+public:
+ UnitRules (UnitType *base) : BaseRules (base), base (base), resolved (nullptr)
+ {}
+ ~UnitRules () {}
+
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ return resolved;
+ }
+
+private:
+ UnitType *base;
+ TyBase *resolved;
+};
+
+class FnRules : protected BaseRules
+{
+public:
+ FnRules (FnType *base) : BaseRules (base), base (base), resolved (nullptr) {}
+ ~FnRules () {}
+
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ return resolved;
+ }
+
+private:
+ FnType *base;
+ TyBase *resolved;
+};
+
+class ParamRules : protected BaseRules
+{
+public:
+ ParamRules (ParamType *base)
+ : BaseRules (base), base (base), resolved (nullptr)
+ {}
+ ~ParamRules () {}
+
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ return resolved;
+ }
+
+private:
+ ParamType *base;
+ TyBase *resolved;
+};
+
+class BoolRules : protected BaseRules
+{
+public:
+ BoolRules (BoolType *base) : BaseRules (base), base (base), resolved (nullptr)
+ {}
+ ~BoolRules () {}
+
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ return resolved;
+ }
+
+ void visit (BoolType &type) override
+ {
+ resolved = new BoolType (type.get_ref ());
+ }
+
+private:
+ BoolType *base;
+ TyBase *resolved;
+};
+
+class IntRules : protected BaseRules
+{
+public:
+ IntRules (IntType *base) : BaseRules (base), base (base), resolved (nullptr)
+ {}
+ ~IntRules () {}
+
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ return resolved;
+ }
+
+ void visit (IntType &type) override
+ {
+ // FIXME we should look at the IntTypeKind and check if i8 vs i16 etc..
+ resolved = new IntType (type.get_ref (), type.get_kind ());
+ }
+
+private:
+ IntType *base;
+ TyBase *resolved;
+};
+
+class UintRules : protected BaseRules
+{
+public:
+ UintRules (UintType *base) : BaseRules (base), base (base), resolved (nullptr)
+ {}
+ ~UintRules () {}
+
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ return resolved;
+ }
+
+ void visit (UintType &type) override
+ {
+ // FIXME we should look at the IntTypeKind and check if u8 vs u16 etc..
+ resolved = new UintType (type.get_ref (), type.get_kind ());
+ }
+
+private:
+ UintType *base;
+ TyBase *resolved;
+};
+
+} // namespace TyTy
+} // namespace Rust
+
+#endif // RUST_TYTY_RULES
diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h
new file mode 100644
index 0000000..68a8a43
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty-visitor.h
@@ -0,0 +1,42 @@
+// 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_TYTY_VISITOR
+#define RUST_TYTY_VISITOR
+
+#include "rust-tyty.h"
+
+namespace Rust {
+namespace TyTy {
+
+class TyVisitor
+{
+public:
+ virtual void visit (UnitType &type) {}
+ virtual void visit (InferType &type) {}
+ virtual void visit (FnType &type) {}
+ virtual void visit (ParamType &type) {}
+ virtual void visit (BoolType &type) {}
+ virtual void visit (IntType &type) {}
+ virtual void visit (UintType &type) {}
+};
+
+} // namespace TyTy
+} // namespace Rust
+
+#endif // RUST_TYTY_VISITOR
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
new file mode 100644
index 0000000..2124408
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -0,0 +1,223 @@
+// 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/>.
+
+#include "rust-tyty.h"
+#include "rust-tyty-visitor.h"
+#include "rust-tyty-call.h"
+#include "rust-hir-type-check-expr.h"
+#include "rust-tyty-rules.h"
+
+namespace Rust {
+namespace TyTy {
+
+void
+UnitType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+UnitType::as_string () const
+{
+ return "()";
+}
+
+TyBase *
+UnitType::combine (TyBase *other)
+{
+ UnitRules r (this);
+ return r.combine (other);
+}
+
+void
+InferType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+InferType::as_string () const
+{
+ return "[_]";
+}
+
+TyBase *
+InferType::combine (TyBase *other)
+{
+ InferRules r (this);
+ return r.combine (other);
+}
+
+void
+FnType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+FnType::as_string () const
+{
+ std::string params_str = "";
+ for (auto &param : params)
+ {
+ params_str += param->as_string ();
+ params_str += ",";
+ }
+
+ std::string ret_str = type->as_string ();
+ return "fn (" + params_str + ") -> " + ret_str;
+}
+
+TyBase *
+FnType::combine (TyBase *other)
+{
+ FnRules r (this);
+ return r.combine (other);
+}
+
+void
+ParamType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+ParamType::as_string () const
+{
+ return "(" + type->as_string () + ")";
+}
+
+TyBase *
+ParamType::combine (TyBase *other)
+{
+ ParamRules r (this);
+ return r.combine (other);
+}
+
+void
+BoolType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+BoolType::as_string () const
+{
+ return "bool";
+}
+
+TyBase *
+BoolType::combine (TyBase *other)
+{
+ BoolRules r (this);
+ return r.combine (other);
+}
+
+void
+IntType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+IntType::as_string () const
+{
+ switch (int_kind)
+ {
+ case I8:
+ return "i8";
+ case I16:
+ return "i16";
+ case I32:
+ return "i32";
+ }
+ gcc_unreachable ();
+ return "__unknown_int_type";
+}
+
+TyBase *
+IntType::combine (TyBase *other)
+{
+ IntRules r (this);
+ return r.combine (other);
+}
+
+void
+UintType::accept_vis (TyVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+UintType::as_string () const
+{
+ switch (uint_kind)
+ {
+ case U8:
+ return "u8";
+ case U16:
+ return "u16";
+ case U32:
+ return "u32";
+ }
+ gcc_unreachable ();
+ return "__unknown_uint_type";
+}
+
+TyBase *
+UintType::combine (TyBase *other)
+{
+ UintRules r (this);
+ return r.combine (other);
+}
+
+void
+TypeCheckCallExpr::visit (FnType &type)
+{
+ if (call.num_params () != type.num_params ())
+ {
+ rust_error_at (call.get_locus (), "differing number of arguments");
+ return;
+ }
+
+ size_t i = 0;
+ call.iterate_params ([&] (HIR::Expr *p) mutable -> bool {
+ TyBase *pt = type.param_at (i);
+ auto t = Resolver::TypeCheckExpr::Resolve (p);
+ if (t == nullptr)
+ {
+ rust_error_at (p->get_locus_slow (), "failed to resolve type");
+ return false;
+ }
+
+ auto res = pt->combine (t);
+ if (res == nullptr)
+ return false;
+
+ i++;
+ return true;
+ });
+
+ if (i != call.num_params ())
+ return;
+
+ resolved = type.get_return_type ();
+}
+
+} // namespace TyTy
+} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
new file mode 100644
index 0000000..688643c
--- /dev/null
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -0,0 +1,208 @@
+// 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_TYTY
+#define RUST_TYTY
+
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace TyTy {
+
+// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variants
+enum TypeKind
+{
+ INFER,
+ ADT,
+ STR,
+ REF,
+ PARAM,
+ ARRAY,
+ FNDEF,
+ TUPLE,
+ BOOL,
+ CHAR,
+ INT,
+ UINT,
+ FLOAT,
+ UNIT,
+ // there are more to add...
+};
+
+class TyVisitor;
+class TyBase
+{
+public:
+ ~TyBase () {}
+
+ HirId get_ref () const { return ref; }
+
+ virtual void accept_vis (TyVisitor &vis) = 0;
+
+ virtual bool is_unit () const { return false; }
+
+ virtual std::string as_string () const = 0;
+
+ virtual TyBase *combine (TyBase *other) = 0;
+
+protected:
+ TyBase (HirId ref, TypeKind kind) : kind (kind), ref (ref) {}
+
+ TypeKind kind;
+ HirId ref;
+};
+
+class InferType : public TyBase
+{
+public:
+ InferType (HirId ref) : TyBase (ref, TypeKind::INFER) {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ bool is_unit () const override { return true; }
+
+ std::string as_string () const override;
+
+ TyBase *combine (TyBase *other) override;
+};
+
+class UnitType : public TyBase
+{
+public:
+ UnitType (HirId ref) : TyBase (ref, TypeKind::UNIT) {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ bool is_unit () const override { return true; }
+
+ std::string as_string () const override;
+
+ TyBase *combine (TyBase *other) override;
+};
+
+class FnType : public TyBase
+{
+public:
+ FnType (HirId ref, std::vector<TyBase *> params, TyBase *type)
+ : TyBase (ref, TypeKind::FNDEF), params (params), type (type)
+ {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ std::string as_string () const override;
+
+ TyBase *return_type () { return type; }
+
+ TyBase *combine (TyBase *other) override;
+
+ size_t num_params () const { return params.size (); }
+
+ TyBase *param_at (size_t idx) { return params[idx]; }
+
+ TyBase *get_return_type () { return type; }
+
+private:
+ std::vector<TyBase *> params;
+ TyBase *type;
+};
+
+class ParamType : public TyBase
+{
+public:
+ ParamType (HirId ref, TyBase *type)
+ : TyBase (ref, TypeKind::PARAM), type (type)
+ {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ std::string as_string () const override;
+
+ TyBase *combine (TyBase *other) override;
+
+private:
+ TyBase *type;
+};
+
+class BoolType : public TyBase
+{
+public:
+ BoolType (HirId ref) : TyBase (ref, TypeKind::BOOL) {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ std::string as_string () const override;
+
+ TyBase *combine (TyBase *other) override;
+};
+
+class IntType : public TyBase
+{
+public:
+ enum IntKind
+ {
+ I8,
+ I16,
+ I32,
+ };
+
+ IntType (HirId ref, IntKind kind)
+ : TyBase (ref, TypeKind::INT), int_kind (kind)
+ {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ std::string as_string () const override;
+
+ TyBase *combine (TyBase *other) override;
+
+ IntKind get_kind () const { return int_kind; }
+
+private:
+ IntKind int_kind;
+};
+
+class UintType : public TyBase
+{
+public:
+ enum UintKind
+ {
+ U8,
+ U16,
+ U32,
+ };
+
+ UintType (HirId ref, UintKind kind)
+ : TyBase (ref, TypeKind::UINT), uint_kind (kind)
+ {}
+
+ void accept_vis (TyVisitor &vis) override;
+
+ std::string as_string () const override;
+
+ TyBase *combine (TyBase *other) override;
+
+ UintKind get_kind () const { return uint_kind; }
+
+private:
+ UintKind uint_kind;
+};
+
+} // namespace TyTy
+} // namespace Rust
+
+#endif // RUST_TYTY
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 094d0e3..70c59f3 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -133,6 +133,8 @@ Mappings::get_current_crate ()
hirIdIter[currentCrateNum] = UNKNOWN_HIRID;
nodeIdIter[currentCrateNum] = UNKNOWN_NODEID;
localIdIter[currentCrateNum] = UNKNOWN_LOCAL_DEFID;
+ nodeIdToHirMappings[currentCrateNum] = {};
+ locations[currentCrateNum] = {};
}
return currentCrateNum;
@@ -157,7 +159,7 @@ Mappings::get_next_hir_id (CrateNum crateNum)
auto id = it->second + 1;
hirIdIter[crateNum] = id;
- return id++;
+ return id;
}
LocalDefId
@@ -238,6 +240,7 @@ Mappings::insert_hir_item (CrateNum crateNum, HirId id, HIR::Item *item)
rust_assert (lookup_hir_item (crateNum, id) == nullptr);
hirItemMappings[crateNum][id] = item;
+ nodeIdToHirMappings[crateNum][item->get_mappings ().get_nodeid ()] = id;
}
HIR::Item *
@@ -260,6 +263,8 @@ Mappings::insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr)
rust_assert (lookup_hir_expr (crateNum, id) == nullptr);
hirExprMappings[crateNum][id] = expr;
+ nodeIdToHirMappings[crateNum][expr->get_mappings ().get_nodeid ()] = id;
+ insert_location (crateNum, id, expr->get_locus_slow ());
}
HIR::Expr *
@@ -277,6 +282,29 @@ Mappings::lookup_hir_expr (CrateNum crateNum, HirId id)
}
void
+Mappings::insert_hir_type (CrateNum crateNum, HirId id, HIR::Type *type)
+{
+ rust_assert (lookup_hir_type (crateNum, id) == nullptr);
+
+ hirTypeMappings[crateNum][id] = type;
+ nodeIdToHirMappings[crateNum][type->get_mappings ().get_nodeid ()] = id;
+}
+
+HIR::Type *
+Mappings::lookup_hir_type (CrateNum crateNum, HirId id)
+{
+ auto it = hirTypeMappings.find (crateNum);
+ if (it == hirTypeMappings.end ())
+ return nullptr;
+
+ auto iy = it->second.find (id);
+ if (iy == it->second.end ())
+ return nullptr;
+
+ return iy->second;
+}
+
+void
Mappings::insert_local_defid_mapping (CrateNum crateNum, LocalDefId id,
HIR::Item *item)
{
@@ -314,5 +342,40 @@ Mappings::walk_local_defids_for_crate (CrateNum crateNum,
}
}
+bool
+Mappings::lookup_node_to_hir (CrateNum crate, NodeId id, HirId *ref)
+{
+ auto it = nodeIdToHirMappings.find (crate);
+ if (it == nodeIdToHirMappings.end ())
+ return false;
+
+ auto iy = it->second.find (id);
+ if (iy == it->second.end ())
+ return false;
+
+ *ref = iy->second;
+ return true;
+}
+
+void
+Mappings::insert_location (CrateNum crate, HirId id, Location locus)
+{
+ locations[crate][id] = locus;
+}
+
+Location
+Mappings::lookup_location (CrateNum crate, HirId id)
+{
+ auto it = locations.find (crate);
+ if (it == locations.end ())
+ return Location ();
+
+ auto iy = it->second.find (id);
+ if (iy == it->second.end ())
+ return Location ();
+
+ return iy->second;
+}
+
} // namespace Analysis
} // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 8929ca4..7fc8777 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -20,6 +20,7 @@
#define RUST_HIR_MAP_H
#include "rust-system.h"
+#include "rust-location.h"
#include "rust-ast-full-decls.h"
#include "rust-hir-full-decls.h"
@@ -40,11 +41,11 @@ typedef uint64_t DefId;
#define DEF_ID_CRATE_MASK 0xFFFFFFFF00000000
#define DEF_ID_LOCAL_DEF_MASK 0x00000000FFFFFFFF
-#define UNKNOWN_CREATENUM ((uint32_t) (-1))
-#define UNKNOWN_NODEID ((uint32_t) (-1))
-#define UNKNOWN_HIRID ((uint32_t) (-1))
-#define UNKNOWN_LOCAL_DEFID ((uint32_t) (-1))
-#define UNKNOWN_DEFID ((uint64_t) (-1))
+#define UNKNOWN_CREATENUM ((uint32_t) (0))
+#define UNKNOWN_NODEID ((uint32_t) (0))
+#define UNKNOWN_HIRID ((uint32_t) (0))
+#define UNKNOWN_LOCAL_DEFID ((uint32_t) (0))
+#define UNKNOWN_DEFID ((uint64_t) (0))
namespace Analysis {
@@ -86,7 +87,10 @@ public:
NodeId get_next_node_id () { return get_next_node_id (get_current_crate ()); }
NodeId get_next_node_id (CrateNum crateNum);
+
+ HirId get_next_hir_id () { return get_next_hir_id (get_current_crate ()); }
HirId get_next_hir_id (CrateNum crateNum);
+
LocalDefId get_next_localdef_id (CrateNum crateNum);
AST::Crate *get_ast_crate (CrateNum crateNum);
@@ -108,9 +112,21 @@ public:
void insert_hir_expr (CrateNum crateNum, HirId id, HIR::Expr *expr);
HIR::Expr *lookup_hir_expr (CrateNum crateNum, HirId id);
+ void insert_hir_type (CrateNum crateNum, HirId id, HIR::Type *type);
+ HIR::Type *lookup_hir_type (CrateNum crateNum, HirId id);
+
void walk_local_defids_for_crate (CrateNum crateNum,
std::function<bool (HIR::Item *)> cb);
+ bool lookup_node_to_hir (CrateNum crate, NodeId id, HirId *ref);
+
+ void insert_location (CrateNum crate, HirId id, Location locus);
+ Location lookup_location (CrateNum crate, HirId id);
+ Location lookup_location (HirId id)
+ {
+ return lookup_location (get_current_crate (), id);
+ }
+
private:
Mappings ();
@@ -127,8 +143,12 @@ private:
std::map<DefId, HIR::Item *> defIdMappings;
std::map<CrateNum, std::map<LocalDefId, HIR::Item *> > localDefIdMappings;
std::map<CrateNum, std::map<HirId, HIR::Item *> > hirItemMappings;
+ std::map<CrateNum, std::map<HirId, HIR::Type *> > hirTypeMappings;
std::map<CrateNum, std::map<HirId, HIR::Expr *> > hirExprMappings;
+ // location info
+ std::map<CrateNum, std::map<NodeId, Location> > locations;
+
// reverse mappings
std::map<CrateNum, std::map<NodeId, HirId> > nodeIdToHirMappings;
};
diff --git a/gcc/rust/util/rust-inference-var.h b/gcc/rust/util/rust-inference-var.h
deleted file mode 100644
index 87decd5..0000000
--- a/gcc/rust/util/rust-inference-var.h
+++ /dev/null
@@ -1,112 +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/>.
-
-#ifndef RUST_HIR_INFERENCE_VAR
-#define RUST_HIR_INFERENCE_VAR
-
-#include "rust-system.h"
-#include "rust-hir-full-decls.h"
-
-namespace Rust {
-namespace HIR {
-
-class GeneralInferenceVariable;
-class IntegralInferenceVariable;
-class FloatInferenceVariable;
-class InferenceVarVisitor
-{
-public:
- virtual void visit (GeneralInferenceVariable &v) {}
- virtual void visit (IntegralInferenceVariable &v) {}
- virtual void visit (FloatInferenceVariable &v) {}
-};
-
-// Base
-class InferenceVariable
-{
-public:
- virtual ~InferenceVariable () {}
-
- virtual std::string as_string () const = 0;
-
- HIR::Type *get_type () { return resolved; }
-
- void set_type (HIR::Type *type) { resolved = type; }
-
- bool was_resolved () { return resolved != nullptr; }
-
- virtual void accept_vis (InferenceVarVisitor &vis) = 0;
-
-protected:
- InferenceVariable () : resolved (nullptr) {}
-
- HIR::Type *resolved;
-};
-
-class GeneralInferenceVariable : public InferenceVariable
-{
-public:
- GeneralInferenceVariable () : InferenceVariable () {}
-
- void accept_vis (InferenceVarVisitor &vis) { vis.visit (*this); };
-
- std::string as_string () const override
- {
- if (resolved)
- return resolved->as_string ();
-
- return "[G::?T]";
- }
-};
-
-class IntegralInferenceVariable : public InferenceVariable
-{
-public:
- IntegralInferenceVariable () : InferenceVariable () {}
-
- void accept_vis (InferenceVarVisitor &vis) { vis.visit (*this); };
-
- std::string as_string () const override
- {
- if (resolved)
- return resolved->as_string ();
-
- return "[I::?T]";
- }
-};
-
-class FloatInferenceVariable : public InferenceVariable
-{
-public:
- FloatInferenceVariable () : InferenceVariable () {}
-
- void accept_vis (InferenceVarVisitor &vis) { vis.visit (*this); };
-
- std::string as_string () const override
- {
- if (resolved)
- return resolved->as_string ();
-
- return "[F::?T]";
- }
-};
-
-} // namespace HIR
-} // namespace Rust
-
-#endif // RUST_HIR_INFERENCE_VAR