Skip to content

Commit

Permalink
gccrs: v0-mangle closures
Browse files Browse the repository at this point in the history
gcc/rust/ChangeLog:

	* backend/rust-compile-expr.cc (CompileExpr::generate_closure_function):
	Fix reference to node.
	* backend/rust-mangle.cc (struct V0Path): Modified to accept closures.
	(v0_crate_path): Modified to accept closures.
	(v0_closure): New function to mangle closures.
	(v0_path): Modified to accept closures
	* util/rust-mapping-common.h (UNKNOWN_NODEID): Change to UINT32_MAX.
	(UNKNOWN_HIRID): Change to UINT32_MAX.

gcc/testsuite/ChangeLog:

	* rust/compile/v0-mangle2.rs: New test.

Signed-off-by: Raiki Tamura <[email protected]>
  • Loading branch information
tamaroning authored and CohenArthur committed Nov 15, 2023
1 parent facd325 commit 31c5637
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 10 deletions.
6 changes: 5 additions & 1 deletion gcc/rust/backend/rust-compile-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2219,8 +2219,12 @@ CompileExpr::generate_closure_function (HIR::ClosureExpr &expr,

const Resolver::CanonicalPath &parent_canonical_path
= closure_tyty.get_ident ().path;
NodeId node_id;
bool ok = ctx->get_mappings ()->lookup_hir_to_node (
expr.get_mappings ().get_hirid (), &node_id);
rust_assert (ok);
Resolver::CanonicalPath path = parent_canonical_path.append (
Resolver::CanonicalPath::new_seg (UNKNOWN_NODEID, "{{closure}}"));
Resolver::CanonicalPath::new_seg (node_id, "{{closure}}"));

std::string ir_symbol_name = path.get ();
std::string asm_name = ctx->mangle_item (&closure_tyty, path);
Expand Down
33 changes: 26 additions & 7 deletions gcc/rust/backend/rust-mangle.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ struct V0Path
std::string path = "";
// Used for "N" and "C"
std::string ident = "";
// Used for "C"
std::string crate_disambiguator = "";
std::string disambiguator = "";
// Used for "M" and "X"
std::string impl_path = "";
std::string impl_type = "";
Expand All @@ -58,13 +57,14 @@ struct V0Path
std::string as_string () const
{
if (prefix == "N")
return generic_prefix + prefix + ns + path + ident + generic_postfix;
return generic_prefix + prefix + ns + path + disambiguator + ident
+ generic_postfix;
else if (prefix == "M")
return prefix + impl_path + impl_type;
else if (prefix == "X")
return prefix + impl_type + trait_type;
else if (prefix == "C")
return prefix + crate_disambiguator + ident;
return prefix + disambiguator + ident;
else
rust_unreachable ();
}
Expand Down Expand Up @@ -427,7 +427,7 @@ v0_crate_path (CrateNum crate_num, std::string ident)
{
V0Path v0path;
v0path.prefix = "C";
v0path.crate_disambiguator = v0_disambiguator (crate_num);
v0path.disambiguator = v0_disambiguator (crate_num);
v0path.ident = ident;
return v0path;
}
Expand Down Expand Up @@ -468,6 +468,18 @@ v0_inherent_or_trait_impl_path (Rust::Compile::Context *ctx,
return v0path;
}

static V0Path
v0_closure (V0Path path, HirId closure)
{
V0Path v0path;
v0path.prefix = "N";
v0path.ns = "C";
v0path.disambiguator = v0_disambiguator (closure);
v0path.path = path.as_string ();
v0path.ident = "0";
return v0path;
}

static std::string
v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
const Resolver::CanonicalPath &cpath)
Expand All @@ -490,6 +502,7 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
= mappings->lookup_hir_implitem (hir_id, &parent_impl_id);
HIR::TraitItem *trait_item = mappings->lookup_hir_trait_item (hir_id);
HIR::Item *item = mappings->lookup_hir_item (hir_id);
HIR::Expr *expr = mappings->lookup_hir_expr (hir_id);

if (impl_item != nullptr)
{
Expand Down Expand Up @@ -567,10 +580,16 @@ v0_path (Rust::Compile::Context *ctx, const TyTy::BaseType *ty,
cpath.get ().c_str ());
break;
}
else if (expr != nullptr)
{
rust_assert (expr->get_expression_type ()
== HIR::Expr::ExprType::Closure);
// Use HIR ID as disambiguator.
v0path = v0_closure (v0path, hir_id);
}
else
{
// Not HIR item, impl item, nor trait impl item. Assume a crate.
// FIXME: Do closures get here?
// Not HIR item, impl item, trait impl item, nor expr. Assume a crate.

// std::string crate_name;
// bool ok = mappings->get_crate_name (path.get_crate_num (),
Expand Down
4 changes: 2 additions & 2 deletions gcc/rust/util/rust-mapping-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ struct DefId
};

#define UNKNOWN_CRATENUM ((uint32_t) (UINT32_MAX))
#define UNKNOWN_NODEID ((uint32_t) (0))
#define UNKNOWN_HIRID ((uint32_t) (0))
#define UNKNOWN_NODEID ((uint32_t) (UINT32_MAX))
#define UNKNOWN_HIRID ((uint32_t) (UINT32_MAX))
#define UNKNOWN_LOCAL_DEFID ((uint32_t) (0))
#define UNKNOWN_DEFID (DefId{0, 0})

Expand Down
17 changes: 17 additions & 0 deletions gcc/testsuite/rust/compile/v0-mangle2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// { dg-additional-options -frust-mangling=v0 }
#[lang = "sized"]
pub trait Sized {}

#[lang = "fn_once"]
pub trait FnOnce<Args> {
#[lang = "fn_once_output"]
type Output;

extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

fn main() {
// { dg-final { scan-assembler "_R.*NC.*NvC.*10v0_mangle24main.*0" } }
let closure_annotated = |i: i32| -> i32 { i + 1 };
let _ = closure_annotated(0) - 1;
}

0 comments on commit 31c5637

Please sign in to comment.