diff options
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 2 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-struct-field-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 10 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-struct-field-expr.h | 13 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.cc | 13 | ||||
-rw-r--r-- | gcc/rust/hir/tree/rust-hir-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h | 5 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 9 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-struct-field.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.cc | 29 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-resolver.h | 68 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 24 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.h | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/struct_init_3.rs | 10 |
15 files changed, 173 insertions, 24 deletions
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 941b2fe..34122bb 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -882,6 +882,8 @@ public: virtual NodeId get_node_id () const { return node_id; } + virtual void set_node_id (NodeId id) { node_id = id; } + protected: // Constructor Expr (std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index 8a1fd6e..6dba7fd 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -1604,6 +1604,8 @@ public: void accept_vis (ASTVisitor &vis) override; + Identifier get_field_name () const { return field_name; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/backend/rust-compile-struct-field-expr.h b/gcc/rust/backend/rust-compile-struct-field-expr.h index 0e54281..0a16f6a 100644 --- a/gcc/rust/backend/rust-compile-struct-field-expr.h +++ b/gcc/rust/backend/rust-compile-struct-field-expr.h @@ -40,6 +40,8 @@ public: void visit (HIR::StructExprFieldIndexValue &field); + void visit (HIR::StructExprFieldIdentifier &field); + private: CompileStructExprField (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index cb6272f..ce6d827 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -234,5 +234,15 @@ CompileStructExprField::visit (HIR::StructExprFieldIndexValue &field) translated = CompileExpr::Compile (field.get_value (), ctx); } +void +CompileStructExprField::visit (HIR::StructExprFieldIdentifier &field) +{ + // we can make the field look like an identifier expr to take advantage of + // existing code + HIR::IdentifierExpr expr (field.get_mappings (), field.get_field_name (), + field.get_locus ()); + translated = CompileExpr::Compile (&expr, ctx); +} + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/hir/rust-ast-lower-struct-field-expr.h b/gcc/rust/hir/rust-ast-lower-struct-field-expr.h index 71c1f1f..c44c9f9 100644 --- a/gcc/rust/hir/rust-ast-lower-struct-field-expr.h +++ b/gcc/rust/hir/rust-ast-lower-struct-field-expr.h @@ -34,10 +34,13 @@ public: field->accept_vis (compiler); rust_assert (compiler.translated != nullptr); - // compiler.mappings->insert_hir_expr ( - // compiler.translated->get_mappings ().get_crate_num (), - // compiler.translated->get_mappings ().get_hirid (), - // compiler.translated); + compiler.mappings->insert_hir_struct_field ( + compiler.translated->get_mappings ().get_crate_num (), + compiler.translated->get_mappings ().get_hirid (), compiler.translated); + compiler.mappings->insert_location ( + compiler.translated->get_mappings ().get_crate_num (), + compiler.translated->get_mappings ().get_hirid (), + field->get_locus_slow ()); return compiler.translated; } @@ -48,6 +51,8 @@ public: void visit (AST::StructExprFieldIndexValue &field); + void visit (AST::StructExprFieldIdentifier &field); + private: ASTLowerStructExprField () : translated (nullptr) {} diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index d4c8224..dac2320 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -228,5 +228,18 @@ ASTLowerStructExprField::visit (AST::StructExprFieldIndexValue &field) field.get_locus ()); } +void +ASTLowerStructExprField::visit (AST::StructExprFieldIdentifier &field) +{ + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, field.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::StructExprFieldIdentifier (mapping, field.get_field_name (), + field.get_locus ()); +} + } // namespace HIR } // namespace Rust diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index a50f744..ff3fbab 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -1496,6 +1496,8 @@ public: void accept_vis (HIRVisitor &vis) override; + Identifier get_field_name () const { return field_name; } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h index 45d3e59..3916473 100644 --- a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h +++ b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h @@ -26,8 +26,7 @@ namespace Rust { namespace Resolver { // this resolves values being assigned not that the field actually exists yet. -// We cant resolve the field to struct until type resolution since the HIR -// Mappings don't exist yet. + class ResolveStructExprField : public ResolverBase { public: @@ -43,6 +42,8 @@ public: void visit (AST::StructExprFieldIndexValue &field); + void visit (AST::StructExprFieldIdentifier &field); + private: ResolveStructExprField (NodeId parent) : ResolverBase (parent) {} }; diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index 910cd86..ec53ae0 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -324,5 +324,14 @@ ResolveStructExprField::visit (AST::StructExprFieldIndexValue &field) ResolveExpr::go (field.get_value ().get (), field.get_node_id ()); } +void +ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field) +{ + AST::IdentifierExpr expr (field.get_field_name (), field.get_locus ()); + expr.set_node_id (field.get_node_id ()); + + ResolveExpr::go (&expr, field.get_node_id ()); +} + } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h index 02bc9df..48ab40f 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-struct-field.h +++ b/gcc/rust/typecheck/rust-hir-type-check-struct-field.h @@ -46,6 +46,8 @@ public: void visit (HIR::StructExprFieldIndexValue &field); + void visit (HIR::StructExprFieldIdentifier &field); + private: TypeCheckStructExpr () : TypeCheckBase (), resolved (nullptr), struct_path_resolved (nullptr) diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index 6819627..6f8c3a1 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -222,5 +222,34 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field) fields_assigned.insert (field_name); } +void +TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifier &field) +{ + auto it = fields_assigned.find (field.get_field_name ()); + if (it != fields_assigned.end ()) + { + rust_fatal_error (field.get_locus (), "used more than once"); + return; + } + + TyTy::StructFieldType *field_type + = struct_path_resolved->get_field (field.get_field_name ()); + if (field_type == nullptr) + { + rust_error_at (field.get_locus (), "unknown field"); + return; + } + + // we can make the field look like an identifier expr to take advantage of + // existing code to figure out the type + HIR::IdentifierExpr expr (field.get_mappings (), field.get_field_name (), + field.get_locus ()); + TyTy::TyBase *value = TypeCheckExpr::Resolve (&expr); + + resolved_field = field_type->get_field_type ()->combine (value); + if (resolved_field != nullptr) + fields_assigned.insert (field.field_name); +} + } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/typecheck/rust-tyty-resolver.h b/gcc/rust/typecheck/rust-tyty-resolver.h index 3c31076..eb03ff9 100644 --- a/gcc/rust/typecheck/rust-tyty-resolver.h +++ b/gcc/rust/typecheck/rust-tyty-resolver.h @@ -44,7 +44,8 @@ public: void go (Rib *rib) { - rib->iterate_decls ([&] (NodeId decl_node_id, Location) mutable -> bool { + rib->iterate_decls ([&] (NodeId decl_node_id, + Location locus) mutable -> bool { // type inference in rust means we need to gather and examine all // references of this decl and combine each to make sure the type is // correctly inferred. Consider the example: @@ -52,33 +53,53 @@ public: // we can only say x is an infer variable then at the assignment // we think x must be an integer + bool ok = true; std::vector<TyTy::TyBase *> gathered_types; rib->iterate_references_for_def ( decl_node_id, [&] (NodeId ref_node) mutable -> bool { HirId hir_node_ref; - bool ok - = mappings->lookup_node_to_hir (mappings->get_current_crate (), - ref_node, &hir_node_ref); - rust_assert (ok); + if (!mappings->lookup_node_to_hir (mappings->get_current_crate (), + ref_node, &hir_node_ref)) + { + rust_error_at (locus, + "failed to reserve lookup HIR node for reference"); + ok = false; + return false; + } TyTy::TyBase *resolved = nullptr; if (!context->lookup_type (hir_node_ref, &resolved)) { // this could be an array/adt type Definition d; - bool ok = resolver->lookup_definition (ref_node, &d); - rust_assert (ok); + if (!resolver->lookup_definition (ref_node, &d)) + { + rust_error_at ( + locus, + "failed to lookup definition for referenced hir node"); + + ok = false; + return false; + } + + if (!mappings->lookup_node_to_hir (mappings->get_current_crate (), + d.parent, &hir_node_ref)) + { + rust_error_at (locus, + "failed to lookup HIR node for parent NodeId"); - ok = mappings->lookup_node_to_hir (mappings->get_current_crate (), - d.parent, &hir_node_ref); - rust_assert (ok); + ok = false; + return false; + } if (!context->lookup_type (hir_node_ref, &resolved)) { - rust_fatal_error ( + rust_error_at ( mappings->lookup_location (hir_node_ref), "failed to lookup type for reference at node [%u]", hir_node_ref); + + ok = false; return false; } } @@ -88,18 +109,29 @@ public: }); Definition d; - bool ok = resolver->lookup_definition (decl_node_id, &d); - rust_assert (ok); + if (!resolver->lookup_definition (decl_node_id, &d)) + { + rust_error_at (locus, "Failed to lookup definition within rib"); + return false; + } HIR::Stmt *decl = nullptr; - ok = mappings->resolve_nodeid_to_stmt (d.parent, &decl); - rust_assert (ok); + if (!mappings->resolve_nodeid_to_stmt (d.parent, &decl)) + { + rust_error_at (locus, "Failed to resolve decl to HIR::Stmt"); + return false; + } TyTy::TyBase *resolved_type = nullptr; - ok = context->lookup_type (decl->get_mappings ().get_hirid (), - &resolved_type); - rust_assert (ok); + if (!context->lookup_type (decl->get_mappings ().get_hirid (), + &resolved_type)) + { + rust_error_at (locus, "Unknown base type for decl in Rib"); + return false; + } + // if it is not infer then it must have been figured out already + // we might need changes for generics later on if (resolved_type->get_kind () != TyTy::TypeKind::INFER) return true; diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index 0fea501..c6e177b 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -350,6 +350,30 @@ Mappings::lookup_hir_param (CrateNum crateNum, HirId id) } void +Mappings::insert_hir_struct_field (CrateNum crateNum, HirId id, + HIR::StructExprField *field) +{ + rust_assert (lookup_hir_stmt (crateNum, id) == nullptr); + + hirStructFieldMappings[crateNum][id] = field; + nodeIdToHirMappings[crateNum][field->get_mappings ().get_nodeid ()] = id; +} + +HIR::StructExprField * +Mappings::lookup_hir_struct_field (CrateNum crateNum, HirId id) +{ + auto it = hirStructFieldMappings.find (crateNum); + if (it == hirStructFieldMappings.end ()) + return nullptr; + + auto iy = it->second.find (id); + if (iy == it->second.end ()) + return nullptr; + + return iy->second; +} + +void Mappings::insert_local_defid_mapping (CrateNum crateNum, LocalDefId id, HIR::Item *item) { diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h index a400265..3818be9 100644 --- a/gcc/rust/util/rust-hir-map.h +++ b/gcc/rust/util/rust-hir-map.h @@ -121,6 +121,10 @@ public: void insert_hir_param (CrateNum crateNum, HirId id, HIR::FunctionParam *type); HIR::FunctionParam *lookup_hir_param (CrateNum crateNum, HirId id); + void insert_hir_struct_field (CrateNum crateNum, HirId id, + HIR::StructExprField *type); + HIR::StructExprField *lookup_hir_struct_field (CrateNum crateNum, HirId id); + void walk_local_defids_for_crate (CrateNum crateNum, std::function<bool (HIR::Item *)> cb); @@ -159,6 +163,8 @@ private: std::map<CrateNum, std::map<HirId, HIR::Expr *> > hirExprMappings; std::map<CrateNum, std::map<HirId, HIR::Stmt *> > hirStmtMappings; std::map<CrateNum, std::map<HirId, HIR::FunctionParam *> > hirParamMappings; + std::map<CrateNum, std::map<HirId, HIR::StructExprField *> > + hirStructFieldMappings; // location info std::map<CrateNum, std::map<NodeId, Location> > locations; diff --git a/gcc/testsuite/rust.test/compilable/struct_init_3.rs b/gcc/testsuite/rust.test/compilable/struct_init_3.rs new file mode 100644 index 0000000..fb1e58e --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/struct_init_3.rs @@ -0,0 +1,10 @@ +struct Foo { + a: i32, + b: i32, +} + +fn main() { + let a = 1; + let b = 2; + let c = Foo { a, b }; +} |