mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Auto merge of #98912 - nrc:provider-it, r=yaahc
core::any: replace some generic types with impl Trait This gives a cleaner API since the caller only specifies the concrete type they usually want to. r? `@yaahc`
This commit is contained in:
commit
8bd12e8cca
@ -125,7 +125,7 @@
|
||||
//! impl dyn MyTrait + '_ {
|
||||
//! /// Get a reference to a field of the implementing struct.
|
||||
//! pub fn get_context_by_ref<T: ?Sized + 'static>(&self) -> Option<&T> {
|
||||
//! request_ref::<T, _>(self)
|
||||
//! request_ref::<T>(self)
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
@ -799,7 +799,7 @@ pub trait Provider {
|
||||
/// impl Provider for SomeConcreteType {
|
||||
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
|
||||
/// demand.provide_ref::<str>(&self.field)
|
||||
/// .provide_value::<i32, _>(|| self.num_field);
|
||||
/// .provide_value::<i32>(|| self.num_field);
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
@ -817,17 +817,16 @@ pub trait Provider {
|
||||
/// # #![feature(provide_any)]
|
||||
/// use std::any::{Provider, request_value};
|
||||
///
|
||||
/// fn get_string<P: Provider>(provider: &P) -> String {
|
||||
/// request_value::<String, _>(provider).unwrap()
|
||||
/// fn get_string(provider: &impl Provider) -> String {
|
||||
/// request_value::<String>(provider).unwrap()
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "provide_any", issue = "96024")]
|
||||
pub fn request_value<'a, T, P>(provider: &'a P) -> Option<T>
|
||||
pub fn request_value<'a, T>(provider: &'a (impl Provider + ?Sized)) -> Option<T>
|
||||
where
|
||||
T: 'static,
|
||||
P: Provider + ?Sized,
|
||||
{
|
||||
request_by_type_tag::<'a, tags::Value<T>, P>(provider)
|
||||
request_by_type_tag::<'a, tags::Value<T>>(provider)
|
||||
}
|
||||
|
||||
/// Request a reference from the `Provider`.
|
||||
@ -840,24 +839,22 @@ where
|
||||
/// # #![feature(provide_any)]
|
||||
/// use std::any::{Provider, request_ref};
|
||||
///
|
||||
/// fn get_str<P: Provider>(provider: &P) -> &str {
|
||||
/// request_ref::<str, _>(provider).unwrap()
|
||||
/// fn get_str(provider: &impl Provider) -> &str {
|
||||
/// request_ref::<str>(provider).unwrap()
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "provide_any", issue = "96024")]
|
||||
pub fn request_ref<'a, T, P>(provider: &'a P) -> Option<&'a T>
|
||||
pub fn request_ref<'a, T>(provider: &'a (impl Provider + ?Sized)) -> Option<&'a T>
|
||||
where
|
||||
T: 'static + ?Sized,
|
||||
P: Provider + ?Sized,
|
||||
{
|
||||
request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>, P>(provider)
|
||||
request_by_type_tag::<'a, tags::Ref<tags::MaybeSizedValue<T>>>(provider)
|
||||
}
|
||||
|
||||
/// Request a specific value by tag from the `Provider`.
|
||||
fn request_by_type_tag<'a, I, P>(provider: &'a P) -> Option<I::Reified>
|
||||
fn request_by_type_tag<'a, I>(provider: &'a (impl Provider + ?Sized)) -> Option<I::Reified>
|
||||
where
|
||||
I: tags::Type<'a>,
|
||||
P: Provider + ?Sized,
|
||||
{
|
||||
let mut tagged = TaggedOption::<'a, I>(None);
|
||||
provider.provide(tagged.as_demand());
|
||||
@ -896,17 +893,16 @@ impl<'a> Demand<'a> {
|
||||
///
|
||||
/// impl Provider for SomeConcreteType {
|
||||
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
|
||||
/// demand.provide_value::<String, _>(|| self.field.clone());
|
||||
/// demand.provide_value::<String>(|| self.field.clone());
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "provide_any", issue = "96024")]
|
||||
pub fn provide_value<T, F>(&mut self, fulfil: F) -> &mut Self
|
||||
pub fn provide_value<T>(&mut self, fulfil: impl FnOnce() -> T) -> &mut Self
|
||||
where
|
||||
T: 'static,
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
self.provide_with::<tags::Value<T>, F>(fulfil)
|
||||
self.provide_with::<tags::Value<T>>(fulfil)
|
||||
}
|
||||
|
||||
/// Provide a reference, note that the referee type must be bounded by `'static`,
|
||||
@ -944,10 +940,9 @@ impl<'a> Demand<'a> {
|
||||
}
|
||||
|
||||
/// Provide a value with the given `Type` tag, using a closure to prevent unnecessary work.
|
||||
fn provide_with<I, F>(&mut self, fulfil: F) -> &mut Self
|
||||
fn provide_with<I>(&mut self, fulfil: impl FnOnce() -> I::Reified) -> &mut Self
|
||||
where
|
||||
I: tags::Type<'a>,
|
||||
F: FnOnce() -> I::Reified,
|
||||
{
|
||||
if let Some(res @ TaggedOption(None)) = self.0.downcast_mut::<I>() {
|
||||
res.0 = Some(fulfil());
|
||||
|
@ -142,7 +142,7 @@ impl Provider for SomeConcreteType {
|
||||
demand
|
||||
.provide_ref::<String>(&self.some_string)
|
||||
.provide_ref::<str>(&self.some_string)
|
||||
.provide_value::<String, _>(|| "bye".to_owned());
|
||||
.provide_value::<String>(|| "bye".to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,9 +151,9 @@ impl Provider for SomeConcreteType {
|
||||
fn test_provider() {
|
||||
let obj: &dyn Provider = &SomeConcreteType { some_string: "hello".to_owned() };
|
||||
|
||||
assert_eq!(&**request_ref::<String, _>(obj).unwrap(), "hello");
|
||||
assert_eq!(&*request_value::<String, _>(obj).unwrap(), "bye");
|
||||
assert_eq!(request_value::<u8, _>(obj), None);
|
||||
assert_eq!(&**request_ref::<String>(obj).unwrap(), "hello");
|
||||
assert_eq!(&*request_value::<String>(obj).unwrap(), "bye");
|
||||
assert_eq!(request_value::<u8>(obj), None);
|
||||
}
|
||||
|
||||
// Test the provide and request mechanisms with a boxed trait object.
|
||||
@ -161,9 +161,9 @@ fn test_provider() {
|
||||
fn test_provider_boxed() {
|
||||
let obj: Box<dyn Provider> = Box::new(SomeConcreteType { some_string: "hello".to_owned() });
|
||||
|
||||
assert_eq!(&**request_ref::<String, _>(&*obj).unwrap(), "hello");
|
||||
assert_eq!(&*request_value::<String, _>(&*obj).unwrap(), "bye");
|
||||
assert_eq!(request_value::<u8, _>(&*obj), None);
|
||||
assert_eq!(&**request_ref::<String>(&*obj).unwrap(), "hello");
|
||||
assert_eq!(&*request_value::<String>(&*obj).unwrap(), "bye");
|
||||
assert_eq!(request_value::<u8>(&*obj), None);
|
||||
}
|
||||
|
||||
// Test the provide and request mechanisms with a concrete object.
|
||||
@ -171,9 +171,9 @@ fn test_provider_boxed() {
|
||||
fn test_provider_concrete() {
|
||||
let obj = SomeConcreteType { some_string: "hello".to_owned() };
|
||||
|
||||
assert_eq!(&**request_ref::<String, _>(&obj).unwrap(), "hello");
|
||||
assert_eq!(&*request_value::<String, _>(&obj).unwrap(), "bye");
|
||||
assert_eq!(request_value::<u8, _>(&obj), None);
|
||||
assert_eq!(&**request_ref::<String>(&obj).unwrap(), "hello");
|
||||
assert_eq!(&*request_value::<String>(&obj).unwrap(), "bye");
|
||||
assert_eq!(request_value::<u8>(&obj), None);
|
||||
}
|
||||
|
||||
trait OtherTrait: Provider {}
|
||||
@ -182,7 +182,7 @@ impl OtherTrait for SomeConcreteType {}
|
||||
|
||||
impl dyn OtherTrait {
|
||||
fn get_ref<T: 'static + ?Sized>(&self) -> Option<&T> {
|
||||
request_ref::<T, _>(self)
|
||||
request_ref::<T>(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user