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 7 pull requests #95944

Merged
merged 22 commits into from
Apr 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6ee3c47
[let_chains] Forbid let inside parentheses
c410-f3r Mar 31, 2022
f1a4041
Return status from futex_wake().
m-ou-se Apr 6, 2022
6cb463c
Add futex-based RwLock on Linux.
m-ou-se Apr 6, 2022
307aa58
Fix typo in futex rwlock.
m-ou-se Apr 8, 2022
bf3ef0d
Switch to the 'normal' basic block for writing asm outputs if needed.
luqmana Apr 9, 2022
0b2f360
Update asm-may_unwind test to handle use of asm with outputs.
luqmana Apr 9, 2022
bb3a071
Fix formatting error in pin.rs docs
nyanpasu64 Apr 10, 2022
b92cd1a
Clarify str::from_utf8_unchecked's invariants
CAD97 Apr 10, 2022
986c168
Remove duplicate aliases for `codegen_{cranelift,gcc}`
jyn514 Apr 10, 2022
4c14383
Add `build compiler/rustc_codegen_gcc` as an alias for `CodegenBackend`
jyn514 Apr 10, 2022
aeb3df7
CI: do not compile libcore twice when performing LLVM PGO
Kobzol Apr 11, 2022
7c28791
Add doc comments to futex operations.
m-ou-se Apr 11, 2022
1f2c2bb
Add comments to futex rwlock implementation.
m-ou-se Apr 11, 2022
c4a4f48
Use compare_exchange_weak in futex rwlock implementation.
m-ou-se Apr 11, 2022
8339381
Use is_ or has_ prefix for pure `-> bool` functions.
m-ou-se Apr 11, 2022
2ad701e
Rollup merge of #95008 - c410-f3r:let-chains-paren, r=wesleywiser
Dylan-DPC Apr 11, 2022
a15ac30
Rollup merge of #95801 - m-ou-se:futex-rwlock, r=Amanieu
Dylan-DPC Apr 11, 2022
3f606ce
Rollup merge of #95864 - luqmana:inline-asm-unwind-store-miscompile, …
Dylan-DPC Apr 11, 2022
82a6463
Rollup merge of #95894 - nyanpasu64:fix-pin-docs, r=Dylan-DPC
Dylan-DPC Apr 11, 2022
ae6f75a
Rollup merge of #95895 - CAD97:patch-2, r=Dylan-DPC
Dylan-DPC Apr 11, 2022
ec95e7d
Rollup merge of #95901 - jyn514:remove-duplicate-aliases, r=Mark-Simu…
Dylan-DPC Apr 11, 2022
070e8ed
Rollup merge of #95927 - Kobzol:ci-pgo-libcore, r=lqd
Dylan-DPC Apr 11, 2022
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
54 changes: 42 additions & 12 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,21 @@ impl<'a> AstValidator<'a> {
let err = "`let` expressions are not supported here";
let mut diag = sess.struct_span_err(expr.span, err);
diag.note("only supported directly in conditions of `if` and `while` expressions");
diag.note("as well as when nested within `&&` and parentheses in those conditions");
if let ForbiddenLetReason::ForbiddenWithOr(span) = forbidden_let_reason {
diag.span_note(
span,
"`||` operators are not currently supported in let chain expressions",
);
match forbidden_let_reason {
ForbiddenLetReason::GenericForbidden => {}
ForbiddenLetReason::NotSupportedOr(span) => {
diag.span_note(
span,
"`||` operators are not supported in let chain expressions",
);
}
ForbiddenLetReason::NotSupportedParentheses(span) => {
diag.span_note(
span,
"`let`s wrapped in parentheses are not supported in a context with let \
chains",
);
}
}
diag.emit();
} else {
Expand Down Expand Up @@ -1009,9 +1018,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.with_let_management(Some(ForbiddenLetReason::GenericForbidden), |this, forbidden_let_reason| {
match &expr.kind {
ExprKind::Binary(Spanned { node: BinOpKind::Or, span }, lhs, rhs) => {
let forbidden_let_reason = Some(ForbiddenLetReason::ForbiddenWithOr(*span));
this.with_let_management(forbidden_let_reason, |this, _| this.visit_expr(lhs));
this.with_let_management(forbidden_let_reason, |this, _| this.visit_expr(rhs));
let local_reason = Some(ForbiddenLetReason::NotSupportedOr(*span));
this.with_let_management(local_reason, |this, _| this.visit_expr(lhs));
this.with_let_management(local_reason, |this, _| this.visit_expr(rhs));
}
ExprKind::If(cond, then, opt_else) => {
this.visit_block(then);
Expand All @@ -1036,7 +1045,23 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}
}
}
ExprKind::Paren(_) | ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, ..) => {
ExprKind::Paren(local_expr) => {
fn has_let_expr(expr: &Expr) -> bool {
match expr.kind {
ExprKind::Binary(_, ref lhs, ref rhs) => has_let_expr(lhs) || has_let_expr(rhs),
ExprKind::Let(..) => true,
_ => false,
}
}
let local_reason = if has_let_expr(local_expr) {
Some(ForbiddenLetReason::NotSupportedParentheses(local_expr.span))
}
else {
forbidden_let_reason
};
this.with_let_management(local_reason, |this, _| this.visit_expr(local_expr));
}
ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, ..) => {
this.with_let_management(forbidden_let_reason, |this, _| visit::walk_expr(this, expr));
return;
}
Expand Down Expand Up @@ -1810,8 +1835,13 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
/// Used to forbid `let` expressions in certain syntactic locations.
#[derive(Clone, Copy)]
enum ForbiddenLetReason {
/// A let chain with the `||` operator
ForbiddenWithOr(Span),
/// `let` is not valid and the source environment is not important
GenericForbidden,
/// A let chain with the `||` operator
NotSupportedOr(Span),
/// A let chain with invalid parentheses
///
/// For exemple, `let 1 = 1 && (expr && expr)` is allowed
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
NotSupportedParentheses(Span),
}
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
}
attributes::apply_to_callsite(result, llvm::AttributePlace::Function, &{ attrs });

// Switch to the 'normal' basic block if we did an `invoke` instead of a `call`
if let Some((dest, _, _)) = dest_catch_funclet {
self.switch_to_block(dest);
}

// Write results to outputs
for (idx, op) in operands.iter().enumerate() {
if let InlineAsmOperandRef::Out { reg, place: Some(place), .. }
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
//! relies on pinning requires unsafe code, but be aware that deciding to make
//! use of pinning in your type (for example by implementing some operation on
//! <code>[Pin]<[&]Self></code> or <code>[Pin]<[&mut] Self></code>) has consequences for your
//! [`Drop`][Drop]implementation as well: if an element of your type could have been pinned,
//! [`Drop`][Drop] implementation as well: if an element of your type could have been pinned,
//! you must treat [`Drop`][Drop] as implicitly taking <code>[Pin]<[&mut] Self></code>.
//!
//! For example, you could implement [`Drop`][Drop] as follows:
Expand Down
6 changes: 1 addition & 5 deletions library/core/src/str/converts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,7 @@ pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
///
/// # Safety
///
/// This function is unsafe because it does not check that the bytes passed to
/// it are valid UTF-8. If this constraint is violated, undefined behavior
/// results, as the rest of Rust assumes that [`&str`]s are valid UTF-8.
///
/// [`&str`]: str
/// The bytes passed in must be valid UTF-8.
///
/// # Examples
///
Expand Down
20 changes: 14 additions & 6 deletions library/std/src/sys/unix/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
use crate::sync::atomic::AtomicI32;
use crate::time::Duration;

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

/// Wake up one thread that's blocked on futex_wait on this futex.
///
/// Returns true if this actually woke up such a thread,
/// or false if no thread was waiting on this futex.
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn futex_wake(futex: &AtomicI32) {
pub fn futex_wake(futex: &AtomicI32) -> bool {
unsafe {
libc::syscall(
libc::SYS_futex,
futex as *const AtomicI32,
libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG,
1,
);
) > 0
}
}

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

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

unsafe {
emscripten_futex_wake(futex as *const AtomicI32, 1);
}
unsafe { emscripten_futex_wake(futex as *const AtomicI32, 1) > 0 }
}
Loading