Skip to content

Commit 3ff0f1a

Browse files
committed
lower: Add base for lowering FormatArgs nodes
gcc/rust/ChangeLog: * Make-lang.in: Compile the new source file. * ast/rust-ast-collector.cc (TokenCollector::visit): Error out when visiting FormatArgs nodes. * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise. * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise. * ast/rust-ast.cc (FormatArgs::get_locus): New. * ast/rust-builtin-ast-nodes.h: Improve FormatArgs API. * ast/rust-fmt.cc (Pieces::~Pieces): Cleanup. (Pieces::Pieces): Likewise. * ast/rust-fmt.h (struct Pieces): Add pieces_vector member. * hir/rust-ast-lower-format-args.cc: New file. * hir/rust-ast-lower-format-args.h: New file.
1 parent afed72d commit 3ff0f1a

10 files changed

+127
-54
lines changed

gcc/rust/Make-lang.in

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ GRS_OBJS = \
118118
rust/rust-ast-lower-expr.o \
119119
rust/rust-ast-lower-type.o \
120120
rust/rust-ast-lower-stmt.o \
121+
rust/rust-ast-lower-format-args.o \
121122
rust/rust-rib.o \
122123
rust/rust-name-resolution-context.o \
123124
rust/rust-default-resolver.o \

gcc/rust/ast/rust-ast-collector.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -2810,7 +2810,8 @@ TokenCollector::visit (BareFunctionType &type)
28102810
void
28112811
TokenCollector::visit (AST::FormatArgs &fmt)
28122812
{
2813-
rust_sorry_at (0, "unimplemented format_args!() visitor");
2813+
rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
2814+
__FILE__, __LINE__);
28142815
}
28152816

28162817
} // namespace AST

gcc/rust/ast/rust-ast.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -5065,7 +5065,7 @@ FormatArgs::as_string () const
50655065
location_t
50665066
FormatArgs::get_locus () const
50675067
{
5068-
rust_unreachable ();
5068+
return loc;
50695069
}
50705070

50715071
bool

gcc/rust/ast/rust-builtin-ast-nodes.h

+8-24
Original file line numberDiff line numberDiff line change
@@ -184,48 +184,32 @@ class FormatArgs : public Expr
184184

185185
FormatArgs (location_t loc, Fmt::Pieces &&template_str,
186186
FormatArguments &&arguments)
187-
: loc (loc), template_str (std::move (template_str)),
187+
: loc (loc), template_pieces (std::move (template_str)),
188188
arguments (std::move (arguments))
189189
{}
190190

191-
FormatArgs (FormatArgs &&other)
192-
: loc (std::move (other.loc)),
193-
template_str (std::move (other.template_str)),
194-
arguments (std::move (other.arguments))
195-
{
196-
std::cerr << "[ARTHUR] moving FormatArgs" << std::endl;
197-
}
198-
199-
// FIXME: This might be invalid - we are reusing the same memory allocated
200-
// on the Rust side for `other`. This is probably valid as long as we only
201-
// ever read that memory and never write to it.
202-
FormatArgs (const FormatArgs &other)
203-
: loc (other.loc), template_str (other.template_str),
204-
arguments (other.arguments)
205-
{
206-
std::cerr << "[ARTHUR] copying FormatArgs" << std::endl;
207-
}
208-
209-
// FormatArgs &operator= (const FormatArgs &other) = default;
210-
// : template_str (other.template_str), arguments (other.arguments)
211-
// {}
191+
FormatArgs (FormatArgs &&other) = default;
192+
FormatArgs (const FormatArgs &other) = default;
193+
FormatArgs &operator= (const FormatArgs &other) = default;
212194

213195
void accept_vis (AST::ASTVisitor &vis) override;
214196

197+
const Fmt::Pieces &get_template () const { return template_pieces; }
198+
virtual location_t get_locus () const override;
199+
215200
private:
216201
location_t loc;
217202
// FIXME: This probably needs to be a separate type - it is one in rustc's
218203
// expansion of format_args!(). There is extra handling associated with it.
219204
// we can maybe do that in rust-fmt.cc? in collect_pieces()? like do the
220205
// transformation into something we can handle better
221-
Fmt::Pieces template_str;
206+
Fmt::Pieces template_pieces;
222207
FormatArguments arguments;
223208

