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 9 pull requests #101315

Closed
wants to merge 28 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
28 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
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
1171697
Generate error index with mdbook instead of raw HTML pages
GuillaumeGomez Aug 29, 2022
630f831
Use `FILE_ATTRIBUTE_TAG_INFO` to get reparse tag
ChrisDenton Sep 1, 2022
f5857d5
Move error code book into a sub folder
GuillaumeGomez Aug 31, 2022
096efc2
rustdoc: remove unused CSS `#main-content > .since`
notriddle Sep 1, 2022
e5d60af
Simplify MIR opt tests
JakobDegen Aug 21, 2022
a53e417
Rollup merge of #99583 - shepmaster:provider-plus-plus, r=yaahc
Dylan-DPC Sep 2, 2022
aae7b23
Rollup merge of #99818 - aliemjay:fix-closure-normalize, r=estebank
Dylan-DPC Sep 2, 2022
0d368cd
Rollup merge of #100121 - Nilstrieb:mir-validator-param-env, r=oli-obk
Dylan-DPC Sep 2, 2022
b15dd6e
Rollup merge of #100200 - petrochenkov:zgccld2, r=lqd,Mark-Simulacrum
Dylan-DPC Sep 2, 2022
77b74d6
Rollup merge of #100827 - JakobDegen:better-tests, r=wesleywiser
Dylan-DPC Sep 2, 2022
19f3a31
Rollup merge of #100928 - CleanCut:rustc_metadata_diagnostics, r=davi…
Dylan-DPC Sep 2, 2022
2143179
Rollup merge of #101166 - GuillaumeGomez:error-index-mdbook, r=notriddle
Dylan-DPC Sep 2, 2022
fc65833
Rollup merge of #101260 - ChrisDenton:attribute-tag, r=thomcc
Dylan-DPC Sep 2, 2022
3b44a86
Rollup merge of #101298 - notriddle:notriddle/rustdoc-main-since, r=G…
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
Expand Up @@ -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")]
Expand Down Expand Up @@ -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>,
Expand Down