aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
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);
+}