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

no_coverage feature-gated on function, not crate? #84836

Closed
Mark-Simulacrum opened this issue May 2, 2021 · 9 comments · Fixed by #84871
Closed

no_coverage feature-gated on function, not crate? #84836

Mark-Simulacrum opened this issue May 2, 2021 · 9 comments · Fixed by #84871
Labels
A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) A-stability Area: `#[stable]`, `#[unstable]` etc. C-bug Category: This is a bug. P-critical Critical priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone

Comments

@Mark-Simulacrum
Copy link
Member

It looks like the no_coverage attribute was added by checking for feature(no_coverage) on the function, but this isn't how feature gating usually works. Additionally, I don't believe that restricts usage of this on stable/beta, since nothing is actually checking this feature gate.

Noticed based on the test case (https://github.com/rust-lang/rust/blob/master/src/test/ui/feature-gates/feature-gate-no_coverage.rs) and while looking at the feature-gating code.

cc @tmandry @richkadel

@Mark-Simulacrum Mark-Simulacrum added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels May 2, 2021
@Mark-Simulacrum Mark-Simulacrum added this to the 1.53.0 milestone May 2, 2021
@Mark-Simulacrum
Copy link
Member Author

cc #84605

@jonas-schievink jonas-schievink added A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) A-stability Area: `#[stable]`, `#[unstable]` etc. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels May 2, 2021
@richkadel
Copy link
Contributor

richkadel commented May 3, 2021

It looks like the no_coverage attribute was added by checking for feature(no_coverage) on the function, but this isn't how feature gating usually works.

Correct. The driving reason for adding the feature was to resolve #83601, and that issue occurred because core/std pushes a hidden function into everything that derives Eq, and we need to hide that function (from coverage instrumentation). So the only way to gate the issue at the crate level would be to automatically enable the feature in any crate that derives Eq (which is just about every crate).

Feature gating at the function level resolved the problem, even though it was non-standard.

I do allow feature-gating at the crate level as well, but it's not used by Eq.

Additionally, I don't believe that restricts usage of this on stable/beta, since nothing is actually checking this feature gate.

I didn't realize this also needs to be checked. Is there an example of how to do this, so I can also implement it in the function-based feature-gate check?

@Mark-Simulacrum
Copy link
Member Author

It should be possible to adjust the normal feature gating to correctly handle macro expanded sources - that is, allow the built-in derives to generate it without it being stabilized. We do this for the Structural trait impls somehow, for example; possibly enough to set the span appropriately. If necessary, I can either provide or track down someone who can, further hints. It might be good to look at how the structural equality worked before the move to the trait impls as it had a similar built-in attribute.

In the meantime we'll likely revert the PR on just branched beta (1.53) so we don't accidentally stabilize the feature.

@richkadel
Copy link
Contributor

@Mark-Simulacrum: I just uploaded a PR to fix this, as an alternative to reverting: #84871

Your call.

Thanks!

@nagisa
Copy link
Member

nagisa commented May 4, 2021

#[allow_internal_unstable] is what we use extensively to utilize unstable features within macros-by-example, so there is definitely already means to enable unstable features within macro-expanded code without user code needing to know about it.

In procedural macros and derive macros stability propagation can be carefully handled (AFAIK) by setting the span (or more precisely its expansion id) up in such a way that it refers to the crate that has feature gates enabled. I'm confident there's somebody on T-compiler who can say something more precise.

I don't think we should be introducing new ways to enable unstable features (by e.g. allowing them to be specified as attributes on items) without a broader buy-in. The ability to have non-crate-level feature gates definitely sounds like at least a MCP material to me, primarily due to complications in the implementation of the compiler & tooling surrounding the unstable feature tracking and relative ease with which an oversight can happen and a feature accidentally stabilized.

@tmandry
Copy link
Member

tmandry commented May 5, 2021

I should have caught this, sorry. #84871 can work as a stopgap, but if we need an MCP to use this mechanism at all we should probably revert.

@richkadel
Copy link
Contributor

In procedural macros and derive macros stability propagation can be carefully handled (AFAIK) by setting the span (or more precisely its expansion id) up in such a way that it refers to the crate that has feature gates enabled

Thanks @nagisa ! This was the hint I needed. I uploaded a revised PR commit with a change in line with your suggestion. All tests work as before (with the exception of test that enabled the feature at the function level; these are now removed).

@richkadel
Copy link
Contributor

if we need an MCP to use this mechanism at all

Just confirming, but I think @nagisa was only referring to function-level feature gating (now removed) as needing an MCP. But since this is gone, I think the feature-gated #[no_coverage] attribute is still OK.

Correct me if I'm wrong.

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 6, 2021
…, r=nagisa

