aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-context.h32
-rw-r--r--gcc/rust/backend/rust-compile-expr.h24
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.h6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h22
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h20
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h20
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h59
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc3
-rw-r--r--gcc/rust/typecheck/rust-tyty.h3
-rw-r--r--gcc/testsuite/rust.test/compilable/tuple1.rs5
-rw-r--r--gcc/testsuite/rust.test/compilable/tuple2.rs4
-rw-r--r--gcc/testsuite/rust.test/fail_compilation/tuple1.rs5
13 files changed, 184 insertions, 22 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index fb227ac..5288e51 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -238,10 +238,34 @@ public:
void visit (TyTy::ADTType &type) override
{
- ::Btype *compiled_type = nullptr;
- bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type);
- rust_assert (ok);
- translated = compiled_type;
+ bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &translated);
+ if (ok)
+ return;
+
+ // create implicit struct
+ std::vector<Backend::Btyped_identifier> fields;
+ for (size_t i = 0; i < type.num_fields (); i++)
+ {
+ TyTy::StructFieldType *field = type.get_field (i);
+ Btype *compiled_field_ty
+ = TyTyCompile::compile (ctx->get_backend (),
+ field->get_field_type ());
+
+ Backend::Btyped_identifier f (field->get_name (), compiled_field_ty,
+ ctx->get_mappings ()->lookup_location (
+ type.get_ty_ref ()));
+ fields.push_back (std::move (f));
+ }
+
+ Btype *struct_type_record = ctx->get_backend ()->struct_type (fields);
+ Btype *named_struct
+ = ctx->get_backend ()->named_type (type.get_name (), struct_type_record,
+ ctx->get_mappings ()->lookup_location (
+ type.get_ty_ref ()));
+
+ ctx->push_type (named_struct);
+ ctx->insert_compiled_type (type.get_ty_ref (), named_struct);
+ translated = named_struct;
}
void visit (TyTy::ArrayType &type) override
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index d38ef04..0d3d9e8 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -46,7 +46,29 @@ public:
return;
}
- gcc_unreachable ();
+ TyTy::TyBase *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (expr.get_mappings ().get_hirid (),
+ &tyty))
+ {
+ rust_fatal_error (expr.get_locus (),
+ "did not resolve type for this TupleExpr");
+ return;
+ }
+
+ Btype *tuple_type = TyTyResolveCompile::compile (ctx, tyty);
+ rust_assert (tuple_type != nullptr);
+
+ // this assumes all fields are in order from type resolution
+ std::vector<Bexpression *> vals;
+ for (auto &elem : expr.get_tuple_elems ())
+ {
+ auto e = CompileExpr::Compile (elem.get (), ctx);
+ vals.push_back (e);
+ }
+
+ translated
+ = ctx->get_backend ()->constructor_expression (tuple_type, vals,
+ expr.get_locus ());
}
void visit (HIR::ReturnExpr &expr)
diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h
index f8c851c..fc369c3 100644
--- a/gcc/rust/hir/tree/rust-hir-type.h
+++ b/gcc/rust/hir/tree/rust-hir-type.h
@@ -393,6 +393,12 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ std::vector<std::unique_ptr<Type> > &get_elems () { return elems; }
+ const std::vector<std::unique_ptr<Type> > &get_elems () const
+ {
+ return elems;
+ }
+
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 abab268..83fb935 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -40,7 +40,8 @@ public:
if (expr.is_unit ())
return;
- gcc_unreachable ();
+ for (auto &elem : expr.get_tuple_elems ())
+ ResolveExpr::go (elem.get (), expr.get_node_id ());
}
void visit (AST::PathInExpression &expr)
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index ae352b9..20fb0b6 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -31,13 +31,7 @@ public:
static void go (AST::Type *type, NodeId parent)
{
ResolveType resolver (parent);
-
type->accept_vis (resolver);
- if (resolver.resolved_node == UNKNOWN_NODEID)
- {
- rust_error_at (resolver.locus, "failed to resolve type %s",
- type->as_string ().c_str ());
- }
};
void visit (AST::TupleType &tuple)
@@ -48,21 +42,23 @@ public:
return;
}
- // TODO see github #78
- gcc_unreachable ();
+ for (auto &elem : tuple.get_elems ())
+ ResolveType::go (elem.get (), tuple.get_node_id ());
}
void visit (AST::TypePath &path)
{
// this will need changed to handle mod/crate/use globs and look
// at the segments in granularity
- if (resolver->get_type_scope ().lookup (path.as_string (), &resolved_node))
+ if (!resolver->get_type_scope ().lookup (path.as_string (), &resolved_node))
{
- resolver->insert_resolved_type (path.get_node_id (), resolved_node);
- resolver->insert_new_definition (path.get_node_id (),
- Definition{path.get_node_id (),
- parent});
+ rust_error_at (path.get_locus (), "failed to resolve TypePath: %s",
+ path.as_string ().c_str ());
+ return;
}
+ resolver->insert_resolved_type (path.get_node_id (), resolved_node);
+ resolver->insert_new_definition (path.get_node_id (),
+ Definition{path.get_node_id (), parent});
}
void visit (AST::ArrayType &type)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 4b474ae..19c6ed4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -59,7 +59,25 @@ public:
return;
}
- gcc_unreachable ();
+ size_t index = 0;
+ std::string identifier = "(";
+ std::vector<TyTy::StructFieldType *> fields;
+ for (auto &elem : expr.get_tuple_elems ())
+ {
+ auto field_ty = TypeCheckExpr::Resolve (elem.get ());
+ identifier += field_ty->as_string ();
+ if ((index + 1) < expr.get_tuple_elems ().size ())
+ identifier += ",";
+
+ auto field_tyty
+ = new TyTy::StructFieldType (elem->get_mappings ().get_hirid (),
+ std::to_string (index), field_ty);
+ fields.push_back (field_tyty);
+ index++;
+ }
+ identifier += ")";
+ infered = new TyTy::ADTType (expr.get_mappings ().get_hirid (), identifier,
+ fields);
}
void visit (HIR::ReturnExpr &expr)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index 1a01774..8b9a77c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -89,7 +89,25 @@ public:
return;
}
- gcc_unreachable ();
+ size_t index = 0;
+ std::string identifier = "(";
+ std::vector<TyTy::StructFieldType *> fields;
+ for (auto &elem : tuple.get_elems ())
+ {
+ auto field_ty = TypeCheckType::Resolve (elem.get ());
+ identifier += field_ty->as_string ();
+ if ((index + 1) < tuple.get_elems ().size ())
+ identifier += ",";
+
+ auto field_tyty
+ = new TyTy::StructFieldType (elem->get_mappings ().get_hirid (),
+ std::to_string (index), field_ty);
+ fields.push_back (field_tyty);
+ index++;
+ }
+ identifier += ")";
+ translated = new TyTy::ADTType (tuple.get_mappings ().get_hirid (),
+ identifier, fields);
}
void visit (HIR::TypePath &path)
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 3bea57d..5353004 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -198,6 +198,16 @@ public:
return resolved;
}
+ void visit (StructFieldType &type)
+ {
+ TyBase *ty = base->get_field_type ()->combine (type.get_field_type ());
+ if (ty == nullptr)
+ return;
+
+ resolved = new TyTy::StructFieldType (type.get_ref (), type.get_ty_ref (),
+ type.get_name (), ty);
+ }
+
private:
StructFieldType *base;
};
@@ -387,6 +397,55 @@ private:
FloatType *base;
};
+class ADTRules : protected BaseRules
+{
+public:
+ ADTRules (ADTType *base) : BaseRules (base), base (base) {}
+
+ TyBase *combine (TyBase *other)
+ {
+ other->accept_vis (*this);
+ return resolved;
+ }
+
+ void visit (ADTType &type)
+ {
+ if (base->num_fields () != type.num_fields ())
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ if (base->get_name ().compare (type.get_name ()) != 0)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ std::vector<TyTy::StructFieldType *> fields;
+ for (size_t i = 0; i < type.num_fields (); ++i)
+ {
+ TyTy::StructFieldType *base_field = base->get_field (i);
+ TyTy::StructFieldType *other_field = type.get_field (i);
+
+ TyBase *combined = base_field->combine (other_field);
+ if (combined == nullptr)
+ {
+ BaseRules::visit (type);
+ return;
+ }
+
+ fields.push_back ((TyTy::StructFieldType *) combined);
+ }
+
+ resolved = new TyTy::ADTType (type.get_ref (), type.get_ty_ref (),
+ type.get_name (), fields);
+ }
+
+private:
+ ADTType *base;
+};
+
} // namespace TyTy
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 6696aa7..e007c1f 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -146,7 +146,8 @@ ADTType::as_string () const
TyBase *
ADTType::combine (TyBase *other)
{
- return nullptr;
+ ADTRules r (this);
+ return r.combine (other);
}
TyBase *
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 2a6d2a8..1e529bd 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -206,6 +206,9 @@ public:
TyBase *clone () final override;
+ std::vector<StructFieldType *> &get_fields () { return fields; }
+ const std::vector<StructFieldType *> &get_fields () const { return fields; }
+
private:
std::string identifier;
std::vector<StructFieldType *> fields;
diff --git a/gcc/testsuite/rust.test/compilable/tuple1.rs b/gcc/testsuite/rust.test/compilable/tuple1.rs
new file mode 100644
index 0000000..8b89601
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/tuple1.rs
@@ -0,0 +1,5 @@
+fn main() {
+ let a: (i32, bool) = (123, true);
+ let b;
+ b = (456, 5f32);
+}
diff --git a/gcc/testsuite/rust.test/compilable/tuple2.rs b/gcc/testsuite/rust.test/compilable/tuple2.rs
new file mode 100644
index 0000000..51333d8
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/tuple2.rs
@@ -0,0 +1,4 @@
+fn main() {
+ let a = 123;
+ let b = (a,);
+}
diff --git a/gcc/testsuite/rust.test/fail_compilation/tuple1.rs b/gcc/testsuite/rust.test/fail_compilation/tuple1.rs
new file mode 100644
index 0000000..d551365
--- /dev/null
+++ b/gcc/testsuite/rust.test/fail_compilation/tuple1.rs
@@ -0,0 +1,5 @@
+fn main() {
+ let a: (i32, bool) = (123, 123);
+ let b;
+ b = (456, 5f32);
+}