Auto merge of #71556 - Dylan-DPC:rollup-9ll4shr, r=Dylan-DPC

Rollup of 7 pull requests

Successful merges:

 - #69041 (proc_macro: Stabilize `Span::resolved_at` and `Span::located_at`)
 - #69813 (Implement BitOr and BitOrAssign for the NonZero integer types)
 - #70712 (stabilize BTreeMap::remove_entry)
 - #71168 (Deprecate `{Box,Rc,Arc}::into_raw_non_null`)
 - #71544 (Replace filter_map().next() calls with find_map())
 - #71545 (Fix comment in docstring example for Error::kind)
 - #71548 (Add missing Send and Sync impls for linked list Cursor and CursorMut.)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-04-25 17:49:00 +00:00
commit 0862458dad
34 changed files with 312 additions and 186 deletions

View File

@ -428,7 +428,12 @@ impl<T: ?Sized> Box<T> {
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
pub fn into_raw(b: Box<T>) -> *mut T {
Box::into_raw_non_null(b).as_ptr()
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
// raw pointer for the type system. Turning it directly into a raw pointer would not be
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
// so all raw pointer methods go through `leak` which creates a (unique)
// mutable reference. Turning *that* to a raw pointer behaves correctly.
Box::leak(b) as *mut T
}
/// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>`.
@ -451,6 +456,7 @@ impl<T: ?Sized> Box<T> {
///
/// ```
/// #![feature(box_into_raw_non_null)]
/// #![allow(deprecated)]
///
/// let x = Box::new(5);
/// let ptr = Box::into_raw_non_null(x);
@ -460,24 +466,34 @@ impl<T: ?Sized> Box<T> {
/// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
/// ```
#[unstable(feature = "box_into_raw_non_null", issue = "47336")]
#[rustc_deprecated(
since = "1.44.0",
reason = "use `Box::leak(b).into()` or `NonNull::from(Box::leak(b))` instead"
)]
#[inline]
pub fn into_raw_non_null(b: Box<T>) -> NonNull<T> {
Box::into_unique(b).into()
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
// raw pointer for the type system. Turning it directly into a raw pointer would not be
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
// so all raw pointer methods go through `leak` which creates a (unique)
// mutable reference. Turning *that* to a raw pointer behaves correctly.
Box::leak(b).into()
}
#[unstable(feature = "ptr_internals", issue = "none", reason = "use into_raw_non_null instead")]
#[unstable(
feature = "ptr_internals",
issue = "none",
reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead"
)]
#[inline]
#[doc(hidden)]
pub fn into_unique(b: Box<T>) -> Unique<T> {
let b = mem::ManuallyDrop::new(b);
let mut unique = b.0;
// Box is kind-of a library type, but recognized as a "unique pointer" by
// Stacked Borrows. This function here corresponds to "reborrowing to
// a raw pointer", but there is no actual reborrow here -- so
// without some care, the pointer we are returning here still carries
// the tag of `b`, with `Unique` permission.
// We round-trip through a mutable reference to avoid that.
unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) }
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
// raw pointer for the type system. Turning it directly into a raw pointer would not be
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
// so all raw pointer methods go through `leak` which creates a (unique)
// mutable reference. Turning *that* to a raw pointer behaves correctly.
Box::leak(b).into()
}
/// Consumes and leaks the `Box`, returning a mutable reference,
@ -523,7 +539,7 @@ impl<T: ?Sized> Box<T> {
where
T: 'a, // Technically not needed, but kept to be explicit.
{
unsafe { &mut *Box::into_raw(b) }
unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() }
}
/// Converts a `Box<T>` into a `Pin<Box<T>>`

View File

@ -923,7 +923,6 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// Basic usage:
///
/// ```
/// #![feature(btreemap_remove_entry)]
/// use std::collections::BTreeMap;
///
/// let mut map = BTreeMap::new();
@ -931,7 +930,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// assert_eq!(map.remove_entry(&1), Some((1, "a")));
/// assert_eq!(map.remove_entry(&1), None);
/// ```
#[unstable(feature = "btreemap_remove_entry", issue = "66714")]
#[stable(feature = "btreemap_remove_entry", since = "1.44.0")]
pub fn remove_entry<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, V)>
where
K: Borrow<Q>,

