-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Forbid usage of hir
Infer
const/ty variants in ambiguous contexts
#135272
base: master
Are you sure you want to change the base?
Forbid usage of hir
Infer
const/ty variants in ambiguous contexts
#135272
Conversation
sry fmease |
Failed to set assignee to
|
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
…y_2, r=<try> [PERF] dont represent infer vars two different ways in hir visitors
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
💔 Test failed - checks-actions |
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
…y_2, r=<try> [PERF] dont represent infer vars two different ways in hir visitors to lampshade a bit for anyone who decides to review a draft PR: yes this is not very a good PR right now
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (9ce13d8): comparison URL. Overall result: ❌ regressions - no action neededBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (secondary -3.6%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (primary 4.3%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 764.798s -> 764.043s (-0.10%) |
yippee |
d53cf04
to
909f1f6
Compare
This comment has been minimized.
This comment has been minimized.
hir
Infer
const/ty variants in ambiguous contexts
Rebased and pushed additional commits for the reviews so if you want to look at just the new stuff u can just look at the commits after |
6fec71e
to
d7b916b
Compare
@bors try |
⌛ Trying commit d7b916b with merge ae258e1fcbee4a062f5f3d869f06004d7cea088e... |
…y_2, r=<try> Forbid usage of `hir` `Infer` const/ty variants in ambiguous contexts The feature `generic_arg_infer` allows providing `_` as an argument to const generics in order to infer them. This introduces a syntactic ambiguity as to whether generic arguments are type or const arguments. In order to get around this we introduced a fourth `GenericArg` variant, `Infer` used to represent `_` as an argument to generic parameters when we don't know if its a type or a const argument. This made hir visitors that care about `TyKind::Infer` or `ConstArgKind::Infer` very error prone as checking for `TyKind::Infer`s in `visit_ty` would find *some* type infer arguments but not *all* of them as they would sometimes be lowered to `GenericArg::Infer` instead. Additionally the `visit_infer` method would previously only visit `GenericArg::Infer` not *all* infers (e.g. `TyKind::Infer`), this made it very easy to override `visit_infer` and expect it to visit all infers when in reality it would only visit *some* infers. --- This PR aims to fix those issues by making the `TyKind` and `ConstArgKind` types generic over whether the infer types/consts are represented by `Ty/ConstArgKind::Infer` or out of line (e.g. by a `GenericArg::Infer` or accessible by overiding `visit_infer`). We then make HIR Visitors convert all const args and types to the versions where infer vars are stored out of line and call `visit_infer` in cases where a `Ty`/`Const` would previously have had a `Ty/ConstArgKind::Infer` variant: API Summary ```rust enum AmbigArg {} enum Ty/ConstArgKind<Unambig = ()> { ... Infer(Unambig), } impl Ty/ConstArg { fn try_as_ambig_ty/ct(self) -> Option<Ty/ConstArg<AmbigArg>>; } impl Ty/ConstArg<AmbigArg> { fn as_unambig_ty/ct(self) -> Ty/ConstArg; } enum InferKind { Ty(Ty), Const(ConstArg), Ambig(InferArg), } trait Visitor { ... fn visit_ty/const_arg(&mut self, Ty/ConstArg<AmbigArg>) -> Self::Result; fn visit_infer(&mut self, id: HirId, sp: Span, kind: InferKind) -> Self::Result; } // blanket impl'd, not meant to be overriden trait VisitorExt { fn visit_ty/const_arg_unambig(&mut self, Ty/ConstArg) -> Self::Result; } fn walk_unambig_ty/const_arg(&mut V, Ty/ConstArg) -> Self::Result; fn walk_ty/const_arg(&mut V, Ty/ConstArg<AmbigArg>) -> Self::Result; ``` The end result is that `visit_infer` visits *all* infer args and is also the *only* way to visit an infer arg, `visit_ty` and `visit_const_arg` can now no longer encounter a `Ty/ConstArgKind::Infer`. Representing this in the type system means that it is now very difficult to mess things up, either accessing `TyKind::Infer` "just works" and you won't miss *some* type infers- or it doesn't work and you have to look at `visit_infer` or some `GenericArg::Infer` which forces you to think about the full complexity involved. Unfortunately there is no lint right now about explicitly matching on uninhabited variants, I can't find the context for why this is the case 🤷♀️ I'm not convinced the framing of un/ambig ty/consts is necessarily the right one but I'm not sure what would be better. I somewhat like calling them full/partial types based on the fact that `Ty<Partial>`/`Ty<Full>` directly specifies how many of the type kinds are actually represented compared to `Ty<Ambig>` which which leaves that to the reader to figure out based on the logical consequences of it the type being in an ambiguous position. --- tool changes have been modified in their own commits for easier reviewing by anyone getting cc'd from subtree changes. I also attempted to split out "bug fixes arising from the refactoring" into their own commit so they arent lumped in with a big general refactor commit Fixes rust-lang#112110
☀️ Try build successful - checks-actions |
@craterbot check |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🎉 Experiment
|
aww lol |
this is not a new bug from this PR this is a pre-existing bug in all the regressions are due to an old version of the |
Always lower to `GenericArg::Infer` Update `PlaceholderCollector` Update closure lifetime binder infer var visitor Fallback visitor handle ambig infer args Ensure type infer args have their type recorded
b827a7b
to
c03a819
Compare
The feature
generic_arg_infer
allows providing_
as an argument to const generics in order to infer them. This introduces a syntactic ambiguity as to whether generic arguments are type or const arguments. In order to get around this we introduced a fourthGenericArg
variant,Infer
used to represent_
as an argument to generic parameters when we don't know if its a type or a const argument.This made hir visitors that care about
TyKind::Infer
orConstArgKind::Infer
very error prone as checking forTyKind::Infer
s invisit_ty
would find some type infer arguments but not all of them as they would sometimes be lowered toGenericArg::Infer
instead.Additionally the
visit_infer
method would previously only visitGenericArg::Infer
not all infers (e.g.TyKind::Infer
), this made it very easy to overridevisit_infer
and expect it to visit all infers when in reality it would only visit some infers.This PR aims to fix those issues by making the
TyKind
andConstArgKind
types generic over whether the infer types/consts are represented byTy/ConstArgKind::Infer
or out of line (e.g. by aGenericArg::Infer
or accessible by overidingvisit_infer
). We then make HIR Visitors convert all const args and types to the versions where infer vars are stored out of line and callvisit_infer
in cases where aTy
/Const
would previously have had aTy/ConstArgKind::Infer
variant:API Summary
The end result is that
visit_infer
visits all infer args and is also the only way to visit an infer arg,visit_ty
andvisit_const_arg
can now no longer encounter aTy/ConstArgKind::Infer
. Representing this in the type system means that it is now very difficult to mess things up, either accessingTyKind::Infer
"just works" and you won't miss some type infers- or it doesn't work and you have to look atvisit_infer
or someGenericArg::Infer
which forces you to think about the full complexity involved.Unfortunately there is no lint right now about explicitly matching on uninhabited variants, I can't find the context for why this is the case 🤷♀️
I'm not convinced the framing of un/ambig ty/consts is necessarily the right one but I'm not sure what would be better. I somewhat like calling them full/partial types based on the fact that
Ty<Partial>
/Ty<Full>
directly specifies how many of the type kinds are actually represented compared toTy<Ambig>
which which leaves that to the reader to figure out based on the logical consequences of it the type being in an ambiguous position.tool changes have been modified in their own commits for easier reviewing by anyone getting cc'd from subtree changes. I also attempted to split out "bug fixes arising from the refactoring" into their own commit so they arent lumped in with a big general refactor commit
Fixes #112110