Skip to content

Commit 4e5baf7

Browse files
bors[bot]philberty
andauthored
Merge #520
520: Add support for struct definitions to be within a block r=philberty a=philberty We still have bugs handling unit-structs but this allows for Tuple Structs and normal named field structs to be declared within a block and referenced lexically. This allows rust statements to follow the correct grammar. Fixes #519 Co-authored-by: Philip Herron <[email protected]>
2 parents ce545f5 + 012401a commit 4e5baf7

File tree

8 files changed

+347
-14
lines changed

8 files changed

+347
-14
lines changed

gcc/rust/backend/rust-compile-stmt.h

+1-10
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,21 @@ class CompileStmt : public HIRCompileBase
3535
{
3636
CompileStmt compiler (ctx);
3737
stmt->accept_vis (compiler);
38-
rust_assert (compiler.ok);
3938
return compiler.translated;
4039
}
4140

4241
void visit (HIR::ExprStmtWithBlock &stmt) override
4342
{
44-
ok = true;
4543
translated = CompileExpr::Compile (stmt.get_expr (), ctx);
4644
}
4745

4846
void visit (HIR::ExprStmtWithoutBlock &stmt) override
4947
{
50-
ok = true;
5148
translated = CompileExpr::Compile (stmt.get_expr (), ctx);
5249
}
5350

5451
void visit (HIR::LetStmt &stmt) override
5552
{
56-
// marks that the statement has been looked at
57-
ok = true;
58-
5953
// nothing to do
6054
if (!stmt.has_init_expr ())
6155
return;
@@ -96,11 +90,8 @@ class CompileStmt : public HIRCompileBase
9690
}
9791

9892
private:
99-
CompileStmt (Context *ctx)
100-
: HIRCompileBase (ctx), ok (false), translated (nullptr)
101-
{}
93+
CompileStmt (Context *ctx) : HIRCompileBase (ctx), translated (nullptr) {}
10294

103-
bool ok;
10495
Bexpression *translated;
10596
};
10697

gcc/rust/hir/rust-ast-lower-stmt.h

+122-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ class ASTLoweringStmt : public ASTLoweringBase
4444
return resolver.translated;
4545
}
4646

47-
virtual ~ASTLoweringStmt () {}
48-
4947
void visit (AST::ExprStmtWithBlock &stmt) override
5048
{
5149
HIR::ExprWithBlock *expr
@@ -110,6 +108,128 @@ class ASTLoweringStmt : public ASTLoweringBase
110108
mappings->insert_hir_stmt (crate_num, mapping.get_hirid (), translated);
111109
}
112110

