diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-01-16 17:25:12 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-01-17 14:20:45 +0000 |
commit | b06df5d4a95ec728ade9230bec945d5d3661f87d (patch) | |
tree | 51a94e9f8118c84893b10ed61d46fd7fd9f30323 /gcc | |
parent | e4a2a52b35e99a40f8bd3992a6b53650908fd188 (diff) | |
download | gcc-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.h | 32 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-expr.h | 24 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-type.h | 6 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.h | 3 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 22 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 20 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.h | 20 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-rules.h | 59 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 3 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/tuple1.rs | 5 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/tuple2.rs | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/fail_compilation/tuple1.rs | 5 |
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); +} |