Skip to content

Commit a5c3f33

Browse files
committed
Use Function instead of TraitItemFunc or TraitItemMethod
gcc/rust/ChangeLog: * ast/rust-item.h (RUST_AST_ITEM_H): Make get_definition() public. * backend/rust-compile-implitem.cc (CompileTraitItem::visit): Use Function instead of TraitItemFunc. * backend/rust-compile-implitem.h: Add visitor for HIR::Function. * backend/rust-mangle-v0.cc (v0_path): Rename get_item_kind() to get trait_item_kind(). * checks/errors/rust-ast-validation.cc (ASTValidation::visit): TRAIT is valid context for function as it will be used instead of TraitItemFunc. * hir/rust-ast-lower-implitem.h: Lower Function as a trait item. * hir/tree/rust-hir-item.h (class Function): Make Function inherit from TraitItem and add necessary functions, also add necessary parameters for constructors. * hir/tree/rust-hir-visitor.h: Add vistor for Function in HIRTraitItemVisitor. * hir/tree/rust-hir.cc (Function::accept_vis): Add accept_vis for Function. * hir/tree/rust-hir.h: Rename get_item_kind() to get trait_item_kind(). * parse/rust-parse-impl.h (Parser::parse_trait_item): Return AST::Function instead of AST::TraitItemFunc or AST::TriatItemMethod. * typecheck/rust-hir-dot-operator.cc (MethodResolver::select): Rename get_item_kind() to get trait_item_kind(). * typecheck/rust-hir-trait-reference.cc (TraitItemReference::get_tyty): Use HIR::Function instead of HIR::TraitItemFunc. * typecheck/rust-hir-trait-reference.h: Add functions for Function instead of TraitItemFunc. * typecheck/rust-hir-trait-resolve.cc (ResolveTraitItemToRef::visit): Add visit to Function. (TraitItemReference::on_resolved): Use HIR::Function instead of HIR::TraitItemFunc. (TraitItemReference::resolve_item): Add resolve_item() for Function. * typecheck/rust-hir-trait-resolve.h: Add visitor for Function. * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn): Add overload for Function. * typecheck/rust-tyty.cc (ClosureType::setup_fn_once_output): Rename get_item_kind() to get trait_item_kind(). Signed-off-by: Kushal Pal <kushalpal109@gmail.com>
1 parent d5ab6c5 commit a5c3f33

18 files changed

+382
-149
lines changed

gcc/rust/ast/rust-item.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
#ifndef RUST_AST_ITEM_H
2020
#define RUST_AST_ITEM_H
2121

22+
#include "optional.h"
2223
#include "rust-ast.h"
2324
#include "rust-hir-map.h"
2425
#include "rust-mapping-common.h"
2526
#include "rust-path.h"
2627
#include "rust-common.h"
2728
#include "rust-expr.h"
29+
#include <memory>
2830

2931
namespace Rust {
3032
namespace AST {
@@ -1323,6 +1325,8 @@ class Function : public VisItem, public TraitItem
13231325

13241326
bool has_body () const { return function_body.has_value (); }
13251327

1328+
tl::optional<std::unique_ptr<BlockExpr>>& get_definition () { return function_body; }
1329+
13261330
// Returns node_id, function is needed as VisItem and TraitItem both have
13271331
// get_node_id()
13281332
NodeId get_node_id () const { return VisItem::node_id; }
@@ -1394,12 +1398,6 @@ class Function : public VisItem, public TraitItem
13941398
return generic_params;
13951399
}
13961400

1397-
// TODO: is this better? Or is a "vis_block" better?
1398-
tl::optional<std::unique_ptr<BlockExpr>> &get_definition ()
1399-
{
1400-
return function_body;
1401-
}
1402-
14031401
const FunctionQualifiers &get_qualifiers () const { return qualifiers; }
14041402

14051403
FunctionQualifiers &get_qualifiers () { return qualifiers; }

gcc/rust/backend/rust-compile-implitem.cc

+48
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,54 @@ CompileTraitItem::visit (HIR::TraitItemConst &constant)
4242
reference = const_expr;
4343
}
4444