111+
void visit (AST::TupleStruct &struct_decl) override
112+
{
113+
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
114+
if (struct_decl.has_generics ())
115+
{
116+
generic_params
117+
= lower_generic_params (struct_decl.get_generic_params ());
118+
}
119+
120+
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
121+
HIR::WhereClause where_clause (std::move (where_clause_items));
122+
HIR::Visibility vis = HIR::Visibility::create_public ();
123+
124+
std::vector<HIR::TupleField> fields;
125+
struct_decl.iterate ([&] (AST::TupleField &field) mutable -> bool {
126+
HIR::Visibility vis = HIR::Visibility::create_public ();
127+
HIR::Type *type
128+
= ASTLoweringType::translate (field.get_field_type ().get ());
129+
130+
auto crate_num = mappings->get_current_crate ();
131+
Analysis::NodeMapping mapping (crate_num, field.get_node_id (),
132+
mappings->get_next_hir_id (crate_num),
133+
mappings->get_next_localdef_id (
134+
crate_num));
135+
136+
// FIXME
137+
// AST::TupleField is missing Location info
138+
Location field_locus;
139+
HIR::TupleField translated_field (mapping,
140+
std::unique_ptr<HIR::Type> (type), vis,
141+
field_locus, field.get_outer_attrs ());
142+
fields.push_back (std::move (translated_field));
143+
return true;
144+
});
145+
146+
auto crate_num = mappings->get_current_crate ();
147+
Analysis::NodeMapping mapping (crate_num, struct_decl.get_node_id (),
148+
mappings->get_next_hir_id (crate_num),
149+
mappings->get_next_localdef_id (crate_num));
150+
151+
translated = new HIR::TupleStruct (mapping, std::move (fields),
152+
struct_decl.get_identifier (),
153+
std::move (generic_params),
154+
std::move (where_clause), vis,
155+
struct_decl.get_outer_attrs (),
156+
struct_decl.get_locus ());
157+
158+
mappings->insert_hir_stmt (mapping.get_crate_num (), mapping.get_hirid (),
159+
translated);
160+
mappings->insert_location (crate_num, mapping.get_hirid (),
161+
struct_decl.get_locus ());
162+
}
163+
164+
void visit (AST::StructStruct &struct_decl) override
165+
{
166+
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
167+
if (struct_decl.has_generics ())
168+
{
169+
generic_params
170+
= lower_generic_params (struct_decl.get_generic_params ());
171+
}
172+
173+
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
174+
HIR::WhereClause where_clause (std::move (where_clause_items));
175+
HIR::Visibility vis = HIR::Visibility::create_public ();
176+
177+
bool is_unit = struct_decl.is_unit_struct ();
178+
std::vector<HIR::StructField> fields;
179+
struct_decl.iterate ([&] (AST::StructField &field) mutable -> bool {
180+
HIR::Visibility vis = HIR::Visibility::create_public ();
181+
HIR::Type *type
182+
= ASTLoweringType::translate (field.get_field_type ().get ());
183+
184+
auto crate_num = mappings->get_current_crate ();
185+
Analysis::NodeMapping mapping (crate_num, field.get_node_id (),
186+
mappings->get_next_hir_id (crate_num),
187+
mappings->get_next_localdef_id (
188+
crate_num));
189+
190+
// FIXME
191+
// AST::StructField is missing Location info
192+
Location field_locus;
193+
HIR::StructField translated_field (mapping, field.get_field_name (),
194+
std::unique_ptr<HIR::Type> (type), vis,
195+
field_locus, field.get_outer_attrs ());
196+
fields.push_back (std::move (translated_field));
197+
return true;
198+
});
199+
200+
auto crate_num = mappings->get_current_crate ();
201+
Analysis::NodeMapping mapping (crate_num, struct_decl.get_node_id (),
202+
mappings->get_next_hir_id (crate_num),
203+
mappings->get_next_localdef_id (crate_num));
204+
205+
translated = new HIR::StructStruct (mapping, std::move (fields),
206+
struct_decl.get_identifier (),
207+
std::move (generic_params),
208+
std::move (where_clause), is_unit, vis,
209+
struct_decl.get_outer_attrs (),
210+
struct_decl.get_locus ());
211+
212+
mappings->insert_hir_stmt (mapping.get_crate_num (), mapping.get_hirid (),
213+
translated);
214+
mappings->insert_location (crate_num, mapping.get_hirid (),
215+
struct_decl.get_locus ());
216+
}
217+
218+
void visit (AST::EmptyStmt &empty) override
219+
{
220+
auto crate_num = mappings->get_current_crate ();
221+
Analysis::NodeMapping mapping (crate_num, empty.get_node_id (),
222+
mappings->get_next_hir_id (crate_num),
223+
mappings->get_next_localdef_id (crate_num));
224+
225+
translated = new HIR::EmptyStmt (mapping, empty.get_locus ());
226+
227+
mappings->insert_hir_stmt (mapping.get_crate_num (), mapping.get_hirid (),
228+
translated);
229+
mappings->insert_location (crate_num, mapping.get_hirid (),
230+
empty.get_locus ());
231+
}
232+
113233
private:
114234
ASTLoweringStmt () : translated (nullptr), terminated (false) {}
115235

gcc/rust/resolve/rust-ast-resolve-stmt.h

+64-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ class ResolveStmt : public ResolverBase
3939
stmt->accept_vis (resolver);
4040
};
4141

