diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index 71eeb076672a..a5c853f17f50 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -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); diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc index 8d104846b847..e1c9e9427c58 100644 --- a/gcc/rust/backend/rust-mangle.cc +++ b/gcc/rust/backend/rust-mangle.cc @@ -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 = ""; @@ -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 (); } @@ -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; } @@ -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) @@ -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) { @@ -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 (), diff --git a/gcc/rust/util/rust-mapping-common.h b/gcc/rust/util/rust-mapping-common.h index 93df863bf673..725eae2a51f3 100644 --- a/gcc/rust/util/rust-mapping-common.h +++ b/gcc/rust/util/rust-mapping-common.h @@ -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}) diff --git a/gcc/testsuite/rust/compile/v0-mangle2.rs b/gcc/testsuite/rust/compile/v0-mangle2.rs new file mode 100644 index 000000000000..d092dcc7a196 --- /dev/null +++ b/gcc/testsuite/rust/compile/v0-mangle2.rs @@ -0,0 +1,17 @@ +// { dg-additional-options -frust-mangling=v0 } +#[lang = "sized"] +pub trait Sized {} + +#[lang = "fn_once"] +pub trait FnOnce { + #[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; +}