Skip to content
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

Rollup of 8 pull requests #101311

Closed
wants to merge 27 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4eae7a1
don't ICE when normalizing closure input tys
aliemjay Jul 27, 2022
6b68921
Change implementation of `-Z gcc-ld` and `lld-wrapper` again
petrochenkov Aug 6, 2022
38de102
Support eager and lazy methods for providing references and values
shepmaster Jul 21, 2022
260ec93
Add `Provider::{would_be_satisfied_by_value_of,would_be_satisfied_by_…
shepmaster Jul 22, 2022
81a583c
Try normalizing types without RevealAll in ParamEnv in mir validation
Noratrieb Aug 3, 2022
96d4137
Only normalize once in mir validator typechecker
Noratrieb Aug 6, 2022
b9d3f65
[drop tracking] Use parent expression for scope
eholk Aug 30, 2022
1080467
access_levels.rs refactor
Bryanskiy Aug 14, 2022
0111fb0
add TestReachabilityVisitor
Bryanskiy Aug 14, 2022
54645e8
set up rustc_metadata for SessionDiagnostics, port dependency_format.rs
CleanCut Aug 23, 2022
3ed9310
port native_libs.rs to SessionDiagnostics
CleanCut Aug 23, 2022
f7e462a
port encoder.rs to SessionDiagnostics
CleanCut Aug 23, 2022
32e1823
port creader.rs to SessionDiagnostics
CleanCut Aug 23, 2022
bd8e312
port fs.rs to SessionDiagnostics
CleanCut Aug 23, 2022
d0ba1fb
port of locator.rs to SessionDiagnostics, fix some of the errors
CleanCut Aug 24, 2022
0d65819
respond to review feedback: mainly eliminate as many conversions as p…
CleanCut Aug 26, 2022
30adfd6
port 5 new diagnostics that appeared in master
CleanCut Aug 27, 2022
f921f56
Use parent_iter instead of a find_parent_node loop
eholk Aug 31, 2022
e5d60af
Simplify MIR opt tests
JakobDegen Aug 21, 2022
c20fe7c
Rollup merge of #99583 - shepmaster:provider-plus-plus, r=yaahc
Dylan-DPC Sep 2, 2022
5596314
Rollup merge of #99818 - aliemjay:fix-closure-normalize, r=estebank
Dylan-DPC Sep 2, 2022
83d2870
Rollup merge of #100121 - Nilstrieb:mir-validator-param-env, r=oli-obk
Dylan-DPC Sep 2, 2022
b39d4c6
Rollup merge of #100147 - Bryanskiy:private-in-public, r=petrochenkov
Dylan-DPC Sep 2, 2022
c772bbf
Rollup merge of #100200 - petrochenkov:zgccld2, r=lqd,Mark-Simulacrum
Dylan-DPC Sep 2, 2022
499cadd
Rollup merge of #100827 - JakobDegen:better-tests, r=wesleywiser
Dylan-DPC Sep 2, 2022
f0bbb83
Rollup merge of #100928 - CleanCut:rustc_metadata_diagnostics, r=davi…
Dylan-DPC Sep 2, 2022
96a3cac
Rollup merge of #101217 - eholk:drop-tracking-73137, r=jyn514
Dylan-DPC Sep 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add `Provider::{would_be_satisfied_by_value_of,would_be_satisfied_by_…
…ref_of}`

While the `provide_*` methods already short-circuit when a value has
been provided, there are times where an expensive computation is
needed to determine if the `provide_*` method can even be called.
  • Loading branch information
shepmaster committed Aug 23, 2022
commit 260ec9347838714ad9fa4f7e083bdc0448f4f9be
165 changes: 165 additions & 0 deletions library/core/src/any.rs
Original file line number Diff line number Diff line change
@@ -1008,6 +1008,156 @@ impl<'a> Demand<'a> {
}
self
}

/// Check if the `Demand` would be satisfied if provided with a
/// value of the specified type. If the type does not match or has
/// already been provided, returns false.
///
/// # Examples
///
/// Check if an `u8` still needs to be provided and then provides
/// it.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
///
/// struct Parent(Option<u8>);
///
/// impl Provider for Parent {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// if let Some(v) = self.0 {
/// demand.provide_value::<u8>(v);
/// }
/// }
/// }
///
/// struct Child {
/// parent: Parent,
/// }
///
/// impl Child {
/// // Pretend that this takes a lot of resources to evaluate.
/// fn an_expensive_computation(&self) -> Option<u8> {
/// Some(99)
/// }
/// }
///
/// impl Provider for Child {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// // In general, we don't know if this call will provide
/// // an `u8` value or not...
/// self.parent.provide(demand);
///
/// // ...so we check to see if the `u8` is needed before
/// // we run our expensive computation.
/// if demand.would_be_satisfied_by_value_of::<u8>() {
/// if let Some(v) = self.an_expensive_computation() {
/// demand.provide_value::<u8>(v);
/// }
/// }
///
/// // The demand will be satisfied now, regardless of if
/// // the parent provided the value or we did.
/// assert!(!demand.would_be_satisfied_by_value_of::<u8>());
/// }
/// }
///
/// let parent = Parent(Some(42));
/// let child = Child { parent };
/// assert_eq!(Some(42), std::any::request_value::<u8>(&child));
///
/// let parent = Parent(None);
/// let child = Child { parent };
/// assert_eq!(Some(99), std::any::request_value::<u8>(&child));
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn would_be_satisfied_by_value_of<T>(&self) -> bool
where
T: 'static,
{
self.would_be_satisfied_by::<tags::Value<T>>()
}

/// Check if the `Demand` would be satisfied if provided with a
/// reference to a value of the specified type. If the type does
/// not match or has already been provided, returns false.
///
/// # Examples
///
/// Check if a `&str` still needs to be provided and then provides
/// it.
///
/// ```rust
/// #![feature(provide_any)]
///
/// use std::any::{Provider, Demand};
///
/// struct Parent(Option<String>);
///
/// impl Provider for Parent {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// if let Some(v) = &self.0 {
/// demand.provide_ref::<str>(v);
/// }
/// }
/// }
///
/// struct Child {
/// parent: Parent,
/// name: String,
/// }
///
/// impl Child {
/// // Pretend that this takes a lot of resources to evaluate.
/// fn an_expensive_computation(&self) -> Option<&str> {
/// Some(&self.name)
/// }
/// }
///
/// impl Provider for Child {
/// fn provide<'a>(&'a self, demand: &mut Demand<'a>) {
/// // In general, we don't know if this call will provide
/// // a `str` reference or not...
/// self.parent.provide(demand);
///
/// // ...so we check to see if the `&str` is needed before
/// // we run our expensive computation.
/// if demand.would_be_satisfied_by_ref_of::<str>() {
/// if let Some(v) = self.an_expensive_computation() {
/// demand.provide_ref::<str>(v);
/// }
/// }
///
/// // The demand will be satisfied now, regardless of if
/// // the parent provided the reference or we did.
/// assert!(!demand.would_be_satisfied_by_ref_of::<str>());
/// }
/// }
///
/// let parent = Parent(Some("parent".into()));
/// let child = Child { parent, name: "child".into() };
/// assert_eq!(Some("parent"), std::any::request_ref::<str>(&child));
///
/// let parent = Parent(None);
/// let child = Child { parent, name: "child".into() };
/// assert_eq!(Some("child"), std::any::request_ref::<str>(&child));
/// ```
#[unstable(feature = "provide_any", issue = "96024")]
pub fn would_be_satisfied_by_ref_of<T>(&self) -> bool
where
T: ?Sized + 'static,
{
self.would_be_satisfied_by::<tags::Ref<tags::MaybeSizedValue<T>>>()
}

fn would_be_satisfied_by<I>(&self) -> bool
where
I: tags::Type<'a>,
{
matches!(self.0.downcast::<I>(), Some(TaggedOption(None)))
}
}

#[unstable(feature = "provide_any", issue = "96024")]
@@ -1112,6 +1262,21 @@ impl<'a> dyn Erased<'a> + 'a {
/// Returns some reference to the dynamic value if it is tagged with `I`,
/// or `None` otherwise.
#[inline]
fn downcast<I>(&self) -> Option<&TaggedOption<'a, I>>
where
I: tags::Type<'a>,
{
if self.tag_id() == TypeId::of::<I>() {
// SAFETY: Just checked whether we're pointing to an I.
Some(unsafe { &*(self as *const Self).cast::<TaggedOption<'a, I>>() })
} else {
None
}
}

/// Returns some mutable reference to the dynamic value if it is tagged with `I`,
/// or `None` otherwise.
#[inline]
fn downcast_mut<I>(&mut self) -> Option<&mut TaggedOption<'a, I>>
where
I: tags::Type<'a>,