42-
~ResolveStmt () {}
43-
4442
void visit (AST::ExprStmtWithBlock &stmt) override
4543
{
4644
ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ());
@@ -67,6 +65,70 @@ class ResolveStmt : public ResolverBase
6765
ResolveType::go (stmt.get_type ().get (), stmt.get_node_id ());
6866
}
6967

68+
void visit (AST::TupleStruct &struct_decl) override
69+
{
70+
auto path = CanonicalPath (struct_decl.get_identifier ());
71+
resolver->get_type_scope ().insert (
72+
path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
73+
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
74+
RichLocation r (struct_decl.get_locus ());
75+
r.add_range (locus);
76+
rust_error_at (r, "redefined multiple times");
77+
});
78+
79+
NodeId scope_node_id = struct_decl.get_node_id ();
80+
resolver->get_type_scope ().push (scope_node_id);
81+
82+
if (struct_decl.has_generics ())
83+
{
84+
for (auto &generic : struct_decl.get_generic_params ())
85+
{
86+
ResolveGenericParam::go (generic.get (),
87+
struct_decl.get_node_id ());
88+
}
89+
}
90+
91+
struct_decl.iterate ([&] (AST::TupleField &field) mutable -> bool {
92+
ResolveType::go (field.get_field_type ().get (),
93+
struct_decl.get_node_id ());
94+
return true;
95+
});
96+
97+
resolver->get_type_scope ().pop ();
98+
}
99+
100+
void visit (AST::StructStruct &struct_decl) override
101+
{
102+
auto path = CanonicalPath (struct_decl.get_identifier ());
103+
resolver->get_type_scope ().insert (
104+
path, struct_decl.get_node_id (), struct_decl.get_locus (), false,
105+
[&] (const CanonicalPath &, NodeId, Location locus) -> void {
106+
RichLocation r (struct_decl.get_locus ());
107+
r.add_range (locus);
108+
rust_error_at (r, "redefined multiple times");
109+
});
110+
111+
NodeId scope_node_id = struct_decl.get_node_id ();
112+
resolver->get_type_scope ().push (scope_node_id);
113+
114+
if (struct_decl.has_generics ())
115+
{
116+
for (auto &generic : struct_decl.get_generic_params ())
117+
{
118+
ResolveGenericParam::go (generic.get (),
119+
struct_decl.get_node_id ());
120+
}
121+
}
122+
123+
struct_decl.iterate ([&] (AST::StructField &field) mutable -> bool {
124+
ResolveType::go (field.get_field_type ().get (),
125+
struct_decl.get_node_id ());
126+
return true;
127+
});
128+
129+
resolver->get_type_scope ().pop ();
130+
}
131+
70132
private:
71133
ResolveStmt (NodeId parent) : ResolverBase (parent) {}
72134
};

gcc/rust/typecheck/rust-hir-type-check-stmt.h

+109
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ class TypeCheckStmt : public TypeCheckBase
4949
infered = TypeCheckExpr::Resolve (stmt.get_expr (), inside_loop);
5050
}
5151

52+
void visit (HIR::EmptyStmt &stmt) override
53+
{
54+
infered
55+
= TyTy::TupleType::get_unit_type (stmt.get_mappings ().get_hirid ());
56+
}
57+
5258
void visit (HIR::LetStmt &stmt) override
5359
{
5460
infered = new TyTy::TupleType (stmt.get_mappings ().get_hirid ());
@@ -107,6 +113,109 @@ class TypeCheckStmt : public TypeCheckBase
107113
rust_assert (ok);
108114
}
109115

