Skip to content

Commit 9067d52

Browse files
committed
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
2 parents 36f4f4a + 55f041e commit 9067d52

File tree

11 files changed

+215
-95
lines changed

11 files changed

+215
-95
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ exclude = [
6060
# verify that this is the case. This requires, however, that the crate is built
6161
# without overflow checks and debug assertions. Forcefully disable debug
6262
# assertions and overflow checks here which should ensure that even if these
63-
# assertions are enabled for libstd we won't enable then for compiler_builtins
63+
# assertions are enabled for libstd we won't enable them for compiler_builtins
6464
# which should ensure we still link everything correctly.
6565
debug-assertions = false
6666
overflow-checks = false

compiler/rustc_codegen_ssa/src/back/linker.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,7 @@ impl<'a> Linker for GccLinker<'a> {
566566
}
567567

568568
fn no_gc_sections(&mut self) {
569-
if self.sess.target.is_like_osx {
570-
self.linker_arg("-no_dead_strip");
571-
} else if self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm {
569+
if self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm {
572570
self.linker_arg("--no-gc-sections");
573571
}
574572
}

library/core/src/char/methods.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -892,7 +892,16 @@ impl char {
892892
///
893893
/// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric
894894
/// characters, and `No` for other numeric characters) are specified in the [Unicode Character
895-
/// Database][ucd] [`UnicodeData.txt`].
895+
/// Database][ucd] [`UnicodeData.txt`]. Note that this means ideographic numbers like '三'
896+
/// are considered alphabetic, not numeric. Please consider to use `is_ascii_digit` or `is_digit`.
897+
///
898+
/// This method doesn't cover everything that could be considered a number, e.g. ideographic numbers like '三'.
899+
/// If you want everything including characters with overlapping purposes then you might want to use
900+
/// a unicode or language-processing library that exposes the appropriate character properties instead
901+
/// of looking at the unicode categories.
902+
///
903+
/// If you want to parse ASCII decimal digits (0-9) or ASCII base-N, use
904+
/// `is_ascii_digit` or `is_digit` instead.
896905
///
897906
/// [Unicode Standard]: https://www.unicode.org/versions/latest/
898907
/// [ucd]: https://www.unicode.org/reports/tr44/
@@ -911,6 +920,7 @@ impl char {
911920
/// assert!(!'K'.is_numeric());
912921
/// assert!(!'و'.is_numeric());
913922
/// assert!(!'藏'.is_numeric());
923+
/// assert!(!'三'.is_numeric());
914924
/// ```
915925
#[must_use]
916926
#[stable(feature = "rust1", since = "1.0.0")]

library/core/src/macros/mod.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -496,10 +496,9 @@ macro_rules! r#try {
496496
#[stable(feature = "rust1", since = "1.0.0")]
497497
#[cfg_attr(not(test), rustc_diagnostic_item = "write_macro")]
498498
macro_rules! write {
499-
($dst:expr, $($arg:tt)*) => {{
500-
let result = $dst.write_fmt($crate::format_args!($($arg)*));
501-
result
502-
}};
499+
($dst:expr, $($arg:tt)*) => {
500+
$dst.write_fmt($crate::format_args!($($arg)*))
501+
};
503502
}
504503

505504
/// Write formatted data into a buffer, with a newline appended.
@@ -554,10 +553,9 @@ macro_rules! writeln {
554553
($dst:expr $(,)?) => {
555554
$crate::write!($dst, "\n")
556555
};
557-
($dst:expr, $($arg:tt)*) => {{
558-
let result = $dst.write_fmt($crate::format_args_nl!($($arg)*));
559-
result
560-
}};
556+
($dst:expr, $($arg:tt)*) => {
557+
$dst.write_fmt($crate::format_args_nl!($($arg)*))
558+
};
561559
}
562560

563561
/// Indicates unreachable code.

src/librustdoc/clean/mod.rs

+55-60
Original file line numberDiff line numberDiff line change
@@ -398,23 +398,19 @@ fn clean_type_outlives_predicate<'tcx>(
398398
})
399399
}
400400

401-
impl<'tcx> Clean<'tcx, Term> for ty::Term<'tcx> {
402-
fn clean(&self, cx: &mut DocContext<'tcx>) -> Term {
403-
match self {
404-
ty::Term::Ty(ty) => Term::Type(clean_middle_ty(*ty, cx, None)),
405-
ty::Term::Const(c) => Term::Constant(clean_middle_const(*c, cx)),
406-
}
401+
fn clean_middle_term<'tcx>(term: ty::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
402+
match term {
403+
ty::Term::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
404+
ty::Term::Const(c) => Term::Constant(clean_middle_const(c, cx)),
407405
}
408406
}
409407

410-
impl<'tcx> Clean<'tcx, Term> for hir::Term<'tcx> {
411-
fn clean(&self, cx: &mut DocContext<'tcx>) -> Term {
412-
match self {
413-
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
414-
hir::Term::Const(c) => {
415-
let def_id = cx.tcx.hir().local_def_id(c.hir_id);
416-
Term::Constant(clean_middle_const(ty::Const::from_anon_const(cx.tcx, def_id), cx))
417-
}
408+
fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
409+
match term {
410+
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
411+
hir::Term::Const(c) => {
412+
let def_id = cx.tcx.hir().local_def_id(c.hir_id);
413+
Term::Constant(clean_middle_const(ty::Const::from_anon_const(cx.tcx, def_id), cx))
418414
}
419415
}
420416
}
@@ -426,7 +422,7 @@ fn clean_projection_predicate<'tcx>(
426422
let ty::ProjectionPredicate { projection_ty, term } = pred;
427423
WherePredicate::EqPredicate {
428424
lhs: clean_projection(projection_ty, cx, None),
429-
rhs: term.clean(cx),
425+
rhs: clean_middle_term(term, cx),
430426
}
431427
}
432428

@@ -474,47 +470,44 @@ fn projection_to_path_segment<'tcx>(
474470
}
475471
}
476472

