initial draft for downcastable Log #739
No reviewers
Labels
No labels
bug
duplicate
easy
enhancement
help wanted
invalid
question
rfc
structured-logging
wontfix
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-rust-lang/log!739
Loading…
Reference in a new issue
No description provided.
Delete branch "djugei/dyn_downcast"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
fixes #666.
i do not expect this to be merged as is, this is more of a discussion helper. Names are up for bikeshedding.
technically this is not a breaking change i think, as anything that implements log automatically implements LogAny though i agree that it looks weird.
can't just have a method on Log sadly as that would introduce a
Sizedrequirement (for some reason). Can't add the Any bound to Log itself as it would need to be 'statici have tested this with indicatif-log-bridge and env_logger and it works
Thanks for the PR @djugei! I think we can get away without the
as_anymethod, since recent Rust releases support dyn trait upcasting. Maybe something like:I did look at a few alternative designs that try to fully hide the downcasting support, but they all had unsatisfying trade-offs since we accept a
Box<dyn Trait>in our public API.just makes user code a bit uglier
log::logger().as_any().downcast_ref()(log::logger() as &'static dyn std::any::Any).downcast_ref()but yes, no additional capabilities so can be removed.
is this feature in general something the project would like to add?
I'd be in favour of this approach with the
as_anymethod removed. I think we should call the traitGlobalLog, and use it as our marker for aLogthat can be plugged into the shared slot.I think this a breaking change. We didn't the
std::any::Anytrait bound on these functions before, now we effectively do. So we might as well dopub trait Log: std::any::Any { ... }.@Thomasdezeeuw Yeh I checked this as well, and couldn’t actually trigger a compile error by flipping from
Box<dyn Log>toBox<dyn GlobalLog>, I believe because of the default'staticobject bound. If there’s any chance this is a breaking change though we should avoid it.Adding an
Anybound toLogitself is almost certainly a breaking change.Not 100% accurate, but I think https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=7e1712bc6dbdeb86780c85de4b0a7e6c shows it's a problem.
i tried doing
Log: Anybut that lead to lifetime issues withimpl Log for &'_ T: Logso i did a separate trait, though i guess those could be tightened to &'static and it would be fine.i think any concrete type that implements Log will also implement Any, but if you have a function that bounds only on Log then the compiler is ignorant of that fact, so yeah i guess this is a breaking change after all, though one that can be fixed with minimal changes/no structural changes.
Ah yes I see. If you explicitly already have a
Box<dyn Log>you can’t pass it to theset_boxed_loggerfunction when we introduceGlobalLog.That would mean we’d have to introduce a new set of APIs for this if we wanted to do it and deprecate the old ones. I’m not sure that level of churn is worth it.
it is even worse than that: since we need to store the logger we have to decide on a concrete type, so those would be 2 completely separate apis, which does not make a lot of sense to me, as it would essentially be keeping two versions. in that case i would just keep one version in the library and let cargo do its job for versioning.
alternatively we can try to think about &'static Log always being Any a bit harder and maybe do an unsafe cast if we can convince ourselves that it is always safe? i sadly do not know a ton about trait objects.
then again this functionality is achievable without using Any at all (see issue) but uses unsafe to do so in the first place. i was hoping for an elegant solution with Any.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.