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