aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/ast/rust-ast.h2
-rw-r--r--gcc/rust/ast/rust-expr.h2
-rw-r--r--gcc/rust/backend/rust-compile-struct-field-expr.h2
-rw-r--r--gcc/rust/backend/rust-compile.cc10
-rw-r--r--gcc/rust/hir/rust-ast-lower-struct-field-expr.h13
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc13
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h5
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc9
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-struct-field.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc29
-rw-r--r--gcc/rust/typecheck/rust-tyty-resolver.h68
-rw-r--r--gcc/rust/util/rust-hir-map.cc24
-rw-r--r--gcc/rust/util/rust-hir-map.h6
-rw-r--r--gcc/testsuite/rust.test/compilable/struct_init_3.rs10
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 };
+}