Auto merge of #123869 - matthiaskrgr:rollup-9kif9c9, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #123654 (typeck: fix `?` suggestion span)
 - #123807 (Remove `sys_common::thread`)
 - #123834 (Don't do coroutine-closure-specific upvar analysis if tainted by errors)
 - #123847 (Suppress `let else` suggestion for uninitialized refutable `let`s)
 - #123857 (std::net: TcpListener shrinks the backlog argument to 32 for Haiku.)
 - #123858 (zkvm: fix path to cmath in zkvm module)
 - #123867 (Add `unsafe` to two functions with safety invariants)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-04-12 20:23:30 +00:00
commit 79424056b0
23 changed files with 230 additions and 145 deletions

View File

@ -1287,12 +1287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::TraitRef::new(self.tcx, into_def_id, [expr_ty, expected_ty]),
))
{
let mut span = expr.span;
while expr.span.eq_ctxt(span)
&& let Some(parent_callsite) = span.parent_callsite()
{
span = parent_callsite;
}
let span = expr.span.find_oldest_ancestor_in_same_ctxt();
let mut sugg = if expr.precedence().order() >= PREC_POSTFIX {
vec![(span.shrink_to_hi(), ".into()".to_owned())]
@ -1897,12 +1892,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None => sugg.to_string(),
};
err.span_suggestion_verbose(
expr.span.shrink_to_hi(),
msg,
sugg,
Applicability::HasPlaceholders,
);
let span = expr.span.find_oldest_ancestor_in_same_ctxt();
err.span_suggestion_verbose(span.shrink_to_hi(), msg, sugg, Applicability::HasPlaceholders);
return true;
}

View File

