1
Fork 0

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,6 +8,7 @@ use crate::convert::Infallible;
use crate::fmt; use crate::fmt;
use crate::intrinsics; use crate::intrinsics;
use crate::mem; use crate::mem;
use crate::ops::{BitOr, BitOrAssign};
use crate::str::FromStr; use crate::str::FromStr;
// Used because the `?` operator is not allowed in a const context. // 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! { impl_nonzero_fmt! {
#[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
} }

View file

@ -141,3 +141,38 @@ fn test_from_str() {
Some(IntErrorKind::Overflow) 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 /// Creates a new span with the same line/column information as `self` but
/// that resolves symbols as though it were at `other`. /// 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 { pub fn resolved_at(&self, other: Span) -> Span {
Span(self.0.resolved_at(other.0)) Span(self.0.resolved_at(other.0))
} }
/// Creates a new span with the same name resolution behavior as `self` but /// Creates a new span with the same name resolution behavior as `self` but
/// with the line/column information of `other`. /// 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 { pub fn located_at(&self, other: Span) -> Span {
other.resolved_at(*self) 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 formats = tcx.dependency_formats(LOCAL_CRATE);
let deps = formats let deps = formats.iter().find_map(|(t, list)| (*t == crate_type).then_some(list)).unwrap();
.iter()
.filter_map(|(t, list)| if *t == crate_type { Some(list) } else { None })
.next()
.unwrap();
for (index, dep_format) in deps.iter().enumerate() { for (index, dep_format) in deps.iter().enumerate() {
let cnum = CrateNum::new(index + 1); let cnum = CrateNum::new(index + 1);

View file

@ -285,9 +285,8 @@ pub trait Emitter {
let has_macro_spans = iter::once(&*span) let has_macro_spans = iter::once(&*span)
.chain(children.iter().map(|child| &child.span)) .chain(children.iter().map(|child| &child.span))
.flat_map(|span| span.primary_spans()) .flat_map(|span| span.primary_spans())
.copied() .flat_map(|sp| sp.macro_backtrace())
.flat_map(|sp| { .find_map(|expn_data| {
sp.macro_backtrace().filter_map(|expn_data| {
match expn_data.kind { match expn_data.kind {
ExpnKind::Root => None, ExpnKind::Root => None,
@ -297,9 +296,7 @@ pub trait Emitter {
ExpnKind::Macro(macro_kind, _) => Some(macro_kind), ExpnKind::Macro(macro_kind, _) => Some(macro_kind),
} }
}) });
})
.next();
if !backtrace { if !backtrace {
self.fix_multispans_in_extern_macros(source_map, span, children); 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 if let Some(msg) = have_as_ref
.iter() .iter()
.filter_map(|(path, msg)| if &path_str == path { Some(msg) } else { None }) .find_map(|(path, msg)| (&path_str == path).then_some(msg))
.next()
{ {
let mut show_suggestion = true; let mut show_suggestion = true;
for (exp_ty, found_ty) in exp_substs.types().zip(found_substs.types()) { 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 return fndecl
.inputs .inputs
.iter() .iter()
.filter_map(|arg| self.find_component_for_bound_region(arg, br)) .find_map(|arg| self.find_component_for_bound_region(arg, br))
.next()
.map(|ty| (ty, &**fndecl)); .map(|ty| (ty, &**fndecl));
} }
} }

View file

@ -58,10 +58,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap(); let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap();
let poly_fn_sig = self.tcx().fn_sig(id); let poly_fn_sig = self.tcx().fn_sig(id);
let fn_sig = self.tcx().liberate_late_bound_regions(id, &poly_fn_sig); let fn_sig = self.tcx().liberate_late_bound_regions(id, &poly_fn_sig);
body.params body.params.iter().enumerate().find_map(|(index, param)| {
.iter()
.enumerate()
.filter_map(|(index, param)| {
// May return None; sometimes the tables are not yet populated. // May return None; sometimes the tables are not yet populated.
let ty = fn_sig.inputs()[index]; let ty = fn_sig.inputs()[index];
let mut found_anon_region = false; let mut found_anon_region = false;
@ -88,7 +85,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
None None
} }
}) })
.next()
} }
// Here, we check for the case where the anonymous region // Here, we check for the case where the anonymous region

View file

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

View file

@ -179,8 +179,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
.stacktrace .stacktrace
.iter() .iter()
.rev() .rev()
.filter_map(|frame| frame.lint_root) .find_map(|frame| frame.lint_root)
.next()
.unwrap_or(lint_root); .unwrap_or(lint_root);
tcx.struct_span_lint_hir( tcx.struct_span_lint_hir(
rustc_session::lint::builtin::CONST_ERR, 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::Ref(_, ty, _) => characteristic_def_id_of_type(ty),
ty::Tuple(ref tys) => { 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, _) 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. /// Returns `Some(n)` with the number to use for the given region, if any.
fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> { fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
self.highlight_regions self.highlight_regions.iter().find_map(|h| match h {
.iter()
.filter_map(|h| match h {
Some((r, n)) if r == region => Some(*n), Some((r, n)) if r == region => Some(*n),
_ => None, _ => None,
}) })
.next()
} }
/// Highlight the given bound region. /// Highlight the given bound region.

View file

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

View file

@ -113,8 +113,7 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>(
.statements .statements
.iter() .iter()
.enumerate() .enumerate()
.filter_map(|(i, stmt)| value_assigned_to_local(stmt, call.arg).map(|rval| (i, rval))) .find_map(|(i, stmt)| value_assigned_to_local(stmt, call.arg).map(|rval| (i, rval)))
.next()
.expect( .expect(
"call to rustc_peek should be preceded by \ "call to rustc_peek should be preceded by \
assignment to temporary holding its argument", 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 next_early_index = self.next_early_index();
let was_in_fn_syntax = self.is_in_fn_syntax; let was_in_fn_syntax = self.is_in_fn_syntax;
self.is_in_fn_syntax = true; self.is_in_fn_syntax = true;
let lifetime_span: Option<Span> = c let lifetime_span: Option<Span> =
.generic_params c.generic_params.iter().rev().find_map(|param| match param.kind {
.iter()
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => Some(param.span), GenericParamKind::Lifetime { .. } => Some(param.span),
_ => None, _ => None,
}) });
.last();
let (span, span_type) = if let Some(span) = lifetime_span { let (span, span_type) = if let Some(span) = lifetime_span {
(span.shrink_to_hi(), ForLifetimeSpanType::TypeTail) (span.shrink_to_hi(), ForLifetimeSpanType::TypeTail)
} else { } else {

View file

@ -1140,13 +1140,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.generic_args() .generic_args()
.bindings .bindings
.iter() .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 }) => { (true, hir::TypeBindingKind::Equality { ty }) => {
sess.source_map().span_to_snippet(ty.span).ok() sess.source_map().span_to_snippet(ty.span).ok()
} }
_ => None, _ => None,
}) })
.next()
.unwrap_or_else(|| "()".to_string()), .unwrap_or_else(|| "()".to_string()),
)), )),
) )

