Skip to content

Commit de392c7

Browse files
committed
Auto merge of rust-lang#95944 - Dylan-DPC:rollup-idggkrh, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - rust-lang#95008 ([`let_chains`] Forbid `let` inside parentheses) - rust-lang#95801 (Replace RwLock by a futex based one on Linux) - rust-lang#95864 (Fix miscompilation of inline assembly with outputs in cases where we emit an invoke instead of call instruction.) - rust-lang#95894 (Fix formatting error in pin.rs docs) - rust-lang#95895 (Clarify str::from_utf8_unchecked's invariants) - rust-lang#95901 (Remove duplicate aliases for `check codegen_{cranelift,gcc}` and fix `build codegen_gcc`) - rust-lang#95927 (CI: do not compile libcore twice when performing LLVM PGO) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 90ca447 + 070e8ed commit de392c7

File tree

16 files changed

+1104
-502
lines changed

16 files changed

+1104
-502
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+42-12
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,21 @@ impl<'a> AstValidator<'a> {
120120
let err = "`let` expressions are not supported here";
121121
let mut diag = sess.struct_span_err(expr.span, err);
122122
diag.note("only supported directly in conditions of `if` and `while` expressions");
123-
diag.note("as well as when nested within `&&` and parentheses in those conditions");
124-
if let ForbiddenLetReason::ForbiddenWithOr(span) = forbidden_let_reason {
125-
diag.span_note(
126-
span,
127-
"`||` operators are not currently supported in let chain expressions",
128-
);
123+
match forbidden_let_reason {
124+
ForbiddenLetReason::GenericForbidden => {}
125+
ForbiddenLetReason::NotSupportedOr(span) => {
126+
diag.span_note(
127+
span,
128+
"`||` operators are not supported in let chain expressions",
129+
);
130+
}
131+
ForbiddenLetReason::NotSupportedParentheses(span) => {
132+
diag.span_note(
133+
span,
134+
"`let`s wrapped in parentheses are not supported in a context with let \
135+
chains",
136+
);
137+
}
129138
}
130139
diag.emit();
131140
} else {
@@ -1009,9 +1018,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10091018
self.with_let_management(Some(ForbiddenLetReason::GenericForbidden), |this, forbidden_let_reason| {
10101019
match &expr.kind {
10111020
ExprKind::Binary(Spanned { node: BinOpKind::Or, span }, lhs, rhs) => {
1012-
let forbidden_let_reason = Some(ForbiddenLetReason::ForbiddenWithOr(*span));
1013-
this.with_let_management(forbidden_let_reason, |this, _| this.visit_expr(lhs));
1014-
this.with_let_management(forbidden_let_reason, |this, _| this.visit_expr(rhs));
1021+
let local_reason = Some(ForbiddenLetReason::NotSupportedOr(*span));
1022+
this.with_let_management(local_reason, |this, _| this.visit_expr(lhs));
1023+
this.with_let_management(local_reason, |this, _| this.visit_expr(rhs));
10151024
}
10161025
ExprKind::If(cond, then, opt_else) => {
10171026
this.visit_block(then);
@@ -1036,7 +1045,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10361045
}
10371046
}
10381047
}
1039-
ExprKind::Paren(_) | ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, ..) => {
1048+
ExprKind::Paren(local_expr) => {
1049+
fn has_let_expr(expr: &Expr) -> bool {
1050+
match expr.kind {
1051+
ExprKind::Binary(_, ref lhs, ref rhs) => has_let_expr(lhs) || has_let_expr(rhs),
1052+
ExprKind::Let(..) => true,
1053+
_ => false,
1054+
}
1055+
}
1056+
let local_reason = if has_let_expr(local_expr) {
1057+
Some(ForbiddenLetReason::NotSupportedParentheses(local_expr.span))
1058+
}
1059+
else {
1060+
forbidden_let_reason
1061+
};
1062+
this.with_let_management(local_reason, |this, _| this.visit_expr(local_expr));
1063+
}
1064+
ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, ..) => {
10401065
this.with_let_management(forbidden_let_reason, |this, _| visit::walk_expr(this, expr));
10411066
return;
10421067
}
@@ -1810,8 +1835,13 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
18101835
/// Used to forbid `let` expressions in certain syntactic locations.
18111836
#[derive(Clone, Copy)]
18121837
enum ForbiddenLetReason {
1813-
/// A let chain with the `||` operator
1814-
ForbiddenWithOr(Span),
18151838
/// `let` is not valid and the source environment is not important
18161839
GenericForbidden,
1840+
/// A let chain with the `||` operator
1841+
NotSupportedOr(Span),
1842+
/// A let chain with invalid parentheses
1843+
///
1844+
/// For exemple, `let 1 = 1 && (expr && expr)` is allowed
1845+
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
1846+
NotSupportedParentheses(Span),
18171847
}

compiler/rustc_codegen_llvm/src/asm.rs

+5
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
290290
}
291291
attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });
292292

