refactor rustc_on_unimplemented's filtering#155940
refactor rustc_on_unimplemented's filtering#155940rust-bors[bot] merged 2 commits intorust-lang:mainfrom
Conversation
|
Some changes occurred in compiler/rustc_hir/src/attrs cc @jdonszelmann, @JonathanBrouwer Some changes occurred in compiler/rustc_attr_parsing |
|
rustbot has assigned @dingxiangfei2009. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
|
r? jdonszelmann (I don't mind taking this one for tomorrow :) |
| pub subcommands: ThinVec<Directive>, | ||
| /// This is never nested more than once, i.e. the directives in this | ||
| /// thinvec have no filters of their own. | ||
| pub filters: ThinVec<(Filter, Directive)>, |
There was a problem hiding this comment.
are toplevel and nested directives any different? like are some fields like mesage always None at the top level? Just wondering if it would maybe make sense to have a TopLevelDirective and a Directive for example
There was a problem hiding this comment.
You can write a rustc_on_unimplemented attribute that populates all those fields, at both top level and secondary level. Just the filters in that secondary level are always empty.
Regular diagnostic attributes are just a much more restricted form of that, where only message, label and note can be populated.
if it would maybe make sense to have a TopLevelDirective and a Directive for example
It's possible; this structure would essentially be:
pub struct DiagnosticAttrDirective {
pub message: Option<(Span, FormatString)>,
pub label: Option<(Span, FormatString)>,
pub notes: ThinVec<FormatString>,
}
pub struct TopRustcOnUnImplDirective {
pub filters: ThinVec<(Filter, RustcOnUnImplDirective)>,
pub message: Option<(Span, FormatString)>,
pub label: Option<(Span, FormatString)>,
pub notes: ThinVec<FormatString>,
pub parent_label: Option<FormatString>,
}
pub struct RustcOnUnImplDirective {
pub message: Option<(Span, FormatString)>,
pub label: Option<(Span, FormatString)>,
pub notes: ThinVec<FormatString>,
pub parent_label: Option<FormatString>,
}presumably we can do clever things with generics so we can reuse things and you end up with fields such as filters: ThinVec<!> etc to enforce this at the type level.
The downside of all of this is that everything becomes more complex, boilerplate-y and harder to read. The upside is that it's harder to misuse. But making things harder to misuse is only really important for the unwashed masses. This is important when you write a http framework because arbitrary people are are programming against your code. It's not as important in this case because diagnostic attr parsing infra is only used by people programming in the same crate. These are the same people that might as well just mess up the types themselves - so what is the point?
|
@rustbot author |
|
Reminder, once the PR becomes ready for a review, use |
|
@rustbot ready |
This comment has been minimized.
This comment has been minimized.
|
Alright, I agree with that reasoning. @bors r+ rollup |
|
📋 This PR cannot be approved because it has merge conflicts. Please resolve the conflicts and try again. |
This comment has been minimized.
This comment has been minimized.
|
@bors r+ rollup |
refactor rustc_on_unimplemented's filtering
Previously when you had a
```rust
pub struct Directive {
pub is_rustc_attr: bool,
pub condition: Option<OnUnimplementedCondition>,
pub subcommands: ThinVec<Directive>,
pub message: Option<(Span, FormatString)>,
...
}
```
that condition would control the emission of the message, label, notes etc. I've changed that to
```rust
pub struct Directive {
pub is_rustc_attr: bool,
pub filters: ThinVec<(Filter, Directive)>,
pub message: Option<(Span, FormatString)>,
...
```
so that the message etc is always emitted, and there's a vec of tuples with (filter, directive) where the filter controls whether that directive is even emitted, which i think is much clearer. That also makes it easier to not have to do the reverse iteration thing and this makes it so that notes are emitted in declaration order (with nonfiltered options always last).
The rename is because I plan on making it available to other diagnostic attributes at some point (very wip) so `OnUnimplementedCondition` and the like would have to be renamed anyway.
Rollup of 7 pull requests Successful merges: - #152487 (core: drop unmapped ZSTs in array `map`) - #155940 (refactor rustc_on_unimplemented's filtering) - #156020 (Improve source code for `librustdoc/visit_ast.rs`) - #156021 (Clean up some traits) - #156028 (Add a `Local::arg(i)` helper constructor) - #156037 (Add AcceptContext::expect_no_args) - #156040 (Add missing alias to mailmap)
refactor rustc_on_unimplemented's filtering
Previously when you had a
```rust
pub struct Directive {
pub is_rustc_attr: bool,
pub condition: Option<OnUnimplementedCondition>,
pub subcommands: ThinVec<Directive>,
pub message: Option<(Span, FormatString)>,
...
}
```
that condition would control the emission of the message, label, notes etc. I've changed that to
```rust
pub struct Directive {
pub is_rustc_attr: bool,
pub filters: ThinVec<(Filter, Directive)>,
pub message: Option<(Span, FormatString)>,
...
```
so that the message etc is always emitted, and there's a vec of tuples with (filter, directive) where the filter controls whether that directive is even emitted, which i think is much clearer. That also makes it easier to not have to do the reverse iteration thing and this makes it so that notes are emitted in declaration order (with nonfiltered options always last).
The rename is because I plan on making it available to other diagnostic attributes at some point (very wip) so `OnUnimplementedCondition` and the like would have to be renamed anyway.
Rollup of 7 pull requests Successful merges: - #155940 (refactor rustc_on_unimplemented's filtering) - #156020 (Improve source code for `librustdoc/visit_ast.rs`) - #156021 (Clean up some traits) - #156028 (Add a `Local::arg(i)` helper constructor) - #156037 (Add AcceptContext::expect_no_args) - #156040 (Add missing alias to mailmap) - #156048 (Make `diverging_type_vars` a vec of `TyVid`)
…uwer Rollup of 9 pull requests Successful merges: - #156030 (Make stable hashing names consistent (part 1)) - #156020 (Improve source code for `librustdoc/visit_ast.rs`) - #156021 (Clean up some traits) - #156028 (Add a `Local::arg(i)` helper constructor) - #156037 (Add AcceptContext::expect_no_args) - #156040 (Add missing alias to mailmap) - #156048 (Make `diverging_type_vars` a vec of `TyVid`) - #156053 (Reuse CTFE MIR for constructors.) - #156059 (compiler: Print valid `-Zmir-enable-passes` names if invalid name is used) Failed merges: - #155940 (refactor rustc_on_unimplemented's filtering) - #156065 (Remove unused spans from AttributeKind)
This comment has been minimized.
This comment has been minimized.
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
@bors r=jdonszelmann |
refactor rustc_on_unimplemented's filtering
Previously when you had a
```rust
pub struct Directive {
pub is_rustc_attr: bool,
pub condition: Option<OnUnimplementedCondition>,
pub subcommands: ThinVec<Directive>,
pub message: Option<(Span, FormatString)>,
...
}
```
that condition would control the emission of the message, label, notes etc. I've changed that to
```rust
pub struct Directive {
pub is_rustc_attr: bool,
pub filters: ThinVec<(Filter, Directive)>,
pub message: Option<(Span, FormatString)>,
...
```
so that the message etc is always emitted, and there's a vec of tuples with (filter, directive) where the filter controls whether that directive is even emitted, which i think is much clearer. That also makes it easier to not have to do the reverse iteration thing and this makes it so that notes are emitted in declaration order (with nonfiltered options always last).
The rename is because I plan on making it available to other diagnostic attributes at some point (very wip) so `OnUnimplementedCondition` and the like would have to be renamed anyway.
…uwer Rollup of 5 pull requests Successful merges: - #152277 (Validate source snippet when format input is raw string) - #155940 (refactor rustc_on_unimplemented's filtering) - #156065 (Remove unused spans from AttributeKind) - #156079 (Move and rename the `clone-never.rs` test) - #156091 (change field `tools` on `AttributeParser` to hold `&'tcx RegisteredTools`)
Rollup of 5 pull requests Successful merges: - #155666 (Interning cleanups) - #155940 (refactor rustc_on_unimplemented's filtering) - #156065 (Remove unused spans from AttributeKind) - #156079 (Move and rename the `clone-never.rs` test) - #156091 (change field `tools` on `AttributeParser` to hold `&'tcx RegisteredTools`)
Rollup merge of #155940 - mejrs:filter, r=jdonszelmann refactor rustc_on_unimplemented's filtering Previously when you had a ```rust pub struct Directive { pub is_rustc_attr: bool, pub condition: Option<OnUnimplementedCondition>, pub subcommands: ThinVec<Directive>, pub message: Option<(Span, FormatString)>, ... } ``` that condition would control the emission of the message, label, notes etc. I've changed that to ```rust pub struct Directive { pub is_rustc_attr: bool, pub filters: ThinVec<(Filter, Directive)>, pub message: Option<(Span, FormatString)>, ... ``` so that the message etc is always emitted, and there's a vec of tuples with (filter, directive) where the filter controls whether that directive is even emitted, which i think is much clearer. That also makes it easier to not have to do the reverse iteration thing and this makes it so that notes are emitted in declaration order (with nonfiltered options always last). The rename is because I plan on making it available to other diagnostic attributes at some point (very wip) so `OnUnimplementedCondition` and the like would have to be renamed anyway.
…uwer Rollup of 9 pull requests Successful merges: - rust-lang/rust#156030 (Make stable hashing names consistent (part 1)) - rust-lang/rust#156020 (Improve source code for `librustdoc/visit_ast.rs`) - rust-lang/rust#156021 (Clean up some traits) - rust-lang/rust#156028 (Add a `Local::arg(i)` helper constructor) - rust-lang/rust#156037 (Add AcceptContext::expect_no_args) - rust-lang/rust#156040 (Add missing alias to mailmap) - rust-lang/rust#156048 (Make `diverging_type_vars` a vec of `TyVid`) - rust-lang/rust#156053 (Reuse CTFE MIR for constructors.) - rust-lang/rust#156059 (compiler: Print valid `-Zmir-enable-passes` names if invalid name is used) Failed merges: - rust-lang/rust#155940 (refactor rustc_on_unimplemented's filtering) - rust-lang/rust#156065 (Remove unused spans from AttributeKind)
…uwer Rollup of 9 pull requests Successful merges: - rust-lang/rust#156030 (Make stable hashing names consistent (part 1)) - rust-lang/rust#156020 (Improve source code for `librustdoc/visit_ast.rs`) - rust-lang/rust#156021 (Clean up some traits) - rust-lang/rust#156028 (Add a `Local::arg(i)` helper constructor) - rust-lang/rust#156037 (Add AcceptContext::expect_no_args) - rust-lang/rust#156040 (Add missing alias to mailmap) - rust-lang/rust#156048 (Make `diverging_type_vars` a vec of `TyVid`) - rust-lang/rust#156053 (Reuse CTFE MIR for constructors.) - rust-lang/rust#156059 (compiler: Print valid `-Zmir-enable-passes` names if invalid name is used) Failed merges: - rust-lang/rust#155940 (refactor rustc_on_unimplemented's filtering) - rust-lang/rust#156065 (Remove unused spans from AttributeKind)
Previously when you had a
that condition would control the emission of the message, label, notes etc. I've changed that to
so that the message etc is always emitted, and there's a vec of tuples with (filter, directive) where the filter controls whether that directive is even emitted, which i think is much clearer. That also makes it easier to not have to do the reverse iteration thing and this makes it so that notes are emitted in declaration order (with nonfiltered options always last).
The rename is because I plan on making it available to other diagnostic attributes at some point (very wip) so
OnUnimplementedConditionand the like would have to be renamed anyway.