View file

@ -177,13 +177,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match expected_ty.kind { match expected_ty.kind {
ty::Dynamic(ref object_type, ..) => { ty::Dynamic(ref object_type, ..) => {
let sig = object_type let sig = object_type.projection_bounds().find_map(|pb| {
.projection_bounds()
.filter_map(|pb| {
let pb = pb.with_self_ty(self.tcx, self.tcx.types.err); let pb = pb.with_self_ty(self.tcx, self.tcx.types.err);
self.deduce_sig_from_projection(None, &pb) self.deduce_sig_from_projection(None, &pb)
}) });
.next();
let kind = object_type let kind = object_type
.principal_def_id() .principal_def_id()
.and_then(|did| self.tcx.fn_trait_kind_from_lang_item(did)); .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(trait_iter)
.zip(impl_m_iter) .zip(impl_m_iter)
.zip(trait_m_iter) .zip(trait_m_iter)
.filter_map( .find_map(|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)| match infcx
|(((&impl_arg_ty, &trait_arg_ty), impl_arg), trait_arg)| match infcx
.at(&cause, param_env) .at(&cause, param_env)
.sub(trait_arg_ty, impl_arg_ty) .sub(trait_arg_ty, impl_arg_ty)
{ {
Ok(_) => None, Ok(_) => None,
Err(_) => Some((impl_arg.span, Some(trait_arg.span))), Err(_) => Some((impl_arg.span, Some(trait_arg.span))),
}, })
)
.next()
.unwrap_or_else(|| { .unwrap_or_else(|| {
if infcx if infcx
.at(&cause, param_env) .at(&cause, param_env)

View file

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

View file

@ -3527,14 +3527,13 @@ fn render_deref_methods(
.inner_impl() .inner_impl()
.items .items
.iter() .iter()
.filter_map(|item| match item.inner { .find_map(|item| match item.inner {
clean::TypedefItem(ref t, true) => Some(match *t { clean::TypedefItem(ref t, true) => Some(match *t {
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
_ => (&t.type_, &t.type_), _ => (&t.type_, &t.type_),
}), }),
_ => None, _ => None,
}) })
.next()
.expect("Expected associated type binding"); .expect("Expected associated type binding");
let what = let what =
AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut }; 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()) .filter(|i| i.inner_impl().trait_.is_some())
.find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did)
{ {
if let Some((target, real_target)) = impl_ if let Some((target, real_target)) =
.inner_impl() impl_.inner_impl().items.iter().find_map(|item| match item.inner {
.items
.iter()
.filter_map(|item| match item.inner {
clean::TypedefItem(ref t, true) => Some(match *t { clean::TypedefItem(ref t, true) => Some(match *t {
clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_),
_ => (&t.type_, &t.type_), _ => (&t.type_, &t.type_),
}), }),
_ => None, _ => None,
}) })
.next()
{ {
let inner_impl = target let inner_impl = target
.def_id() .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() { if cleaner.keep_item(for_) && trait_.def_id() == cx.tcx.lang_items().deref_trait() {
let target = items let target = items
.iter() .iter()
.filter_map(|item| match item.inner { .find_map(|item| match item.inner {
TypedefItem(ref t, true) => Some(&t.type_), TypedefItem(ref t, true) => Some(&t.type_),
_ => None, _ => None,
}) })
.next()
.expect("Deref impl without Target type"); .expect("Deref impl without Target type");
if let Some(prim) = target.primitive_type() { if let Some(prim) = target.primitive_type() {

View file

@ -164,10 +164,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
body: hir::BodyId, body: hir::BodyId,
) { ) {
debug!("visiting fn"); debug!("visiting fn");
let macro_kind = item let macro_kind = item.attrs.iter().find_map(|a| {
.attrs
.iter()
.filter_map(|a| {
if a.check_name(sym::proc_macro) { if a.check_name(sym::proc_macro) {
Some(MacroKind::Bang) Some(MacroKind::Bang)
} else if a.check_name(sym::proc_macro_derive) { } else if a.check_name(sym::proc_macro_derive) {
@ -177,15 +174,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
} else { } else {
None None
} }
}) });
.next();
match macro_kind { match macro_kind {
Some(kind) => { Some(kind) => {
let name = if kind == MacroKind::Derive { let name = if kind == MacroKind::Derive {
item.attrs item.attrs
.lists(sym::proc_macro_derive) .lists(sym::proc_macro_derive)
.filter_map(|mi| mi.ident()) .find_map(|mi| mi.ident())
.next()
.expect("proc-macro derives require a name") .expect("proc-macro derives require a name")
.name .name
} else { } 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 // Find the last newline, and failing that write the whole buffer
let last_newline = bufs let last_newline = bufs.iter().enumerate().rev().find_map(|(i, buf)| {
.iter()
.enumerate()
.rev()
.filter_map(|(i, buf)| {
let pos = memchr::memrchr(b'\n', buf)?; let pos = memchr::memrchr(b'\n', buf)?;
Some((i, pos)) Some((i, pos))
}) });
.next();
let (i, j) = match last_newline { let (i, j) = match last_newline {
Some(pair) => pair, Some(pair) => pair,
None => return self.inner.write_vectored(bufs), None => return self.inner.write_vectored(bufs),

View file

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

View file

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

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`.