View File

@ -143,7 +143,7 @@ impl<T> LinkedList<T> {
unsafe {
node.next = self.head;
node.prev = None;
let node = Some(Box::into_raw_non_null(node));
let node = Some(Box::leak(node).into());
match self.head {
None => self.tail = node,
@ -184,7 +184,7 @@ impl<T> LinkedList<T> {
unsafe {
node.next = None;
node.prev = self.tail;
let node = Some(Box::into_raw_non_null(node));
let node = Some(Box::leak(node).into());
match self.tail {
None => self.head = node,
@ -1133,11 +1133,9 @@ impl<T> IterMut<'_, T> {
Some(prev) => prev,
};
let node = Some(Box::into_raw_non_null(box Node {
next: Some(head),
prev: Some(prev),
element,
}));
let node = Some(
Box::leak(box Node { next: Some(head), prev: Some(prev), element }).into(),
);
// Not creating references to entire nodes to not invalidate the
// reference to `element` we handed to the user.
@ -1450,7 +1448,7 @@ impl<'a, T> CursorMut<'a, T> {
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn insert_after(&mut self, item: T) {
unsafe {
let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item)));
let spliced_node = Box::leak(Box::new(Node::new(item))).into();
let node_next = match self.current {
None => self.list.head,
Some(node) => node.as_ref().next,
@ -1470,7 +1468,7 @@ impl<'a, T> CursorMut<'a, T> {
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn insert_before(&mut self, item: T) {
unsafe {
let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item)));
let spliced_node = Box::leak(Box::new(Node::new(item))).into();
let node_prev = match self.current {
None => self.list.tail,
Some(node) => node.as_ref().prev,
@ -1843,3 +1841,15 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
#[unstable(feature = "linked_list_cursors", issue = "58533")]
unsafe impl<T: Sync> Send for Cursor<'_, T> {}
#[unstable(feature = "linked_list_cursors", issue = "58533")]
unsafe impl<T: Sync> Sync for Cursor<'_, T> {}
#[unstable(feature = "linked_list_cursors", issue = "58533")]
unsafe impl<T: Send> Send for CursorMut<'_, T> {}
#[unstable(feature = "linked_list_cursors", issue = "58533")]
unsafe impl<T: Sync> Sync for CursorMut<'_, T> {}

View File

@ -77,7 +77,6 @@
#![feature(allocator_api)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(box_into_raw_non_null)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_sanitize)]

View File

@ -323,11 +323,9 @@ impl<T> Rc<T> {
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
Self::from_inner(Box::into_raw_non_null(box RcBox {
strong: Cell::new(1),
weak: Cell::new(1),
value,
}))
Self::from_inner(
Box::leak(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value }).into(),
)
}
/// Constructs a new `Rc` with uninitialized contents.
@ -661,6 +659,7 @@ impl<T: ?Sized> Rc<T> {
///
/// ```
/// #![feature(rc_into_raw_non_null)]
/// #![allow(deprecated)]
///
/// use std::rc::Rc;
///
@ -670,6 +669,7 @@ impl<T: ?Sized> Rc<T> {
/// assert_eq!(deref, "hello");
/// ```
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
#[rustc_deprecated(since = "1.44.0", reason = "use `Rc::into_raw` instead")]
#[inline]
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
// safe because Rc guarantees its pointer is non-null

View File

@ -324,7 +324,7 @@ impl<T> Arc<T> {
weak: atomic::AtomicUsize::new(1),
data,
};
Self::from_inner(Box::into_raw_non_null(x))
Self::from_inner(Box::leak(x).into())
}
/// Constructs a new `Arc` with uninitialized contents.
@ -658,6 +658,7 @@ impl<T: ?Sized> Arc<T> {
///
/// ```
/// #![feature(rc_into_raw_non_null)]
/// #![allow(deprecated)]
///
/// use std::sync::Arc;
///
@ -667,6 +668,7 @@ impl<T: ?Sized> Arc<T> {
/// assert_eq!(deref, "hello");
/// ```
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
#[rustc_deprecated(since = "1.44.0", reason = "use `Arc::into_raw` instead")]
#[inline]
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
// safe because Arc guarantees its pointer is non-null

View File

@ -8,6 +8,7 @@ use crate::convert::Infallible;
use crate::fmt;
use crate::intrinsics;
use crate::mem;
use crate::ops::{BitOr, BitOrAssign};
use crate::str::FromStr;
// Used because the `?` operator is not allowed in a const context.
@ -110,6 +111,57 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
}
}
#[stable(feature = "nonzero_bitor", since = "1.43.0")]
impl BitOr for $Ty {
type Output = Self;
#[inline]
fn bitor(self, rhs: Self) -> Self::Output {
// Safety: since `self` and `rhs` are both nonzero, the
// result of the bitwise-or will be nonzero.
unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
}
}
#[stable(feature = "nonzero_bitor", since = "1.43.0")]
impl BitOr<$Int> for $Ty {
type Output = Self;
#[inline]
fn bitor(self, rhs: $Int) -> Self::Output {
// Safety: since `self` is nonzero, the result of the
// bitwise-or will be nonzero regardless of the value of
// `rhs`.
unsafe { $Ty::new_unchecked(self.get() | rhs) }
}
}
#[stable(feature = "nonzero_bitor", since = "1.43.0")]
impl BitOr<$Ty> for $Int {
type Output = $Ty;
#[inline]
fn bitor(self, rhs: $Ty) -> Self::Output {
// Safety: since `rhs` is nonzero, the result of the
// bitwise-or will be nonzero regardless of the value of
// `self`.
unsafe { $Ty::new_unchecked(self | rhs.get()) }
}
}
#[stable(feature = "nonzero_bitor", since = "1.43.0")]
impl BitOrAssign for $Ty {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
*self = *self | rhs;
}
}
#[stable(feature = "nonzero_bitor", since = "1.43.0")]
impl BitOrAssign<$Int> for $Ty {
#[inline]
fn bitor_assign(&mut self, rhs: $Int) {
*self = *self | rhs;
}
}
impl_nonzero_fmt! {
#[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
}

View File

@ -141,3 +141,38 @@ fn test_from_str() {
Some(IntErrorKind::Overflow)
);
}
#[test]
fn test_nonzero_bitor() {
let nz_alt = NonZeroU8::new(0b1010_1010).unwrap();
let nz_low = NonZeroU8::new(0b0000_1111).unwrap();
let both_nz: NonZeroU8 = nz_alt | nz_low;
assert_eq!(both_nz.get(), 0b1010_1111);
let rhs_int: NonZeroU8 = nz_low | 0b1100_0000u8;
assert_eq!(rhs_int.get(), 0b1100_1111);
let rhs_zero: NonZeroU8 = nz_alt | 0u8;
assert_eq!(rhs_zero.get(), 0b1010_1010);
let lhs_int: NonZeroU8 = 0b0110_0110u8 | nz_alt;
assert_eq!(lhs_int.get(), 0b1110_1110);
let lhs_zero: NonZeroU8 = 0u8 | nz_low;
assert_eq!(lhs_zero.get(), 0b0000_1111);
}
#[test]
fn test_nonzero_bitor_assign() {
let mut target = NonZeroU8::new(0b1010_1010).unwrap();
target |= NonZeroU8::new(0b0000_1111).unwrap();
assert_eq!(target.get(), 0b1010_1111);
target |= 0b0001_0000;
assert_eq!(target.get(), 0b1011_1111);
target |= 0;
assert_eq!(target.get(), 0b1011_1111);
}

View File

@ -351,14 +351,14 @@ impl Span {
/// Creates a new span with the same line/column information as `self` but
/// that resolves symbols as though it were at `other`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[stable(feature = "proc_macro_span_resolved_at", since = "1.43.0")]
pub fn resolved_at(&self, other: Span) -> Span {
Span(self.0.resolved_at(other.0))
}
/// Creates a new span with the same name resolution behavior as `self` but
/// with the line/column information of `other`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[stable(feature = "proc_macro_span_located_at", since = "1.43.0")]
pub fn located_at(&self, other: Span) -> Span {
other.resolved_at(*self)
}

View File

@ -1127,11 +1127,7 @@ fn exported_symbols(tcx: TyCtxt<'_>, crate_type: CrateType) -> Vec<String> {
}
let formats = tcx.dependency_formats(LOCAL_CRATE);
let deps = formats
.iter()
.filter_map(|(t, list)| if *t == crate_type { Some(list) } else { None })
.next()
.unwrap();
let deps = formats.iter().find_map(|(t, list)| (*t == crate_type).then_some(list)).unwrap();
for (index, dep_format) in deps.iter().enumerate() {
let cnum = CrateNum::new(index + 1);

View File

@ -285,21 +285,18 @@ pub trait Emitter {
let has_macro_spans = iter::once(&*span)
.chain(children.iter().map(|child| &child.span))
.flat_map(|span| span.primary_spans())
.copied()
.flat_map(|sp| {
sp.macro_backtrace().filter_map(|expn_data| {
match expn_data.kind {
ExpnKind::Root => None,
.flat_map(|sp| sp.macro_backtrace())
.find_map(|expn_data| {
match expn_data.kind {
ExpnKind::Root => None,
// Skip past non-macro entries, just in case there
// are some which do actually involve macros.
ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None,
// Skip past non-macro entries, just in case there
// are some which do actually involve macros.
ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None,
ExpnKind::Macro(macro_kind, _) => Some(macro_kind),
}
})
})
.next();
ExpnKind::Macro(macro_kind, _) => Some(macro_kind),
}
});
if !backtrace {
self.fix_multispans_in_extern_macros(source_map, span, children);

View File

@ -1632,8 +1632,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
];
if let Some(msg) = have_as_ref
.iter()
.filter_map(|(path, msg)| if &path_str == path { Some(msg) } else { None })
.next()
.find_map(|(path, msg)| (&path_str == path).then_some(msg))
{
let mut show_suggestion = true;
for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) {

View File

@ -47,8 +47,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
return fndecl
.inputs
.iter()
.filter_map(|arg| self.find_component_for_bound_region(arg, br))
.next()
.find_map(|arg| self.find_component_for_bound_region(arg, br))
.map(|ty| (ty, &**fndecl));
}
}

View File

@ -58,37 +58,33 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap();
let poly_fn_sig = self.tcx().fn_sig(id);
let fn_sig = self.tcx().liberate_late_bound_regions(id, &poly_fn_sig);
body.params
.iter()
.enumerate()
.filter_map(|(index, param)| {
// May return None; sometimes the tables are not yet populated.
let ty = fn_sig.inputs()[index];
let mut found_anon_region = false;
let new_param_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
if *r == *anon_region {
found_anon_region = true;
replace_region
} else {
r
}
});
if found_anon_region {
let ty_hir_id = fn_decl.inputs[index].hir_id;
let param_ty_span = hir.span(ty_hir_id);
let is_first = index == 0;
Some(AnonymousParamInfo {
param,
param_ty: new_param_ty,
param_ty_span,
bound_region,
is_first,
})
body.params.iter().enumerate().find_map(|(index, param)| {
// May return None; sometimes the tables are not yet populated.
let ty = fn_sig.inputs()[index];
let mut found_anon_region = false;
let new_param_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
if *r == *anon_region {
found_anon_region = true;
replace_region
} else {
None
r
}
})
.next()
});
if found_anon_region {
let ty_hir_id = fn_decl.inputs[index].hir_id;
let param_ty_span = hir.span(ty_hir_id);
let is_first = index == 0;
Some(AnonymousParamInfo {
param,
param_ty: new_param_ty,
param_ty_span,
bound_region,
is_first,
})
} else {
None
}
})
}
// Here, we check for the case where the anonymous region

View File

@ -267,17 +267,14 @@ pub fn rustc_path<'a>() -> Option<&'a Path> {
}
fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
sysroot_candidates()
.iter()
.filter_map(|sysroot| {
let candidate = sysroot.join(bin_path).join(if cfg!(target_os = "windows") {
"rustc.exe"
} else {
"rustc"
});
candidate.exists().then_some(candidate)
})
.next()
sysroot_candidates().iter().find_map(|sysroot| {
let candidate = sysroot.join(bin_path).join(if cfg!(target_os = "windows") {
"rustc.exe"
} else {
"rustc"
});
candidate.exists().then_some(candidate)
})
}
fn sysroot_candidates() -> Vec<PathBuf> {

View File

@ -179,8 +179,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
.stacktrace
.iter()
.rev()
.filter_map(|frame| frame.lint_root)
.next()
.find_map(|frame| frame.lint_root)
.unwrap_or(lint_root);
tcx.struct_span_lint_hir(
rustc_session::lint::builtin::CONST_ERR,

View File

@ -278,7 +278,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
ty::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
ty::Tuple(ref tys) => {
tys.iter().filter_map(|ty| characteristic_def_id_of_type(ty.expect_ty())).next()
tys.iter().find_map(|ty| characteristic_def_id_of_type(ty.expect_ty()))
}
ty::FnDef(def_id, _)

View File

@ -150,13 +150,10 @@ impl RegionHighlightMode {
/// Returns `Some(n)` with the number to use for the given region, if any.
fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
self.highlight_regions
.iter()
.filter_map(|h| match h {
Some((r, n)) if r == region => Some(*n),
_ => None,
})
.next()
self.highlight_regions.iter().find_map(|h| match h {
Some((r, n)) if r == region => Some(*n),
_ => None,
})
}
/// Highlight the given bound region.

View File

@ -1815,11 +1815,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
RegionElement::PlaceholderRegion(error_placeholder) => self
.definitions
.iter_enumerated()
.filter_map(|(r, definition)| match definition.origin {
.find_map(|(r, definition)| match definition.origin {
NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
_ => None,
})
.next()
.unwrap(),
}
}

View File

@ -113,8 +113,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>(
.statements
.iter()
.enumerate()
.filter_map(|(i, stmt)| value_assigned_to_local(stmt, call.arg).map(|rval| (i, rval)))
.next()
.find_map(|(i, stmt)| value_assigned_to_local(stmt, call.arg).map(|rval| (i, rval)))
.expect(
"call to rustc_peek should be preceded by \
assignment to temporary holding its argument",

View File

@ -480,14 +480,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
let next_early_index = self.next_early_index();
let was_in_fn_syntax = self.is_in_fn_syntax;
self.is_in_fn_syntax = true;
let lifetime_span: Option<Span> = c
.generic_params
.iter()
.filter_map(|param| match param.kind {
let lifetime_span: Option<Span> =
c.generic_params.iter().rev().find_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => Some(param.span),
_ => None,
})
.last();
});
let (span, span_type) = if let Some(span) = lifetime_span {
(span.shrink_to_hi(), ForLifetimeSpanType::TypeTail)
} else {

View File

@ -1140,13 +1140,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.generic_args()
.bindings
.iter()
.filter_map(|b| match (b.ident.as_str() == "Output", &b.kind) {
.find_map(|b| match (b.ident.as_str() == "Output", &b.kind) {
(true, hir::TypeBindingKind::Equality { ty }) => {
sess.source_map().span_to_snippet(ty.span).ok()
}
_ => None,
})
.next()
.unwrap_or_else(|| "()".to_string()),
)),
)

View File

@ -177,13 +177,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match expected_ty.kind {
ty::Dynamic(ref object_type, ..) => {
let sig = object_type
.projection_bounds()
.filter_map(|pb| {
let pb = pb.with_self_ty(self.tcx, self.tcx.types.err);
self.deduce_sig_from_projection(None, &pb)
})
.next();
let sig = object_type.projection_bounds().find_map(|pb| {
let pb = pb.with_self_ty(self.tcx, self.tcx.types.err);
self.deduce_sig_from_projection(None, &pb)
});
let kind = object_type
.principal_def_id()
.and_then(|did| self.tcx.fn_trait_kind_from_lang_item(did));

View File

@ -453,16 +453,13 @@ fn extract_spans_for_error_reporting<'a, 'tcx>(
.zip(trait_iter)
.zip(impl_m_iter)
.zip(trait_m_iter)
.filter_map(
|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)| match infcx
.at(&cause, param_env)
.sub(trait_arg_ty, impl_arg_ty)
{
Ok(_) => None,
Err(_) => Some((impl_arg.span, Some(trait_arg.span))),
},
)
.next()
.find_map(|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)| match infcx
.at(&cause, param_env)
.sub(trait_arg_ty, impl_arg_ty)
{
Ok(_) => None,
Err(_) => Some((impl_arg.span, Some(trait_arg.span))),
})
.unwrap_or_else(|| {
if infcx
.at(&cause, param_env)

View File

@ -269,7 +269,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
self.fcx
.autoderef(self.span, self_ty)
.include_raw_pointers()
.filter_map(|(ty, _)| match ty.kind {
.find_map(|(ty, _)| match ty.kind {
ty::Dynamic(ref data, ..) => Some(closure(
self,
ty,
@ -279,7 +279,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
)),
_ => None,
})
.next()
.unwrap_or_else(|| {
span_bug!(
self.span,
@ -579,20 +578,18 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
.predicates
.iter()
.zip(predicates.spans.iter())
.filter_map(
.find_map(
|(p, span)| if *p == obligation.predicate { Some(*span) } else { None },
)
.next()
.unwrap_or(rustc_span::DUMMY_SP);
Some((trait_pred, span))
}
_ => None,
})
.filter_map(|(trait_pred, span)| match trait_pred.skip_binder().self_ty().kind {
.find_map(|(trait_pred, span)| match trait_pred.skip_binder().self_ty().kind {
ty::Dynamic(..) => Some(span),
_ => None,
})
.next()
}
fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) {

View File

@ -3527,14 +3527,13 @@ fn render_deref_methods(
.inner_impl()
.items
.iter()
.filter_map(|item| match item.inner {
.find_map(|item| match item.inner {
clean::TypedefItem(ref t, true) => Some(match *t {
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
_ => (&t.type_, &t.type_),
}),
_ => None,
})
.next()
.expect("Expected associated type binding");
let what =
AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut };
@ -4111,18 +4110,14 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
.filter(|i| i.inner_impl().trait_.is_some())
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
{
if let Some((target, real_target)) = impl_
.inner_impl()
.items
.iter()
.filter_map(|item| match item.inner {
if let Some((target, real_target)) =
impl_.inner_impl().items.iter().find_map(|item| match item.inner {
clean::TypedefItem(ref t, true) => Some(match *t {
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
_ => (&t.type_, &t.type_),
}),
_ => None,
})
.next()
{
let inner_impl = target
.def_id()

View File

@ -89,11 +89,10 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
if cleaner.keep_item(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
let target = items
.iter()
.filter_map(|item| match item.inner {
.find_map(|item| match item.inner {
TypedefItem(ref t, true) => Some(&t.type_),
_ => None,
})
.next()
.expect("Deref impl without Target type");
if let Some(prim) = target.primitive_type() {

View File

@ -164,28 +164,23 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
body: hir::BodyId,
) {
debug!("visiting fn");
let macro_kind = item
.attrs
.iter()
.filter_map(|a| {
if a.check_name(sym::proc_macro) {
Some(MacroKind::Bang)
} else if a.check_name(sym::proc_macro_derive) {
Some(MacroKind::Derive)
} else if a.check_name(sym::proc_macro_attribute) {
Some(MacroKind::Attr)
} else {
None
}
})
.next();
let macro_kind = item.attrs.iter().find_map(|a| {
if a.check_name(sym::proc_macro) {
Some(MacroKind::Bang)
} else if a.check_name(sym::proc_macro_derive) {
Some(MacroKind::Derive)
} else if a.check_name(sym::proc_macro_attribute) {
Some(MacroKind::Attr)
} else {
None
}
});
match macro_kind {
Some(kind) => {
let name = if kind == MacroKind::Derive {
item.attrs
.lists(sym::proc_macro_derive)
.filter_map(|mi| mi.ident())
.next()
.find_map(|mi| mi.ident())
.expect("proc-macro derives require a name")
.name
} else {

View File

@ -1043,15 +1043,10 @@ impl<W: Write> Write for LineWriter<W> {
}
// Find the last newline, and failing that write the whole buffer
let last_newline = bufs
.iter()
.enumerate()
.rev()
.filter_map(|(i, buf)| {
let pos = memchr::memrchr(b'\n', buf)?;
Some((i, pos))
})
.next();
let last_newline = bufs.iter().enumerate().rev().find_map(|(i, buf)| {
let pos = memchr::memrchr(b'\n', buf)?;
Some((i, pos))
});
let (i, j) = match last_newline {
Some(pair) => pair,
None => return self.inner.write_vectored(bufs),

View File

@ -487,9 +487,9 @@ impl Error {
/// }
///
/// fn main() {
/// // Will print "No inner error".
/// // Will print "Other".
/// print_error(Error::last_os_error());
/// // Will print "Inner error: ...".
/// // Will print "AddrInUse".
/// print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
/// }
/// ```

View File

@ -173,14 +173,13 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
fn reset(&mut self) -> io::Result<bool> {
// are there any terminals that have color/attrs and not sgr0?
// Try falling back to sgr, then op
let cmd =
match ["sgr0", "sgr", "op"].iter().filter_map(|cap| self.ti.strings.get(*cap)).next() {
Some(op) => match expand(&op, &[], &mut Variables::new()) {
Ok(cmd) => cmd,
Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
},
None => return Ok(false),
};
let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) {
Some(op) => match expand(&op, &[], &mut Variables::new()) {
Ok(cmd) => cmd,
Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
},
None => return Ok(false),
};
self.out.write_all(&cmd).and(Ok(true))
}

View File

@ -0,0 +1,32 @@
// force-host
// no-prefer-dynamic
#![feature(proc_macro_def_site)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_hygiene)]
#![feature(proc_macro_quote)]
#![crate_type = "proc-macro"]
extern crate proc_macro;
use proc_macro::*;
#[proc_macro]
pub fn resolve_located_at(input: TokenStream) -> TokenStream {
match &*input.into_iter().collect::<Vec<_>>() {
[a, b, ..] => {
// The error is reported at input `a`.
let mut diag = Diagnostic::new(Level::Error, "expected error");
diag.set_spans(Span::def_site().located_at(a.span()));
diag.emit();
// Resolves to `struct S;` at def site, but the error is reported at input `b`.
let s = TokenTree::Ident(Ident::new("S", b.span().resolved_at(Span::def_site())));
quote!({
struct S;
$s
})
}
_ => panic!("unexpected input"),
}
}

View File

@ -0,0 +1,12 @@
// aux-build:resolved-located-at.rs
#![feature(proc_macro_hygiene)]
#[macro_use]
extern crate resolved_located_at;
fn main() {
resolve_located_at!(a b)
//~^ ERROR expected error
//~| ERROR mismatched types
}

View File

@ -0,0 +1,21 @@
error: expected error
--> $DIR/resolved-located-at.rs:9:25
|
LL | resolve_located_at!(a b)
| ^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> $DIR/resolved-located-at.rs:9:27
|
LL | fn main() {
| - expected `()` because of default return type
LL | resolve_located_at!(a b)
| ^ expected `()`, found struct `main::S`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.