477-
impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef {
478-
fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef {
479-
let (name, kind) = match self.kind {
480-
ty::GenericParamDefKind::Lifetime => {
481-
(self.name, GenericParamDefKind::Lifetime { outlives: vec![] })
482-
}
483-
ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
484-
let default = if has_default {
485-
Some(clean_middle_ty(cx.tcx.type_of(self.def_id), cx, Some(self.def_id)))
486-
} else {
487-
None
488-
};
489-
(
490-
self.name,
491-
GenericParamDefKind::Type {
492-
did: self.def_id,
493-
bounds: vec![], // These are filled in from the where-clauses.
494-
default: default.map(Box::new),
495-
synthetic,
496-
},
497-
)
498-
}
499-
ty::GenericParamDefKind::Const { has_default } => (
500-
self.name,
501-
GenericParamDefKind::Const {
502-
did: self.def_id,
503-
ty: Box::new(clean_middle_ty(
504-
cx.tcx.type_of(self.def_id),
505-
cx,
506-
Some(self.def_id),
507-
)),
508-
default: match has_default {
509-
true => Some(Box::new(cx.tcx.const_param_default(self.def_id).to_string())),
510-
false => None,
511-
},
473+
fn clean_generic_param_def<'tcx>(
474+
def: &ty::GenericParamDef,
475+
cx: &mut DocContext<'tcx>,
476+
) -> GenericParamDef {
477+
let (name, kind) = match def.kind {
478+
ty::GenericParamDefKind::Lifetime => {
479+
(def.name, GenericParamDefKind::Lifetime { outlives: vec![] })
480+
}
481+
ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
482+
let default = if has_default {
483+
Some(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id)))
484+
} else {
485+
None
486+
};
487+
(
488+
def.name,
489+
GenericParamDefKind::Type {
490+
did: def.def_id,
491+
bounds: vec![], // These are filled in from the where-clauses.
492+
default: default.map(Box::new),
493+
synthetic,
512494
},
513-
),
514-
};
495+
)
496+
}
497+
ty::GenericParamDefKind::Const { has_default } => (
498+
def.name,
499+
GenericParamDefKind::Const {
500+
did: def.def_id,
501+
ty: Box::new(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id))),
502+
default: match has_default {
503+
true => Some(Box::new(cx.tcx.const_param_default(def.def_id).to_string())),
504+
false => None,
505+
},
506+
},
507+
),
508+
};
515509

