Match query key types as $K:tt instead of $($K:tt)*#152833
Match query key types as $K:tt instead of $($K:tt)*#152833Zalathar wants to merge 2 commits intorust-lang:mainfrom
$K:tt instead of $($K:tt)*#152833Conversation
This comment has been minimized.
This comment has been minimized.
The trick to making this work is to have the proc-macro surround every key type with parentheses, so that it remains a valid type but also matches as a single token tree. Due to how macro fragment specifiers work, matching as `$K:ty` would prevent us from inspecting the key type in `maybe_into_query_param!`.
b1d3b27 to
5bdaff4
Compare
|
The current code implements the query-key-conversion stuff partly in the #152779 eliminates the macro parts, so it is fully in the type system. And we end up using This PR spreads the complexity more: partly in the proc macro, partly in -- About #152779's, you said "it clutters the signature of every single query method in a way that adds real friction." I don't understand what that "friction" is. |
It wrecks type inference, it wrecks error messages, and it wrecks documentation. That's not something I want to inflict on contributors for hundreds of methods that don't need it, especially if the only payoff is being able to write |
|
The first commit is good. Just yesterday I was puzzling over the difference between The second commit increases coupling between the proc macro and the declarative macro in a way I don't like. I guess we'll just have to live with |
|
…ercote Clarify some variable names in the query proc-macro These are some cleanups to the `rustc_macros::query`, extracted from rust-lang#152833. r? nnethercote
…ercote Clarify some variable names in the query proc-macro These are some cleanups to the `rustc_macros::query`, extracted from rust-lang#152833. r? nnethercote
…ercote Clarify some variable names in the query proc-macro These are some cleanups to the `rustc_macros::query`, extracted from rust-lang#152833. r? nnethercote
When query-plumbing macros match on a query key type, they currently have to perform a clunky match on
$($K:tt)*, instead of the more obvious$K:ty.Switching to
$K:tyis currently not feasible, because that would prevent us from inspecting the specific key type in a helper macro that decides whether to replace$Kwithimpl IntoQueryParam<$K>, if the key type happens to beDefIdorLocalDefId.1However, we can switch from
$($K:tt)*to the simpler$K:ttif we modify the proc-macro to always emit key types surrounded in parentheses, guaranteeing that they always form a legal type that is also a single token tree.(In some of the helper macros, this PR does switch to
$K:tybecause the inner token structure is not needed there.)Background on
impl IntoQueryParam<K>Of the ~300 queries currently used by the compiler, about 100 have a key type of
DefIdorLocalDefId. For those two key types, the query plumbing macros have special logic to declare the corresponding query methods as takingimpl IntoQueryParam<DefId>orimpl IntoQueryParam<LocalDefId>instead. That allows callers to pass IDs that are actually strongly-typed wrappers for a subset ofDefId/LocalDefId2, without having to explicitly convert at the call site.There are arguments for or against doing that kind of trait-based argument conversion,3 but there are enough call sites currently relying on it that stopping would be a pretty substantial change.
Meanwhile, there are good reasons to not want to extend that practice to the other ~200 queries that don't need it. Auto-converting to
DefIdis common enough to arguably be worth it, whereas cluttering the real signatures of query methods that don't need auto-conversion adds real friction4 for almost no benefit.The first commit is a general cleanup of
rustc_macros::querythat makes the subsequent changes more readable. It could be merged on its own if desired.impl IntoQueryParamchanges in Clarify aspects of query macros #152779.r? nnethercote
Footnotes
In macro-rules macros, any input matched by something that isn't
ttis subsequently treated as an opaque unit, whose sub-tokens cannot be inspected. ↩Example conversions include
LocalDefId→DefId,ModDefId→DefId, andLocalModDefId→LocalDefId. ↩E.g. callers could just write
.into()explicitly instead. ↩Parameters involving conversion traits have less helpful type inference, less helpful error messages, and complicate otherwise-straightforward signatures as seen in documentation or IDE hover tips. ↩