mirror of
https://github.com/rust-lang/rust
synced 2024-09-20 17:02:37 +00:00
Rollup merge of #126328 - RalfJung:is_none_or, r=workingjubilee
Add Option::is_none_or ACP: https://github.com/rust-lang/libs-team/issues/212
This commit is contained in:
commit
f5af7eea1a
|
@ -1057,7 +1057,7 @@ fn is_very_trivially_sized(ty: Ty<'_>) -> bool {
|
|||
|
||||
ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false,
|
||||
|
||||
ty::Tuple(tys) => tys.last().iter().all(|ty| is_very_trivially_sized(**ty)),
|
||||
ty::Tuple(tys) => tys.last().is_none_or(|ty| is_very_trivially_sized(*ty)),
|
||||
|
||||
ty::Pat(ty, ..) => is_very_trivially_sized(*ty),
|
||||
|
||||
|
|
|
@ -446,7 +446,7 @@ fn check_and_deref_ptr<T>(
|
|||
let (alloc_size, _alloc_align, ret_val) = alloc_size(alloc_id, offset, prov)?;
|
||||
// Test bounds.
|
||||
// It is sufficient to check this for the end pointer. Also check for overflow!
|
||||
if offset.checked_add(size, &self.tcx).map_or(true, |end| end > alloc_size) {
|
||||
if offset.checked_add(size, &self.tcx).is_none_or(|end| end > alloc_size) {
|
||||
throw_ub!(PointerOutOfBounds {
|
||||
alloc_id,
|
||||
alloc_size,
|
||||
|
|
|
@ -300,7 +300,7 @@ fn project_subslice<P: Projectable<'tcx, M::Provenance>>(
|
|||
) -> InterpResult<'tcx, P> {
|
||||
let len = base.len(self)?; // also asserts that we have a type where this makes sense
|
||||
let actual_to = if from_end {
|
||||
if from.checked_add(to).map_or(true, |to| to > len) {
|
||||
if from.checked_add(to).is_none_or(|to| to > len) {
|
||||
// This can only be reached in ConstProp and non-rustc-MIR.
|
||||
throw_ub!(BoundsCheckFailed { len: len, index: from.saturating_add(to) });
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#![feature(box_patterns)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(is_none_or)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![feature(rustdoc_internals)]
|
||||
|
|
|
@ -234,7 +234,7 @@ fn suggest_removing_semicolon_for_coerce(
|
|||
let ret_ty = ret_coercion.borrow().expected_ty();
|
||||
let ret_ty = self.infcx.shallow_resolve(ret_ty);
|
||||
self.can_coerce(arm_ty, ret_ty)
|
||||
&& prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty))
|
||||
&& prior_arm.is_none_or(|(_, ty, _)| self.can_coerce(ty, ret_ty))
|
||||
// The match arms need to unify for the case of `impl Trait`.
|
||||
&& !matches!(ret_ty.kind(), ty::Alias(ty::Opaque, ..))
|
||||
}
|
||||
|
|
|
@ -913,7 +913,7 @@ fn coerce_closure_to_fn(
|
|||
if self
|
||||
.tcx
|
||||
.upvars_mentioned(closure_def_id_a.expect_local())
|
||||
.map_or(true, |u| u.is_empty()) =>
|
||||
.is_none_or(|u| u.is_empty()) =>
|
||||
{
|
||||
// We coerce the closure, which has fn type
|
||||
// `extern "rust-call" fn((arg0,arg1,...)) -> _`
|
||||
|
|
|
@ -1557,7 +1557,7 @@ fn check_repeat_element_needs_copy_bound(
|
|||
|
||||
// If the length is 0, we don't create any elements, so we don't copy any. If the length is 1, we
|
||||
// don't copy that one element, we move it. Only check for Copy if the length is larger.
|
||||
if count.try_eval_target_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
|
||||
if count.try_eval_target_usize(tcx, self.param_env).is_none_or(|len| len > 1) {
|
||||
let lang_item = self.tcx.require_lang_item(LangItem::Copy, None);
|
||||
let code = traits::ObligationCauseCode::RepeatElementCopy {
|
||||
is_constable,
|
||||
|
|
|
@ -2240,7 +2240,7 @@ fn label_fn_like(
|
|||
for (idx, (generic_param, param)) in
|
||||
params_with_generics.iter().enumerate().filter(|(idx, _)| {
|
||||
check_for_matched_generics
|
||||
|| expected_idx.map_or(true, |expected_idx| expected_idx == *idx)
|
||||
|| expected_idx.is_none_or(|expected_idx| expected_idx == *idx)
|
||||
})
|
||||
{
|
||||
let Some(generic_param) = generic_param else {
|
||||
|
|
|
@ -440,7 +440,7 @@ pub fn suggest_deref_ref_or_into(
|
|||
};
|
||||
// Given `Result<_, E>`, check our expected ty is `Result<_, &E>` for
|
||||
// `as_ref` and `as_deref` compatibility.
|
||||
let error_tys_equate_as_ref = error_tys.map_or(true, |(found, expected)| {
|
||||
let error_tys_equate_as_ref = error_tys.is_none_or(|(found, expected)| {
|
||||
self.can_eq(
|
||||
self.param_env,
|
||||
Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, found),
|
||||
|
@ -492,7 +492,7 @@ pub fn suggest_deref_ref_or_into(
|
|||
&& Some(adt.did()) == self.tcx.lang_items().string()
|
||||
&& peeled.is_str()
|
||||
// `Result::map`, conversely, does not take ref of the error type.
|
||||
&& error_tys.map_or(true, |(found, expected)| {
|
||||
&& error_tys.is_none_or(|(found, expected)| {
|
||||
self.can_eq(self.param_env, found, expected)
|
||||
})
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#![feature(box_patterns)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(is_none_or)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![feature(try_blocks)]
|
||||
|
|
|
@ -654,6 +654,32 @@ pub const fn is_none(&self) -> bool {
|
|||
!self.is_some()
|
||||
}
|
||||
|
||||
/// Returns `true` if the option is a [`None`] or the value inside of it matches a predicate.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(is_none_or)]
|
||||
///
|
||||
/// let x: Option<u32> = Some(2);
|
||||
/// assert_eq!(x.is_none_or(|x| x > 1), true);
|
||||
///
|
||||
/// let x: Option<u32> = Some(0);
|
||||
/// assert_eq!(x.is_none_or(|x| x > 1), false);
|
||||
///
|
||||
/// let x: Option<u32> = None;
|
||||
/// assert_eq!(x.is_none_or(|x| x > 1), true);
|
||||
/// ```
|
||||
#[must_use]
|
||||
#[inline]
|
||||
#[unstable(feature = "is_none_or", issue = "none")]
|
||||
pub fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool {
|
||||
match self {
|
||||
None => true,
|
||||
Some(x) => f(x),
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Adapter for working with references
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#![feature(lint_reasons)]
|
||||
#![feature(trait_upcasting)]
|
||||
#![feature(strict_overflow_ops)]
|
||||
#![feature(is_none_or)]
|
||||
// Configure clippy and other lints
|
||||
#![allow(
|
||||
clippy::collapsible_else_if,
|
||||
|
|
|
@ -396,12 +396,12 @@ fn emulate_foreign_item_inner(
|
|||
// If the newly promised alignment is bigger than the native alignment of this
|
||||
// allocation, and bigger than the previously promised alignment, then set it.
|
||||
if align > alloc_align
|
||||
&& !this
|
||||
&& this
|
||||
.machine
|
||||
.symbolic_alignment
|
||||
.get_mut()
|
||||
.get(&alloc_id)
|
||||
.is_some_and(|&(_, old_align)| align <= old_align)
|
||||
.is_none_or(|&(_, old_align)| align > old_align)
|
||||
{
|
||||
this.machine.symbolic_alignment.get_mut().insert(alloc_id, (offset, align));
|
||||
}
|
||||
|
|
|
@ -1387,6 +1387,7 @@ fn generic_args_sans_defaults<'ga>(
|
|||
}
|
||||
// otherwise, if the arg is equal to the param default, hide it (unless the
|
||||
// default is an error which can happen for the trait Self type)
|
||||
#[allow(unstable_name_collisions)]
|
||||
default_parameters.get(i).is_none_or(|default_parameter| {
|
||||
// !is_err(default_parameter.skip_binders())
|
||||
// &&
|
||||
|
|
Loading…
Reference in a new issue