diff options
Diffstat (limited to 'gcc')
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); +} |