From patchwork Thu Aug 1 14:56:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arthur Cohen X-Patchwork-Id: 94992 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 922703861000 for ; Thu, 1 Aug 2024 15:16:55 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by sourceware.org (Postfix) with ESMTPS id B54223860C37 for ; Thu, 1 Aug 2024 14:59:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B54223860C37 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org B54223860C37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::52b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722524382; cv=none; b=KGLZGjWoxPZc4rO3XlPvTr7uwXYs4JgyDjAjlM9hvTFKaiiFAiCPmFJ46bln9/hRlUQsEQSVDIx0ZbwqTbo+VXCMA67mSM7fQoO0RSQxmNSGpn6qtMQUSa+vkUCnKgm7rs/ZjXF6Wxu4qk1KMQ6xp/PsQeY51yzb7hjMXQEuwMY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722524382; c=relaxed/simple; bh=yfdYLQKBWFegZjc/t7sK7mgZvL+aVFBgOgR+rhitFMQ=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=EoDvl7Vq4W0uzYSl+VJ/LxRhwqrglB2am+vWrhQYnU0+zNCh91fz9cIKWW3Hs6TpVuP3LHMxFT+qxd35O2IIdtBIx1l5UlIUtecT12l4nWgIaBsWtV42EjqYWEIYyr9SPKo8iASN7IMV6HwG8zrk6bNYiO6fAdI8U6o6OtaIRyI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ed1-x52b.google.com with SMTP id 4fb4d7f45d1cf-5afa207b8bfso7403499a12.0 for ; Thu, 01 Aug 2024 07:59:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1722524350; x=1723129150; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/+mUTrquhjgxe0PlxrytdHuwxlK3UlHfqedJVdom2SY=; b=J0oTlbBLA4Np9M8kMS654vil74mn1YQzd2dAR9EEXhbfIqAGrvSMhBLkJn3gRYDTGa xMbJIKlSoVX5p1EVGrKkrmWtXrcO4wJy9WDQmpYWetftml1OmU6luJtQcibeO3DGiM1L HApAlTCbL9mbmAHs5E1+NZyNrVXJn6OtQgqVZ7fCEnAQRq+6MCyQhHIk4f17Ghyq29BH ZAu0bCaj87npFvZVQWGpDoPKLXVSI8ob9aKTYm+BIhFoflxTKRN40lYycVINAwzQMRv8 Nm43xZdORNHuLRNWQ9dWbFxFZTbeiX0m6mfQwiZwnBBNFxqyaG2qZRLGY1sOBYZczk4U mNYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722524350; x=1723129150; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/+mUTrquhjgxe0PlxrytdHuwxlK3UlHfqedJVdom2SY=; b=hgmf0F9C/68KqOSfLLscEwKfwTkuf6l/oy+LOUXQB7wikXjAb5urrhR2en7oqz0rMR eGoWKKOXMZ1RRLnCueFtIHsrIbLXe2Ak7RfXwS1p6wFuBYK+ZiupFN/hN5MfBC2+Rr/8 LxBv1xfMHaKYMQe/N8iQkqiP/hyIWrDBCm6nXwN6hRkpwh7Wt66IbMhZAAiPLXNL07uI daNjME27YV0W5ubwbD5zbCFiwmMRHy7al7Dz9PBZbjM1jf1rJ9JpX3nIYU0gFmDhUbWS 3DntwIZz3v4mH2Gz7TdQRPH7LQbIOUhN1zX2CF9j2LVEvI7uNpZDW34oYhje1oj1I6gy QwwA== X-Gm-Message-State: AOJu0Yy40S5yqCAuNECi7hakRM4VoLL1Dx9J2J7MlH6LKdpkGVBv5Tr3 YyQxNvC1dPQft8U5SdK7GURZ8WU/YYkXHH+NDFvbnLrrmhbNdoPFLa9+rJXA6JRPnkvoXlpksDF ySRpI X-Google-Smtp-Source: AGHT+IFqAeEKjxAaECqiygllyorl3lb672rM1ckd00cI8YezIS91omn5wgAcx7dUs2X5wpKuXE7wWw== X-Received: by 2002:a05:6402:40c:b0:59e:a1a6:134d with SMTP id 4fb4d7f45d1cf-5b7f56fc987mr429891a12.32.1722524349950; Thu, 01 Aug 2024 07:59:09 -0700 (PDT) Received: from platypus.lan ([2a04:cec2:9:dc84:3622:6733:ff49:ee91]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5ac63590592sm10252456a12.25.2024.08.01.07.59.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Aug 2024 07:59:09 -0700 (PDT) From: Arthur Cohen To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Arthur Cohen Subject: [PATCH 049/125] gccrs: format-args: Add basic expansion of unnamed Display::fmt arguments. Date: Thu, 1 Aug 2024 16:56:45 +0200 Message-ID: <20240801145809.366388-51-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240801145809.366388-2-arthur.cohen@embecosm.com> References: <20240801145809.366388-2-arthur.cohen@embecosm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-14.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~patchwork=sourceware.org@gcc.gnu.org gcc/rust/ChangeLog: * ast/rust-ast-builder.h: Rename AST::AstBuilder -> AST::Builder * ast/rust-ast-builder.cc: Likewise. * expand/rust-derive.cc: Use new AST::Builder name. * expand/rust-derive.h: Likewise. * ast/rust-builtin-ast-nodes.h: Add required getters. * expand/rust-expand-format-args.cc (format_arg): New. (get_trait_name): New. (expand_format_args): Properly expand basic format_args!() invocations. * expand/rust-expand-format-args.h (expand_format_args): Fix signature. * expand/rust-macro-builtins.cc (MacroBuiltin::format_args_handler): Call into expand_format_args(). --- gcc/rust/ast/rust-ast-builder.cc | 66 ++++++++----- gcc/rust/ast/rust-ast-builder.h | 51 ++++++---- gcc/rust/ast/rust-builtin-ast-nodes.h | 5 + gcc/rust/expand/rust-derive.cc | 2 +- gcc/rust/expand/rust-derive.h | 2 +- gcc/rust/expand/rust-expand-format-args.cc | 107 +++++++++++++++++++-- gcc/rust/expand/rust-expand-format-args.h | 5 +- gcc/rust/expand/rust-macro-builtins.cc | 23 +++-- 8 files changed, 205 insertions(+), 56 deletions(-) diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index 0d5218c6381..1138d3dc2b2 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -17,53 +17,73 @@ // . #include "rust-ast-builder.h" +#include "rust-ast-full-decls.h" #include "rust-ast-full.h" +#include "rust-expr.h" +#include "rust-token.h" +#include "rust-make-unique.h" namespace Rust { namespace AST { std::unique_ptr -AstBuilder::call (std::unique_ptr &&path, - std::vector> &&args) +Builder::literal_string (std::string &&content) const +{ + return std::unique_ptr ( + new AST::LiteralExpr (std::move (content), Literal::LitType::STRING, + PrimitiveCoreType::CORETYPE_STR, {}, loc)); +} + +std::unique_ptr +Builder::call (std::unique_ptr &&path, + std::vector> &&args) const { return std::unique_ptr ( new CallExpr (std::move (path), std::move (args), {}, loc)); } std::unique_ptr -AstBuilder::identifier (std::string name) +Builder::array (std::vector> &&members) const +{ + auto elts = Rust::make_unique (std::move (members), loc); + + return std::unique_ptr (new ArrayExpr (std::move (elts), {}, {}, loc)); +} + +std::unique_ptr +Builder::identifier (std::string name) const { return std::unique_ptr (new IdentifierExpr (name, {}, loc)); } std::unique_ptr -AstBuilder::tuple_idx (std::string receiver, int idx) +Builder::tuple_idx (std::string receiver, int idx) const { return std::unique_ptr ( new TupleIndexExpr (identifier (receiver), idx, {}, loc)); } FunctionQualifiers -AstBuilder::fn_qualifiers () +Builder::fn_qualifiers () const { return FunctionQualifiers (loc, Async::No, Const::No, Unsafety::Normal); } PathExprSegment -AstBuilder::path_segment (std::string seg) +Builder::path_segment (std::string seg) const { return PathExprSegment (PathIdentSegment (seg, loc), loc); } std::unique_ptr -AstBuilder::type_path_segment (std::string seg) +Builder::type_path_segment (std::string seg) const { return std::unique_ptr ( new TypePathSegment (seg, false, loc)); } std::unique_ptr -AstBuilder::single_type_path (std::string type) +Builder::single_type_path (std::string type) const { auto segments = std::vector> (); segments.emplace_back (type_path_segment (type)); @@ -72,7 +92,7 @@ AstBuilder::single_type_path (std::string type) } PathInExpression -AstBuilder::path_in_expression (std::vector &&segments) +Builder::path_in_expression (std::vector &&segments) const { auto path_segments = std::vector (); for (auto &seg : segments) @@ -82,8 +102,8 @@ AstBuilder::path_in_expression (std::vector &&segments) } std::unique_ptr -AstBuilder::block (std::vector> &&stmts, - std::unique_ptr &&tail_expr) +Builder::block (std::vector> &&stmts, + std::unique_ptr &&tail_expr) const { return std::unique_ptr (new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {}, @@ -91,8 +111,8 @@ AstBuilder::block (std::vector> &&stmts, } std::unique_ptr -AstBuilder::let (std::unique_ptr pattern, std::unique_ptr type, - std::unique_ptr init) +Builder::let (std::unique_ptr pattern, std::unique_ptr type, + std::unique_ptr init) const { return std::unique_ptr (new LetStmt (std::move (pattern), std::move (init), std::move (type), @@ -100,28 +120,29 @@ AstBuilder::let (std::unique_ptr pattern, std::unique_ptr type, } std::unique_ptr -AstBuilder::ref (std::unique_ptr &&of, bool mut) +Builder::ref (std::unique_ptr &&of, bool mut) const { return std::unique_ptr ( new BorrowExpr (std::move (of), mut, /* is double */ false, {}, loc)); } std::unique_ptr -AstBuilder::deref (std::unique_ptr &&of) +Builder::deref (std::unique_ptr &&of) const { return std::unique_ptr (new DereferenceExpr (std::move (of), {}, loc)); } std::unique_ptr -AstBuilder::struct_expr_struct (std::string struct_name) +Builder::struct_expr_struct (std::string struct_name) const { return std::unique_ptr ( new StructExprStruct (path_in_expression ({struct_name}), {}, {}, loc)); } std::unique_ptr -AstBuilder::struct_expr (std::string struct_name, - std::vector> &&fields) +Builder::struct_expr ( + std::string struct_name, + std::vector> &&fields) const { return std::unique_ptr ( new StructExprStructFields (path_in_expression ({struct_name}), @@ -129,22 +150,23 @@ AstBuilder::struct_expr (std::string struct_name, } std::unique_ptr -AstBuilder::struct_expr_field (std::string field_name, - std::unique_ptr &&value) +Builder::struct_expr_field (std::string field_name, + std::unique_ptr &&value) const { return std::unique_ptr ( new StructExprFieldIdentifierValue (field_name, std::move (value), loc)); } std::unique_ptr -AstBuilder::field_access (std::unique_ptr &&instance, std::string field) +Builder::field_access (std::unique_ptr &&instance, + std::string field) const { return std::unique_ptr ( new FieldAccessExpr (std::move (instance), field, {}, loc)); } std::unique_ptr -AstBuilder::wildcard () +Builder::wildcard () const { return std::unique_ptr (new WildcardPattern (loc)); } diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h index c0b4fa7b2cb..5c33954131f 100644 --- a/gcc/rust/ast/rust-ast-builder.h +++ b/gcc/rust/ast/rust-ast-builder.h @@ -28,80 +28,93 @@ namespace AST { /* Builder class with helper methods to create AST nodes. This builder is * tailored towards generating multiple AST nodes from a single location, and * may not be suitable to other purposes */ -class AstBuilder +class Builder { public: - AstBuilder (location_t loc) : loc (loc) {} + Builder (location_t loc) : loc (loc) {} + + /* Create a string literal expression ("content") */ + std::unique_ptr literal_string (std::string &&content) const; /* Create an identifier expression (`variable`) */ - std::unique_ptr identifier (std::string name); + std::unique_ptr identifier (std::string name) const; /* Create a tuple index expression (`receiver.0`) */ - std::unique_ptr tuple_idx (std::string receiver, int idx); + std::unique_ptr tuple_idx (std::string receiver, int idx) const; /* Create a reference to an expression (`&of`) */ - std::unique_ptr ref (std::unique_ptr &&of, bool mut = false); + std::unique_ptr ref (std::unique_ptr &&of, + bool mut = false) const; /* Create a dereference of an expression (`*of`) */ - std::unique_ptr deref (std::unique_ptr &&of); + std::unique_ptr deref (std::unique_ptr &&of) const; /* Create a block with an optional tail expression */ std::unique_ptr block (std::vector> &&stmts, - std::unique_ptr &&tail_expr = nullptr); + std::unique_ptr &&tail_expr + = nullptr) const; /* Create a let binding with an optional type and initializer (`let : * = `) */ std::unique_ptr let (std::unique_ptr pattern, std::unique_ptr type = nullptr, - std::unique_ptr init = nullptr); + std::unique_ptr init = nullptr) const; /** * Create a call expression to a function, struct or enum variant, given its * arguments (`path(arg0, arg1, arg2)`) */ std::unique_ptr call (std::unique_ptr &&path, - std::vector> &&args); + std::vector> &&args) const; + + /** + * Create an array expression (`[member0, member1, member2]`) + */ + std::unique_ptr + array (std::vector> &&members) const; /* Empty function qualifiers, with no specific qualifiers */ - FunctionQualifiers fn_qualifiers (); + FunctionQualifiers fn_qualifiers () const; /* Create a single path segment from one string */ - PathExprSegment path_segment (std::string seg); + PathExprSegment path_segment (std::string seg) const; /* And similarly for type path segments */ - std::unique_ptr type_path_segment (std::string seg); + std::unique_ptr type_path_segment (std::string seg) const; /* Create a Type from a single string - the most basic kind of type in our AST */ - std::unique_ptr single_type_path (std::string type); + std::unique_ptr single_type_path (std::string type) const; /** * Create a path in expression from multiple segments (`Clone::clone`). You * do not need to separate the segments using `::`, you can simply provide a * vector of strings to the functions which will get turned into path segments */ - PathInExpression path_in_expression (std::vector &&segments); + PathInExpression + path_in_expression (std::vector &&segments) const; /* Create a struct expression for unit structs (`S`) */ - std::unique_ptr struct_expr_struct (std::string struct_name); + std::unique_ptr struct_expr_struct (std::string struct_name) const; /** * Create an expression for struct instantiation with fields (`S { a, b: c }`) */ std::unique_ptr struct_expr (std::string struct_name, - std::vector> &&fields); + std::vector> &&fields) const; /* Create a field expression for struct instantiation (`field_name: value`) */ std::unique_ptr - struct_expr_field (std::string field_name, std::unique_ptr &&value); + struct_expr_field (std::string field_name, + std::unique_ptr &&value) const; /* Create a field access expression (`instance.field`) */ std::unique_ptr field_access (std::unique_ptr &&instance, - std::string field); + std::string field) const; /* Create a wildcard pattern (`_`) */ - std::unique_ptr wildcard (); + std::unique_ptr wildcard () const; private: /** diff --git a/gcc/rust/ast/rust-builtin-ast-nodes.h b/gcc/rust/ast/rust-builtin-ast-nodes.h index 780d1a9d4e9..3e21d7e718d 100644 --- a/gcc/rust/ast/rust-builtin-ast-nodes.h +++ b/gcc/rust/ast/rust-builtin-ast-nodes.h @@ -132,6 +132,9 @@ public: return *this; } + FormatArgumentKind get_kind () const { return kind; } + const Expr &get_expr () const { return *expr; } + private: FormatArgument (FormatArgumentKind::Kind kind, tl::optional ident, std::unique_ptr expr) @@ -159,6 +162,7 @@ public: FormatArguments &operator= (const FormatArguments &other) = default; void push (FormatArgument &&elt) { args.emplace_back (std::move (elt)); } + const FormatArgument at (size_t idx) const { return args.at (idx); } private: std::vector args; @@ -195,6 +199,7 @@ public: void accept_vis (AST::ASTVisitor &vis) override; const Fmt::Pieces &get_template () const { return template_pieces; } + const FormatArguments &get_arguments () const { return arguments; } virtual location_t get_locus () const override; private: diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc index e9927df1559..4177004eccf 100644 --- a/gcc/rust/expand/rust-derive.cc +++ b/gcc/rust/expand/rust-derive.cc @@ -24,7 +24,7 @@ namespace Rust { namespace AST { DeriveVisitor::DeriveVisitor (location_t loc) - : loc (loc), builder (AstBuilder (loc)) + : loc (loc), builder (Builder (loc)) {} std::unique_ptr diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h index cbe5bbbcbea..48f6594a636 100644 --- a/gcc/rust/expand/rust-derive.h +++ b/gcc/rust/expand/rust-derive.h @@ -41,7 +41,7 @@ protected: DeriveVisitor (location_t loc); location_t loc; - AstBuilder builder; + Builder builder; private: // the 4 "allowed" visitors, which a derive-visitor can specify and override diff --git a/gcc/rust/expand/rust-expand-format-args.cc b/gcc/rust/expand/rust-expand-format-args.cc index 276ffd58c50..3f76344ea5b 100644 --- a/gcc/rust/expand/rust-expand-format-args.cc +++ b/gcc/rust/expand/rust-expand-format-args.cc @@ -17,27 +17,122 @@ // . #include "rust-expand-format-args.h" +#include "rust-ast-fragment.h" +#include "rust-ast.h" #include "rust-builtin-ast-nodes.h" +#include "rust-ast-builder.h" +#include "rust-diagnostics.h" +#include "rust-expr.h" +#include "rust-fmt.h" +#include "rust-path.h" +#include "rust-system.h" +#include "rust-token.h" namespace Rust { +namespace Fmt { + +static std::unique_ptr +format_arg (const AST::Builder &builder, std::unique_ptr &&to_format, + const std::string &trait) +{ + auto formatter_fn = std::unique_ptr (new AST::PathInExpression ( + builder.path_in_expression ({"core", "fmt", trait, "fmt"}))); + + auto path = std::unique_ptr (new AST::PathInExpression ( + builder.path_in_expression ({"core", "fmt", "ArgumentV1", "new"}))); + + auto args = std::vector> (); + args.emplace_back (std::move (to_format)); + args.emplace_back (std::move (formatter_fn)); + + return builder.call (std::move (path), std::move (args)); +} + +const std::string & +get_trait_name (ffi::FormatSpec format_specifier) +{ + static const std::unordered_map spec_map = { + {"", "Display"}, {"?", "Debug"}, {"e", "LowerExp"}, + {"E", "UpperExp"}, {"o", "Octal"}, {"p", "Pointer"}, + {"b", "Binary"}, {"x", "LowerHex"}, {"X", "UpperHex"}, + }; + + auto it = spec_map.find (format_specifier.ty.to_string ()); + + if (it == spec_map.end ()) + rust_unreachable (); + + return it->second; +} tl::optional -expand_format_args (AST::FormatArgs &fmt) +expand_format_args (AST::FormatArgs &fmt, + std::vector> &&tokens) { + auto loc = fmt.get_locus (); + auto builder = AST::Builder (loc); + auto &arguments = fmt.get_arguments (); + + auto static_pieces = std::vector> (); + auto args + = std::vector, ffi::FormatSpec>> (); + for (const auto &node : fmt.get_template ().get_pieces ()) { switch (node.tag) { - case Fmt::ffi::Piece::Tag::String: - // rust_debug ("[ARTHUR]: %s", node.string._0.c_str ()); + case ffi::Piece::Tag::String: + static_pieces.emplace_back ( + builder.literal_string (node.string._0.to_string ())); + break; + case ffi::Piece::Tag::NextArgument: { + auto next_argument = node.next_argument._0; + switch (node.next_argument._0.position.tag) + { + case ffi::Position::Tag::ArgumentImplicitlyIs: { + auto idx = next_argument.position.argument_implicitly_is._0; + auto trait = next_argument.format; + auto arg = arguments.at (idx); + + // FIXME(Arthur): This API sucks + rust_assert (arg.get_kind ().kind + == AST::FormatArgumentKind::Kind::Normal); - case Fmt::ffi::Piece::Tag::NextArgument: - rust_debug ("[ARTHUR]: NextArgument"); + args.push_back ({arg.get_expr ().clone_expr (), trait}); + } + break; + case ffi::Position::Tag::ArgumentIs: + case ffi::Position::Tag::ArgumentNamed: + rust_sorry_at (loc, "unhandled argument position specifier"); + break; + } + } break; } } - return tl::nullopt; + auto args_array = std::vector> (); + for (auto &&arg : args) + args_array.emplace_back (format_arg (builder, + builder.ref (std::move (arg.first)), + get_trait_name (arg.second))); + + auto pieces = builder.ref (builder.array (std::move (static_pieces))); + auto args_slice = builder.ref (builder.array (std::move (args_array))); + + auto final_path = make_unique ( + builder.path_in_expression ({"core", "fmt", "Arguments", "new_v1"})); + auto final_args = std::vector> (); + final_args.emplace_back (std::move (pieces)); + final_args.emplace_back (std::move (args_slice)); + + auto final_call + = builder.call (std::move (final_path), std::move (final_args)); + + auto node = AST::SingleASTNode (std::move (final_call)); + + return AST::Fragment ({node}, std::move (tokens)); } +} // namespace Fmt } // namespace Rust diff --git a/gcc/rust/expand/rust-expand-format-args.h b/gcc/rust/expand/rust-expand-format-args.h index 1481f3605ed..0a17de53597 100644 --- a/gcc/rust/expand/rust-expand-format-args.h +++ b/gcc/rust/expand/rust-expand-format-args.h @@ -23,10 +23,13 @@ #include "rust-ast-fragment.h" namespace Rust { +namespace Fmt { tl::optional -expand_format_args (AST::FormatArgs &fmt); +expand_format_args (AST::FormatArgs &fmt, + std::vector> &&tokens); +} // namespace Fmt } // namespace Rust #endif //! RUST_EXPAND_FORMAT_ARGS_H diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index 8cf32051c7a..112713a4f97 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -20,6 +20,7 @@ #include "libproc_macro_internal/tokenstream.h" #include "rust-ast-full-decls.h" #include "rust-builtin-ast-nodes.h" +#include "rust-expand-format-args.h" #include "rust-token-converter.h" #include "rust-system.h" #include "rust-macro-builtins.h" @@ -1102,13 +1103,23 @@ MacroBuiltin::format_args_handler (location_t invoc_locus, // TODO: we now need to take care of creating `unfinished_literal`? this is // for creating the `template` - auto fmt_args_node = new AST::FormatArgs (invoc_locus, std::move (pieces), - std::move (input->args)); - auto node = std::unique_ptr (fmt_args_node); - auto single_node = AST::SingleASTNode (std::move (node)); + auto fmt_args_node = AST::FormatArgs (invoc_locus, std::move (pieces), + std::move (input->args)); - return AST::Fragment ({std::move (single_node)}, - invoc.get_delim_tok_tree ().to_token_stream ()); + auto expanded + = Fmt::expand_format_args (fmt_args_node, + invoc.get_delim_tok_tree ().to_token_stream ()); + + if (!expanded.has_value ()) + return AST::Fragment::create_error (); + + return *expanded; + + // auto node = std::unique_ptr (fmt_args_node); + // auto single_node = AST::SingleASTNode (std::move (node)); + + // return AST::Fragment ({std::move (single_node)}, + // invoc.get_delim_tok_tree ().to_token_stream ()); } tl::optional