diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index db7420954a091..3d657396a9feb 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -428,7 +428,12 @@ impl Box { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box) -> *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`. @@ -451,6 +456,7 @@ impl Box { /// /// ``` /// #![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 Box { /// 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) -> NonNull { - 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) -> Unique { - 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 Box { 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` into a `Pin>` diff --git a/src/liballoc/collections/btree/map.rs b/src/liballoc/collections/btree/map.rs index 8d0cd191c2a90..099687bd6b082 100644 --- a/src/liballoc/collections/btree/map.rs +++ b/src/liballoc/collections/btree/map.rs @@ -923,7 +923,6 @@ impl BTreeMap { /// Basic usage: /// /// ``` - /// #![feature(btreemap_remove_entry)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); @@ -931,7 +930,7 @@ impl BTreeMap { /// 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(&mut self, key: &Q) -> Option<(K, V)> where K: Borrow, diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index af341e6c1caab..9dd7fc6d7ee78 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -143,7 +143,7 @@ impl LinkedList { 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 LinkedList { 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 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 Send for IterMut<'_, T> {} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl Sync for IterMut<'_, T> {} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] +unsafe impl Send for Cursor<'_, T> {} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] +unsafe impl Sync for Cursor<'_, T> {} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] +unsafe impl Send for CursorMut<'_, T> {} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] +unsafe impl Sync for CursorMut<'_, T> {} diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index f422c3f66e147..ecec1fb039b33 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 8144fe0128ee8..2f9505ec79ffa 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -323,11 +323,9 @@ impl Rc { // 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 Rc { /// /// ``` /// #![feature(rc_into_raw_non_null)] + /// #![allow(deprecated)] /// /// use std::rc::Rc; /// @@ -670,6 +669,7 @@ impl Rc { /// 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 { // safe because Rc guarantees its pointer is non-null diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index adce23c42c0e8..a81e0cf7e1d2a 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -324,7 +324,7 @@ impl Arc { 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 Arc { /// /// ``` /// #![feature(rc_into_raw_non_null)] + /// #![allow(deprecated)] /// /// use std::sync::Arc; /// @@ -667,6 +668,7 @@ impl Arc { /// 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 { // safe because Arc guarantees its pointer is non-null diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 7ba4004d8609c..0349678b07b22 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::>(), 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 6c5d19845e406..0227a66b8633a 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 eb7677e9345f2..5995f64dc7806 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 9ca8f743f6586..5a911fcdc7d62 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 { } 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 0023ff595fc54..b22da86c09187 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 8b53019106537..9de7dcc845f1d 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 190a2dcc556e9..de71363cbde5c 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 5c45f75843606..22b130cdf5ffe 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 02bf1aded3bc3..fda0172544333 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 { - 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 { diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs index 2510dbcea0bdc..4b5c6177b2532 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 a932f334dde68..6bdc65eb05643 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 { 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 828f7f6a767b4..8c8d20655f96f 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 { - 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 7987b77997d71..832f4278149bb 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 88af60dbeb657..b9302d58cd59e 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 0deb0af448e7b..d95481b959037 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 = c - .generic_params - .iter() - .filter_map(|param| match param.kind { + let lifetime_span: Option = + 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 c7d749815febb..39fcd07564516 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 fc4ca1e04b97b..1acbcc038891d 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 590726ce8ed37..6e4af6d769add 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 3f81689cdc90f..23c7954d08878 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 b91aab44f10a2..387ef03f06773 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 6ef01c3dec79f..0fdeefd79e9f2 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 2050c6c57bab0..acfcfe9d0159b 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 8862226adbbd3..16ca539b3c178 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -1043,15 +1043,10 @@ impl Write for LineWriter { } // 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 3b55d9b900235..d80a38819ead0 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 918875e792a66..fec59aaa0c279 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -173,14 +173,13 @@ impl Terminal for TerminfoTerminal { fn reset(&mut self) -> io::Result { // 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 0000000000000..9416c133e5661 --- /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::>() { + [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 0000000000000..9976284e222e6 --- /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 0000000000000..0df7ced27a777 --- /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`.