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

lint: add bad opt access internal lint #99710

Merged
merged 3 commits into from
Jul 27, 2022

Conversation

davidtwco
Copy link
Member

@davidtwco davidtwco commented Jul 25, 2022

Prompted by Zulip discussion.

Some command-line options accessible through sess.opts are best accessed through wrapper functions on Session, TyCtxt or otherwise, rather than through field access on the option struct in the Session.

Adds a new lint which triggers on those options that should be accessed through a wrapper function so that this is prohibited. Options are annotated with a new attribute rustc_lint_opt_deny_field_access which can specify the error message (i.e. "use this other function instead") to be emitted.

A simpler alternative would be to simply rename the options in the option type so that it is clear they should not be used, however this doesn't prevent uses, just discourages them. Another alternative would be to make the option fields private, and adding accessor functions on the option types, however the wrapper functions sometimes rely on additional state from Session or TyCtxt which wouldn't be available in an function on the option type, so the accessor would simply make the field available and its use would be discouraged too.

Leave a comment if there's an option I should add this to.

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jul 25, 2022
@rust-highfive
Copy link
Collaborator

r? @lcnr

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 25, 2022
@bjorn3
Copy link
Member

bjorn3 commented Jul 25, 2022

Maybe also enable this lint for cli_forced_codegen_units, verify_llvm_ir, lto, thinlto and plt? Or even for all fields which have a wrapper, no matter how small?

@rust-log-analyzer

This comment was marked as resolved.

@rustbot
Copy link
Collaborator

rustbot commented Jul 25, 2022

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rust-log-analyzer

This comment was marked as resolved.

@RalfJung
Copy link
Member

A simpler alternative would be to simply rename the options

An even simpler alternative would be to make these fields inaccessible using standard Rust visibility restrictions?

@bjorn3
Copy link
Member

bjorn3 commented Jul 25, 2022

Sometimes they need to be accessed without an available Session. For example https://github.com/rust-lang/rust/pull/99710/files#diff-96da842aaf6582a52b9f23b4b353ef42214149dfb874819da8b616bacfb4b43eR564 for crate_types. Or every option for custom drivers that want to change options. (for example when cg_clif used a custom driver, it set panic=abort from inside the driver)

@davidtwco
Copy link
Member Author

davidtwco commented Jul 25, 2022

A simpler alternative would be to simply rename the options

An even simpler alternative would be to make these fields inaccessible using standard Rust visibility restrictions?

That's the second alternative I listed, it would absolutely work, and we could add our wrapper functions to Options/CodegenOptions/DebuggingOptions. But as soon as those wrapper functions need to make use of something from Session or TyCtxt, then we either need to pass those in (possible for Session, but probably not for TyCtxt), or the wrapper function just becomes a getter function that another wrapper on Session/TyCtxt uses - in which case it could be used accidentally just like a public field. A lint is a bit more machinery but it keeps the option accessible for the wrapper function, wherever that exists, but also prevents it from being used otherwise. I might be missing something though.

@bors

This comment was marked as resolved.

@davidtwco davidtwco force-pushed the internal-lint-opts branch 2 times, most recently from c0263b5 to 56f778d Compare July 26, 2022 12:01
@rustbot
Copy link
Collaborator

rustbot commented Jul 26, 2022

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

Copy link
Contributor

@lcnr lcnr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a few nits, then r=me

haven't really checked the fields which have this lint, but even if one of the fields is incorrectly linted, that shouldn't hurt too much

compiler/rustc_session/src/session.rs Show resolved Hide resolved
compiler/rustc_session/src/session.rs Outdated Show resolved Hide resolved
compiler/rustc_session/src/session.rs Outdated Show resolved Hide resolved
compiler/rustc_session/src/session.rs Outdated Show resolved Hide resolved
@bors

This comment was marked as resolved.

Add a brief comment explaining why the diagnostic migration lints aren't
included in the `rustc::internal` diagnostic group.

Signed-off-by: David Wood <david.wood@huawei.com>
If an internal lint uses `typeck_results` or similar queries then that
can result in rustdoc checking code that it shouldn't (e.g. from other
platforms) and emit compilation errors.

Signed-off-by: David Wood <david.wood@huawei.com>
Some command-line options accessible through `sess.opts` are best
accessed through wrapper functions on `Session`, `TyCtxt` or otherwise,
rather than through field access on the option struct in the `Session`.

Adds a new lint which triggers on those options that should be accessed
through a wrapper function so that this is prohibited. Options are
annotated with a new attribute `rustc_lint_opt_deny_field_access` which
can specify the error message (i.e. "use this other function instead")
to be emitted.

A simpler alternative would be to simply rename the options in the
option type so that it is clear they should not be used, however this
doesn't prevent uses, just discourages them. Another alternative would
be to make the option fields private, and adding accessor functions on
the option types, however the wrapper functions sometimes rely on
additional state from `Session` or `TyCtxt` which wouldn't be available
in an function on the option type, so the accessor would simply make the
field available and its use would be discouraged too.

Signed-off-by: David Wood <david.wood@huawei.com>
@davidtwco
Copy link
Member Author

@bors r=lcnr

@bors
Copy link
Contributor

bors commented Jul 27, 2022

📌 Commit 7bab769 has been approved by lcnr

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 27, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Jul 27, 2022
…laumeGomez

Rollup of 7 pull requests

Successful merges:

 - rust-lang#94247 (Fix slice::ChunksMut aliasing)
 - rust-lang#99358 (Allow `ValTree::try_to_raw_bytes` on `u8` array)
 - rust-lang#99651 (Deeply deny fn and raw ptrs in const generics)
 - rust-lang#99710 (lint: add bad opt access internal lint)
 - rust-lang#99717 (Add some comments to the docs issue template to clarify)
 - rust-lang#99728 (Clean up HIR-based lifetime resolution)
 - rust-lang#99812 (Fix headings colors)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit dda74fe into rust-lang:master Jul 27, 2022
@rustbot rustbot added this to the 1.64.0 milestone Jul 27, 2022
@davidtwco davidtwco deleted the internal-lint-opts branch July 28, 2022 08:01
@jyn514
Copy link
Member

jyn514 commented Aug 9, 2022

Another alternative would be to make the option fields private, and adding accessor functions on the option types, however the wrapper functions sometimes rely on additional state from Session or TyCtxt which wouldn't be available in an function on the option type, so the accessor would simply make the field available and its use would be discouraged too.

Can we instead move those fields to be defined in the same crate as Session? This seems like an improvement over the status quo, but at the cost of increased complexity ...

@davidtwco
Copy link
Member Author

Another alternative would be to make the option fields private, and adding accessor functions on the option types, however the wrapper functions sometimes rely on additional state from Session or TyCtxt which wouldn't be available in an function on the option type, so the accessor would simply make the field available and its use would be discouraged too.

Can we instead move those fields to be defined in the same crate as Session? This seems like an improvement over the status quo, but at the cost of increased complexity ...

They already are, we could use pub(crate) (honestly, that skipped my mind entirely when writing this, for some reason, I only considered pub). If we want to do that instead then I don't mind r=me'ing a PR that removes this and does that instead.

@bjorn3
Copy link
Member

bjorn3 commented Aug 9, 2022

pub(crate) wouldn't allow options to be changed in rustc_driver::Callbacks::config.

@Mark-Simulacrum
Copy link
Member

It also doesn't prevent other accessors not using the accessor for this field - I think to do that we'd need wrapper structs in private modules or something, which feels ungreat. I think the lint is a pretty OK method of achieving our goals here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants