From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x42e.google.com (mail-wr1-x42e.google.com [IPv6:2a00:1450:4864:20::42e]) by sourceware.org (Postfix) with ESMTPS id 575F1384FB66 for ; Tue, 21 Feb 2023 12:04:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 575F1384FB66 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com Received: by mail-wr1-x42e.google.com with SMTP id 6so3758069wrb.11 for ; Tue, 21 Feb 2023 04:04:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=DyIW1+oDgSzhRnE28nbxqnk8ukPdAgXqz5DDTys8nMk=; b=Ud25AQqgQELrw5eXsswMcECfu7QsI/hmeN1LYbXukfIXEktJAnfL/9yD2KOnTaq3pZ pdLHX1wh+8Vhai9Btb7jz4b29LKlH1WjbspQG0fyYVR0G2NZH+4yBfvzbrxbf+mYO2eI vRZJlNsdNWTcyKWX6/vZatiseIxclh7sWUqIYvQ1Hye49NOpvQKJrmv5ciXDn5JYGQf6 o2X2lxvyH+slWI78bCLSuVcBBPJFsmgjZtzgPI2YKk2WODs3nEKnzCKDyhT5c1Bedr6B lV3kQA6WZlj2odduVN/nq8spc7NmIwW03IkjIRY9orymagUIWOccov+TkzKOWQvwGM7I Ke8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:reply-to: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=DyIW1+oDgSzhRnE28nbxqnk8ukPdAgXqz5DDTys8nMk=; b=YYDKt7YsKnH2T5vZh1W4cHgdxGsI51HGi14LJGPfbWA3kk9tlwG0a41GnrsGePLIiE Mo/n/VN3ZX4ygizqkIghXMcJgGHE46FtAAB+d7gD3X9SmDLVx/4ezAtTWvAh+s4qUMWc p8Ln9o9s3L8kE3PA4LnsZATt0qpuxToruiMR0B6QPg0odnTj3nYPGD6+zXyLrHUXpQdo D9zs+L6DVRgE8gadHprAvj4cP7GVAYXNI8png9bjSDwiMSyMrxTu7DaafQ1xHP/PODu2 +YfWDa/2hnd3pwiZQufXgVLJR/zETrYaHEP+7A/iDBIVbdS87BLzfPNRovy1r0iVliac SNyQ== X-Gm-Message-State: AO0yUKXVmG+6FTn/0T7PS7waDFSe+BmpVsvAHV+dmNYy+3qKoYTAVsRp QluFBWOJaJd+hGPwPgYUx09T+syXOhokZQcHSw== X-Google-Smtp-Source: AK7set/xeNgJqR90mXcSyx/whPpK8Ad7kBildgf++kvpHakiZiEVqlLF1UA2jvlnhvIMkZ/K8kw8Ew== X-Received: by 2002:a5d:5306:0:b0:2c5:588f:c5c4 with SMTP id e6-20020a5d5306000000b002c5588fc5c4mr2804459wrv.37.1676981046911; Tue, 21 Feb 2023 04:04:06 -0800 (PST) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id c15-20020adffb4f000000b002c55b0e6ef1sm5013811wrs.4.2023.02.21.04.04.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Feb 2023 04:04:06 -0800 (PST) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Philip Herron Subject: [committed 054/103] gccrs: Support Closure calls as generic trait bounds Date: Tue, 21 Feb 2023 13:01:44 +0100 Message-Id: <20230221120230.596966-55-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230221120230.596966-1-arthur.cohen@embecosm.com> References: <20230221120230.596966-1-arthur.cohen@embecosm.com> Reply-To: arthur.cohen@embecosm.com MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,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 List-Id: From: Philip Herron gcc/rust/ChangeLog: * backend/rust-compile-expr.cc (CompileExpr::visit): Refactor checking of closures. (CompileExpr::generate_possible_fn_trait_call): New function. * backend/rust-compile-expr.h: Declare `generate_possible_fn_trait_call`. gcc/testsuite/ChangeLog: * rust/execute/torture/closure2.rs: New test. --- gcc/rust/backend/rust-compile-expr.cc | 116 +++++++++++------- gcc/rust/backend/rust-compile-expr.h | 3 + .../rust/execute/torture/closure2.rs | 32 +++++ 3 files changed, 104 insertions(+), 47 deletions(-) create mode 100644 gcc/testsuite/rust/execute/torture/closure2.rs diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index d2d9ae0a233..8169ba02b84 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -1693,53 +1693,10 @@ CompileExpr::visit (HIR::CallExpr &expr) auto fn_address = CompileExpr::Compile (expr.get_fnexpr (), ctx); // is this a closure call? - if (RS_CLOSURE_TYPE_P (TREE_TYPE (fn_address))) - { - rust_assert (tyty->get_kind () == TyTy::TypeKind::CLOSURE); - TyTy::ClosureType *closure = static_cast (tyty); - - std::vector tuple_arg_vals; - for (auto &argument : expr.get_arguments ()) - { - auto rvalue = CompileExpr::Compile (argument.get (), ctx); - tuple_arg_vals.push_back (rvalue); - } - - tree tuple_args_tyty - = TyTyResolveCompile::compile (ctx, &closure->get_parameters ()); - tree tuple_args - = ctx->get_backend ()->constructor_expression (tuple_args_tyty, false, - tuple_arg_vals, -1, - expr.get_locus ()); - - // need to apply any autoderef's to the self argument - HirId autoderef_mappings_id = expr.get_mappings ().get_hirid (); - std::vector *adjustments = nullptr; - bool ok - = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id, - &adjustments); - rust_assert (ok); - - // apply adjustments for the fn call - tree self - = resolve_adjustements (*adjustments, fn_address, expr.get_locus ()); - - // args are always self, and the tuple of the args we are passing where - // self is the path of the call-expr in this case the fn_address - std::vector args; - args.push_back (self); - args.push_back (tuple_args); - - // get the fn call address - tree closure_call_site = ctx->lookup_closure_decl (closure); - tree closure_call_address - = address_expression (closure_call_site, expr.get_locus ()); - translated - = ctx->get_backend ()->call_expression (closure_call_address, args, - nullptr /* static chain ?*/, - expr.get_locus ()); - return; - } + bool possible_trait_call + = generate_possible_fn_trait_call (expr, fn_address, &translated); + if (possible_trait_call) + return; bool is_varadic = false; if (tyty->get_kind () == TyTy::TypeKind::FNDEF) @@ -3073,5 +3030,70 @@ CompileExpr::generate_closure_fntype (HIR::ClosureExpr &expr, return TyTyResolveCompile::compile (ctx, item_tyty); } +bool +CompileExpr::generate_possible_fn_trait_call (HIR::CallExpr &expr, + tree receiver, tree *result) +{ + TyTy::FnType *fn_sig = nullptr; + bool found_overload = ctx->get_tyctx ()->lookup_operator_overload ( + expr.get_mappings ().get_hirid (), &fn_sig); + if (!found_overload) + return false; + + auto id = fn_sig->get_ty_ref (); + auto dId = fn_sig->get_id (); + + tree function = error_mark_node; + bool found_closure = ctx->lookup_function_decl (id, &function, dId, fn_sig); + if (!found_closure) + { + // something went wrong we still return true as this was meant to be an fn + // trait call + *result = error_mark_node; + return true; + } + + // need to apply any autoderef's to the self argument + HirId autoderef_mappings_id = expr.get_mappings ().get_hirid (); + std::vector *adjustments = nullptr; + bool ok = ctx->get_tyctx ()->lookup_autoderef_mappings (autoderef_mappings_id, + &adjustments); + rust_assert (ok); + + // apply adjustments for the fn call + tree self = resolve_adjustements (*adjustments, receiver, expr.get_locus ()); + + // resolve the arguments + std::vector tuple_arg_vals; + for (auto &argument : expr.get_arguments ()) + { + auto rvalue = CompileExpr::Compile (argument.get (), ctx); + tuple_arg_vals.push_back (rvalue); + } + + // this is always the 2nd argument in the function signature + tree fnty = TREE_TYPE (function); + tree fn_arg_tys = TYPE_ARG_TYPES (fnty); + tree tuple_args_tyty_chain = TREE_CHAIN (fn_arg_tys); + tree tuple_args_tyty = TREE_VALUE (tuple_args_tyty_chain); + + tree tuple_args + = ctx->get_backend ()->constructor_expression (tuple_args_tyty, false, + tuple_arg_vals, -1, + expr.get_locus ()); + + // args are always self, and the tuple of the args we are passing where + // self is the path of the call-expr in this case the fn_address + std::vector args; + args.push_back (self); + args.push_back (tuple_args); + + tree call_address = address_expression (function, expr.get_locus ()); + *result = ctx->get_backend ()->call_expression (call_address, args, + nullptr /* static chain ?*/, + expr.get_locus ()); + return true; +} + } // namespace Compile } // namespace Rust diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h index c734406e0da..150a7a4788a 100644 --- a/gcc/rust/backend/rust-compile-expr.h +++ b/gcc/rust/backend/rust-compile-expr.h @@ -152,6 +152,9 @@ protected: tree compiled_closure_tyty, TyTy::FnType **fn_tyty); + bool generate_possible_fn_trait_call (HIR::CallExpr &expr, tree receiver, + tree *result); + private: CompileExpr (Context *ctx); diff --git a/gcc/testsuite/rust/execute/torture/closure2.rs b/gcc/testsuite/rust/execute/torture/closure2.rs new file mode 100644 index 00000000000..45b3b5ce8b4 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/closure2.rs @@ -0,0 +1,32 @@ +// { dg-output "3\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +#[lang = "fn_once"] +pub trait FnOnce { + #[lang = "fn_once_output"] + type Output; + + extern "rust-call" fn call_once(self, args: Args) -> Self::Output; +} + +fn f i32>(g: F) { + let call = g(1); + unsafe { + let a = "%i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, call); + } +} + +pub fn main() -> i32 { + let a = |i: i32| { + let b = i + 2; + b + }; + f(a); + 0 +} -- 2.39.1