-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Introduce trait DebugWithInfcx
to debug format types with universe info
#112984
Conversation
This comment has been minimized.
This comment has been minimized.
4376364
to
b4eff64
Compare
ty::
stuff with universes showntrait DebugWithInfcx
to debug format types with universe info
☔ The latest upstream changes (presumably #113370) made this pull request unmergeable. Please resolve the merge conflicts. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine, though it seems like there's still some more migration to do and more impls to add? Seems like good newcomer work.
Can you make a tracking issue or at least put a checkbox somewhere so that we track the things that still need to be done to make this trait more useful/utilized?
Ideally that one would also have a check-box for "consider ergonomics of adding derive(DebugWithInfcx)
" or sth, too. I'd like to see that done eventually or at least a good explanation why it's not a good idea.
use InferTy::*; | ||
match ty { | ||
// FIXME(BoxyUwU): this is kind of jank and means that printing unresolved | ||
// ty infers will give you the universe of the var it resolved to not the universe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow yeah that's jank. The way regions does it is so much better.
} | ||
|
||
fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> { | ||
Some(self.universe_of_region_vid(lt)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lmao if only we stored the universe not in the eq relation table for ty/ct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably perf-negative but I'd like to see it tested, perhaps as a follow-up by someone who's interested in contributing.
@@ -119,6 +120,14 @@ impl<T: fmt::Debug> fmt::Debug for List<T> { | |||
(**self).fmt(f) | |||
} | |||
} | |||
impl<'tcx, T: super::DebugWithInfcx<TyCtxt<'tcx>>> super::DebugWithInfcx<TyCtxt<'tcx>> for List<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ideally, if we found some new contributor, it would be cool if we could derive(DebugWithInfcx)
or sth. Manual impls are not the worst thing in the world, though..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I would love to see a derive(DebugWithInfcx)
Also this needs documentation on the @bors r+ |
Opened #113582 |
☀️ Test successful - checks-actions |
Finished benchmarking commit (993deaa): comparison URL. Overall result: ✅ improvements - no action needed@rustbot label: -perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis 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.
CyclesResultsThis 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: 656.572s -> 656.821s (0.04%) |
Seeing universes of infer vars is valuable for debugging but currently we have no way of easily debug formatting a type with the universes of all the infer vars shown. In the future I hope to augment the new solver's proof tree output with a
DebugWithInfcx
impl so that it can show universes but I left that out of this PR as it would be non trivial and this is already large and complex enough.The goal here is to make the various abstractions taking
T: Debug
able to use the codepath for printing out universes, that way we can dodebug!("{:?}", my_x)
and havemy_x
have universes shown, same for thewrite!
macro. It's not possible to put theInfcx: InferCtxtLike<I>
into the formatter argument toDebug::fmt
so it has to go into the self ty. For this we introduce the typeOptWithInfcx<I: Interner, Infcx: InferCtxtLike<I>, T>
which has the dataT
optionally coupled with the infcx (more on why it's optional later).Because of coherence/orphan rules it's not possible to write the impl
Debug for OptWithInfcx<..., MyType>
whenOptWithInfcx
is in a upstream crate. This necessitates a blanket impl in the crate definingOptWithInfcx
like so:impl<T: DebugWithInfcx> Debug for OptWithInfcx<..., T>
. It is not intended for people to manually callDebugWithInfcx::fmt
, theDebug
impl forOptWithInfcx
should be preferred.The infcx has to be optional in
OptWithInfcx
as otherwise we would end up with a large amount of code duplication. Almost all types that want to be used withOptWithInfcx
do not themselves need access to the infcx so if we were to not optional we would end up with largeDebug
andDebugWithInfcx
impls that were practically identical other than that when formatting their fields we wrap the field inOptWithInfcx
instead of formatting it alone.The only types that need access to the infcx themselves are ty/const/region infer vars, everything else is implemented by having the
Debug
impl defer toOptWithInfcx
with no infcx available. TheDebugWithInfcx
impl is pretty much just the standardDebug
impl except that instead of recursively formatting fields withwrite!(f, "{x:?}")
we must dowrite!(f, "{:?}", opt_infcx.wrap(x))
. This is some pretty rough boilerplate but I could not think of an alternative unfortunately.OptWithInfcx::wrap
is an eagerOption::map
because 99% of callsites were discarding the existing data inOptWithInfcx
and did not need lazy evaluation.A trait
InferCtxtLike
was added instead of usingInferCtxt<'tcx>
as we need to implementDebugWithInfcx
for types living inrustc_type_ir
which are generic over an interner and do not have access toInferCtxt
since it lives inrustc_infer
. Additionally I suspect that adding universe info to new solver proof tree output will require an implementation ofInferCtxtLike
for something that is not anInferCtxt
although this is not the primary motivaton.To summarize:
OptWithInfcx
which bundles some data optionally with an infcx with allows us to pass an infcx into aDebug
impl. It's optional instead of being there unconditionally so that we can share code forDebug
andDebugWithInfcx
impls that don't care about whether there is an infcx available but have fields that might care.DebugWithInfcx
which allows downstream crates to add impls of the formDebug for OptWithInfcx<...>
which would normally be forbidden by orphan rules/coherence.InferCtxtLike
to allow us to implementDebugWithInfcx
for types that live inrustc_type_ir
This allows debug formatting various
ty::*
structures with universes shown by using theDebug
impl forOptWithInfcx::new(ty, infcx)
This PR does not add
DebugWithInfcx
impls to absolutely everything that should realistically have them, for example you cannot useOptWithInfcx<Obligation<Predicate>>
. I am leaving this to a future PR to do so as it would likely be a lot more work to do.