45+
void
46+
CompileTraitItem::visit (HIR::Function &func)
47+
{
48+
rust_assert (concrete->get_kind () == TyTy::TypeKind::FNDEF);
49+
TyTy::FnType *fntype = static_cast<TyTy::FnType *> (concrete);
50+
fntype->monomorphize ();
51+
// items can be forward compiled which means we may not need to invoke this
52+
// code. We might also have already compiled this generic function as well.
53+
tree lookup = NULL_TREE;
54+
if (ctx->lookup_function_decl (fntype->get_ty_ref (), &lookup,
55+
fntype->get_id (), fntype))
56+
{
57+
// has this been added to the list then it must be finished
58+
if (ctx->function_completed (lookup))
59+
{
60+
tree dummy = NULL_TREE;
61+
if (!ctx->lookup_function_decl (fntype->get_ty_ref (), &dummy))
62+
{
63+
ctx->insert_function_decl (fntype, lookup);
64+
}
65+
66+
reference = address_expression (lookup, ref_locus);
67+
return;
68+
}
69+
}
70+
71+
if (fntype->has_substitutions_defined ())
72+
{
73+
// override the Hir Lookups for the substituions in this context
74+
fntype->override_context ();
75+
}
76+
77+
const Resolver::CanonicalPath *canonical_path = nullptr;
78+
bool ok = ctx->get_mappings ()->lookup_canonical_path (
79+
func.get_mappings ().get_nodeid (), &canonical_path);
80+
rust_assert (ok);
81+
82+
// FIXME: How do we get the proper visibility here?
83+
auto vis = HIR::Visibility (HIR::Visibility::VisType::PUBLIC);
84+
tree fndecl
85+
= compile_function (func.get_function_name ().as_string (),
86+
func.get_self (), func.get_function_params (),
87+
func.get_qualifiers (), vis,
88+
func.get_outer_attrs (), func.get_locus (),
89+
func.get_definition ().get (), canonical_path, fntype);
90+
reference = address_expression (fndecl, ref_locus);
91+
}
92+
4593
void
4694
CompileTraitItem::visit (HIR::TraitItemFunc &func)
4795
{

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

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class CompileTraitItem : public HIRCompileBase, public HIR::HIRTraitItemVisitor
6969

7070
void visit (HIR::TraitItemConst &constant) override;
7171
void visit (HIR::TraitItemFunc &func) override;
72+
void visit (HIR::Function &func) override;
7273

7374
void visit (HIR::TraitItemType &typ) override {}
7475

gcc/rust/backend/rust-mangle-v0.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
410410
}
411411
else if (trait_item != nullptr)
412412
{
413-
switch (trait_item->get_item_kind ())
413+
switch (trait_item->get_trait_item_kind ())
414414
{
415415
case HIR::TraitItem::FUNC: {
416416
HIR::Function *fn = static_cast<HIR::Function *> (impl_item);

gcc/rust/checks/errors/rust-ast-validation.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void
9696
ASTValidation::visit (AST::Function &function)
9797
{
9898
std::set<Context> valid_context
99-
= {Context::INHERENT_IMPL, Context::TRAIT_IMPL};
99+
= {Context::INHERENT_IMPL, Context::TRAIT_IMPL, Context::TRAIT};
100100

101101
const auto &qualifiers = function.get_qualifiers ();
102102
if (qualifiers.is_async () && qualifiers.is_const ())

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

+76
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "rust-ast-lower-expr.h"
2424
#include "rust-ast-lower-pattern.h"
2525
#include "rust-ast-lower-block.h"
26+
#include "rust-ast-lower.h"
2627
#include "rust-item.h"
2728

2829
namespace Rust {
@@ -240,6 +241,81 @@ class ASTLowerTraitItem : public ASTLoweringBase
240241
return resolver.translated;
241242
}
242243

244+
void visit (AST::Function &function) override
245+
{
246+
std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
247+
HIR::WhereClause where_clause (std::move (where_clause_items));
248+
HIR::FunctionQualifiers qualifiers
249+
= lower_qualifiers (function.get_qualifiers ());
250+
251+
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
252+
if (function.has_generics ())
253+
{
254+
generic_params = lower_generic_params (function.get_generic_params ());
255+
}
256+
257+
std::unique_ptr<HIR::Type> return_type
258+
= function.has_return_type () ? std::unique_ptr<HIR::Type> (
259+
ASTLoweringType::translate (function.get_return_type ().get ()))
260+
: nullptr;
261+
262+
HIR::SelfParam self_param = lower_self (function.get_self_param ());
263+
std::vector<HIR::FunctionParam> function_params;
264+
for (auto &p : function.get_function_params ())
265+
{
266+
if (p->is_variadic () || p->is_self ())
267+
continue;
268+
269+
auto param = static_cast<AST::FunctionParam *> (p.get ());
270+
271+
auto translated_pattern = std::unique_ptr<HIR::Pattern> (
272+
ASTLoweringPattern::translate (param->get_pattern ().get ()));
273+
auto translated_type = std::unique_ptr<HIR::Type> (
274+
ASTLoweringType::translate (param->get_type ().get ()));
275+
276+
auto crate_num = mappings->get_current_crate ();
277+
Analysis::NodeMapping mapping (crate_num, param->get_node_id (),
278+
mappings->get_next_hir_id (crate_num),
279+
UNKNOWN_LOCAL_DEFID);
280+
281+
auto hir_param
282+
= HIR::FunctionParam (mapping, std::move (translated_pattern),
283+
std::move (translated_type),
284+
param->get_locus ());
285+
function_params.push_back (std::move (hir_param));
286+
}
287+
288+
bool terminated = false;
289+
std::unique_ptr<HIR::BlockExpr> block_expr
290+
= function.has_body () ? std::unique_ptr<HIR::BlockExpr> (
291+
ASTLoweringBlock::translate (function.get_definition ()->get (),
292+
&terminated))
293+
: nullptr;
294+
295+
auto crate_num = mappings->get_current_crate ();
296+
Analysis::NodeMapping mapping (crate_num, function.get_node_id (),
297+
mappings->get_next_hir_id (crate_num),
298+
mappings->get_next_localdef_id (crate_num));
299+
300+
HIR::Visibility vis = translate_visibility (function.get_visibility ());
301+
HIR::Function *trait_item
302+
= new HIR::Function (mapping, function.get_function_name (),
303+
std::move (qualifiers), std::move (generic_params),
304+
std::move (function_params), std::move (return_type),
305+
std::move (where_clause), std::move (block_expr),
306+
vis, function.get_outer_attrs (), self_param,
307+
function.get_locus ());
308+
309+
translated = trait_item;
310+
311+
// add the mappings for the function params at the end
312+
for (auto &param : trait_item->get_function_params ())
313+
{
314+
mappings->insert_hir_param (&param);
315+
mappings->insert_location (mapping.get_hirid (), param.get_locus ());
316+
}
317+
}
318+
243319
void visit (AST::TraitItemFunc &func) override
244320
{
245321
AST::TraitFunctionDecl &ref = func.get_trait_function_decl ();

gcc/rust/hir/tree/rust-hir-item.h

+50-8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "rust-hir-expr.h"
2626
#include "rust-hir.h"
2727
#include "rust-hir-path.h"
28+
#include <memory>
2829

2930
namespace Rust {
3031
namespace HIR {
@@ -1081,7 +1082,7 @@ class UseDeclaration : public VisItem
10811082
class LetStmt;
10821083

10831084
// Rust function declaration HIR node
1084-
class Function : public VisItem, public ImplItem
1085+
class Function : public VisItem, public ImplItem, public TraitItem
10851086
{
10861087
FunctionQualifiers qualifiers;
10871088
Identifier function_name;
@@ -1115,6 +1116,40 @@ class Function : public VisItem, public ImplItem
11151116

11161117
ItemKind get_item_kind () const override { return ItemKind::Function; }
11171118

1119+
TraitItemKind get_trait_item_kind () const override
1120+
{
1121+
return TraitItemKind::FUNC;
1122+
}
1123+
1124+
const std::string trait_identifier () const override
1125+
{
1126+
return function_name.as_string ();
1127+
}
1128+
1129+
location_t get_trait_locus () const override { return locus; }
1130+
1131+
AST::AttrVec &get_outer_attrs () override final { return outer_attrs; }
1132+
1133+
const AST::AttrVec &get_outer_attrs () const override final
1134+
{
1135+
return outer_attrs;
1136+
}
1137+
1138+
// Returns mappings, this function is needed otherwise call is ambigious as
1139+
// both VisItem and TraiItem have this function
1140+
const Analysis::NodeMapping &get_mappings () const
1141+
{
1142+
return VisItem::get_mappings();
1143+
}
1144+
1145+
// Returns whether function has a body
1146+
bool has_body() const { return function_body != nullptr; }
1147+
1148+
// Returns function body/definition
1149+
std::unique_ptr<BlockExpr>& get_body () { return function_body; }
1150+
1151+
SelfParam& get_self() { return self; }
1152+
11181153
// Mega-constructor with all possible fields
11191154
Function (Analysis::NodeMapping mappings, Identifier function_name,
11201155
FunctionQualifiers qualifiers,
@@ -1123,8 +1158,8 @@ class Function : public VisItem, public ImplItem
11231158
std::unique_ptr<Type> return_type, WhereClause where_clause,
11241159
std::unique_ptr<BlockExpr> function_body, Visibility vis,
11251160
AST::AttrVec outer_attrs, SelfParam self, location_t locus)
1126-
: VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)),
1127-
qualifiers (std::move (qualifiers)),
1161+
: VisItem (mappings, std::move (vis), std::move (outer_attrs)),
1162+
TraitItem (std::move (mappings)), qualifiers (std::move (qualifiers)),
11281163
function_name (std::move (function_name)),
11291164
generic_params (std::move (generic_params)),
11301165
function_params (std::move (function_params)),
@@ -1136,7 +1171,7 @@ class Function : public VisItem, public ImplItem
11361171

11371172
// Copy constructor with clone
11381173
Function (Function const &other)
1139-
: VisItem (other), qualifiers (other.qualifiers),
1174+
: VisItem (other), TraitItem (other), qualifiers (other.qualifiers),
11401175
function_name (other.function_name),
11411176
function_params (other.function_params),
11421177
where_clause (other.where_clause),
@@ -1158,6 +1193,7 @@ class Function : public VisItem, public ImplItem
11581193
Function &operator= (Function const &other)
11591194
{
11601195
VisItem::operator= (other);
1196+
TraitItem::operator= (other);
11611197
function_name = other.function_name;
11621198
qualifiers = other.qualifiers;
11631199
function_params = other.function_params;
@@ -1188,12 +1224,13 @@ class Function : public VisItem, public ImplItem
11881224

11891225
void accept_vis (HIRFullVisitor &vis) override;
11901226
void accept_vis (HIRImplVisitor &vis) override;
1227+
void accept_vis (HIRTraitItemVisitor &vis) override;
11911228
void accept_vis (HIRStmtVisitor &vis) override;
11921229
void accept_vis (HIRVisItemVisitor &vis) override;
11931230

11941231
Analysis::NodeMapping get_impl_mappings () const override
11951232
{
1196-
return get_mappings ();
1233+
return VisItem::get_mappings ();
11971234
};
11981235

11991236
std::vector<FunctionParam> &get_function_params () { return function_params; }
@@ -1246,6 +1283,11 @@ class Function : public VisItem, public ImplItem
12461283
{
12471284
return new Function (*this);
12481285
}
1286+
1287+
Function *clone_trait_item_impl () const override
1288+
{
1289+
return new Function (*this);
1290+
}
12491291
};
12501292

12511293
// Rust type alias (i.e. typedef) HIR node
@@ -2400,7 +2442,7 @@ class TraitItemFunc : public TraitItem
24002442
return decl.get_function_name ().as_string ();
24012443
}
24022444

2403-
TraitItemKind get_item_kind () const override final
2445+
TraitItemKind get_trait_item_kind () const override final
24042446
{
24052447
return TraitItemKind::FUNC;
24062448
}
@@ -2487,7 +2529,7 @@ class TraitItemConst : public TraitItem
24872529
return name.as_string ();
24882530
}
24892531

2490-
TraitItemKind get_item_kind () const override final
2532+
TraitItemKind get_trait_item_kind () const override final
24912533
{
24922534
return TraitItemKind::CONST;
24932535
}
@@ -2579,7 +2621,7 @@ class TraitItemType : public TraitItem
25792621
return name.as_string ();
25802622
}
25812623

2582-
TraitItemKind get_item_kind () const override final
2624+
TraitItemKind get_trait_item_kind () const override final
25832625
{
25842626
return TraitItemKind::TYPE;
25852627
}

gcc/rust/hir/tree/rust-hir-visitor.h

+1
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ class HIRExternalItemVisitor
311311
class HIRTraitItemVisitor
312312
{
313313
public:
314+
virtual void visit (Function &item) = 0;
314315
virtual void visit (TraitItemFunc &item) = 0;
315316
virtual void visit (TraitItemConst &item) = 0;
316317
virtual void visit (TraitItemType &item) = 0;

gcc/rust/hir/tree/rust-hir.cc

+6
Original file line numberDiff line numberDiff line change
@@ -4986,6 +4986,12 @@ Function::accept_vis (HIRImplVisitor &vis)
49864986
vis.visit (*this);
49874987
}
49884988

4989+
void
4990+
Function::accept_vis (HIRTraitItemVisitor &vis)
4991+
{
4992+
vis.visit (*this);
4993+
}
4994+
49894995
void
49904996
Union::accept_vis (HIRStmtVisitor &vis)
49914997
{

gcc/rust/hir/tree/rust-hir.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ class TraitItem : public Node, public FullVisitable
821821

822822
virtual location_t get_trait_locus () const = 0;
823823

824-
virtual TraitItemKind get_item_kind () const = 0;
824+
virtual TraitItemKind get_trait_item_kind () const = 0;
825825

826826
virtual AST::AttrVec &get_outer_attrs () = 0;
827827
virtual const AST::AttrVec &get_outer_attrs () const = 0;

0 commit comments

Comments
 (0)