aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-01-16 17:25:12 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-01-17 14:20:45 +0000
commitb06df5d4a95ec728ade9230bec945d5d3661f87d (patch)
tree51a94e9f8118c84893b10ed61d46fd7fd9f30323 /gcc
parente4a2a52b35e99a40f8bd3992a6b53650908fd188 (diff)
downloadgcc-b06df5d4a95ec728ade9230bec945d5d3661f87d.zip
gcc-b06df5d4a95ec728ade9230bec945d5d3661f87d.tar.gz
gcc-b06df5d4a95ec728ade9230bec945d5d3661f87d.tar.bz2
This adds supports for tuples
More testing is required but this adds tuples apart from TupleStructs which are parsed as CallExpr. This will be the primitives required to finish that work.
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);
+}