Feature gate: #![feature(provide_any)]
This is a tracking issue for RFC 3192
This RFC proposes extending the
anymodule of the core library with a generic API for objects to provide type-based access to data. (In contrast to the existing APIs which provides type-driven downcasting, the proposed extension integrates downcasting into data access to provide a safer and more ergonomic API).
The initial motivating use case for this API is to provide the necessary functionality to add generic member access to the Error trait to generalize extracting context like Backtrace and to make it possible to move the Error trait into core while leaving Backtrace in std.
Public API
// core::any pub trait Provider { fn provide<'a>(&'a self, demand: &mut Demand<'a>); } pub fn request_value<'a, T>(provider: &'a (impl Provider + ?Sized)) -> Option<T> where T: 'static; pub fn request_ref<'a, T>(provider: &'a (impl Provider + ?Sized)) -> Option<&'a T> where T: 'static + ?Sized; #[repr(transparent)] pub struct Demand<'a>(_); impl<'a> Demand<'a> { pub fn provide_value<T>(&mut self, value: T) -> &mut Self where T: 'static; pub fn provide_value_with<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self where T: 'static; pub fn provide_ref<T: ?Sized + 'static>(&mut self, value: &'a T) -> &mut Self; pub fn provide_ref_with<T: ?Sized + 'static>( &mut self, fulfil: impl FnOnce() -> &'a T, ) -> &mut Self; pub fn would_be_satisfied_by_value_of<T>(&self) -> bool where T: 'static; pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool where T: ?Sized + 'static, } impl<'a> fmt::Debug for Demand<'a> {} // core::error impl<E> Provider for E where E: Error + ?Sized;
Steps / History
- Implementation: Add the Provider api to core::any #91970
- Delete the
Providertrait and merge its functionality intoError. - Pick either
demandorrequestand use that name consistently. - LLVM is unable to optimize multiple
.provide_*calls into a switch table because each call fetches the type id fromErased::type_idseparately each time and the compiler doesn't know that these calls all return the same value. This should be fixed. See Add provide_any module to core rfcs#3192 (comment) for one possible solution (although alternative solutions may be possible). - Final comment period (FCP)
- Stabilization PR
Unresolved Questions
- Should the APIs be named
demand_*orrequest_*?