Auto merge of #99863 - Dylan-DPC:rollup-lq9w047, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #99628 (add more docs regarding ideographic numbers) - #99689 (Revert `write!` and `writeln!` to late drop temporaries) - #99807 (Fix PermissionDenied UI tests on WSL) - #99817 (rustdoc: remove Clean trait impls for more items) - #99851 (Fix small typo in Cargo.toml comment) - #99856 (fix: remove fake no_dead_strip for osx) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
9067d5277d
11 changed files with 215 additions and 95 deletions
|
@ -60,7 +60,7 @@ exclude = [
|
||||||
# verify that this is the case. This requires, however, that the crate is built
|
# verify that this is the case. This requires, however, that the crate is built
|
||||||
# without overflow checks and debug assertions. Forcefully disable debug
|
# without overflow checks and debug assertions. Forcefully disable debug
|
||||||
# assertions and overflow checks here which should ensure that even if these
|
# assertions and overflow checks here which should ensure that even if these
|
||||||
# assertions are enabled for libstd we won't enable then for compiler_builtins
|
# assertions are enabled for libstd we won't enable them for compiler_builtins
|
||||||
# which should ensure we still link everything correctly.
|
# which should ensure we still link everything correctly.
|
||||||
debug-assertions = false
|
debug-assertions = false
|
||||||
overflow-checks = false
|
overflow-checks = false
|
||||||
|
|
|
@ -566,9 +566,7 @@ impl<'a> Linker for GccLinker<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_gc_sections(&mut self) {
|
fn no_gc_sections(&mut self) {
|
||||||
if self.sess.target.is_like_osx {
|
if self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm {
|
||||||
self.linker_arg("-no_dead_strip");
|
|
||||||
} else if self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm {
|
|
||||||
self.linker_arg("--no-gc-sections");
|
self.linker_arg("--no-gc-sections");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -892,7 +892,16 @@ impl char {
|
||||||
///
|
///
|
||||||
/// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric
|
/// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric
|
||||||
/// characters, and `No` for other numeric characters) are specified in the [Unicode Character
|
/// characters, and `No` for other numeric characters) are specified in the [Unicode Character
|
||||||
/// Database][ucd] [`UnicodeData.txt`].
|
/// Database][ucd] [`UnicodeData.txt`]. Note that this means ideographic numbers like '三'
|
||||||
|
/// are considered alphabetic, not numeric. Please consider to use `is_ascii_digit` or `is_digit`.
|
||||||
|
///
|
||||||
|
/// This method doesn't cover everything that could be considered a number, e.g. ideographic numbers like '三'.
|
||||||
|
/// If you want everything including characters with overlapping purposes then you might want to use
|
||||||
|
/// a unicode or language-processing library that exposes the appropriate character properties instead
|
||||||
|
/// of looking at the unicode categories.
|
||||||
|
///
|
||||||
|
/// If you want to parse ASCII decimal digits (0-9) or ASCII base-N, use
|
||||||
|
/// `is_ascii_digit` or `is_digit` instead.
|
||||||
///
|
///
|
||||||
/// [Unicode Standard]: https://www.unicode.org/versions/latest/
|
/// [Unicode Standard]: https://www.unicode.org/versions/latest/
|
||||||
/// [ucd]: https://www.unicode.org/reports/tr44/
|
/// [ucd]: https://www.unicode.org/reports/tr44/
|
||||||
|
@ -911,6 +920,7 @@ impl char {
|
||||||
/// assert!(!'K'.is_numeric());
|
/// assert!(!'K'.is_numeric());
|
||||||
/// assert!(!'و'.is_numeric());
|
/// assert!(!'و'.is_numeric());
|
||||||
/// assert!(!'藏'.is_numeric());
|
/// assert!(!'藏'.is_numeric());
|
||||||
|
/// assert!(!'三'.is_numeric());
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
|
|
@ -496,10 +496,9 @@ macro_rules! r#try {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "write_macro")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "write_macro")]
|
||||||
macro_rules! write {
|
macro_rules! write {
|
||||||
($dst:expr, $($arg:tt)*) => {{
|
($dst:expr, $($arg:tt)*) => {
|
||||||
let result = $dst.write_fmt($crate::format_args!($($arg)*));
|
$dst.write_fmt($crate::format_args!($($arg)*))
|
||||||
result
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write formatted data into a buffer, with a newline appended.
|
/// Write formatted data into a buffer, with a newline appended.
|
||||||
|
@ -554,10 +553,9 @@ macro_rules! writeln {
|
||||||
($dst:expr $(,)?) => {
|
($dst:expr $(,)?) => {
|
||||||
$crate::write!($dst, "\n")
|
$crate::write!($dst, "\n")
|
||||||
};
|
};
|
||||||
($dst:expr, $($arg:tt)*) => {{
|
($dst:expr, $($arg:tt)*) => {
|
||||||
let result = $dst.write_fmt($crate::format_args_nl!($($arg)*));
|
$dst.write_fmt($crate::format_args_nl!($($arg)*))
|
||||||
result
|
};
|
||||||
}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates unreachable code.
|
/// Indicates unreachable code.
|
||||||
|
|
|
@ -398,23 +398,19 @@ fn clean_type_outlives_predicate<'tcx>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Term> for ty::Term<'tcx> {
|
fn clean_middle_term<'tcx>(term: ty::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Term {
|
match term {
|
||||||
match self {
|
ty::Term::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
|
||||||
ty::Term::Ty(ty) => Term::Type(clean_middle_ty(*ty, cx, None)),
|
ty::Term::Const(c) => Term::Constant(clean_middle_const(c, cx)),
|
||||||
ty::Term::Const(c) => Term::Constant(clean_middle_const(*c, cx)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, Term> for hir::Term<'tcx> {
|
fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> Term {
|
match term {
|
||||||
match self {
|
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
|
||||||
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
|
hir::Term::Const(c) => {
|
||||||
hir::Term::Const(c) => {
|
let def_id = cx.tcx.hir().local_def_id(c.hir_id);
|
||||||
let def_id = cx.tcx.hir().local_def_id(c.hir_id);
|
Term::Constant(clean_middle_const(ty::Const::from_anon_const(cx.tcx, def_id), cx))
|
||||||
Term::Constant(clean_middle_const(ty::Const::from_anon_const(cx.tcx, def_id), cx))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -426,7 +422,7 @@ fn clean_projection_predicate<'tcx>(
|
||||||
let ty::ProjectionPredicate { projection_ty, term } = pred;
|
let ty::ProjectionPredicate { projection_ty, term } = pred;
|
||||||
WherePredicate::EqPredicate {
|
WherePredicate::EqPredicate {
|
||||||
lhs: clean_projection(projection_ty, cx, None),
|
lhs: clean_projection(projection_ty, cx, None),
|
||||||
rhs: term.clean(cx),
|
rhs: clean_middle_term(term, cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,47 +470,44 @@ fn projection_to_path_segment<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef {
|
fn clean_generic_param_def<'tcx>(
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef {
|
def: &ty::GenericParamDef,
|
||||||
let (name, kind) = match self.kind {
|
cx: &mut DocContext<'tcx>,
|
||||||
ty::GenericParamDefKind::Lifetime => {
|
) -> GenericParamDef {
|
||||||
(self.name, GenericParamDefKind::Lifetime { outlives: vec![] })
|
let (name, kind) = match def.kind {
|
||||||
}
|
ty::GenericParamDefKind::Lifetime => {
|
||||||
ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
|
(def.name, GenericParamDefKind::Lifetime { outlives: vec![] })
|
||||||
let default = if has_default {
|
}
|
||||||
Some(clean_middle_ty(cx.tcx.type_of(self.def_id), cx, Some(self.def_id)))
|
ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
|
||||||
} else {
|
let default = if has_default {
|
||||||
None
|
Some(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id)))
|
||||||
};
|
} else {
|
||||||
(
|
None
|
||||||
self.name,
|
};
|
||||||
GenericParamDefKind::Type {
|
(
|
||||||
did: self.def_id,
|
def.name,
|
||||||
bounds: vec![], // These are filled in from the where-clauses.
|
GenericParamDefKind::Type {
|
||||||
default: default.map(Box::new),
|
did: def.def_id,
|
||||||
synthetic,
|
bounds: vec![], // These are filled in from the where-clauses.
|
||||||
},
|
default: default.map(Box::new),
|
||||||
)
|
synthetic,
|
||||||
}
|
|
||||||
ty::GenericParamDefKind::Const { has_default } => (
|
|
||||||
self.name,
|
|
||||||
GenericParamDefKind::Const {
|
|
||||||
did: self.def_id,
|
|
||||||
ty: Box::new(clean_middle_ty(
|
|
||||||
cx.tcx.type_of(self.def_id),
|
|
||||||
cx,
|
|
||||||
Some(self.def_id),
|
|
||||||
)),
|
|
||||||
default: match has_default {
|
|
||||||
true => Some(Box::new(cx.tcx.const_param_default(self.def_id).to_string())),
|
|
||||||
false => None,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
),
|
)
|
||||||
};
|
}
|
||||||
|
ty::GenericParamDefKind::Const { has_default } => (
|
||||||
|
def.name,
|
||||||
|
GenericParamDefKind::Const {
|
||||||
|
did: def.def_id,
|
||||||
|
ty: Box::new(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id))),
|
||||||
|
default: match has_default {
|
||||||
|
true => Some(Box::new(cx.tcx.const_param_default(def.def_id).to_string())),
|
||||||
|
false => None,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
GenericParamDef { name, kind }
|
GenericParamDef { name, kind }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clean_generic_param<'tcx>(
|
fn clean_generic_param<'tcx>(
|
||||||
|
@ -672,7 +665,7 @@ fn clean_ty_generics<'tcx>(
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|param| match param.kind {
|
.filter_map(|param| match param.kind {
|
||||||
ty::GenericParamDefKind::Lifetime if param.name == kw::UnderscoreLifetime => None,
|
ty::GenericParamDefKind::Lifetime if param.name == kw::UnderscoreLifetime => None,
|
||||||
ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
|
ty::GenericParamDefKind::Lifetime => Some(clean_generic_param_def(param, cx)),
|
||||||
ty::GenericParamDefKind::Type { synthetic, .. } => {
|
ty::GenericParamDefKind::Type { synthetic, .. } => {
|
||||||
if param.name == kw::SelfUpper {
|
if param.name == kw::SelfUpper {
|
||||||
assert_eq!(param.index, 0);
|
assert_eq!(param.index, 0);
|
||||||
|
@ -682,9 +675,9 @@ fn clean_ty_generics<'tcx>(
|
||||||
impl_trait.insert(param.index.into(), vec![]);
|
impl_trait.insert(param.index.into(), vec![]);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some(param.clean(cx))
|
Some(clean_generic_param_def(param, cx))
|
||||||
}
|
}
|
||||||
ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)),
|
ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)),
|
||||||
})
|
})
|
||||||
.collect::<Vec<GenericParamDef>>();
|
.collect::<Vec<GenericParamDef>>();
|
||||||
|
|
||||||
|
@ -1682,7 +1675,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||||
.projection_ty,
|
.projection_ty,
|
||||||
cx,
|
cx,
|
||||||
),
|
),
|
||||||
kind: TypeBindingKind::Equality { term: pb.skip_binder().term.clean(cx) },
|
kind: TypeBindingKind::Equality {
|
||||||
|
term: clean_middle_term(pb.skip_binder().term, cx),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1746,7 +1741,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||||
Some(TypeBinding {
|
Some(TypeBinding {
|
||||||
assoc: projection_to_path_segment(proj.projection_ty, cx),
|
assoc: projection_to_path_segment(proj.projection_ty, cx),
|
||||||
kind: TypeBindingKind::Equality {
|
kind: TypeBindingKind::Equality {
|
||||||
term: proj.term.clean(cx),
|
term: clean_middle_term(proj.term, cx),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
@ -2283,7 +2278,7 @@ impl<'tcx> Clean<'tcx, TypeBindingKind> for hir::TypeBindingKind<'tcx> {
|
||||||
fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBindingKind {
|
fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBindingKind {
|
||||||
match *self {
|
match *self {
|
||||||
hir::TypeBindingKind::Equality { ref term } => {
|
hir::TypeBindingKind::Equality { ref term } => {
|
||||||
TypeBindingKind::Equality { term: term.clean(cx) }
|
TypeBindingKind::Equality { term: clean_hir_term(term, cx) }
|
||||||
}
|
}
|
||||||
hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint {
|
hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint {
|
||||||
bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(),
|
bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(),
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
// build-fail
|
// build-fail
|
||||||
// dont-check-compiler-stderr
|
// dont-check-compiler-stderr
|
||||||
// compile-flags: -C linker=llllll -C linker-flavor=ld
|
// compile-flags: -C linker=llllll -C linker-flavor=ld
|
||||||
// error-pattern: linker `llllll` not found
|
// error-pattern: `llllll`
|
||||||
|
|
||||||
|
// Before, the error-pattern checked for "not found". On WSL with appendWindowsPath=true, running
|
||||||
|
// in invalid command returns a PermissionDenied instead.
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
}
|
}
|
||||||
|
|
37
src/test/ui/macros/format-args-temporaries-async.rs
Normal file
37
src/test/ui/macros/format-args-temporaries-async.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// check-pass
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
use std::fmt::{self, Display};
|
||||||
|
use std::future::Future;
|
||||||
|
use std::io;
|
||||||
|
use std::pin::Pin;
|
||||||
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
|
struct AsyncStdout;
|
||||||
|
|
||||||
|
impl AsyncStdout {
|
||||||
|
fn write_fmt<'a>(&'a mut self, _args: fmt::Arguments) -> WriteFmtFuture<'a, Self>
|
||||||
|
where
|
||||||
|
Self: Unpin,
|
||||||
|
{
|
||||||
|
WriteFmtFuture(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WriteFmtFuture<'a, T>(&'a mut T);
|
||||||
|
|
||||||
|
impl<'a, T> Future for WriteFmtFuture<'a, T> {
|
||||||
|
type Output = io::Result<()>;
|
||||||
|
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn async_main() {
|
||||||
|
let _write = write!(&mut AsyncStdout, "...").await;
|
||||||
|
let _writeln = writeln!(&mut AsyncStdout, "...").await;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = async_main;
|
||||||
|
}
|
50
src/test/ui/macros/format-args-temporaries-in-write.rs
Normal file
50
src/test/ui/macros/format-args-temporaries-in-write.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// check-fail
|
||||||
|
|
||||||
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
|
struct Mutex;
|
||||||
|
|
||||||
|
impl Mutex {
|
||||||
|
fn lock(&self) -> MutexGuard {
|
||||||
|
MutexGuard(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MutexGuard<'a>(&'a Mutex);
|
||||||
|
|
||||||
|
impl<'a> Drop for MutexGuard<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
// Empty but this is a necessary part of the repro. Otherwise borrow
|
||||||
|
// checker is fine with 'a dangling at the time that MutexGuard goes out
|
||||||
|
// of scope.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Out;
|
||||||
|
|
||||||
|
impl Out {
|
||||||
|
fn write_fmt(&self, _args: fmt::Arguments) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Display for MutexGuard<'a> {
|
||||||
|
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// FIXME(dtolnay): We actually want both of these to work. I think it's
|
||||||
|
// sadly unimplementable today though.
|
||||||
|
|
||||||
|
let _write = {
|
||||||
|
let mutex = Mutex;
|
||||||
|
write!(Out, "{}", mutex.lock()) /* no semicolon */
|
||||||
|
//~^ ERROR `mutex` does not live long enough
|
||||||
|
};
|
||||||
|
|
||||||
|
let _writeln = {
|
||||||
|
let mutex = Mutex;
|
||||||
|
writeln!(Out, "{}", mutex.lock()) /* no semicolon */
|
||||||
|
//~^ ERROR `mutex` does not live long enough
|
||||||
|
};
|
||||||
|
}
|
43
src/test/ui/macros/format-args-temporaries-in-write.stderr
Normal file
43
src/test/ui/macros/format-args-temporaries-in-write.stderr
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
error[E0597]: `mutex` does not live long enough
|
||||||
|
--> $DIR/format-args-temporaries-in-write.rs:41:27
|
||||||
|
|
|
||||||
|
LL | write!(Out, "{}", mutex.lock()) /* no semicolon */
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| borrowed value does not live long enough
|
||||||
|
| a temporary with access to the borrow is created here ...
|
||||||
|
LL |
|
||||||
|
LL | };
|
||||||
|
| -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard`
|
||||||
|
| |
|
||||||
|
| `mutex` dropped here while still borrowed
|
||||||
|
|
|
||||||
|
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
|
||||||
|
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | $dst.write_fmt($crate::format_args!($($arg)*));
|
||||||
|
| +
|
||||||
|
|
||||||
|
error[E0597]: `mutex` does not live long enough
|
||||||
|
--> $DIR/format-args-temporaries-in-write.rs:47:29
|
||||||
|
|
|
||||||
|
LL | writeln!(Out, "{}", mutex.lock()) /* no semicolon */
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
| |
|
||||||
|
| borrowed value does not live long enough
|
||||||
|
| a temporary with access to the borrow is created here ...
|
||||||
|
LL |
|
||||||
|
LL | };
|
||||||
|
| -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard`
|
||||||
|
| |
|
||||||
|
| `mutex` dropped here while still borrowed
|
||||||
|
|
|
||||||
|
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
|
||||||
|
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | $dst.write_fmt($crate::format_args_nl!($($arg)*));
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0597`.
|
|
@ -20,10 +20,6 @@ impl<'a> Drop for MutexGuard<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MutexGuard<'a> {
|
|
||||||
fn write_fmt(&self, _args: fmt::Arguments) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Display for MutexGuard<'a> {
|
impl<'a> Display for MutexGuard<'a> {
|
||||||
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -31,18 +27,6 @@ impl<'a> Display for MutexGuard<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _write = {
|
|
||||||
let out = Mutex;
|
|
||||||
let mutex = Mutex;
|
|
||||||
write!(out.lock(), "{}", mutex.lock()) /* no semicolon */
|
|
||||||
};
|
|
||||||
|
|
||||||
let _writeln = {
|
|
||||||
let out = Mutex;
|
|
||||||
let mutex = Mutex;
|
|
||||||
writeln!(out.lock(), "{}", mutex.lock()) /* no semicolon */
|
|
||||||
};
|
|
||||||
|
|
||||||
let _print = {
|
let _print = {
|
||||||
let mutex = Mutex;
|
let mutex = Mutex;
|
||||||
print!("{}", mutex.lock()) /* no semicolon */
|
print!("{}", mutex.lock()) /* no semicolon */
|
||||||
|
|
|
@ -6,9 +6,11 @@ use std::io::ErrorKind;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(Command::new("nonexistent")
|
let result = Command::new("nonexistent").spawn().unwrap_err().kind();
|
||||||
.spawn()
|
|
||||||
.unwrap_err()
|
assert!(matches!(
|
||||||
.kind(),
|
result,
|
||||||
ErrorKind::NotFound);
|
// Under WSL with appendWindowsPath=true, this fails with PermissionDenied
|
||||||
|
ErrorKind::NotFound | ErrorKind::PermissionDenied
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue