Skip to content

Rollup of 6 pull requests #99863

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

Merged
merged 18 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ exclude = [
# verify that this is the case. This requires, however, that the crate is built
# without overflow checks and debug assertions. Forcefully disable debug
# 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.
debug-assertions = false
overflow-checks = false
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,7 @@ impl<'a> Linker for GccLinker<'a> {
}

fn no_gc_sections(&mut self) {
if self.sess.target.is_like_osx {
self.linker_arg("-no_dead_strip");
} else if self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm {
if self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm {
self.linker_arg("--no-gc-sections");
}
}
Expand Down
12 changes: 11 additions & 1 deletion library/core/src/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,16 @@ impl char {
///
/// 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
/// 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/
/// [ucd]: https://www.unicode.org/reports/tr44/
Expand All @@ -911,6 +920,7 @@ impl char {
/// assert!(!'K'.is_numeric());
/// assert!(!'و'.is_numeric());
/// assert!(!'藏'.is_numeric());
/// assert!(!'三'.is_numeric());
/// ```
#[must_use]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
14 changes: 6 additions & 8 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,10 +496,9 @@ macro_rules! r#try {
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "write_macro")]
macro_rules! write {
($dst:expr, $($arg:tt)*) => {{
let result = $dst.write_fmt($crate::format_args!($($arg)*));
result
}};
($dst:expr, $($arg:tt)*) => {
$dst.write_fmt($crate::format_args!($($arg)*))
};
}

/// Write formatted data into a buffer, with a newline appended.
Expand Down Expand Up @@ -554,10 +553,9 @@ macro_rules! writeln {
($dst:expr $(,)?) => {
$crate::write!($dst, "\n")
};
($dst:expr, $($arg:tt)*) => {{
let result = $dst.write_fmt($crate::format_args_nl!($($arg)*));
result
}};
($dst:expr, $($arg:tt)*) => {
$dst.write_fmt($crate::format_args_nl!($($arg)*))
};
}

/// Indicates unreachable code.
Expand Down
115 changes: 55 additions & 60 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,23 +398,19 @@ fn clean_type_outlives_predicate<'tcx>(
})
}

impl<'tcx> Clean<'tcx, Term> for ty::Term<'tcx> {
fn clean(&self, cx: &mut DocContext<'tcx>) -> Term {
match self {
ty::Term::Ty(ty) => Term::Type(clean_middle_ty(*ty, cx, None)),
ty::Term::Const(c) => Term::Constant(clean_middle_const(*c, cx)),
}
fn clean_middle_term<'tcx>(term: ty::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
match term {
ty::Term::Ty(ty) => Term::Type(clean_middle_ty(ty, cx, None)),
ty::Term::Const(c) => Term::Constant(clean_middle_const(c, cx)),
}
}

impl<'tcx> Clean<'tcx, Term> for hir::Term<'tcx> {
fn clean(&self, cx: &mut DocContext<'tcx>) -> Term {
match self {
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
hir::Term::Const(c) => {
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))
}
fn clean_hir_term<'tcx>(term: &hir::Term<'tcx>, cx: &mut DocContext<'tcx>) -> Term {
match term {
hir::Term::Ty(ty) => Term::Type(clean_ty(ty, cx)),
hir::Term::Const(c) => {
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))
}
}
}
Expand All @@ -426,7 +422,7 @@ fn clean_projection_predicate<'tcx>(
let ty::ProjectionPredicate { projection_ty, term } = pred;
WherePredicate::EqPredicate {
lhs: clean_projection(projection_ty, cx, None),
rhs: term.clean(cx),
rhs: clean_middle_term(term, cx),
}
}

Expand Down Expand Up @@ -474,47 +470,44 @@ fn projection_to_path_segment<'tcx>(
}
}

impl<'tcx> Clean<'tcx, GenericParamDef> for ty::GenericParamDef {
fn clean(&self, cx: &mut DocContext<'tcx>) -> GenericParamDef {
let (name, kind) = match self.kind {
ty::GenericParamDefKind::Lifetime => {
(self.name, GenericParamDefKind::Lifetime { outlives: vec![] })
}
ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
let default = if has_default {
Some(clean_middle_ty(cx.tcx.type_of(self.def_id), cx, Some(self.def_id)))
} else {
None
};
(
self.name,
GenericParamDefKind::Type {
did: self.def_id,
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,
},
fn clean_generic_param_def<'tcx>(
def: &ty::GenericParamDef,
cx: &mut DocContext<'tcx>,
) -> GenericParamDef {
let (name, kind) = match def.kind {
ty::GenericParamDefKind::Lifetime => {
(def.name, GenericParamDefKind::Lifetime { outlives: vec![] })
}
ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
let default = if has_default {
Some(clean_middle_ty(cx.tcx.type_of(def.def_id), cx, Some(def.def_id)))
} else {
None
};
(
def.name,
GenericParamDefKind::Type {
did: def.def_id,
bounds: vec![], // These are filled in from the where-clauses.
default: default.map(Box::new),
synthetic,
},
),
};
)
}
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>(
Expand Down Expand Up @@ -672,7 +665,7 @@ fn clean_ty_generics<'tcx>(
.iter()
.filter_map(|param| match param.kind {
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, .. } => {
if param.name == kw::SelfUpper {
assert_eq!(param.index, 0);
Expand All @@ -682,9 +675,9 @@ fn clean_ty_generics<'tcx>(
impl_trait.insert(param.index.into(), vec![]);
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>>();

Expand Down Expand Up @@ -1682,7 +1675,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
.projection_ty,
cx,
),
kind: TypeBindingKind::Equality { term: pb.skip_binder().term.clean(cx) },
kind: TypeBindingKind::Equality {
term: clean_middle_term(pb.skip_binder().term, cx),
},
});
}

Expand Down Expand Up @@ -1746,7 +1741,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
Some(TypeBinding {
assoc: projection_to_path_segment(proj.projection_ty, cx),
kind: TypeBindingKind::Equality {
term: proj.term.clean(cx),
term: clean_middle_term(proj.term, cx),
},
})
} else {
Expand Down Expand Up @@ -2283,7 +2278,7 @@ impl<'tcx> Clean<'tcx, TypeBindingKind> for hir::TypeBindingKind<'tcx> {
fn clean(&self, cx: &mut DocContext<'tcx>) -> TypeBindingKind {
match *self {
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 {
bounds: bounds.iter().filter_map(|b| b.clean(cx)).collect(),
Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/linkage-attr/issue-10755.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// build-fail
// dont-check-compiler-stderr
// 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() {
}
37 changes: 37 additions & 0 deletions src/test/ui/macros/format-args-temporaries-async.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 50 additions & 0 deletions src/test/ui/macros/format-args-temporaries-in-write.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 43 additions & 0 deletions src/test/ui/macros/format-args-temporaries-in-write.stderr
Original file line number Diff line number Diff line change
@@ -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`.
Loading