516-
GenericParamDef { name, kind }
517-
}
510+
GenericParamDef { name, kind }
518511
}
519512

520513
fn clean_generic_param<'tcx>(
@@ -672,7 +665,7 @@ fn clean_ty_generics<'tcx>(
672665
.iter()
673666
.filter_map(|param| match param.kind {
674667
ty::GenericParamDefKind::Lifetime if param.name == kw::UnderscoreLifetime => None,
675-
ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
668+
ty::GenericParamDefKind::Lifetime => Some(clean_generic_param_def(param, cx)),
676669
ty::GenericParamDefKind::Type { synthetic, .. } => {
677670
if param.name == kw::SelfUpper {
678671
assert_eq!(param.index, 0);
@@ -682,9 +675,9 @@ fn clean_ty_generics<'tcx>(
682675
impl_trait.insert(param.index.into(), vec![]);
683676
return None;
684677
}
685-
Some(param.clean(cx))
678+
Some(clean_generic_param_def(param, cx))
686679
}
687-
ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)),
680+
ty::GenericParamDefKind::Const { .. } => Some(clean_generic_param_def(param, cx)),
688681
})
689682
.collect::<Vec<GenericParamDef>>();
690683

@@ -1682,7 +1675,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
16821675
.projection_ty,
16831676
cx,
16841677
),
1685-
kind: TypeBindingKind::Equality { term: pb.skip_binder().term.clean(cx) },
1678+
kind: TypeBindingKind::Equality {
1679+
term: clean_middle_term(pb.skip_binder().term, cx),
1680+
},
16861681
});
16871682
}
16881683