@ -43,7 +43,8 @@ use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, Pro
use rustc_middle::mir::FakeReadCause;
use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::{
self, ClosureSizeProfileData, Ty, TyCtxt, TypeckResults, UpvarArgs, UpvarCapture,
self, ClosureSizeProfileData, Ty, TyCtxt, TypeVisitableExt as _, TypeckResults, UpvarArgs,
UpvarCapture,
};
use rustc_session::lint;
use rustc_span::sym;
@ -191,6 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}
};
let args = self.resolve_vars_if_possible(args);
let closure_def_id = closure_def_id.expect_local();
assert_eq!(self.tcx.hir().body_owner_def_id(body.id()), closure_def_id);
@ -361,7 +363,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// For coroutine-closures, we additionally must compute the
// `coroutine_captures_by_ref_ty` type, which is used to generate the by-ref
// version of the coroutine-closure's output coroutine.
if let UpvarArgs::CoroutineClosure(args) = args {
if let UpvarArgs::CoroutineClosure(args) = args
&& !args.references_error()
{
let closure_env_region: ty::Region<'_> = ty::Region::new_bound(
self.tcx,
ty::INNERMOST,

View File

@ -771,7 +771,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
}
}
#[derive(Debug, Copy, Clone, HashStable)]
#[derive(Debug, Copy, Clone, HashStable, TypeFoldable, TypeVisitable)]
pub enum UpvarArgs<'tcx> {
Closure(GenericArgsRef<'tcx>),
Coroutine(GenericArgsRef<'tcx>),

View File

@ -674,6 +674,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
if let Some(span) = sp
&& self.tcx.sess.source_map().is_span_accessible(span)
&& interpreted_as_const.is_none()
&& scrut.is_some()
{
let mut bindings = vec![];
pat.each_binding(|name, _, _, _| bindings.push(name));

View File

@ -743,6 +743,45 @@ impl Span {
Some(self)
}
/// Recursively walk down the expansion ancestors to find the oldest ancestor span with the same
/// [`SyntaxContext`] the initial span.
///
/// This method is suitable for peeling through *local* macro expansions to find the "innermost"
/// span that is still local and shares the same [`SyntaxContext`]. For example, given
///
/// ```ignore (illustrative example, contains type error)
/// macro_rules! outer {
/// ($x: expr) => {
/// inner!($x)
/// }
/// }
///
/// macro_rules! inner {
/// ($x: expr) => {
/// format!("error: {}", $x)
/// //~^ ERROR mismatched types
/// }
/// }
///
/// fn bar(x: &str) -> Result<(), Box<dyn std::error::Error>> {
/// Err(outer!(x))
/// }
/// ```
///
/// if provided the initial span of `outer!(x)` inside `bar`, this method will recurse
/// the parent callsites until we reach `format!("error: {}", $x)`, at which point it is the
/// oldest ancestor span that is both still local and shares the same [`SyntaxContext`] as the
/// initial span.
pub fn find_oldest_ancestor_in_same_ctxt(self) -> Span {
let mut cur = self;
while cur.eq_ctxt(self)
&& let Some(parent_callsite) = cur.parent_callsite()
{
cur = parent_callsite;
}
cur
}
/// Edition of the crate from which this span came.
pub fn edition(self) -> edition::Edition {
self.ctxt().edition()

View File

@ -45,13 +45,11 @@ impl Thread {
Err(io::Error::last_os_error())
};
extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
unsafe {
// Next, reserve some stack space for if we otherwise run out of stack.
stack_overflow::reserve_stack();
// Finally, let's run some code.
Box::from_raw(main as *mut Box<dyn FnOnce()>)();
}
unsafe extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
// Next, reserve some stack space for if we otherwise run out of stack.
stack_overflow::reserve_stack();
// Finally, let's run some code.
Box::from_raw(main as *mut Box<dyn FnOnce()>)();
0
}
}
@ -59,15 +57,19 @@ impl Thread {
pub fn set_name(name: &CStr) {
if let Ok(utf8) = name.to_str() {
if let Ok(utf16) = to_u16s(utf8) {
Self::set_name_wide(&utf16)
unsafe {
// SAFETY: the vec returned by `to_u16s` ends with a zero value
Self::set_name_wide(&utf16)
}
};
};
}
pub fn set_name_wide(name: &[u16]) {
unsafe {
c::SetThreadDescription(c::GetCurrentThread(), name.as_ptr());
};
/// # Safety
///
/// `name` must end with a zero value
pub unsafe fn set_name_wide(name: &[u16]) {
c::SetThreadDescription(c::GetCurrentThread(), name.as_ptr());
}
pub fn join(self) {

View File

@ -12,8 +12,6 @@ const WORD_SIZE: usize = core::mem::size_of::<u32>();
pub mod alloc;
#[path = "../zkvm/args.rs"]
pub mod args;
#[path = "../unix/cmath.rs"]
pub mod cmath;
pub mod env;
#[path = "../unsupported/fs.rs"]
pub mod fs;

View File

@ -25,7 +25,6 @@ pub mod fs;
pub mod io;
pub mod lazy_box;
pub mod process;
pub mod thread;
pub mod thread_local_dtor;
pub mod thread_parking;
pub mod wstr;

View File

@ -417,6 +417,10 @@ impl TcpListener {
// it allows up to about 37, but other times it doesn't even
// accept 32. There may be a global limitation causing this.
let backlog = 20;
} else if #[cfg(target_os = "haiku")] {
// Haiku does not support a queue length > 32
// https://github.com/haiku/haiku/blob/979a0bc487864675517fb2fab28f87dc8bf43041/headers/posix/sys/socket.h#L81
let backlog = 32;
} else {
// The default for all other platforms
let backlog = 128;

View File

@ -1,18 +0,0 @@
use crate::env;
use crate::sync::atomic::{self, Ordering};
use crate::sys::thread as imp;
pub fn min_stack() -> usize {
static MIN: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
match MIN.load(Ordering::Relaxed) {
0 => {}
n => return n - 1,
}
let amt = env::var_os("RUST_MIN_STACK").and_then(|s| s.to_str().and_then(|s| s.parse().ok()));
let amt = amt.unwrap_or(imp::DEFAULT_MIN_STACK_SIZE);
// 0 is our sentinel value, so ensure that we'll never see 0 after
// initialization has run
MIN.store(amt + 1, Ordering::Relaxed);
amt
}

View File

@ -160,6 +160,7 @@ mod tests;
use crate::any::Any;
use crate::cell::{OnceCell, UnsafeCell};
use crate::env;
use crate::ffi::{CStr, CString};
use crate::fmt;
use crate::io;
@ -171,9 +172,9 @@ use crate::panicking;
use crate::pin::Pin;
use crate::ptr::addr_of_mut;
use crate::str;
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::Arc;
use crate::sys::thread as imp;
use crate::sys_common::thread;
use crate::sys_common::thread_parking::Parker;
use crate::sys_common::{AsInner, IntoInner};
use crate::time::{Duration, Instant};
@ -468,7 +469,23 @@ impl Builder {
{
let Builder { name, stack_size } = self;
let stack_size = stack_size.unwrap_or_else(thread::min_stack);
let stack_size = stack_size.unwrap_or_else(|| {
static MIN: AtomicUsize = AtomicUsize::new(0);
match MIN.load(Ordering::Relaxed) {
0 => {}
n => return n - 1,
}
let amt = env::var_os("RUST_MIN_STACK")
.and_then(|s| s.to_str().and_then(|s| s.parse().ok()))
.unwrap_or(imp::DEFAULT_MIN_STACK_SIZE);
// 0 is our sentinel value, so ensure that we'll never see 0 after
// initialization has run
MIN.store(amt + 1, Ordering::Relaxed);
amt
});
let my_thread = Thread::new(name.map(|name| {
CString::new(name).expect("thread name may not contain interior null bytes")
@ -1191,17 +1208,17 @@ impl ThreadId {
cfg_if::cfg_if! {
if #[cfg(target_has_atomic = "64")] {
use crate::sync::atomic::{AtomicU64, Ordering::Relaxed};
use crate::sync::atomic::AtomicU64;
static COUNTER: AtomicU64 = AtomicU64::new(0);
let mut last = COUNTER.load(Relaxed);
let mut last = COUNTER.load(Ordering::Relaxed);
loop {
let Some(id) = last.checked_add(1) else {
exhausted();
};
match COUNTER.compare_exchange_weak(last, id, Relaxed, Relaxed) {
match COUNTER.compare_exchange_weak(last, id, Ordering::Relaxed, Ordering::Relaxed) {
Ok(_) => return ThreadId(NonZero::new(id).unwrap()),
Err(id) => last = id,
}

View File

@ -0,0 +1,23 @@
//@ edition: 2021
#![feature(async_closure)]
struct DropMe;
trait Impossible {}
fn trait_error<T: Impossible>() {}
pub fn main() {
let b = DropMe;
let async_closure = async move || {
// Type error here taints the environment. This causes us to fallback all
// variables to `Error`. This means that when we compute the upvars for the
// *outer* coroutine-closure, we don't actually see any upvars since `MemCategorization`
// and `ExprUseVisitor`` will bail early when it sees error. This means
// that our underlying assumption that the parent and child captures are
// compatible ends up being broken, previously leading to an ICE.
trait_error::<()>();
//~^ ERROR the trait bound `(): Impossible` is not satisfied
let _b = b;
};
}

View File

@ -0,0 +1,20 @@
error[E0277]: the trait bound `(): Impossible` is not satisfied
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:19:23
|
LL | trait_error::<()>();
| ^^ the trait `Impossible` is not implemented for `()`
|
help: this trait has no implementations, consider adding one
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:7:1
|
LL | trait Impossible {}
| ^^^^^^^^^^^^^^^^
note: required by a bound in `trait_error`
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:8:19
|
LL | fn trait_error<T: Impossible>() {}
| ^^^^^^^^^^ required by this bound in `trait_error`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.

View File

@ -46,10 +46,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let ...$e; { todo!() }
| ++ +++++++++++
error: aborting due to 6 previous errors

View File

@ -67,10 +67,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let $e...; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/half-open-range-pats-inclusive-no-end.rs:20:17
@ -85,10 +81,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let $e..=; { todo!() }
| ++ +++++++++++
error: aborting due to 8 previous errors

View File

@ -0,0 +1,8 @@
// https://github.com/rust-lang/rust/issues/123844
// An uninitialized refutable let should not suggest `let else`, as it can't be used with deferred
// initialization.
fn main() {
let Some(x); //~ ERROR refutable pattern in local binding
x = 1;
}

View File

@ -0,0 +1,13 @@
error[E0005]: refutable pattern in local binding
--> $DIR/uninitialized-refutable-let-issue-123844.rs:6:9
|
LL | let Some(x);
| ^^^^^^^ pattern `None` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `Option<i32>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0005`.

View File

@ -491,10 +491,6 @@ LL | mac2!(0, 1);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variants that aren't matched
|
LL | if let $e1..$e2; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/recover-range-pats.rs:138:17
@ -509,10 +505,6 @@ LL | mac2!(0, 1);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variants that aren't matched
|
LL | if let $e1...$e2; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/recover-range-pats.rs:142:17
@ -527,10 +519,6 @@ LL | mac2!(0, 1);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variants that aren't matched
|
LL | if let $e1..=$e2; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/recover-range-pats.rs:151:17
@ -545,10 +533,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let ..$e; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/recover-range-pats.rs:153:17
@ -563,10 +547,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let ...$e; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/recover-range-pats.rs:156:17
@ -581,10 +561,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let ..=$e; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/recover-range-pats.rs:158:17
@ -599,10 +575,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let $e..; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/recover-range-pats.rs:160:17
@ -617,10 +589,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let $e...; { todo!() }
| ++ +++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/recover-range-pats.rs:162:17
@ -635,10 +603,6 @@ LL | mac!(0);
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `i32`
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let $e..=; { todo!() }
| ++ +++++++++++
error: aborting due to 69 previous errors

View File

@ -1,37 +0,0 @@
//@ run-rustfix
#![allow(dead_code)]
// https://github.com/rust-lang/rust/issues/112007
fn bug_report<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
if true {
writeln!(w, "`;?` here ->")?;
} else {
return writeln!(w, "but not here");
//~^ ERROR mismatched types
};
Ok(())
}
macro_rules! baz {
($w: expr) => {
bar!($w)
}
}
macro_rules! bar {
($w: expr) => {
writeln!($w, "but not here")
//~^ ERROR mismatched types
}
}
fn foo<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
if true {
writeln!(w, "`;?` here ->")?;
} else {
return baz!(w);
};
Ok(())
}
fn main() {}

View File

@ -1,8 +1,16 @@
//@ run-rustfix
#![allow(dead_code)]
// Check that we don't leak stdlib implementation details through suggestions.
// Also check that the suggestion provided tries as hard as it can to see through local macros.
//
// FIXME(jieyouxu): this test is NOT run-rustfix because this test contains conflicting
// MaybeIncorrect suggestions:
//
// 1. `return ... ;`
// 2. `?`
//
// when the suggestions are applied to the same file, it becomes uncompilable.
// https://github.com/rust-lang/rust/issues/112007
fn bug_report<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
pub fn bug_report<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
if true {
writeln!(w, "`;?` here ->")?;
} else {
@ -25,7 +33,7 @@ macro_rules! bar {
}
}
fn foo<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
pub fn foo<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
if true {
writeln!(w, "`;?` here ->")?;
} else {
@ -34,4 +42,4 @@ fn foo<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
Ok(())
}
fn main() {}
pub fn main() {}

View File

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/issue-112007-leaked-writeln-macro-internals.rs:9:9
--> $DIR/issue-112007-leaked-writeln-macro-internals.rs:17:9
|
LL | / if true {
LL | | writeln!(w, "`;?` here ->")?;
@ -21,9 +21,13 @@ help: you might have meant to return this value
|
LL | return writeln!(w, "but not here");
| ++++++ +
help: use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller
|
LL | writeln!(w, "but not here")?
| +
error[E0308]: mismatched types
--> $DIR/issue-112007-leaked-writeln-macro-internals.rs:32:9
--> $DIR/issue-112007-leaked-writeln-macro-internals.rs:40:9
|
LL | / if true {
LL | | writeln!(w, "`;?` here ->")?;
@ -44,6 +48,10 @@ help: you might have meant to return this value
|
LL | return baz!(w);
| ++++++ +
help: use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller
|
LL | writeln!($w, "but not here")?
| +
error: aborting due to 2 previous errors

View File

@ -0,0 +1,22 @@
// Check that we don't construct a span for `?` suggestions that point into non-local macros
// like into the stdlib where the user has no control over.
//
// FIXME(jieyouxu): this test is currently NOT run-rustfix because there are conflicting
// MaybeIncorrect suggestions:
//
// 1. adding `return ... ;`, and
// 2. adding `?`.
//
// When rustfix puts those together, the fixed file now contains uncompilable code.
#![crate_type = "lib"]
pub fn bug_report<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
if true {
writeln!(w, "`;?` here ->")?;
} else {
writeln!(w, "but not here")
//~^ ERROR mismatched types
}
Ok(())
}

View File

@ -0,0 +1,31 @@
error[E0308]: mismatched types
--> $DIR/question-mark-operator-suggestion-span.rs:18:9
|
LL | / if true {
LL | | writeln!(w, "`;?` here ->")?;
LL | | } else {
LL | | writeln!(w, "but not here")
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Result<(), Error>`
LL | |
LL | | }
| |_____- expected this to be `()`
|
= note: expected unit type `()`
found enum `Result<(), std::fmt::Error>`
= note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider using a semicolon here
|
LL | };
| +
help: you might have meant to return this value
|
LL | return writeln!(w, "but not here");
| ++++++ +
help: use the `?` operator to extract the `Result<(), std::fmt::Error>` value, propagating a `Result::Err` value to the caller
|
LL | writeln!(w, "but not here")?
| +
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.