Skip to content

#[export_visibility = ...] attribute #881

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 of 3 tasks
anforowicz opened this issue Jun 4, 2025 · 3 comments
Closed
1 of 3 tasks

#[export_visibility = ...] attribute #881

anforowicz opened this issue Jun 4, 2025 · 3 comments
Labels
major-change A proposal to make a major change to rustc T-compiler Add this label so rfcbot knows to poll the compiler team

Comments

@anforowicz
Copy link

Proposal

I propose to add #[export_visibility = …] attribute, which could be used to override the default visibility that is currently forced whenever using #[export_name = …] or #[no_mangle].

I propose that the new attribute can only be applied to items that are exported as SymbolExportLevel::C / contains_extern_indicator.

I propose that the visibility would be computed as follows:

  • Regular function (without the new attribute, and without #[export_name = …] nor #[no_mangle]): no changes = visibility is based on the platform, or on the -Zdefault-visibility=... cmdline flag
  • #[export_name = …] or #[no_mangle] without the new attribute: no changes = public export
  • #[export_name = …] or #[no_mangle] with the new attribute:
    • Any of the values supported by -Zdefault-visibility=... (e.g. hidden, protected, or interposable) would result in this specific visibility.
    • The special #[export_visibility = “inherit”] value would result in using the target platform’s or cmdline flag’s visibility (basically this would mean: don’t let #[export_name] / #[no_mangle] affect the baseline visibility).

Motivation

I believe that this proposal is a tractable way to resolve rust-lang/rust#73958. (The direct motivation for me is https://crbug.com/418073233 which has the same root cause.)

Feedback please?

I hope to get 3 kinds of feedback:

  • Process feedback. For example:

    • Whether instead of this Major Change Proposal (MCP), maybe I should have submitted a Request For Comments (RFC) as described here? If so, then hopefully the MCP discussion will help to start this in the right way.
    • What specific next steps/actions should I take if this MCP seems desirable to pursue? For example - I assume that before raising https://github.com/anforowicz/rust/tree/export-visibility as a pull request, I should first take care of some prerequisites, but I am not sure what those are and what their ordering should be (e.g. getting some kind of an indication of an agreement about the proposed approach? editing the https://doc.rust-lang.org/stable/unstable-book/? open a tracking issue for the new unstable feature at https://github.com/rust-lang/rust/issues?)
  • High-level / directional feedback. For example:

    • Whether one of the alternatives discussed below should be pursued instead? In other words, whether having a per-symbol mechanism to specify the visibility is the best way forward?
    • Whether there are some unforeseen, high-level issues with the #[export_visibility = …]-based approach?
    • Whether the proposal seems like something that could be adopted by cxx? (/cc @dtolnay)
      • #[export_visibility = …] in cxx/src/symbols can potentially be controlled by a new crate-level feature
      • #[export_visibility = …] in #[cxx::bridge]-generated code may be a bit trickier: it is unclear 1) how to opt into emitting #[export_visibility = …] (cxxbridge-macro build-time crate feature? #[cxx::bridge(..., export_visibility = …)]? Some other mechanism?) and 2) who/where is responsible for uttering the #![feature(export_visibility)] incantation to opt into the proposed unstable feature.
      • See changes in https://crrev.com/c/6580611/2 under third_party/rust/chromium_crates_io/vendor/… for an example of a quick&dirty way to test the new attribute in cxx.
  • Low-level / technical feedback. For example:

    • How to name the “inherit” visibility? (Other ideas: “baseline”, “preset”, “inherent”, “intrinsic”)
    • How to name the new attribute? (export_visibility? link_visibility? symbol_visibility? else?)

Alternatives

Instead of adopting this proposal, we could also consider one of the following alternatives:

  • Do nothing. For example, cxx#1500 example dtolnay/cxx#1520 demonstrates how to work around the problem by controlling symbol visibility with version scripts passed to the linker.
  • Change the semantics of #[export_name = …] and/or #[no_mangle] at an edition boundary.
    • I think this is what is proposed in Ability from the top-level of the compilation not to mark #[no_mangle] items exported from shared library rust#73958 (comment). In my initial reply to this alternative proposal it seemed to me that this will only work when linking is driven by rustc rather than by an external linker such as ldd - I am now thinking that maybe I was wrong about this. But I still don’t understand why global, link-time reasoning is needed (e.g. considering “symbols reachable from the public API of the top-level crate”)
    • Maybe we can instead consider a simpler proposal of changing the meaning of #[export_name = …] and #[no_mangle] so that:
      • In editions <= 2024 the current behavior is preserved (symbol is publicly exported)
      • In edition >= 2027 those naming attributes wouldn’t have any symbol/linker visibility impact on their own (which gives us the desired semantics combined with -Zdefault-visibility=...). If a publicly exported symbol was desirable, then this could be expressed with either A) #[used] or B) #[export_visibility = …].
    • At any rate, changing the semantics of #[export_name = …] in a future Rust edition seems compatible with the #[export_visibility = …] proposal. It seems that the visibility attribute would be useful in the current world and may also continue to be useful in the (hypothetical) new edition behavior (in both cases/editions overriding the default behavior of #[export_name = …] may sometimes be desirable).
  • -Zdefault-visibility-for-c-exports=...
    • This would offer a global (rather than per-symbol) override of the semantics of #[export_name = …] and #[no_mangle]. Implementation-wise, I think that this could be done by changing the code here
    • This alternative seems suboptimal, because one may want to 1) hide all cxx-generated symbols, but still 2) export some other symbols.
  • We could also consider a different spelling of an attribute-based approach - maybe one that avoids introducing a new attribute:

Other notes

Mentors or Reviewers

Maybe @bjorn3, who has participated in the discussion in rust-lang/rust#73958?

Process

The main points of the Major Change Process are as follows:

  • File an issue describing the proposal.
  • A compiler team member or contributor who is knowledgeable in the area can second by writing @rustbot second.
    • Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a -C flag, then full team check-off is required.
    • Compiler team members can initiate a check-off via @rfcbot fcp merge on either the MCP or the PR.
  • Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered approved.

You can read more about Major Change Proposals on forge.

@anforowicz anforowicz added T-compiler Add this label so rfcbot knows to poll the compiler team major-change A proposal to make a major change to rustc labels Jun 4, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 4, 2025

Important

This issue is not meant to be used for technical discussion. There is a Zulip stream for that.
Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

Concerns or objections can formally be registered here by adding a comment.

@rustbot concern reason-for-concern
<description of the concern>

Concerns can be lifted with:

@rustbot resolve reason-for-concern

See documentation at https://forge.rust-lang.org

cc @rust-lang/compiler

@rustbot rustbot added the to-announce Announce this issue on triage meeting label Jun 4, 2025
@apiraino apiraino changed the title MCP: #[export_visibility = ...] attribute #[export_visibility = ...] attribute Jun 5, 2025
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Jun 5, 2025
@Noratrieb
Copy link
Member

As mentioned in #t-compiler/major changes > `#[export_visibility = ...]` attribute compiler-team#881 @ 💬, a compiler MCP isn't quite the right avenue here, as attributes are part of the language.

@anforowicz
Copy link
Author

As mentioned in #t-compiler/major changes > #[export_visibility = ...] attribute compiler-team#881 @ 💬, a compiler MCP isn't quite the right avenue here, as attributes are part of the language.

Ack. I think this means that I should close this issue and instead purse this through an RFC.

Based on the feedback and discussion in the Zulip stream (thanks everyone!), I think the RFC should cover:

  • Issues between hidden visibility and dylibs
  • Comparison between controlling visibility using version scripts vs using attributes
  • How visibility levels will work on different platforms (e.g. Windows and/or Wasm)

I'll try to create a draft of the RFC within 1-2 weeks and post a link here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
major-change A proposal to make a major change to rustc T-compiler Add this label so rfcbot knows to poll the compiler team
Projects
None yet
Development

No branches or pull requests

4 participants