@@ -1746,7 +1741,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
17461741
Some(TypeBinding {
17471742
assoc: projection_to_path_segment(proj.projection_ty, cx),
17481743
kind: TypeBindingKind::Equality {
1749-
term: proj.term.clean(cx),
1744+
term: clean_middle_term(proj.term, cx),
17501745
},
17511746
})
17521747
} else {
@@ -2283,7 +2278,7 @@ impl<'tcx> Clean<'tcx, TypeBindingKind> for hir::TypeBindingKind<'tcx> {
22832278
fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBindingKind {
22842279
match *self {
22852280
hir::TypeBindingKind::Equality { ref term } => {
2286-
TypeBindingKind::Equality { term: term.clean(cx) }
2281+
TypeBindingKind::Equality { term: clean_hir_term(term, cx) }
22872282
}
22882283
hir::TypeBindingKind::Constraint { bounds } => TypeBindingKind::Constraint {
22892284
bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(),
+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// build-fail
22
// dont-check-compiler-stderr
33
// compile-flags: -C linker=llllll -C linker-flavor=ld
4-
// error-pattern: linker `llllll` not found
4+
// error-pattern: `llllll`
5+
6+
// Before, the error-pattern checked for "not found". On WSL with appendWindowsPath=true, running
7+
// in invalid command returns a PermissionDenied instead.
58

69
fn main() {
710
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// check-pass
2+
// edition:2021
3+
4+
use std::fmt::{self, Display};
5+
use std::future::Future;
6+
use std::io;
7+
use std::pin::Pin;
8+
use std::task::{Context, Poll};
9+
10+
struct AsyncStdout;
11+
12+
impl AsyncStdout {
13+
fn write_fmt<'a>(&'a mut self, _args: fmt::Arguments) -> WriteFmtFuture<'a, Self>
14+
where
15+
Self: Unpin,
16+
{
17+
WriteFmtFuture(self)
18+
}
19+
}
20+
21+
struct WriteFmtFuture<'a, T>(&'a mut T);
22+
23+
impl<'a, T> Future for WriteFmtFuture<'a, T> {
24+
type Output = io::Result<()>;
25+
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
26+
unimplemented!()
27+
}
28+
}
29+
30+
async fn async_main() {
31+
let _write = write!(&mut AsyncStdout, "...").await;
32+
let _writeln = writeln!(&mut AsyncStdout, "...").await;
33+
}
34+
35+
fn main() {
36+
let _ = async_main;
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// check-fail
2+
3+
use std::fmt::{self, Display};
4+
5+
struct Mutex;
6+
7+
impl Mutex {
8+
fn lock(&self) -> MutexGuard {
9+
MutexGuard(self)
10+
}
11+
}
12+
13+
struct MutexGuard<'a>(&'a Mutex);
14+
15+
impl<'a> Drop for MutexGuard<'a> {
16+
fn drop(&mut self) {
17+
// Empty but this is a necessary part of the repro. Otherwise borrow
18+
// checker is fine with 'a dangling at the time that MutexGuard goes out
19+
// of scope.
20+
}
21+
}
22+
23+
struct Out;
24+
25+
impl Out {
26+
fn write_fmt(&self, _args: fmt::Arguments) {}
27+
}
28+
29+
impl<'a> Display for MutexGuard<'a> {
30+
fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
31+
Ok(())
32+
}
33+
}
34+
35+
fn main() {
36+
// FIXME(dtolnay): We actually want both of these to work. I think it's
37+
// sadly unimplementable today though.
38+
39+
let _write = {
40+
let mutex = Mutex;
41+
write!(Out, "{}", mutex.lock()) /* no semicolon */
42+
//~^ ERROR `mutex` does not live long enough
43+
};
44+
45+
let _writeln = {
46+
let mutex = Mutex;
47+
writeln!(Out, "{}", mutex.lock()) /* no semicolon */
48+
//~^ ERROR `mutex` does not live long enough
49+
};
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
error[E0597]: `mutex` does not live long enough
2+
--> $DIR/format-args-temporaries-in-write.rs:41:27
3+
|
4+
LL | write!(Out, "{}", mutex.lock()) /* no semicolon */
5+
| ^^^^^^^^^^^^
6+
| |
7+
| borrowed value does not live long enough
8+
| a temporary with access to the borrow is created here ...
9+
LL |
10+
LL | };
11+
| -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard`
12+
| |
13+
| `mutex` dropped here while still borrowed
14+
|
15+
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
16+
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
17+
|
18+
LL | $dst.write_fmt($crate::format_args!($($arg)*));
19+
| +
20+
21+
error[E0597]: `mutex` does not live long enough
22+
--> $DIR/format-args-temporaries-in-write.rs:47:29
23+
|
24+
LL | writeln!(Out, "{}", mutex.lock()) /* no semicolon */
25+
| ^^^^^^^^^^^^
26+
| |
27+
| borrowed value does not live long enough
28+
| a temporary with access to the borrow is created here ...
29+
LL |
30+
LL | };
31+
| -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `MutexGuard`
32+
| |
33+
| `mutex` dropped here while still borrowed
34+
|
35+
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
36+
--> $SRC_DIR/core/src/macros/mod.rs:LL:COL
37+
|
38+
LL | $dst.write_fmt($crate::format_args_nl!($($arg)*));
39+
| +
40+
41+
error: aborting due to 2 previous errors
42+
43+
For more information about this error, try `rustc --explain E0597`.

0 commit comments

Comments
 (0)