diff options
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); +} |