116+
void visit (HIR::TupleStruct &struct_decl) override
117+
{
118+
std::vector<TyTy::SubstitutionParamMapping> substitutions;
119+
if (struct_decl.has_generics ())
120+
{
121+
for (auto &generic_param : struct_decl.get_generic_params ())
122+
{
123+
switch (generic_param.get ()->get_kind ())
124+
{
125+
case HIR::GenericParam::GenericKind::LIFETIME:
126+
// Skipping Lifetime completely until better handling.
127+
break;
128+
129+
case HIR::GenericParam::GenericKind::TYPE: {
130+
auto param_type
131+
= TypeResolveGenericParam::Resolve (generic_param.get ());
132+
context->insert_type (generic_param->get_mappings (),
133+
param_type);
134+
135+
substitutions.push_back (TyTy::SubstitutionParamMapping (
136+
static_cast<HIR::TypeParam &> (*generic_param),
137+
param_type));
138+
}
139+
break;
140+
}
141+
}
142+
}
143+
144+
std::vector<TyTy::StructFieldType *> fields;
145+
146+
size_t idx = 0;
147+
struct_decl.iterate ([&] (HIR::TupleField &field) mutable -> bool {
148+
TyTy::BaseType *field_type
149+
= TypeCheckType::Resolve (field.get_field_type ().get ());
150+
TyTy::StructFieldType *ty_field
151+
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
152+
std::to_string (idx), field_type);
153+
fields.push_back (ty_field);
154+
context->insert_type (field.get_mappings (), ty_field->get_field_type ());
155+
idx++;
156+
return true;
157+
});
158+
159+
TyTy::BaseType *type
160+
= new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
161+
mappings->get_next_hir_id (),
162+
struct_decl.get_identifier (), true,
163+
std::move (fields), std::move (substitutions));
164+
165+
context->insert_type (struct_decl.get_mappings (), type);
166+
infered = type;
167+
}
168+
169+
void visit (HIR::StructStruct &struct_decl) override
170+
{
171+
std::vector<TyTy::SubstitutionParamMapping> substitutions;
172+
if (struct_decl.has_generics ())
173+
{
174+
for (auto &generic_param : struct_decl.get_generic_params ())
175+
{
176+
switch (generic_param.get ()->get_kind ())
177+
{
178+
case HIR::GenericParam::GenericKind::LIFETIME:
179+
// Skipping Lifetime completely until better handling.
180+
break;
181+
182+
case HIR::GenericParam::GenericKind::TYPE: {
183+
auto param_type
184+
= TypeResolveGenericParam::Resolve (generic_param.get ());
185+
context->insert_type (generic_param->get_mappings (),
186+
param_type);
187+
188+
substitutions.push_back (TyTy::SubstitutionParamMapping (
189+
static_cast<HIR::TypeParam &> (*generic_param),
190+
param_type));
191+
}
192+
break;
193+
}
194+
}
195+
}
196+
197+
std::vector<TyTy::StructFieldType *> fields;
198+
struct_decl.iterate ([&] (HIR::StructField &field) mutable -> bool {
199+
TyTy::BaseType *field_type
200+
= TypeCheckType::Resolve (field.get_field_type ().get ());
201+
TyTy::StructFieldType *ty_field
202+
= new TyTy::StructFieldType (field.get_mappings ().get_hirid (),
203+
field.get_field_name (), field_type);
204+
fields.push_back (ty_field);
205+
context->insert_type (field.get_mappings (), ty_field->get_field_type ());
206+
return true;
207+
});
208+
209+
TyTy::BaseType *type
210+
= new TyTy::ADTType (struct_decl.get_mappings ().get_hirid (),
211+
mappings->get_next_hir_id (),
212+
struct_decl.get_identifier (), false,
213+
std::move (fields), std::move (substitutions));
214+
215+
context->insert_type (struct_decl.get_mappings (), type);
216+
infered = type;
217+
}
218+
110219
private:
111220
TypeCheckStmt (bool inside_loop)
112221
: TypeCheckBase (), infered (nullptr), inside_loop (inside_loop)

gcc/rust/typecheck/rust-tyty.h

+2
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ class TupleType : public BaseType
342342
: BaseType (ref, ty_ref, TypeKind::TUPLE, refs), fields (fields)
343343
{}
344344

345+
static TupleType *get_unit_type (HirId ref) { return new TupleType (ref); }
346+
345347
void accept_vis (TyVisitor &vis) override;
346348

347349
bool is_unit () const override { return this->fields.empty (); }

0 commit comments

Comments
 (0)