Closed eddyb closed 5 years ago
What do you mean by private data / per-crate data? I'm not sure what this would be used for.
For the local crate, it's pretty much all of the stuff that's right now injected into TyCtxt
at creation time (arguably a lot of this will end up behind queries eventually).
For other crates, it'd replace this use of dyn Any
to get access to a rustc_metadata
type (cstore::CrateMetadata
) from a TyCtxt
:
https://github.com/rust-lang/rust/blob/4f03f4a989d1c8346c19dfb417a77c09b34408b8/src/librustc_metadata/rmeta/decoder/cstore_impl.rs#L53-L55
For the local crate, it's pretty much all of the stuff that's right now injected into
TyCtxt
at creation time (arguably a lot of this will end up behind queries eventually).
My PRs which moves stuff into queries probably do get rid of these.
For other crates, it'd replace this use of
dyn Any
to get access to arustc_metadata
type (cstore::CrateMetadata
) from aTyCtxt
:
rustc_metadata
should get replaced by some mechanism which caches / exports query result from other crates, so I wouldn't do anything because of that.
rustc_metadata
should get replaced by some mechanism which caches / exports query result from other crates, so I wouldn't do anything because of that.
If we move Table
from rustc_metadata::rmeta
to somewhere in rustc
, I think we can start doing this today for some queries (I guess we'll need some of Lazy
, too).
Overall I think I agree with you and this is just another thing we should refactor into irrelevance.
Part of the motivation here is that for non-local crates, we right now have to go through
dyn Any
to actually get access to per-crate data, whereas ifProviders
were replaced with a trait object, the implementer would have direct access to any private data they may happen to need.However,
Providers
is really handy in that we can construct it at runtime, piece by piece, but there is nothing equivalent to that when it comes totrait
methods, short of this hack:Instead of:
we'd likely need:
Each of
{foo,bar,baz}::Provide<T>
would have to be a newtype (ofT
) with animpl
that delegates all but a few methods, toT
. (Also, we could use free functionsfn provide(impl Provider) -> impl Provider
, and have the entirety of the newtype as an implementation detail hidden inside the body, perhaps by using a macro?)We can probably automate some of this this by having a marker
trait DelegateTo<T>: Deref<Target = T> {}
which enables adefault impl
ofProvider
delegating all the methods toT
, and then the regularimpl
ofProvider
for each individualProvide<T>
newtype would contain only the methods that are relevant to it.This still feels horribly inefficient but at least we don't have to generate the delegation using macros so maybe it's not that bad?
cc @nikomatsakis @michaelwoerister @Zoxc