293+
// Switch to the 'normal' basic block if we did an `invoke` instead of a `call`
294+
if let Some((dest, _, _)) = dest_catch_funclet {
295+
self.switch_to_block(dest);
296+
}
297+
293298
// Write results to outputs
294299
for (idx, op) in operands.iter().enumerate() {
295300
if let InlineAsmOperandRef::Out { reg, place: Some(place), .. }

library/core/src/pin.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@
175175
//! relies on pinning requires unsafe code, but be aware that deciding to make
176176
//! use of pinning in your type (for example by implementing some operation on
177177
//! <code>[Pin]<[&]Self></code> or <code>[Pin]<[&mut] Self></code>) has consequences for your
178-
//! [`Drop`][Drop]implementation as well: if an element of your type could have been pinned,
178+
//! [`Drop`][Drop] implementation as well: if an element of your type could have been pinned,
179179
//! you must treat [`Drop`][Drop] as implicitly taking <code>[Pin]<[&mut] Self></code>.
180180
//!
181181
//! For example, you could implement [`Drop`][Drop] as follows:

library/core/src/str/converts.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,7 @@ pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
144144
///
145145
/// # Safety
146146
///
147-
/// This function is unsafe because it does not check that the bytes passed to
148-
/// it are valid UTF-8. If this constraint is violated, undefined behavior
149-
/// results, as the rest of Rust assumes that [`&str`]s are valid UTF-8.
150-
///
151-
/// [`&str`]: str
147+
/// The bytes passed in must be valid UTF-8.
152148
///
153149
/// # Examples
154150
///

library/std/src/sys/unix/futex.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
use crate::sync::atomic::AtomicI32;
88
use crate::time::Duration;
99

10+
/// Wait for a futex_wake operation to wake us.
11+
///
12+
/// Returns directly if the futex doesn't hold the expected value.
13+
///
14+
/// Returns false on timeout, and true in all other cases.
1015
#[cfg(any(target_os = "linux", target_os = "android"))]
1116
pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) -> bool {
1217
use super::time::Timespec;
@@ -68,18 +73,23 @@ pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option<Duration>) {
6873
}
6974
}
7075

76+
/// Wake up one thread that's blocked on futex_wait on this futex.
77+
///
78+
/// Returns true if this actually woke up such a thread,
79+
/// or false if no thread was waiting on this futex.
7180
#[cfg(any(target_os = "linux", target_os = "android"))]
72-
pub fn futex_wake(futex: &AtomicI32) {
81+
pub fn futex_wake(futex: &AtomicI32) -> bool {
7382
unsafe {
7483
libc::syscall(
7584
libc::SYS_futex,
7685
futex as *const AtomicI32,
7786
libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
7887
1,
79-
);
88+
) > 0
8089
}
8190
}
8291

92+
/// Wake up all threads that are waiting on futex_wait on this futex.
8393
#[cfg(any(target_os = "linux", target_os = "android"))]
8494
pub fn futex_wake_all(futex: &AtomicI32) {
8595
unsafe {
@@ -93,12 +103,10 @@ pub fn futex_wake_all(futex: &AtomicI32) {
93103
}
94104

95105
#[cfg(target_os = "emscripten")]
96-
pub fn futex_wake(futex: &AtomicI32) {
106+
pub fn futex_wake(futex: &AtomicI32) -> bool {
97107
extern "C" {
98108
fn emscripten_futex_wake(addr: *const AtomicI32, count: libc::c_int) -> libc::c_int;
99109
}
100110

101-
unsafe {
102-
emscripten_futex_wake(futex as *const AtomicI32, 1);
103-
}
111+
unsafe { emscripten_futex_wake(futex as *const AtomicI32, 1) > 0 }
104112
}

0 commit comments

Comments
 (0)