about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/boxed.rs46
-rw-r--r--src/liballoc/collections/btree/map.rs3
-rw-r--r--src/liballoc/collections/linked_list.rs28
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/rc.rs10
-rw-r--r--src/liballoc/sync.rs4
-rw-r--r--src/libcore/num/mod.rs52
-rw-r--r--src/libcore/tests/nonzero.rs35
-rw-r--r--src/libproc_macro/lib.rs4
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs6
-rw-r--r--src/librustc_errors/emitter.rs23
-rw-r--r--src/librustc_infer/infer/error_reporting/mod.rs3
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs3
-rw-r--r--src/librustc_infer/infer/error_reporting/nice_region_error/util.rs54
-rw-r--r--src/librustc_interface/util.rs19
-rw-r--r--src/librustc_middle/mir/interpret/error.rs3
-rw-r--r--src/librustc_middle/ty/print/mod.rs2
-rw-r--r--src/librustc_middle/ty/print/pretty.rs11
-rw-r--r--src/librustc_mir/borrow_check/region_infer/mod.rs3
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs3
-rw-r--r--src/librustc_resolve/late/lifetimes.rs9
-rw-r--r--src/librustc_typeck/astconv.rs3
-rw-r--r--src/librustc_typeck/check/closure.rs11
-rw-r--r--src/librustc_typeck/check/compare_method.rs17
-rw-r--r--src/librustc_typeck/check/method/confirm.rs9
-rw-r--r--src/librustdoc/html/render.rs11
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs3
-rw-r--r--src/librustdoc/visit_ast.rs29
-rw-r--r--src/libstd/io/buffered.rs13
-rw-r--r--src/libstd/io/error.rs4
-rw-r--r--src/libterm/terminfo/mod.rs15
-rw-r--r--src/test/ui/proc-macro/auxiliary/resolved-located-at.rs32
-rw-r--r--src/test/ui/proc-macro/resolved-located-at.rs12
-rw-r--r--src/test/ui/proc-macro/resolved-located-at.stderr21
34 files changed, 314 insertions, 188 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index db7420954a0..3d657396a9f 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -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()
-    }
-
-    #[unstable(feature = "ptr_internals", issue = "none", reason = "use into_raw_non_null instead")]
+        // 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 `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>>`
diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs
index 8d0cd191c2a..099687bd6b0 100644
--- a/src/liballoc/collections/btree/map.rs
+++ b/src/liballoc/collections/btree/map.rs
@@ -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>,
diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index af341e6c1ca..9dd7fc6d7ee 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -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> {}
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index f422c3f66e1..ecec1fb039b 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -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)]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 8144fe0128e..2f9505ec79f 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -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
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index adce23c42c0..a81e0cf7e1d 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -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
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 7ba4004d860..0349678b07b 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -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
             }
diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs
index 6c5d19845e4..0227a66b863 100644
--- a/src/libcore/tests/nonzero.rs
+++ b/src/libcore/tests/nonzero.rs
@@ -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);
+}
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index eb7677e9345..5995f64dc78 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -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)
     }
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 9ca8f743f65..5a911fcdc7d 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -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);
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 0023ff595fc..b22da86c091 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -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);
diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index 8b530191065..9de7dcc845f 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -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()) {
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs
index 190a2dcc556..de71363cbde 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -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));
             }
         }
diff --git a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
index 5c45f758436..22b130cdf5f 100644
--- a/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc_infer/infer/error_reporting/nice_region_error/util.rs
@@ -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
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 02bf1aded3b..fda01725443 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -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> {
diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs
index 2510dbcea0b..4b5c6177b25 100644
--- a/src/librustc_middle/mir/interpret/error.rs
+++ b/src/librustc_middle/mir/interpret/error.rs
@@ -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,
diff --git a/src/librustc_middle/ty/print/mod.rs b/src/librustc_middle/ty/print/mod.rs
index a932f334dde..6bdc65eb056 100644
--- a/src/librustc_middle/ty/print/mod.rs
+++ b/src/librustc_middle/ty/print/mod.rs
@@ -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, _)
diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index 828f7f6a767..8c8d20655f9 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -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.
diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs
index 7987b77997d..832f4278149 100644
--- a/src/librustc_mir/borrow_check/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/region_infer/mod.rs
@@ -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(),
         }
     }
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 88af60dbeb6..b9302d58cd5 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -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",
diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs
index 0deb0af448e..d95481b9590 100644
--- a/src/librustc_resolve/late/lifetimes.rs
+++ b/src/librustc_resolve/late/lifetimes.rs
@@ -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 {
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index c7d749815fe..39fcd075645 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -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()),
                     )),
                 )
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index fc4ca1e04b9..1acbcc03889 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -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));
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 590726ce8ed..6e4af6d769a 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -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)
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 3f81689cdc9..23c7954d088 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -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<'_>) {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index b91aab44f10..387ef03f067 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -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()
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 6ef01c3dec7..0fdeefd79e9 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -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() {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 2050c6c57ba..acfcfe9d015 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -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 {
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 8862226adbb..16ca539b3c1 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -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),
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index 3b55d9b9002..d80a38819ea 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -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!"));
     /// }
     /// ```
diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs
index 918875e792a..fec59aaa0c2 100644
--- a/src/libterm/terminfo/mod.rs
+++ b/src/libterm/terminfo/mod.rs
@@ -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))
     }
 
diff --git a/src/test/ui/proc-macro/auxiliary/resolved-located-at.rs b/src/test/ui/proc-macro/auxiliary/resolved-located-at.rs
new file mode 100644
index 00000000000..9416c133e56
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/resolved-located-at.rs
@@ -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"),
+    }
+}
diff --git a/src/test/ui/proc-macro/resolved-located-at.rs b/src/test/ui/proc-macro/resolved-located-at.rs
new file mode 100644
index 00000000000..9976284e222
--- /dev/null
+++ b/src/test/ui/proc-macro/resolved-located-at.rs
@@ -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
+}
diff --git a/src/test/ui/proc-macro/resolved-located-at.stderr b/src/test/ui/proc-macro/resolved-located-at.stderr
new file mode 100644
index 00000000000..0df7ced27a7
--- /dev/null
+++ b/src/test/ui/proc-macro/resolved-located-at.stderr
@@ -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`.