Skip to content
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

Do not munge visibility attribute for targets created by symbolic macros #23855

Open
brandjon opened this issue Oct 3, 2024 · 2 comments
Open
Assignees
Labels
P1 I'll work on this now. (Assignee required) team-Loading-API BUILD file and macro processing: labels, package(), visibility, glob type: bug

Comments

@brandjon
Copy link
Member

brandjon commented Oct 3, 2024

@bazel-io flag 8.0.0
This potentially blocks Bazel 8.0 because without fixing this, the bazel query-introspected visibility value of targets created in Symbolic Macros is misleading/inconsistent.


Currently, for targets created within a symbolic macro, the visibility attribute that gets stored on the target is munged to include the instantiating location. This contrasts with the raw visibility attribute that gets stored on targets not in symbolic macros, which matches whatever the visibility = argument passed to the instantiation site was.

We can't munge for targets not in symbolic macros, because it would likely imply a memory regression for the overwhelming majority of the build, and it would change the introspected visibility value for those targets relative to what is seen today in native.existing_rules and bazel query. But at the same time, the munging for targets in symbolic macros is also problematic, both due to the inconsistency and because tooling that reads the introspected values might expect them to match the source text of a BUILD file.

The proper solution is probably to be consistent by

  1. not munging visibility for any target
  2. computing the VisibilityProvider at analysis time without relying on said munging, deferring the concatenation of the callsite location to that point in time
  3. creating a synthetic attribute, $actual_visibility, to hold the munged value (regardless of whether the target is inside a symbolic macro), that can be introspected in bazel query but not in native.existing_rules. This attribute should not be materialized in normal builds.

Symbolic macros themselves also have a visibility attribute, and it must always be munged (as it currently is) so that the implementation function sees the correct value for its visibility parameter. But if we expose symbolic macro attributes via bazel query in the future, we may very well want to avoid the munging to preserve consistency with rules. Note that munging happens at every level of a chain of symbolic macro calls, and the raw visibility for one macro is the munged visibility for its caller.

Implementing this probably just requires a little work in RuleFactory and ConfiguredTargetFactory, plus updating some code comments that explain the outdated invariant. I'm not completely sure what the precedent is for synthetic query-only attributes.

@brandjon brandjon added type: bug P1 I'll work on this now. (Assignee required) team-Loading-API BUILD file and macro processing: labels, package(), visibility, glob labels Oct 3, 2024
@brandjon
Copy link
Member Author

brandjon commented Oct 7, 2024

Let's track the synthetic attribute part separately as FR #23893, without necessarily blocking 8.0 on that part. (The rest of this issue still blocks 8.0.)

@brandjon
Copy link
Member Author

@bazel-io fork 8.0.0

copybara-service bot pushed a commit that referenced this issue Oct 24, 2024
This CL simplifies RuleVisibility concatenation by inlining concatWithElement() into concatWithPackage(). The latter was the only caller of the former in production. The implementation no longer has to handle the case where the RHS is public or private -- something that was not needed in practice, but which was required in abstract for the deleted method's API to be correct. It also now doesn't need to parse an untrusted label, so there's no need to catch or throw EvalException.

concatWithPackage() is also made non-static, which looks nicer at the call sites.

The validate() method is renamed to checkForVisibilityMisspelling(), since that's the only thing it does now. (A previous CL removed its other job of detecting formerly illegal combinations of public/private visibility with other items in a list.)

Added an equals() and hashCode() while we're at it, to avoid depending on singleton identity (I'm not sure whether @SerializationConstant lets us assume that). It's based on just getDeclaredLabels() since that should superset any information returned by getDependencyLabels(). Changed RuleVisibility from an interface to an abstract class too -- I would've made it `sealed`, but the singleton PUBLIC and PRIVATE anonymous subclasses prevent that and it's not worth making them named classes.

MacroInstance.java
- Implement the TODO. (I went with "getDefinitionPackage" over "getDefiningPackage" because the latter might be confused with the package that defines the macro *instance*.)

MacroClass.java
- Condense to if-expr form now that the else branch is more concise.

RuleVisibilityTest.java
- Add pkg() helper for concatenation() test case.
- Remove assertEqual() now that we have a RuleVisibility#equals() method.
- Rename "B" -> "B_PG" for clarity/contrast with "A" and "C".
- Delete test cases for concatWithElement that are no longer applicable (where the RHS is public or private visibility)

Work toward #23855.

PiperOrigin-RevId: 689400241
Change-Id: I6b7a1c9f87c4b3c9e5cd99d5dc4d906b5d798d28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P1 I'll work on this now. (Assignee required) team-Loading-API BUILD file and macro processing: labels, package(), visibility, glob type: bug
Projects
None yet
Development

No branches or pull requests

2 participants