224209
bool marked_for_strip = false;
225210

226211
protected:
227212
virtual std::string as_string () const override;
228-
virtual location_t get_locus () const override;
229213
virtual bool is_expr_without_block () const override;
230214
virtual void mark_for_strip () override;
231215
virtual bool is_marked_for_strip () const override;

gcc/rust/ast/rust-fmt.cc

+15-24
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,23 @@ Pieces::collect (std::string &&to_parse, bool append_newline)
2727
{
2828
auto piece_slice = collect_pieces (to_parse.c_str (), append_newline);
2929

30-
rust_debug ("[ARTHUR] %p, %lu", (const void *) piece_slice.base_ptr,
31-
piece_slice.len);
32-
3330
// this performs multiple copies, can we avoid them maybe?
34-
// auto pieces = std::vector<Piece> (piece_slice.base_ptr,
35-
// piece_slice.base_ptr + piece_slice.len);
36-
37-
return Pieces (piece_slice, std::move (to_parse));
31+
// TODO: Instead of just creating a vec of, basically, `ffi::Piece`s, we
32+
// should transform them into the proper C++ type which we can work with. so
33+
// transform all the strings into C++ strings? all the Option<T> into
34+
// tl::optional<T>?
35+
auto pieces = std::vector<Piece> (piece_slice.base_ptr,
36+
piece_slice.base_ptr + piece_slice.len);
37+
38+
return Pieces (std::move (pieces), piece_slice, std::move (to_parse));
3839
}
3940

40-
Pieces::~Pieces ()
41-
{
42-
std::cerr << "Arthur: destoying pieces. this: " << (void *) this
43-
<< " slice: " << slice.base_ptr << std::endl;
44-
destroy_pieces (slice);
45-
}
41+
Pieces::~Pieces () { destroy_pieces (slice); }
4642

47-
Pieces::Pieces (const Pieces &other) : to_parse (other.to_parse)
43+
Pieces::Pieces (const Pieces &other)
44+
: pieces_vector (other.pieces_vector), to_parse (other.to_parse)
4845
{
4946
slice = clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap);
50-
std::cerr << "Arthur: copying pieces: other.to_parse: "
51-
<< (void *) other.to_parse.c_str ()
52-
<< " ours to_parse: " << (void *) to_parse.c_str () << std::endl;
53-
// auto pieces = std::vector (slice.base_ptr, slice.base_ptr + slice.len);
5447
}
5548

5649
Pieces &
@@ -63,13 +56,11 @@ Pieces::operator= (const Pieces &other)
6356
}
6457

6558
Pieces::Pieces (Pieces &&other)
66-
: slice (
67-
clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap)),
59+
: pieces_vector (std::move (other.pieces_vector)),
60+
slice (
61+
clone_pieces (other.slice.base_ptr, other.slice.len, other.slice.cap)),
6862
to_parse (std::move (other.to_parse))
69-
{
70-
std::cerr << "Arthur: moving pieces. to_parse: " << (void *) to_parse.c_str ()
71-
<< " base_ptr/slice: " << (void *) slice.base_ptr << std::endl;
72-
}
63+
{}
7364

7465
} // namespace Fmt
7566
} // namespace Rust

gcc/rust/ast/rust-fmt.h

+11-2
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ struct Pieces
262262

263263
Pieces (Pieces &&other);
264264

265+
const std::vector<Piece> &get_pieces () const { return pieces_vector; }
266+
265267
// {
266268
// slice = clone_pieces (&other.slice);
267269
// to_parse = other.to_parse;
@@ -270,10 +272,17 @@ struct Pieces
270272
// }
271273

272274
private:
273-
Pieces (PieceSlice slice, std::string &&to_parse)
274-
: slice (slice), to_parse (std::move (to_parse))
275+
Pieces (std::vector<Piece> &&pieces_vector, PieceSlice slice,
276+
std::string &&to_parse)
277+
: pieces_vector (std::move (pieces_vector)), slice (slice),
278+
to_parse (std::move (to_parse))
275279
{}
276280

281+
std::vector<Piece> pieces_vector;
282+
283+
// this memory is held for FFI reasons - it needs to be released and cloned
284+
// precisely, so try to not access it/modify it if possible. you should
285+
// instead work with `pieces_vector`
277286
PieceSlice slice;
278287
std::string to_parse;
279288
};

