aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-01-18 14:51:36 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-01-20 09:59:22 +0000
commit9a942d6fbd0cc087cbc801ce4681a498e59dce2c (patch)
tree5198e76f054e741f5ba9793e111bfd63be88e80d /gcc
parent89631998d2ffda0c0c05066c148c6fc19398da5c (diff)
downloadgcc-9a942d6fbd0cc087cbc801ce4681a498e59dce2c.zip
gcc-9a942d6fbd0cc087cbc801ce4681a498e59dce2c.tar.gz
gcc-9a942d6fbd0cc087cbc801ce4681a498e59dce2c.tar.bz2
Add in TupleStruct support
This adds in tuple struct support with name and type resolution. The arguments and number of arguments are validated against. Test cases added for those errors too.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-item.h25
-rw-r--r--gcc/rust/backend/rust-compile-expr.h19
-rw-r--r--gcc/rust/backend/rust-compile-item.h47
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc12
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.h2
-rw-r--r--gcc/rust/backend/rust-compile.cc47
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h61
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h38
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h1
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h12
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h7
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h23
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h29
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h2
-rw-r--r--gcc/rust/typecheck/rust-tyty-call.h5
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h5
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc64
-rw-r--r--gcc/rust/typecheck/rust-tyty.h12
-rw-r--r--gcc/testsuite/rust.test/compilable/tuple_struct1.rs5
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/func2.rs7
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/func3.rs7
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/tuple_struct1.rs8
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/tuple_struct2.rs5
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/tuple_struct3.rs5
24 files changed, 359 insertions, 89 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 6ebb2e9..a1b505d 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1817,13 +1817,14 @@ public:
Visibility vis,
std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
: outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
- field_name (std::move (field_name)), field_type (std::move (field_type))
+ field_name (std::move (field_name)), field_type (std::move (field_type)),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
// Copy constructor
StructField (StructField const &other)
: outer_attrs (other.outer_attrs), visibility (other.visibility),
- field_name (other.field_name)
+ field_name (other.field_name), node_id (other.node_id)
{
// guard to prevent null dereference
if (other.field_type != nullptr)
@@ -1838,6 +1839,7 @@ public:
field_name = other.field_name;
visibility = other.visibility;
outer_attrs = other.outer_attrs;
+ node_id = other.node_id;
// guard to prevent null dereference
if (other.field_type != nullptr)
@@ -1959,6 +1961,7 @@ private:
std::unique_ptr<Type> field_type;
// should this store location info?
+ NodeId node_id;
public:
// Returns whether tuple field has outer attributes.
@@ -1972,12 +1975,14 @@ public:
TupleField (std::unique_ptr<Type> field_type, Visibility vis,
std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
: outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
- field_type (std::move (field_type))
+ field_type (std::move (field_type)),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
{}
// Copy constructor with clone
TupleField (TupleField const &other)
- : outer_attrs (other.outer_attrs), visibility (other.visibility)
+ : outer_attrs (other.outer_attrs), visibility (other.visibility),
+ node_id (other.node_id)
{
// guard to prevent null dereference (only required if error)
if (other.field_type != nullptr)
@@ -1991,6 +1996,7 @@ public:
{
visibility = other.visibility;
outer_attrs = other.outer_attrs;
+ node_id = other.node_id;
// guard to prevent null dereference (only required if error)
if (other.field_type != nullptr)
@@ -2016,6 +2022,8 @@ public:
std::string as_string () const;
+ NodeId get_node_id () const { return node_id; };
+
// TODO: this mutable getter seems really dodgy. Think up better way.
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
@@ -2053,6 +2061,15 @@ public:
std::vector<TupleField> &get_fields () { return fields; }
const std::vector<TupleField> &get_fields () const { return fields; }
+ void iterate (std::function<bool (TupleField &)> cb)
+ {
+ for (auto &field : fields)
+ {
+ if (!cb (field))
+ return;
+ }
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 98e8ee1..8b99574 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -86,24 +86,7 @@ public:
ctx->add_statement (s);
}
- void visit (HIR::CallExpr &expr)
- {
- Bexpression *fn = ResolvePathRef::Compile (expr.get_fnexpr (), ctx);
- rust_assert (fn != nullptr);
-
- std::vector<Bexpression *> 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, args,
- nullptr, expr.get_locus ());
- }
+ void visit (HIR::CallExpr &expr);
void visit (HIR::IdentifierExpr &expr)
{
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index a367ac7..c8cffc7 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -37,35 +37,32 @@ public:
item->accept_vis (compiler);
}
- virtual ~CompileItem () {}
-
- void visit (HIR::StructStruct &struct_decl)
+ void visit (HIR::TupleStruct &struct_decl)
{
- std::vector<Backend::Btyped_identifier> fields;
- struct_decl.iterate ([&] (HIR::StructField &field) mutable -> bool {
- TyTy::TyBase *resolved_type = nullptr;
- bool ok
- = ctx->get_tyctx ()->lookup_type (field.get_mappings ().get_hirid (),
- &resolved_type);
- rust_assert (ok);
+ TyTy::TyBase *resolved = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (
+ struct_decl.get_mappings ().get_hirid (), &resolved))
+ {
+ rust_fatal_error (struct_decl.get_locus (),
+ "Failed to lookup type for struct decl");
+ return;
+ }
- Btype *compiled_field_ty
- = TyTyCompile::compile (ctx->get_backend (), resolved_type);
+ TyTyResolveCompile::compile (ctx, resolved);
+ }
- Backend::Btyped_identifier f (field.field_name, compiled_field_ty,
- field.get_locus ());
- fields.push_back (std::move (f));
- return true;
- });
+ void visit (HIR::StructStruct &struct_decl)
+ {
+ TyTy::TyBase *resolved = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (
+ struct_decl.get_mappings ().get_hirid (), &resolved))
+ {
+ rust_fatal_error (struct_decl.get_locus (),
+ "Failed to lookup type for struct decl");
+ return;
+ }
- Btype *struct_type_record = ctx->get_backend ()->struct_type (fields);
- Btype *named_struct
- = ctx->get_backend ()->named_type (struct_decl.get_identifier (),
- struct_type_record,
- struct_decl.get_locus ());
- ctx->push_type (named_struct);
- ctx->insert_compiled_type (struct_decl.get_mappings ().get_hirid (),
- named_struct);
+ TyTyResolveCompile::compile (ctx, resolved);
}
void visit (HIR::StaticItem &var)
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 374f8a0..37285b7 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -32,7 +32,6 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
if (!ctx->get_resolver ()->lookup_resolved_name (
expr.get_mappings ().get_nodeid (), &ref_node_id))
{
- rust_fatal_error (expr.get_locus (), "failed to look up resolved name");
return;
}
@@ -40,7 +39,7 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
if (!ctx->get_mappings ()->lookup_node_to_hir (
expr.get_mappings ().get_crate_num (), ref_node_id, &ref))
{
- rust_fatal_error (expr.get_locus (), "reverse lookup failure");
+ rust_error_at (expr.get_locus (), "reverse lookup failure");
return;
}
@@ -54,14 +53,14 @@ ResolvePathRef::visit (HIR::PathInExpression &expr)
expr.get_mappings ().get_crate_num (), ref);
if (resolved_item == nullptr)
{
- rust_fatal_error (expr.get_locus (), "failed to lookup forward decl");
+ rust_error_at (expr.get_locus (), "failed to lookup forward decl");
return;
}
CompileItem::compile (resolved_item, ctx);
if (!ctx->lookup_function_decl (ref, &fn))
{
- rust_fatal_error (expr.get_locus (), "forward decl was not compiled");
+ rust_error_at (expr.get_locus (), "forward decl was not compiled");
return;
}
}
@@ -78,7 +77,6 @@ ResolvePathType::visit (HIR::PathInExpression &expr)
if (!ctx->get_resolver ()->lookup_resolved_type (
expr.get_mappings ().get_nodeid (), &ref_node_id))
{
- rust_fatal_error (expr.get_locus (), "failed to look up resolved name");
return;
}
@@ -86,14 +84,14 @@ ResolvePathType::visit (HIR::PathInExpression &expr)
if (!ctx->get_mappings ()->lookup_node_to_hir (
expr.get_mappings ().get_crate_num (), ref_node_id, &ref))
{
- rust_fatal_error (expr.get_locus (), "reverse lookup failure");
+ rust_error_at (expr.get_locus (), "reverse lookup failure");
return;
}
// assumes paths are functions for now
if (!ctx->lookup_compiled_types (ref, &resolved))
{
- rust_fatal_error (expr.get_locus (), "forward decl was not compiled");
+ rust_error_at (expr.get_locus (), "forward decl was not compiled");
return;
}
}
diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h
index a5543d2..2f3cb68 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.h
+++ b/gcc/rust/backend/rust-compile-resolve-path.h
@@ -32,7 +32,6 @@ public:
{
ResolvePathRef resolver (ctx);
expr->accept_vis (resolver);
- rust_assert (resolver.resolved != nullptr);
return resolver.resolved;
}
@@ -51,7 +50,6 @@ public:
{
ResolvePathType resolver (ctx);
expr->accept_vis (resolver);
- rust_assert (resolver.resolved != nullptr);
return resolver.resolved;
}
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 772d975..6519a47 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -48,6 +48,53 @@ CompileCrate::go ()
CompileItem::compile (item.get (), ctx, true);
}
+// rust-compile-expr.h
+
+void
+CompileExpr::visit (HIR::CallExpr &expr)
+{
+ // this can be a function call or it can be a constructor for a tuple struct
+ Bexpression *fn = ResolvePathRef::Compile (expr.get_fnexpr (), ctx);
+ if (fn != nullptr)
+ {
+ std::vector<Bexpression *> 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, args,
+ nullptr, expr.get_locus ());
+ }
+ else
+ {
+ Btype *type = ResolvePathType::Compile (expr.get_fnexpr (), ctx);
+ if (type == nullptr)
+ {
+ rust_fatal_error (expr.get_locus (),
+ "failed to lookup type associated with call");
+ return;
+ }
+
+ // this assumes all fields are in order from type resolution and if a base
+ // struct was specified those fields are filed via accesors
+ std::vector<Bexpression *> vals;
+ expr.iterate_params ([&] (HIR::Expr *argument) mutable -> bool {
+ Bexpression *e = CompileExpr::Compile (argument, ctx);
+ vals.push_back (e);
+ return true;
+ });
+
+ translated
+ = ctx->get_backend ()->constructor_expression (type, vals,
+ expr.get_locus ());
+ }
+}
+
// rust-compile-block.h
void
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index 3cf044e..6122335 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -38,10 +38,67 @@ public:
{
ASTLoweringItem resolver;
item->accept_vis (resolver);
+
+ // this is useful for debugging
+ // if (resolver.translated == nullptr)
+ // {
+ // rust_fatal_error (item->get_locus_slow (), "failed to lower: %s",
+ // item->as_string ().c_str ());
+ // return nullptr;
+ // }
+
return resolver.translated;
}
- virtual ~ASTLoweringItem () {}
+ void visit (AST::TupleStruct &struct_decl)
+ {
+ std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+ std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+ HIR::WhereClause where_clause (std::move (where_clause_items));
+ HIR::Visibility vis = HIR::Visibility::create_public ();
+ std::vector<HIR::Attribute> outer_attrs;
+
+ std::vector<HIR::TupleField> fields;
+ struct_decl.iterate ([&] (AST::TupleField &field) mutable -> bool {
+ std::vector<HIR::Attribute> outer_attrs;
+ HIR::Visibility vis = HIR::Visibility::create_public ();
+ HIR::Type *type
+ = ASTLoweringType::translate (field.get_field_type ().get ());
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, field.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (
+ crate_num));
+
+ // FIXME
+ // AST::TupleField is missing Location info
+ Location field_locus;
+ HIR::TupleField translated_field (mapping,
+ std::unique_ptr<HIR::Type> (type), vis,
+ field_locus, outer_attrs);
+ fields.push_back (std::move (translated_field));
+ return true;
+ });
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, struct_decl.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
+ translated = new HIR::TupleStruct (mapping, std::move (fields),
+ struct_decl.get_identifier (),
+ std::move (generic_params),
+ std::move (where_clause), vis,
+ std::move (outer_attrs),
+ struct_decl.get_locus ());
+
+ mappings->insert_defid_mapping (mapping.get_defid (), translated);
+ mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (),
+ translated);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ struct_decl.get_locus ());
+ }
void visit (AST::StructStruct &struct_decl)
{
@@ -51,7 +108,7 @@ public:
HIR::Visibility vis = HIR::Visibility::create_public ();
std::vector<HIR::Attribute> outer_attrs;
- bool is_unit = false;
+ bool is_unit = struct_decl.is_unit_struct ();
std::vector<HIR::StructField> fields;
struct_decl.iterate ([&] (AST::StructField &field) mutable -> bool {
std::vector<HIR::Attribute> outer_attrs;
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index 69e39c8..6a58ca0 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -1604,7 +1604,9 @@ private:
std::unique_ptr<Type> field_type;
- // should this store location info?
+ Location locus;
+
+ Analysis::NodeMapping mappings;
public:
// Returns whether tuple field has outer attributes.
@@ -1615,16 +1617,18 @@ public:
bool has_visibility () const { return !visibility.is_error (); }
// Complete constructor
- TupleField (std::unique_ptr<Type> field_type, Visibility vis,
+ TupleField (Analysis::NodeMapping mapping, std::unique_ptr<Type> field_type,
+ Visibility vis, Location locus,
std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
: outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)),
- field_type (std::move (field_type))
+ field_type (std::move (field_type)), locus (locus), mappings (mapping)
{}
// Copy constructor with clone
TupleField (TupleField const &other)
: outer_attrs (other.outer_attrs), visibility (other.visibility),
- field_type (other.field_type->clone_type ())
+ field_type (other.field_type->clone_type ()), locus (other.locus),
+ mappings (other.mappings)
{}
~TupleField () = default;
@@ -1635,6 +1639,8 @@ public:
field_type = other.field_type->clone_type ();
visibility = other.visibility;
outer_attrs = other.outer_attrs;
+ locus = other.locus;
+ mappings = other.mappings;
return *this;
}
@@ -1646,13 +1652,13 @@ public:
// Returns whether tuple field is in an error state.
bool is_error () const { return field_type == nullptr; }
- // Creates an error state tuple field.
- static TupleField create_error ()
- {
- return TupleField (nullptr, Visibility::create_error ());
- }
-
std::string as_string () const;
+
+ Analysis::NodeMapping get_mappings () { return mappings; }
+
+ Location get_locus () const { return locus; }
+
+ std::unique_ptr<HIR::Type> &get_field_type () { return field_type; }
};
// Rust tuple declared using struct keyword HIR node
@@ -1677,6 +1683,18 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ std::vector<TupleField> &get_fields () { return fields; }
+ const std::vector<TupleField> &get_fields () const { return fields; }
+
+ void iterate (std::function<bool (TupleField &)> cb)
+ {
+ for (auto &field : fields)
+ {
+ if (!cb (field))
+ return;
+ }
+ }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 21b2194..9a7e231 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -83,7 +83,6 @@ public:
ResolveExpr::go (p, expr.get_node_id ());
return true;
});
- // resolver->insert_resolved_name(NodeId refId,NodeId defId)
}
void visit (AST::AssignmentExpr &expr)
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index b0b979f..02d6dfa 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -40,10 +40,20 @@ public:
~ResolveItem () {}
+ void visit (AST::TupleStruct &struct_decl)
+ {
+ struct_decl.iterate ([&] (AST::TupleField &field) mutable -> bool {
+ ResolveType::go (field.get_field_type ().get (),
+ struct_decl.get_node_id ());
+ return true;
+ });
+ }
+
void visit (AST::StructStruct &struct_decl)
{
struct_decl.iterate ([&] (AST::StructField &field) mutable -> bool {
- ResolveType::go (field.get_field_type ().get (), field.get_node_id ());
+ ResolveType::go (field.get_field_type ().get (),
+ struct_decl.get_node_id ());
return true;
});
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 447fe4b..47435a7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -36,6 +36,13 @@ public:
~ResolveTopLevel () {}
+ void visit (AST::TupleStruct &struct_decl)
+ {
+ resolver->get_type_scope ().insert (struct_decl.get_identifier (),
+ struct_decl.get_node_id (),
+ struct_decl.get_locus ());
+ }
+
void visit (AST::StructStruct &struct_decl)
{
resolver->get_type_scope ().insert (struct_decl.get_identifier (),
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index a49dc70..5f2477e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -77,7 +77,7 @@ public:
}
identifier += ")";
infered = new TyTy::ADTType (expr.get_mappings ().get_hirid (), identifier,
- fields);
+ true, fields);
}
void visit (HIR::ReturnExpr &expr)
@@ -94,14 +94,17 @@ public:
auto fn = expr.get_fnexpr ();
auto fn_node_id = fn->get_mappings ().get_nodeid ();
- // then lookup the reference_node_id
+ // CallExpr might be a function but it might also be a TupleStruct
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;
+ if (!resolver->lookup_resolved_type (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
@@ -109,7 +112,8 @@ public:
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");
+ rust_error_at (expr.get_locus (), "reverse lookup failure for node %u",
+ ref_node_id);
return;
}
@@ -125,6 +129,11 @@ public:
}
infered = TyTy::TypeCheckCallExpr::go (lookup, expr);
+ if (infered == nullptr)
+ {
+ rust_error_at (expr.get_locus (), "failed to lookup type to CallExpr");
+ return;
+ }
TyTy::InferType infer (expr.get_mappings ().get_hirid ());
infered = infer.combine (infered);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index ecee372..55c0d38 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -37,6 +37,32 @@ public:
item->accept_vis (resolver);
}
+ void visit (HIR::TupleStruct &struct_decl)
+ {
+ std::vector<TyTy::StructFieldType *> fields;
+
+ size_t idx = 0;
+ struct_decl.iterate ([&] (HIR::TupleField &field) mutable -> bool {
+ TyTy::TyBase *field_type
+ = TypeCheckType::Resolve (field.get_field_type ().get ());
+ TyTy::StructFieldType *ty_field
+ = new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
+ std::to_string (idx), field_type);
+ fields.push_back (ty_field);
+ context->insert_type (field.get_mappings ().get_hirid (),
+ ty_field->get_field_type ());
+ idx++;
+ return true;
+ });
+
+ TyTy::TyBase *type
+ = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
+ struct_decl.get_identifier (), true,
+ std::move (fields));
+
+ context->insert_type (struct_decl.get_mappings ().get_hirid (), type);
+ }
+
void visit (HIR::StructStruct &struct_decl)
{
std::vector<TyTy::StructFieldType *> fields;
@@ -54,7 +80,8 @@ public:
TyTy::TyBase *type
= new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
- struct_decl.get_identifier (), std::move (fields));
+ struct_decl.get_identifier (), false,
+ std::move (fields));
context->insert_type (struct_decl.get_mappings ().get_hirid (), type);
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index 8b9a77c..77dc9c0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -107,7 +107,7 @@ public:
}
identifier += ")";
translated = new TyTy::ADTType (tuple.get_mappings ().get_hirid (),
- identifier, fields);
+ identifier, true, fields);
}
void visit (HIR::TypePath &path)
diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h
index c3fcb1a..06918c2 100644
--- a/gcc/rust/typecheck/rust-tyty-call.h
+++ b/gcc/rust/typecheck/rust-tyty-call.h
@@ -41,7 +41,6 @@ public:
void visit (UnitType &type) override { gcc_unreachable (); }
void visit (InferType &type) override { gcc_unreachable (); }
void visit (StructFieldType &type) override { gcc_unreachable (); }
- void visit (ADTType &type) override { gcc_unreachable (); }
void visit (ParamType &type) override { gcc_unreachable (); }
void visit (ArrayType &type) override { gcc_unreachable (); }
void visit (BoolType &type) override { gcc_unreachable (); }
@@ -50,6 +49,10 @@ public:
void visit (FloatType &type) override { gcc_unreachable (); }
void visit (ErrorType &type) override { gcc_unreachable (); }
+ // tuple-structs
+ void visit (ADTType &type) override;
+
+ // call fns
void visit (FnType &type) override;
private:
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 5353004..0d8d856 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -438,8 +438,9 @@ public:
fields.push_back ((TyTy::StructFieldType *) combined);
}
- resolved = new TyTy::ADTType (type.get_ref (), type.get_ty_ref (),
- type.get_name (), fields);
+ resolved
+ = new TyTy::ADTType (type.get_ref (), type.get_ty_ref (),
+ type.get_name (), type.is_tuple_struct (), fields);
}
private:
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index e007c1f..7ca60c8 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -157,7 +157,8 @@ ADTType::clone ()
for (auto &f : fields)
cloned_fields.push_back ((StructFieldType *) f->clone ());
- return new ADTType (get_ref (), get_ty_ref (), get_name (), cloned_fields);
+ return new ADTType (get_ref (), get_ty_ref (), get_name (),
+ is_tuple_struct (), cloned_fields);
}
void
@@ -387,11 +388,62 @@ FloatType::clone ()
}
void
+TypeCheckCallExpr::visit (ADTType &type)
+{
+ if (!type.is_tuple_struct ())
+ {
+ rust_error_at (call.get_locus (), "Expected TupleStruct");
+ return;
+ }
+
+ if (call.num_params () != type.num_fields ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ call.num_params (), type.num_fields ());
+ return;
+ }
+
+ size_t i = 0;
+ call.iterate_params ([&] (HIR::Expr *p) mutable -> bool {
+ StructFieldType *field = type.get_field (i);
+ TyBase *field_tyty = field->get_field_type ();
+
+ TyBase *arg = Resolver::TypeCheckExpr::Resolve (p);
+ if (arg == nullptr)
+ {
+ rust_error_at (p->get_locus_slow (), "failed to resolve argument type");
+ return false;
+ }
+
+ auto res = field_tyty->combine (arg);
+ if (res == nullptr)
+ return false;
+
+ delete res;
+ i++;
+ return true;
+ });
+
+ if (i != call.num_params ())
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu", i,
+ call.num_params ());
+ return;
+ }
+
+ resolved = type.clone ();
+}
+
+void
TypeCheckCallExpr::visit (FnType &type)
{
if (call.num_params () != type.num_params ())
{
- rust_error_at (call.get_locus (), "differing number of arguments");
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu",
+ call.num_params (), type.num_params ());
return;
}
@@ -409,12 +461,18 @@ TypeCheckCallExpr::visit (FnType &type)
if (res == nullptr)
return false;
+ delete res;
i++;
return true;
});
if (i != call.num_params ())
- return;
+ {
+ rust_error_at (call.get_locus (),
+ "unexpected number of arguments %lu expected %lu", i,
+ call.num_params ());
+ return;
+ }
resolved = type.get_return_type ();
}
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index db34f7e..b0ccf24 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -169,15 +169,16 @@ private:
class ADTType : public TyBase
{
public:
- ADTType (HirId ref, std::string identifier,
+ ADTType (HirId ref, std::string identifier, bool is_tuple,
std::vector<StructFieldType *> fields)
- : TyBase (ref, ref, TypeKind::ADT), identifier (identifier), fields (fields)
+ : TyBase (ref, ref, TypeKind::ADT), identifier (identifier),
+ is_tuple (is_tuple), fields (fields)
{}
- ADTType (HirId ref, HirId ty_ref, std::string identifier,
+ ADTType (HirId ref, HirId ty_ref, std::string identifier, bool is_tuple,
std::vector<StructFieldType *> fields)
: TyBase (ref, ty_ref, TypeKind::ADT), identifier (identifier),
- fields (fields)
+ is_tuple (is_tuple), fields (fields)
{}
void accept_vis (TyVisitor &vis) override;
@@ -192,6 +193,8 @@ public:
std::string get_name () const { return identifier; }
+ bool is_tuple_struct () const { return is_tuple; }
+
StructFieldType *get_field (size_t index) { return fields.at (index); }
StructFieldType *get_field (const std::string &lookup,
@@ -218,6 +221,7 @@ public:
private:
std::string identifier;
+ bool is_tuple;
std::vector<StructFieldType *> fields;
};
diff --git a/gcc/testsuite/rust.test/compilable/tuple_struct1.rs b/gcc/testsuite/rust.test/compilable/tuple_struct1.rs
new file mode 100644
index 0000000..65e29f7
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/tuple_struct1.rs
@@ -0,0 +1,5 @@
+struct Foo(i32, i32, bool);
+
+fn main() {
+ let a = Foo(1, 2, true);
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/func2.rs b/gcc/testsuite/rust.test/fail_compilation/func2.rs
new file mode 100644
index 0000000..eae433a
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/func2.rs
@@ -0,0 +1,7 @@
+fn test(a: i32, b: i32) -> i32 {
+ a + b
+}
+
+fn main() {
+ let a = test(1);
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/func3.rs b/gcc/testsuite/rust.test/fail_compilation/func3.rs
new file mode 100644
index 0000000..781caf7
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/func3.rs
@@ -0,0 +1,7 @@
+fn test(a: i32, b: i32) -> i32 {
+ a + b
+}
+
+fn main() {
+ let a = test(1, true);
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/tuple_struct1.rs b/gcc/testsuite/rust.test/fail_compilation/tuple_struct1.rs
new file mode 100644
index 0000000..0df07d9
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/tuple_struct1.rs
@@ -0,0 +1,8 @@
+struct Foo {
+ one: i32,
+ two: i32,
+}
+
+fn main() {
+ let a = Foo(1, 2);
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/tuple_struct2.rs b/gcc/testsuite/rust.test/fail_compilation/tuple_struct2.rs
new file mode 100644
index 0000000..6c3c0ab
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/tuple_struct2.rs
@@ -0,0 +1,5 @@
+struct Bar(i32, i32, bool);
+
+fn main() {
+ let a = Bar(1, 2);
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/tuple_struct3.rs b/gcc/testsuite/rust.test/fail_compilation/tuple_struct3.rs
new file mode 100644
index 0000000..832df8b
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/tuple_struct3.rs
@@ -0,0 +1,5 @@
+struct Foo(i32, i32, bool);
+
+fn main() {
+ let c = Foo(1, 2f32, true);
+}