Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #106866

Merged
merged 24 commits into from
Jan 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a8b5d4b
libcore: make result type of iter::from_generator concrete
Xiretza Dec 10, 2022
17a0740
libcore: make result of iter::from_generator Clone
Xiretza Dec 10, 2022
753e576
Fix up stat test in libc-fs-with-isolation
mjguzik Jan 11, 2023
b49aa8d
Stop probing for statx unless necessary
mjguzik Jan 10, 2023
60cc778
evade clones
klensy Jan 12, 2023
4e1258c
IndexItem.name String -> Symbol
klensy Jan 13, 2023
cda6efe
generate_macro_def_id_path: don't eagerly stringify Symbols
klensy Jan 13, 2023
81b637b
fmt_type: don't alloc const String, use &str instead
klensy Jan 13, 2023
ffb2e84
Playground.crate_name String -> Symbol
klensy Jan 13, 2023
8998bd3
CrateData: don't allocate String when Serialize, &str is enough
klensy Jan 13, 2023
5314ed5
rustdoc: remove `docblock` class from notable trait popover
notriddle Jan 13, 2023
ea13023
Allocate one less vec in `parser/expr.rs`
WaffleLapkin Jan 14, 2023
6821adb
Deprioritize fulfillment errors that come from expansions.
m-ou-se Jan 13, 2023
4f64de8
Fix `unused_braces` on generic const expr macro call
clubby789 Jan 7, 2023
0b35f44
Remove various double spaces in source comments.
anden3 Jan 14, 2023
2fea03f
Fix some missed double spaces.
anden3 Jan 14, 2023
085d2f1
Rollup merge of #105526 - Xiretza:iter-from-generator-derive, r=scottmcm
matthiaskrgr Jan 14, 2023
d7bc758
Rollup merge of #106563 - clubby789:gce-macro-braces, r=TaKO8Ki
matthiaskrgr Jan 14, 2023
4313471
Rollup merge of #106661 - mjguzik:linux_statx, r=Mark-Simulacrum
matthiaskrgr Jan 14, 2023
f04f97c
Rollup merge of #106820 - m-ou-se:macro-type-error-thing, r=estebank
matthiaskrgr Jan 14, 2023
14fbc21
Rollup merge of #106828 - notriddle:notriddle/notable-trait-docblock,…
matthiaskrgr Jan 14, 2023
9db8e6d
Rollup merge of #106849 - WaffleLapkin:unvec, r=Nilstrieb
matthiaskrgr Jan 14, 2023
bc0c816
Rollup merge of #106855 - klensy:rd-s, r=notriddle
matthiaskrgr Jan 14, 2023
e0eb63a
Rollup merge of #106860 - anden3:doc-double-spaces, r=Dylan-DPC
matthiaskrgr Jan 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,7 @@ impl UnusedDelimLint for UnusedBraces {
|| matches!(expr.kind, ast::ExprKind::Lit(_)))
&& !cx.sess().source_map().is_multiline(value.span)
&& value.attrs.is_empty()
&& !expr.span.from_expansion()
&& !value.span.from_expansion()
&& !inner.span.from_expansion()
{
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1475,9 +1475,8 @@ impl<'a> Parser<'a> {
} else if self.eat(&token::Comma) {
// Vector with two or more elements.
let sep = SeqSep::trailing_allowed(token::Comma);
let (remaining_exprs, _) = self.parse_seq_to_end(close, sep, |p| p.parse_expr())?;
let mut exprs = vec![first_expr];
exprs.extend(remaining_exprs);
let (mut exprs, _) = self.parse_seq_to_end(close, sep, |p| p.parse_expr())?;
exprs.insert(0, first_expr);
ExprKind::Array(exprs)
} else {
// Vector with one element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}

for (error, suppressed) in iter::zip(errors, is_suppressed) {
if !suppressed {
self.report_fulfillment_error(error, body_id);
for from_expansion in [false, true] {
for (error, suppressed) in iter::zip(errors, &is_suppressed) {
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
self.report_fulfillment_error(error, body_id);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use core::marker::Destruct;
mod tests;

extern "Rust" {
// These are the magic symbols to call the global allocator. rustc generates
// These are the magic symbols to call the global allocator. rustc generates
// them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute
// (the code expanding that attribute macro generates those functions), or to call
// the default implementations in std (`__rdl_alloc` etc. in `library/std/src/alloc.rs`)
Expand Down Expand Up @@ -353,7 +353,7 @@ pub(crate) const unsafe fn box_free<T: ?Sized, A: ~const Allocator + ~const Dest

#[cfg(not(no_global_oom_handling))]
extern "Rust" {
// This is the magic symbol to call the global alloc error handler. rustc generates
// This is the magic symbol to call the global alloc error handler. rustc generates
// it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the
// default implementations below (`__rdl_oom`) otherwise.
fn __rust_alloc_error_handler(size: usize, align: usize) -> !;
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2179,7 +2179,7 @@ pub struct Weak<T: ?Sized> {
// This is a `NonNull` to allow optimizing the size of this type in enums,
// but it is not necessarily a valid pointer.
// `Weak::new` sets this to `usize::MAX` so that it doesn’t need
// to allocate space on the heap. That's not a value a real pointer
// to allocate space on the heap. That's not a value a real pointer
// will ever have because RcBox has alignment at least 2.
// This is only possible when `T: Sized`; unsized `T` never dangle.
ptr: NonNull<RcBox<T>>,
Expand Down
8 changes: 4 additions & 4 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ pub struct Weak<T: ?Sized> {
// This is a `NonNull` to allow optimizing the size of this type in enums,
// but it is not necessarily a valid pointer.
// `Weak::new` sets this to `usize::MAX` so that it doesn’t need
// to allocate space on the heap. That's not a value a real pointer
// to allocate space on the heap. That's not a value a real pointer
// will ever have because RcBox has alignment at least 2.
// This is only possible when `T: Sized`; unsized `T` never dangle.
ptr: NonNull<ArcInner<T>>,
Expand Down Expand Up @@ -1656,7 +1656,7 @@ impl<T: ?Sized> Arc<T> {
//
// The acquire label here ensures a happens-before relationship with any
// writes to `strong` (in particular in `Weak::upgrade`) prior to decrements
// of the `weak` count (via `Weak::drop`, which uses release). If the upgraded
// of the `weak` count (via `Weak::drop`, which uses release). If the upgraded
// weak ref was never dropped, the CAS here will fail so we do not care to synchronize.
if self.inner().weak.compare_exchange(1, usize::MAX, Acquire, Relaxed).is_ok() {
// This needs to be an `Acquire` to synchronize with the decrement of the `strong`
Expand Down Expand Up @@ -1712,7 +1712,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
}

// This fence is needed to prevent reordering of use of the data and
// deletion of the data. Because it is marked `Release`, the decreasing
// deletion of the data. Because it is marked `Release`, the decreasing
// of the reference count synchronizes with this `Acquire` fence. This
// means that use of the data happens before decreasing the reference
// count, which happens before this fence, which happens before the
Expand Down Expand Up @@ -2172,7 +2172,7 @@ impl<T: ?Sized> Clone for Weak<T> {
} else {
return Weak { ptr: self.ptr };
};
// See comments in Arc::clone() for why this is relaxed. This can use a
// See comments in Arc::clone() for why this is relaxed. This can use a
// fetch_add (ignoring the lock) because the weak count is only locked
// where are *no other* weak pointers in existence. (So we can't be
// running this code in that case).
Expand Down
6 changes: 3 additions & 3 deletions library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub struct IntoIter<
// to avoid dropping the allocator twice we need to wrap it into ManuallyDrop
pub(super) alloc: ManuallyDrop<A>,
pub(super) ptr: *const T,
pub(super) end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
pub(super) end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
// ptr == end is a quick test for the Iterator being empty, that works
// for both ZST and non-ZST.
}
Expand Down Expand Up @@ -146,9 +146,9 @@ impl<T, A: Allocator> IntoIter<T, A> {
let mut this = ManuallyDrop::new(self);

// SAFETY: This allocation originally came from a `Vec`, so it passes
// all those checks. We have `this.buf` ≤ `this.ptr` ≤ `this.end`,
// all those checks. We have `this.buf` ≤ `this.ptr` ≤ `this.end`,
// so the `sub_ptr`s below cannot wrap, and will produce a well-formed
// range. `end` ≤ `buf + cap`, so the range will be in-bounds.
// range. `end` ≤ `buf + cap`, so the range will be in-bounds.
// Taking `alloc` is ok because nothing else is going to look at it,
// since our `Drop` impl isn't going to run so there's no more code.
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/vec/is_zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ unsafe impl<T: IsZero, const N: usize> IsZero for [T; N] {
#[inline]
fn is_zero(&self) -> bool {
// Because this is generated as a runtime check, it's not obvious that
// it's worth doing if the array is really long. The threshold here
// it's worth doing if the array is really long. The threshold here
// is largely arbitrary, but was picked because as of 2022-07-01 LLVM
// fails to const-fold the check in `vec![[1; 32]; n]`
// See https://github.com/rust-lang/rust/pull/97581#issuecomment-1166628022
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2429,7 +2429,7 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
self.reserve(range.len());

// SAFETY:
// - `slice::range` guarantees that the given range is valid for indexing self
// - `slice::range` guarantees that the given range is valid for indexing self
unsafe {
self.spec_extend_from_within(range);
}
Expand Down Expand Up @@ -2686,7 +2686,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {

// HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is
// required for this method definition, is not available. Instead use the
// `slice::to_vec` function which is only available with cfg(test)
// `slice::to_vec` function which is only available with cfg(test)
// NB see the slice::hack module in slice.rs for more information
#[cfg(test)]
fn clone(&self) -> Self {
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/tests/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1849,7 +1849,7 @@ fn test_stable_pointers() {
}

// Test that, if we reserved enough space, adding and removing elements does not
// invalidate references into the vector (such as `v0`). This test also
// invalidate references into the vector (such as `v0`). This test also
// runs in Miri, which would detect such problems.
// Note that this test does *not* constitute a stable guarantee that all these functions do not
// reallocate! Only what is explicitly documented at
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/array/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ impl<T, const N: usize> IntoIter<T, N> {
/// use std::array::IntoIter;
/// use std::mem::MaybeUninit;
///
/// # // Hi! Thanks for reading the code. This is restricted to `Copy` because
/// # // otherwise it could leak. A fully-general version this would need a drop
/// # // Hi! Thanks for reading the code. This is restricted to `Copy` because
/// # // otherwise it could leak. A fully-general version this would need a drop
/// # // guard to handle panics from the iterator, but this works for an example.
/// fn next_chunk<T: Copy, const N: usize>(
/// it: &mut impl Iterator<Item = T>,
Expand Down Expand Up @@ -211,7 +211,7 @@ impl<T, const N: usize> IntoIter<T, N> {
let initialized = 0..0;

// SAFETY: We're telling it that none of the elements are initialized,
// which is trivially true. And ∀N: usize, 0 <= N.
// which is trivially true. And ∀N: usize, 0 <= N.
unsafe { Self::new_unchecked(buffer, initialized) }
}

Expand Down
2 changes: 1 addition & 1 deletion library/core/src/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ impl<A: Step> Iterator for ops::Range<A> {
where
Self: TrustedRandomAccessNoCoerce,
{
// SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
// SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
// that is in bounds.
// Additionally Self: TrustedRandomAccess is only implemented for Copy types
// which means even repeated reads of the same index would be safe.
Expand Down
23 changes: 19 additions & 4 deletions library/core/src/iter/sources/from_generator.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::fmt;
use crate::ops::{Generator, GeneratorState};
use crate::pin::Pin;

Expand All @@ -23,14 +24,21 @@ use crate::pin::Pin;
/// ```
#[inline]
#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
pub fn from_generator<G: Generator<Return = ()> + Unpin>(
generator: G,
) -> impl Iterator<Item = G::Yield> {
pub fn from_generator<G: Generator<Return = ()> + Unpin>(generator: G) -> FromGenerator<G> {
FromGenerator(generator)
}

struct FromGenerator<G>(G);
/// An iterator over the values yielded by an underlying generator.
///
/// This `struct` is created by the [`iter::from_generator()`] function. See its documentation for
/// more.
///
/// [`iter::from_generator()`]: from_generator
#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
#[derive(Clone)]
pub struct FromGenerator<G>(G);

#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
impl<G: Generator<Return = ()> + Unpin> Iterator for FromGenerator<G> {
type Item = G::Yield;

Expand All @@ -41,3 +49,10 @@ impl<G: Generator<Return = ()> + Unpin> Iterator for FromGenerator<G> {
}
}
}

#[unstable(feature = "iter_from_generator", issue = "43122", reason = "generators are unstable")]
impl<G> fmt::Debug for FromGenerator<G> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("FromGenerator").finish()
}
}
2 changes: 1 addition & 1 deletion library/core/src/num/dec2flt/fpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ mod fpu_precision {
/// Developer's Manual (Volume 1).
///
/// The only field which is relevant for the following code is PC, Precision Control. This
/// field determines the precision of the operations performed by the FPU. It can be set to:
/// field determines the precision of the operations performed by the FPU. It can be set to:
/// - 0b00, single precision i.e., 32-bits
/// - 0b10, double precision i.e., 64-bits
/// - 0b11, double extended precision i.e., 80-bits (default state)
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1538,7 +1538,7 @@ macro_rules! int_impl {
///
/// ```
/// #![feature(bigint_helper_methods)]
/// // Only the most significant word is signed.
/// // Only the most significant word is signed.
/// //
#[doc = concat!("// 10 MAX (a = 10 × 2^", stringify!($BITS), " + 2^", stringify!($BITS), " - 1)")]
#[doc = concat!("// + -5 9 (b = -5 × 2^", stringify!($BITS), " + 9)")]
Expand Down Expand Up @@ -1646,7 +1646,7 @@ macro_rules! int_impl {
///
/// ```
/// #![feature(bigint_helper_methods)]
/// // Only the most significant word is signed.
/// // Only the most significant word is signed.
/// //
#[doc = concat!("// 6 8 (a = 6 × 2^", stringify!($BITS), " + 8)")]
#[doc = concat!("// - -5 9 (b = -5 × 2^", stringify!($BITS), " + 9)")]
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ impl<P: DerefMut> Pin<P> {
impl<'a, T: ?Sized> Pin<&'a T> {
/// Constructs a new pin by mapping the interior value.
///
/// For example, if you wanted to get a `Pin` of a field of something,
/// For example, if you wanted to get a `Pin` of a field of something,
/// you could use this to get access to that field in one line of code.
/// However, there are several gotchas with these "pinning projections";
/// see the [`pin` module] documentation for further details on that topic.
Expand Down Expand Up @@ -856,7 +856,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {

/// Construct a new pin by mapping the interior value.
///
/// For example, if you wanted to get a `Pin` of a field of something,
/// For example, if you wanted to get a `Pin` of a field of something,
/// you could use this to get access to that field in one line of code.
/// However, there are several gotchas with these "pinning projections";
/// see the [`pin` module] documentation for further details on that topic.
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usiz
// offset is not a multiple of `stride`, the input pointer was misaligned and no pointer
// offset will be able to produce a `p` aligned to the specified `a`.
//
// The naive `-p (mod a)` equation inhibits LLVM's ability to select instructions
// The naive `-p (mod a)` equation inhibits LLVM's ability to select instructions
// like `lea`. We compute `(round_up_to_next_alignment(p, a) - p)` instead. This
// redistributes operations around the load-bearing, but pessimizing `and` instruction
// sufficiently for LLVM to be able to utilize the various optimizations it knows about.
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ fn size_from_ptr<T>(_: *const T) -> usize {
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Iter<'a, T: 'a> {
ptr: NonNull<T>,
end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
// ptr == end is a quick test for the Iterator being empty, that works
// for both ZST and non-ZST.
_marker: PhantomData<&'a T>,
Expand Down Expand Up @@ -186,7 +186,7 @@ impl<T> AsRef<[T]> for Iter<'_, T> {
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct IterMut<'a, T: 'a> {
ptr: NonNull<T>,
end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
// ptr == end is a quick test for the Iterator being empty, that works
// for both ZST and non-ZST.
_marker: PhantomData<&'a mut T>,
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/iter/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ macro_rules! len {
$self.end.addr().wrapping_sub(start.as_ptr().addr())
} else {
// We know that `start <= end`, so can do better than `offset_from`,
// which needs to deal in signed. By setting appropriate flags here
// which needs to deal in signed. By setting appropriate flags here
// we can tell LLVM this, which helps it remove bounds checks.
// SAFETY: By the type invariant, `start <= end`
let diff = unsafe { unchecked_sub($self.end.addr(), start.as_ptr().addr()) };
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ impl<T> [T] {

// Because this function is first compiled in isolation,
// this check tells LLVM that the indexing below is
// in-bounds. Then after inlining -- once the actual
// in-bounds. Then after inlining -- once the actual
// lengths of the slices are known -- it's removed.
let (a, b) = (&mut a[..n], &mut b[..n]);

Expand Down Expand Up @@ -1248,7 +1248,7 @@ impl<T> [T] {
ArrayChunksMut::new(self)
}

/// Returns an iterator over overlapping windows of `N` elements of a slice,
/// Returns an iterator over overlapping windows of `N` elements of a slice,
/// starting at the beginning of the slice.
///
/// This is the const generic equivalent of [`windows`].
Expand Down Expand Up @@ -2476,7 +2476,7 @@ impl<T> [T] {
let mid = left + size / 2;

// SAFETY: the while condition means `size` is strictly positive, so
// `size/2 < size`. Thus `left + size/2 < left + size`, which
// `size/2 < size`. Thus `left + size/2 < left + size`, which
// coupled with the `left + size <= self.len()` invariant means
// we have `left + size/2 < self.len()`, and this is in-bounds.
let cmp = f(unsafe { self.get_unchecked(mid) });
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/slice/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ struct CopyOnDrop<T> {

impl<T> Drop for CopyOnDrop<T> {
fn drop(&mut self) {
// SAFETY: This is a helper class.
// Please refer to its usage for correctness.
// Namely, one must be sure that `src` and `dst` does not overlap as required by `ptr::copy_nonoverlapping`.
// SAFETY: This is a helper class.
// Please refer to its usage for correctness.
// Namely, one must be sure that `src` and `dst` does not overlap as required by `ptr::copy_nonoverlapping`.
unsafe {
ptr::copy_nonoverlapping(self.src, self.dest, 1);
}
Expand Down
2 changes: 1 addition & 1 deletion library/core/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1488,7 +1488,7 @@ mod slice_index {
// optional:
//
// one or more similar inputs for which data[input] succeeds,
// and the corresponding output as an array. This helps validate
// and the corresponding output as an array. This helps validate
// "critical points" where an input range straddles the boundary
// between valid and invalid.
// (such as the input `len..len`, which is just barely valid)
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1512,7 +1512,7 @@ impl FileType {
}

/// Tests whether this file type represents a regular file.
/// The result is mutually exclusive to the results of
/// The result is mutually exclusive to the results of
/// [`is_dir`] and [`is_symlink`]; only zero or one of these
/// tests may pass.
///
Expand Down
Loading