diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-stmt.h | 11 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-stmt.h | 124 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-stmt.h | 66 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-stmt.h | 109 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/struct_init_10.rs | 9 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/struct_init_11.rs | 34 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/struct_init_9.rs | 6 |
8 files changed, 347 insertions, 14 deletions
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h index 5f37e07..73f6f22 100644 --- a/gcc/rust/backend/rust-compile-stmt.h +++ b/gcc/rust/backend/rust-compile-stmt.h @@ -35,27 +35,21 @@ public: { CompileStmt compiler (ctx); stmt->accept_vis (compiler); - rust_assert (compiler.ok); return compiler.translated; } void visit (HIR::ExprStmtWithBlock &stmt) override { - ok = true; translated = CompileExpr::Compile (stmt.get_expr (), ctx); } void visit (HIR::ExprStmtWithoutBlock &stmt) override { - ok = true; translated = CompileExpr::Compile (stmt.get_expr (), ctx); } void visit (HIR::LetStmt &stmt) override { - // marks that the statement has been looked at - ok = true; - // nothing to do if (!stmt.has_init_expr ()) return; @@ -96,11 +90,8 @@ public: } private: - CompileStmt (Context *ctx) - : HIRCompileBase (ctx), ok (false), translated (nullptr) - {} + CompileStmt (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {} - bool ok; Bexpression *translated; }; diff --git a/gcc/rust/hir/rust-ast-lower-stmt.h b/gcc/rust/hir/rust-ast-lower-stmt.h index b0763e6..c495932 100644 --- a/gcc/rust/hir/rust-ast-lower-stmt.h +++ b/gcc/rust/hir/rust-ast-lower-stmt.h @@ -44,8 +44,6 @@ public: return resolver.translated; } - virtual ~ASTLoweringStmt () {} - void visit (AST::ExprStmtWithBlock &stmt) override { HIR::ExprWithBlock *expr @@ -110,6 +108,128 @@ public: mappings->insert_hir_stmt (crate_num, mapping.get_hirid (), translated); } + void visit (AST::TupleStruct &struct_decl) override + { + std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + if (struct_decl.has_generics ()) + { + generic_params + = lower_generic_params (struct_decl.get_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::TupleField> fields; + struct_decl.iterate ([&] (AST::TupleField &field) mutable -> bool { + 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, field.get_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, + struct_decl.get_outer_attrs (), + struct_decl.get_locus ()); + + mappings->insert_hir_stmt (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) override + { + std::vector<std::unique_ptr<HIR::GenericParam> > generic_params; + if (struct_decl.has_generics ()) + { + generic_params + = lower_generic_params (struct_decl.get_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 (); + + bool is_unit = struct_decl.is_unit_struct (); + std::vector<HIR::StructField> fields; + struct_decl.iterate ([&] (AST::StructField &field) mutable -> bool { + 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::StructField is missing Location info + Location field_locus; + HIR::StructField translated_field (mapping, field.get_field_name (), + std::unique_ptr<HIR::Type> (type), vis, + field_locus, field.get_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::StructStruct (mapping, std::move (fields), + struct_decl.get_identifier (), + std::move (generic_params), + std::move (where_clause), is_unit, vis, + struct_decl.get_outer_attrs (), + struct_decl.get_locus ()); + + mappings->insert_hir_stmt (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_location (crate_num, mapping.get_hirid (), + struct_decl.get_locus ()); + } + + void visit (AST::EmptyStmt &empty) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, empty.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + translated = new HIR::EmptyStmt (mapping, empty.get_locus ()); + + mappings->insert_hir_stmt (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_location (crate_num, mapping.get_hirid (), + empty.get_locus ()); + } + private: ASTLoweringStmt () : translated (nullptr), terminated (false) {} diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index 7ff80e4..3fd1cfa 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -39,8 +39,6 @@ public: stmt->accept_vis (resolver); }; - ~ResolveStmt () {} - void visit (AST::ExprStmtWithBlock &stmt) override { ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ()); @@ -67,6 +65,70 @@ public: ResolveType::go (stmt.get_type ().get (), stmt.get_node_id ()); } + void visit (AST::TupleStruct &struct_decl) override + { + auto path = CanonicalPath (struct_decl.get_identifier ()); + resolver->get_type_scope ().insert ( + path, struct_decl.get_node_id (), struct_decl.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (struct_decl.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + NodeId scope_node_id = struct_decl.get_node_id (); + resolver->get_type_scope ().push (scope_node_id); + + if (struct_decl.has_generics ()) + { + for (auto &generic : struct_decl.get_generic_params ()) + { + ResolveGenericParam::go (generic.get (), + struct_decl.get_node_id ()); + } + } + + struct_decl.iterate ([&] (AST::TupleField &field) mutable -> bool { + ResolveType::go (field.get_field_type ().get (), + struct_decl.get_node_id ()); + return true; + }); + + resolver->get_type_scope ().pop (); + } + + void visit (AST::StructStruct &struct_decl) override + { + auto path = CanonicalPath (struct_decl.get_identifier ()); + resolver->get_type_scope ().insert ( + path, struct_decl.get_node_id (), struct_decl.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (struct_decl.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + NodeId scope_node_id = struct_decl.get_node_id (); + resolver->get_type_scope ().push (scope_node_id); + + if (struct_decl.has_generics ()) + { + for (auto &generic : struct_decl.get_generic_params ()) + { + ResolveGenericParam::go (generic.get (), + struct_decl.get_node_id ()); + } + } + + struct_decl.iterate ([&] (AST::StructField &field) mutable -> bool { + ResolveType::go (field.get_field_type ().get (), + struct_decl.get_node_id ()); + return true; + }); + + resolver->get_type_scope ().pop (); + } + private: ResolveStmt (NodeId parent) : ResolverBase (parent) {} }; diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h index e0e7adc..0e55df8 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h @@ -49,6 +49,12 @@ public: infered = TypeCheckExpr::Resolve (stmt.get_expr (), inside_loop); } + void visit (HIR::EmptyStmt &stmt) override + { + infered + = TyTy::TupleType::get_unit_type (stmt.get_mappings ().get_hirid ()); + } + void visit (HIR::LetStmt &stmt) override { infered = new TyTy::TupleType (stmt.get_mappings ().get_hirid ()); @@ -107,6 +113,109 @@ public: rust_assert (ok); } + void visit (HIR::TupleStruct &struct_decl) override + { + std::vector<TyTy::SubstitutionParamMapping> substitutions; + if (struct_decl.has_generics ()) + { + for (auto &generic_param : struct_decl.get_generic_params ()) + { + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), + param_type); + + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast<HIR::TypeParam &> (*generic_param), + param_type)); + } + break; + } + } + } + + std::vector<TyTy::StructFieldType *> fields; + + size_t idx = 0; + struct_decl.iterate ([&] (HIR::TupleField &field) mutable -> bool { + TyTy::BaseType *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 (), ty_field->get_field_type ()); + idx++; + return true; + }); + + TyTy::BaseType *type + = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (), + mappings->get_next_hir_id (), + struct_decl.get_identifier (), true, + std::move (fields), std::move (substitutions)); + + context->insert_type (struct_decl.get_mappings (), type); + infered = type; + } + + void visit (HIR::StructStruct &struct_decl) override + { + std::vector<TyTy::SubstitutionParamMapping> substitutions; + if (struct_decl.has_generics ()) + { + for (auto &generic_param : struct_decl.get_generic_params ()) + { + switch (generic_param.get ()->get_kind ()) + { + case HIR::GenericParam::GenericKind::LIFETIME: + // Skipping Lifetime completely until better handling. + break; + + case HIR::GenericParam::GenericKind::TYPE: { + auto param_type + = TypeResolveGenericParam::Resolve (generic_param.get ()); + context->insert_type (generic_param->get_mappings (), + param_type); + + substitutions.push_back (TyTy::SubstitutionParamMapping ( + static_cast<HIR::TypeParam &> (*generic_param), + param_type)); + } + break; + } + } + } + + std::vector<TyTy::StructFieldType *> fields; + struct_decl.iterate ([&] (HIR::StructField &field) mutable -> bool { + TyTy::BaseType *field_type + = TypeCheckType::Resolve (field.get_field_type ().get ()); + TyTy::StructFieldType *ty_field + = new TyTy::StructFieldType (field.get_mappings ().get_hirid (), + field.get_field_name (), field_type); + fields.push_back (ty_field); + context->insert_type (field.get_mappings (), ty_field->get_field_type ()); + return true; + }); + + TyTy::BaseType *type + = new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (), + mappings->get_next_hir_id (), + struct_decl.get_identifier (), false, + std::move (fields), std::move (substitutions)); + + context->insert_type (struct_decl.get_mappings (), type); + infered = type; + } + private: TypeCheckStmt (bool inside_loop) : TypeCheckBase (), infered (nullptr), inside_loop (inside_loop) diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index dfab81d..fcf4d86 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -342,6 +342,8 @@ public: : BaseType (ref, ty_ref, TypeKind::TUPLE, refs), fields (fields) {} + static TupleType *get_unit_type (HirId ref) { return new TupleType (ref); } + void accept_vis (TyVisitor &vis) override; bool is_unit () const override { return this->fields.empty (); } diff --git a/gcc/testsuite/rust/compile/torture/struct_init_10.rs b/gcc/testsuite/rust/compile/torture/struct_init_10.rs new file mode 100644 index 0000000..7fbceb0 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/struct_init_10.rs @@ -0,0 +1,9 @@ +fn main() { + struct foo { + a: i32, + b: f32, + }; + + let a; + a = foo { a: 123, b: 456f32 }; +} diff --git a/gcc/testsuite/rust/compile/torture/struct_init_11.rs b/gcc/testsuite/rust/compile/torture/struct_init_11.rs new file mode 100644 index 0000000..16a2f07 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/struct_init_11.rs @@ -0,0 +1,34 @@ +pub fn main() { + struct O(i32); + struct T(i32, i32); + struct M(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32); + + // tuples + let z = (); + let o = (0,); + let f = o.0; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + let t = (0, 1); + let s = t.1; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + let m = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + let l = m.10; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + // tuple structs + let so = O(0); + let sf = so.0; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + let st = T(0, 1); + let fs = st.1; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + let sm = M(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + let sl = sm.10; + // { dg-warning "unused name" "" { target *-*-* } .-1 } + + z +} diff --git a/gcc/testsuite/rust/compile/torture/struct_init_9.rs b/gcc/testsuite/rust/compile/torture/struct_init_9.rs new file mode 100644 index 0000000..2daa078 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/struct_init_9.rs @@ -0,0 +1,6 @@ +fn main() { + struct foo(i32, f32); + + let a; + a = foo(123, 456f32); +} |