gcc/rust/hir/rust-ast-lower-expr.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "rust-ast-lower-expr.h"
2020
#include "rust-ast-lower-base.h"
2121
#include "rust-ast-lower-block.h"
22+
#include "rust-ast-lower-format-args.h"
2223
#include "rust-ast-lower-struct-field-expr.h"
2324
#include "rust-ast-lower-pattern.h"
2425
#include "rust-ast-lower-type.h"
@@ -833,7 +834,11 @@ ASTLoweringExpr::visit (AST::ClosureExprInnerTyped &expr)
833834
void
834835
ASTLoweringExpr::visit (AST::FormatArgs &fmt)
835836
{
836-
rust_sorry_at (0, "unimplemented format_args!() visitor");
837+
// Lowering FormatArgs is complex, and this file is already very long
838+
translated = FormatArgsLowering ().go (fmt);
839+
840+
rust_sorry_at (fmt.get_locus (),
841+
"FormatArgs lowering is not implemented yet");
837842
}
838843

839844
} // namespace HIR
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (C) 2024 Free Software Foundation, Inc.
2+
3+
// This file is part of GCC.
4+
5+
// GCC is free software; you can redistribute it and/or modify it under
6+
// the terms of the GNU General Public License as published by the Free
7+
// Software Foundation; either version 3, or (at your option) any later
8+
// version.
9+
10+
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11+
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
// for more details.
14+
15+
// You should have received a copy of the GNU General Public License
16+
// along with GCC; see the file COPYING3. If not see
17+
// <http://www.gnu.org/licenses/>.
18+
19+
#include "rust-ast-lower-format-args.h"
20+
#include "rust-ast-full.h"
21+
#include "rust-hir-full.h"
22+
23+
namespace Rust {
24+
namespace HIR {
25+
26+
FormatArgsLowering::FormatArgsLowering () {}
27+
28+
HIR::Expr *
29+
FormatArgsLowering::go (AST::FormatArgs &fmt)
30+
{
31+
// Eventually, we will ned to perform format_args!() expansion as part of HIR
32+
// lowering - this enables a couple of interesting optimizations such as
33+
// format_args flattening and the inlining of constants into the format
34+
// strings. However, this is not a priority at the moment and it is easier to
35+
// do "regular" macro expansion for `format_arsg!()`
36+
37+
return nullptr;
38+
}
39+
40+
} // namespace HIR
41+
} // namespace Rust
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (C) 2024 Free Software Foundation, Inc.
2+
3+
// This file is part of GCC.
4+
5+
// GCC is free software; you can redistribute it and/or modify it under
6+
// the terms of the GNU General Public License as published by the Free
7+
// Software Foundation; either version 3, or (at your option) any later
8+
// version.
9+
10+
// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11+
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
// for more details.
14+
15+
// You should have received a copy of the GNU General Public License
16+
// along with GCC; see the file COPYING3. If not see
17+
// <http://www.gnu.org/licenses/>.
18+
19+
#ifndef RUST_AST_LOWER_FORMAT_ARGS
20+
#define RUST_AST_LOWER_FORMAT_ARGS
21+
22+
#include "rust-ast-full-decls.h"
23+
#include "rust-hir-full-decls.h"
24+
25+
namespace Rust {
26+
namespace HIR {
27+
28+
class FormatArgsLowering
29+
{
30+
public:
31+
FormatArgsLowering ();
32+
HIR::Expr *go (AST::FormatArgs &fmt);
33+
34+
private:
35+
};
36+
37+
} // namespace HIR
38+
} // namespace Rust
39+
40+
#endif // ! RUST_AST_LOWER_FORMAT_ARGS

gcc/rust/resolve/rust-ast-resolve-base.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,8 @@ ResolverBase::visit (AST::FunctionParam &)
653653
void
654654
ResolverBase::visit (AST::FormatArgs &fmt)
655655
{
656-
rust_sorry_at (0, "unimplemented format_args!() visitor");
656+
rust_sorry_at (fmt.get_locus (), "%s:%u: unimplemented FormatArgs visitor",
657+
__FILE__, __LINE__);
657658
}
658659

659660
} // namespace Resolver

0 commit comments

Comments
 (0)