Disallows `#![feature(no_coverage)]` on stable and beta (using standard crate-level gating)

Fixes: rust-lang#84836

Removes the function-level feature gating solution originally implemented, and solves the same problem using `allow_internal_unstable`, so normal crate-level feature gating mechanism can still be used (which disallows the feature on stable and beta).

I tested this, building the compiler with and without `CFG_DISABLE_UNSTABLE_FEATURES=1`

With unstable features disabled, I get the expected result as shown here:

```shell
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc     src/test/run-make-fulldeps/coverage/no_cov_crate.rs
error[E0554]: `#![feature]` may not be used on the dev release channel
 --> src/test/run-make-fulldeps/coverage/no_cov_crate.rs:2:1
  |
2 | #![feature(no_coverage)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0554`.
```

r? `@Mark-Simulacrum`
cc: `@tmandry` `@wesleywiser`
@apiraino
Copy link
Contributor

apiraino commented May 6, 2021

Assigning P-critical for the record, as discussed in the Zulip thread of the Prioritization Working Group.

@rustbot label -I-prioritize +P-critical

@rustbot rustbot added P-critical Critical priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels May 6, 2021
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 6, 2021
…, r=nagisa

Disallows `#![feature(no_coverage)]` on stable and beta (using standard crate-level gating)

Fixes: rust-lang#84836

Removes the function-level feature gating solution originally implemented, and solves the same problem using `allow_internal_unstable`, so normal crate-level feature gating mechanism can still be used (which disallows the feature on stable and beta).

I tested this, building the compiler with and without `CFG_DISABLE_UNSTABLE_FEATURES=1`

With unstable features disabled, I get the expected result as shown here:

```shell
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc     src/test/run-make-fulldeps/coverage/no_cov_crate.rs
error[E0554]: `#![feature]` may not be used on the dev release channel
 --> src/test/run-make-fulldeps/coverage/no_cov_crate.rs:2:1
  |
2 | #![feature(no_coverage)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0554`.
```

r? ``@Mark-Simulacrum``
cc: ``@tmandry`` ``@wesleywiser``
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 6, 2021
…, r=nagisa

Disallows `#![feature(no_coverage)]` on stable and beta (using standard crate-level gating)

Fixes: rust-lang#84836

Removes the function-level feature gating solution originally implemented, and solves the same problem using `allow_internal_unstable`, so normal crate-level feature gating mechanism can still be used (which disallows the feature on stable and beta).

I tested this, building the compiler with and without `CFG_DISABLE_UNSTABLE_FEATURES=1`

With unstable features disabled, I get the expected result as shown here:

```shell
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc     src/test/run-make-fulldeps/coverage/no_cov_crate.rs
error[E0554]: `#![feature]` may not be used on the dev release channel
 --> src/test/run-make-fulldeps/coverage/no_cov_crate.rs:2:1
  |
2 | #![feature(no_coverage)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0554`.
```

r? ```@Mark-Simulacrum```
cc: ```@tmandry``` ```@wesleywiser```
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 6, 2021
…, r=nagisa

Disallows `#![feature(no_coverage)]` on stable and beta (using standard crate-level gating)

Fixes: rust-lang#84836

Removes the function-level feature gating solution originally implemented, and solves the same problem using `allow_internal_unstable`, so normal crate-level feature gating mechanism can still be used (which disallows the feature on stable and beta).

I tested this, building the compiler with and without `CFG_DISABLE_UNSTABLE_FEATURES=1`

With unstable features disabled, I get the expected result as shown here:

```shell
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc     src/test/run-make-fulldeps/coverage/no_cov_crate.rs
error[E0554]: `#![feature]` may not be used on the dev release channel
 --> src/test/run-make-fulldeps/coverage/no_cov_crate.rs:2:1
  |
2 | #![feature(no_coverage)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0554`.
```

r? ````@Mark-Simulacrum````
cc: ````@tmandry```` ````@wesleywiser````
@bors bors closed this as completed in 3584c1d May 7, 2021
Mark-Simulacrum pushed a commit to Mark-Simulacrum/rust that referenced this issue May 22, 2021
using allow_internal_unstable (as recommended)

Fixes: rust-lang#84836

```shell
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc     src/test/run-make-fulldeps/coverage/no_cov_crate.rs
error[E0554]: `#![feature]` may not be used on the dev release channel
 --> src/test/run-make-fulldeps/coverage/no_cov_crate.rs:2:1
  |
2 | #![feature(no_coverage)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0554`.
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-code-coverage Area: Source-based code coverage (-Cinstrument-coverage) A-stability Area: `#[stable]`, `#[unstable]` etc. C-bug Category: This is a bug. P-critical Critical priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
7 participants