From 950a249e7869ab8287c4c0d4b78174d5803a0c13 Mon Sep 17 00:00:00 2001 From: Dmitry Murzin Date: Wed, 5 Jul 2023 16:18:32 +0300 Subject: [PATCH 1/7] Add `suggestion` for some `#[deprecated]` items --- library/alloc/src/lib.rs | 1 + library/alloc/src/slice.rs | 2 +- library/core/src/error.rs | 3 ++- library/core/src/mem/mod.rs | 4 ++-- library/core/src/str/mod.rs | 2 +- library/std/src/os/unix/process.rs | 6 +++++- library/std/src/sync/condvar.rs | 6 +++++- library/std/src/thread/mod.rs | 8 ++++++-- ...issue-84637-deprecated-associated-function.fixed | 2 ++ .../issue-84637-deprecated-associated-function.rs | 2 ++ ...ssue-84637-deprecated-associated-function.stderr | 13 ++++++++++++- 11 files changed, 39 insertions(+), 10 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 967ad3a0e6901..9d9743a437829 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -118,6 +118,7 @@ #![feature(const_waker)] #![feature(core_intrinsics)] #![feature(core_panic)] +#![feature(deprecated_suggestion)] #![feature(dispatch_from_dyn)] #![feature(error_generic_member_access)] #![feature(error_in_core)] diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 093dcbbe8bf77..aa3b7b7e1914b 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -592,7 +592,7 @@ impl [T] { /// ``` #[rustc_allow_incoherent_impl] #[stable(feature = "rust1", since = "1.0.0")] - #[deprecated(since = "1.3.0", note = "renamed to join")] + #[deprecated(since = "1.3.0", note = "renamed to join", suggestion = "join")] pub fn connect(&self, sep: Separator) -> >::Output where Self: Join, diff --git a/library/core/src/error.rs b/library/core/src/error.rs index 11cb082757864..8b4b34a5a1ef9 100644 --- a/library/core/src/error.rs +++ b/library/core/src/error.rs @@ -114,7 +114,8 @@ pub trait Error: Debug + Display { #[stable(feature = "rust1", since = "1.0.0")] #[deprecated( since = "1.33.0", - note = "replaced by Error::source, which can support downcasting" + note = "replaced by Error::source, which can support downcasting", + suggestion = "source" )] #[allow(missing_docs)] fn cause(&self) -> Option<&dyn Error> { diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 2fff3f0efd73a..732fcce0f2930 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -413,7 +413,7 @@ pub const unsafe fn size_of_val_raw(val: *const T) -> usize { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[deprecated(note = "use `align_of` instead", since = "1.2.0")] +#[deprecated(note = "use `align_of` instead", since = "1.2.0", suggestion = "align_of")] pub fn min_align_of() -> usize { intrinsics::min_align_of::() } @@ -436,7 +436,7 @@ pub fn min_align_of() -> usize { #[inline] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] -#[deprecated(note = "use `align_of_val` instead", since = "1.2.0")] +#[deprecated(note = "use `align_of_val` instead", since = "1.2.0", suggestion = "align_of_val")] pub fn min_align_of_val(val: &T) -> usize { // SAFETY: val is a reference, so it's a valid raw pointer unsafe { intrinsics::min_align_of_val(val) } diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 9a93bb72903f2..5f5d931a26729 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -993,7 +993,7 @@ impl str { /// An iterator over the lines of a string. #[stable(feature = "rust1", since = "1.0.0")] - #[deprecated(since = "1.4.0", note = "use lines() instead now")] + #[deprecated(since = "1.4.0", note = "use lines() instead now", suggestion = "lines")] #[inline] #[allow(deprecated)] pub fn lines_any(&self) -> LinesAny<'_> { diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 2b40b672d9f0a..a1d2a77b2e7ac 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -109,7 +109,11 @@ pub trait CommandExt: Sealed { /// /// [`pre_exec`]: CommandExt::pre_exec #[stable(feature = "process_exec", since = "1.15.0")] - #[deprecated(since = "1.37.0", note = "should be unsafe, use `pre_exec` instead")] + #[deprecated( + since = "1.37.0", + note = "should be unsafe, use `pre_exec` instead", + suggestion = "pre_exec" + )] fn before_exec(&mut self, f: F) -> &mut process::Command where F: FnMut() -> io::Result<()> + Send + Sync + 'static, diff --git a/library/std/src/sync/condvar.rs b/library/std/src/sync/condvar.rs index 76a1b4a2a86cd..8b5195e94fc40 100644 --- a/library/std/src/sync/condvar.rs +++ b/library/std/src/sync/condvar.rs @@ -305,7 +305,11 @@ impl Condvar { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[deprecated(since = "1.6.0", note = "replaced by `std::sync::Condvar::wait_timeout`")] + #[deprecated( + since = "1.6.0", + note = "replaced by `std::sync::Condvar::wait_timeout`", + suggestion = "wait_timeout" + )] pub fn wait_timeout_ms<'a, T>( &self, guard: MutexGuard<'a, T>, diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index e4581c2de7825..762e2f25c122e 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -825,7 +825,7 @@ pub fn panicking() -> bool { /// thread::sleep_ms(2000); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -#[deprecated(since = "1.6.0", note = "replaced by `std::thread::sleep`")] +#[deprecated(since = "1.6.0", note = "replaced by `std::thread::sleep`", suggestion = "sleep")] pub fn sleep_ms(ms: u32) { sleep(Duration::from_millis(ms as u64)) } @@ -1004,7 +1004,11 @@ pub fn park() { /// /// See the [park documentation][`park`] for more detail. #[stable(feature = "rust1", since = "1.0.0")] -#[deprecated(since = "1.6.0", note = "replaced by `std::thread::park_timeout`")] +#[deprecated( + since = "1.6.0", + note = "replaced by `std::thread::park_timeout`", + suggestion = "park_timeout" +)] pub fn park_timeout_ms(ms: u32) { park_timeout(Duration::from_millis(ms as u64)) } diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed index 85e882870946b..659b546552229 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed @@ -6,4 +6,6 @@ fn main() { let _foo = str::trim_start(" aoeu"); //~ ERROR use of deprecated method `core::str::::trim_left`: superseded by `trim_start` [deprecated] let _bar = " aoeu".trim_start(); //~ ERROR use of deprecated method `core::str::::trim_left`: superseded by `trim_start` [deprecated] + + let _baz = ["a", "b"].join(" "); //~ ERROR use of deprecated method `std::slice::::connect`: renamed to join [deprecated] } diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs index 246de2f5e4bfe..cfc6c4450b4ab 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs @@ -6,4 +6,6 @@ fn main() { let _foo = str::trim_left(" aoeu"); //~ ERROR use of deprecated method `core::str::::trim_left`: superseded by `trim_start` [deprecated] let _bar = " aoeu".trim_left(); //~ ERROR use of deprecated method `core::str::::trim_left`: superseded by `trim_start` [deprecated] + + let _baz = ["a", "b"].connect(" "); //~ ERROR use of deprecated method `std::slice::::connect`: renamed to join [deprecated] } diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr index 3b518d1802bc8..d1f5ea3602a8f 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr @@ -25,5 +25,16 @@ help: replace the use of the deprecated method LL | let _bar = " aoeu".trim_start(); | ~~~~~~~~~~ -error: aborting due to 2 previous errors +error: use of deprecated method `std::slice::::connect`: renamed to join + --> $DIR/issue-84637-deprecated-associated-function.rs:10:27 + | +LL | let _baz = ["a", "b"].connect(" "); + | ^^^^^^^ + | +help: replace the use of the deprecated method + | +LL | let _baz = ["a", "b"].join(" "); + | ~~~~ + +error: aborting due to 3 previous errors From 98e434a01eafce54fc862fa36f44e0392a6fb9f7 Mon Sep 17 00:00:00 2001 From: Easyoakland <97992568+Easyoakland@users.noreply.github.com> Date: Mon, 7 Aug 2023 20:29:50 -0600 Subject: [PATCH 2/7] Increase clarity about Hash - Eq consistency in HashMap and HashSet docs --- library/std/src/collections/hash/map.rs | 6 ++++-- library/std/src/collections/hash/set.rs | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index a083b65604d4e..be173a7ace6d8 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -49,12 +49,14 @@ use crate::sys; /// ``` /// /// In other words, if two keys are equal, their hashes must be equal. +/// Violating this property is a logic error. /// -/// It is a logic error for a key to be modified in such a way that the key's +/// It is also a logic error for a key to be modified in such a way that the key's /// hash, as determined by the [`Hash`] trait, or its equality, as determined by /// the [`Eq`] trait, changes while it is in the map. This is normally only /// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code. -/// The behavior resulting from such a logic error is not specified, but will +/// +/// The behavior resulting from either logic error is not specified, but will /// be encapsulated to the `HashMap` that observed the logic error and not /// result in undefined behavior. This could include panics, incorrect results, /// aborts, memory leaks, and non-termination. diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 959403e164476..6d85b26af5fa2 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -24,13 +24,14 @@ use super::map::{map_try_reserve_error, RandomState}; /// ``` /// /// In other words, if two keys are equal, their hashes must be equal. +/// Violating this property is a logic error. /// -/// -/// It is a logic error for a key to be modified in such a way that the key's +/// It is also a logic error for a key to be modified in such a way that the key's /// hash, as determined by the [`Hash`] trait, or its equality, as determined by /// the [`Eq`] trait, changes while it is in the map. This is normally only /// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code. -/// The behavior resulting from such a logic error is not specified, but will +/// +/// The behavior resulting from either logic error is not specified, but will /// be encapsulated to the `HashSet` that observed the logic error and not /// result in undefined behavior. This could include panics, incorrect results, /// aborts, memory leaks, and non-termination. From e94ba4ae78bbca55b14967c05639a7bdf18bab26 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Fri, 18 Aug 2023 00:09:03 +0200 Subject: [PATCH 3/7] Inline strlen_rt in CStr::from_ptr This enables LLVM to optimize this function as if it was strlen without having to enable std-aware LTO. --- library/core/src/ffi/c_str.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 92e38df404980..163a65c909e45 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -253,7 +253,7 @@ impl CStr { /// ``` /// /// [valid]: core::ptr#safety - #[inline] + #[inline] // inline is necessary for codegen to see strlen. #[must_use] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")] @@ -280,6 +280,8 @@ impl CStr { len } + // `inline` is necessary for codegen to see strlen. + #[inline] fn strlen_rt(s: *const c_char) -> usize { extern "C" { /// Provided by libc or compiler_builtins. From 11716830ace2bb94a53a9003fcb8842df0c302bb Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 17 Aug 2023 15:15:09 +0200 Subject: [PATCH 4/7] instantiate response: no unnecessary new universe this previously was a off-by-one error. --- .../src/solve/eval_ctxt/canonical.rs | 2 +- .../generalize-proj-new-universe-index-1.rs | 73 ++++++++++++++++++ .../generalize-proj-new-universe-index-2.rs | 75 +++++++++++++++++++ ...eneralize-proj-new-universe-index-2.stderr | 9 +++ 4 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs create mode 100644 tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs create mode 100644 tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index 0990b9bee90f6..523841951b078 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -215,7 +215,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // created inside of the query directly instead of returning them to the // caller. let prev_universe = self.infcx.universe(); - let universes_created_in_query = response.max_universe.index() + 1; + let universes_created_in_query = response.max_universe.index(); for _ in 0..universes_created_in_query { self.infcx.create_next_universe(); } diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs new file mode 100644 index 0000000000000..b0b9b6bbd2063 --- /dev/null +++ b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-1.rs @@ -0,0 +1,73 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +// A minimization of an ambiguity when using typenum. See +// https://github.com/rust-lang/trait-system-refactor-initiative/issues/55 +// for more details. +trait Id { + type Assoc: ?Sized; +} +impl Id for T { + type Assoc = T; +} + +trait WithAssoc { + type Assoc: ?Sized; +} + + +struct Leaf; +struct Wrapper(U); + +impl WithAssoc for Leaf { + type Assoc = U; +} + +impl WithAssoc> for Wrapper
    +where + Ul: WithAssoc, +{ + type Assoc = <
      >::Assoc as Id>::Assoc; +} + +fn bound() +where + T: WithAssoc, +{ +} + +// normalize self type to `Wrapper` +// This succeeds, HOWEVER, instantiating the query response previously +// incremented the universe index counter. +// equate impl headers: +// as WithAssoc< as Id>::Assoc>> +// as WithAssoc>> +// ~> AliasRelate( as Id>::Assoc, Equate, Wrapper) +// add where bounds: +// ~> Leaf: WithAssoc +// equate with assoc type: +// ?0t +// >::Assoc as Id>::Assoc +// ~> AliasRelate( +// <>::Assoc as Id>::Assoc, +// Equate, +// <>::Assoc as Id>::Assoc, +// ) +// +// We do not reuse `?3t` during generalization because `?0t` cannot name `?4t` as we created +// it after incrementing the universe index while normalizing the self type. +// +// evaluate_added_goals_and_make_query_response: +// AliasRelate( as Id>::Assoc, Equate, Wrapper) +// YES, constrains ?3t to Leaf +// AliasRelate( +// <>::Assoc as Id>::Assoc, +// Equate, +// <>::Assoc as Id>::Assoc, +// ) +// +// Normalizing <>::Assoc as Id>::Assoc then *correctly* +// results in ambiguity. +fn main() { + bound::< as Id>::Assoc, as Id>::Assoc, _>() +} diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs new file mode 100644 index 0000000000000..544051fca4332 --- /dev/null +++ b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs @@ -0,0 +1,75 @@ +// compile-flags: -Ztrait-solver=next + +// Generalizing a projection containing an inference variable +// which cannot be named by the `root_vid` can result in ambiguity. +// +// Because we do not decrement the universe index when exiting a forall, +// this can cause unexpected failures. +// +// See generalize-proj-new-universe-index-1.rs for more details. + +// For this reproduction we need: +// - an inference variable with a lower universe +// - enter a binder to increment the current universe +// - create a new inference variable which is constrained by proving a goal +// - equate a projection containing the new variable with the first variable +// - generalization creates yet another inference variable which is then +// part of an alias-relate, resulting this to fail with ambiguity. +// +// Because we need to enter the binder in-between the creation of the first +// and second inference variable, this is easiest via +// `assemble_candidates_after_normalizing_self_ty` because eagerly call +// `try_evaluate_added_goals` there before creating the inference variables +// for the impl parameters. +trait Id { + type Assoc: ?Sized; +} +impl Id for T { + type Assoc = T; +} + +// By adding an higher ranked bound to the impl we currently +// propagate this bound to the caller, forcing us to create a new +// universe. +trait IdHigherRankedBound { + type Assoc: ?Sized; +} + +impl IdHigherRankedBound for T +where + for<'a> T: 'a, +{ + type Assoc = T; +} + +trait WithAssoc { + type Assoc: ?Sized; +} + + +struct Leaf; +struct Wrapper(U); +struct Rigid; + +impl WithAssoc for Leaf { + type Assoc = U; +} + + +impl WithAssoc> for Rigid +where + Leaf: WithAssoc, +{ + type Assoc = <>::Assoc as Id>::Assoc; +} + +fn bound() +where + T: WithAssoc, +{ +} + +fn main() { + bound::<::Assoc, as Id>::Assoc, _>() + //~^ ERROR type annotations needed +} diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr new file mode 100644 index 0000000000000..3fe96c8688804 --- /dev/null +++ b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/generalize-proj-new-universe-index-2.rs:72:5 + | +LL | bound::<::Assoc, as Id>::Assoc, _>() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. From ee04744e6411368e9cf3460bde8396999778a6f8 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 18 Aug 2023 23:59:49 +0200 Subject: [PATCH 5/7] change to known bug --- .../generalize/generalize-proj-new-universe-index-2.rs | 2 +- .../generalize/generalize-proj-new-universe-index-2.stderr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs index 544051fca4332..94d645a98592c 100644 --- a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs +++ b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.rs @@ -1,4 +1,5 @@ // compile-flags: -Ztrait-solver=next +// known-bug: trait-system-refactor-initiative#60 // Generalizing a projection containing an inference variable // which cannot be named by the `root_vid` can result in ambiguity. @@ -71,5 +72,4 @@ where fn main() { bound::<::Assoc, as Id>::Assoc, _>() - //~^ ERROR type annotations needed } diff --git a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr index 3fe96c8688804..9a8060133b819 100644 --- a/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr +++ b/tests/ui/traits/new-solver/generalize/generalize-proj-new-universe-index-2.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/generalize-proj-new-universe-index-2.rs:72:5 + --> $DIR/generalize-proj-new-universe-index-2.rs:74:5 | LL | bound::<::Assoc, as Id>::Assoc, _>() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound` From 4504cc513fb794116d0d2b9b73a40658a2f472cc Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 19 Aug 2023 14:32:15 +0800 Subject: [PATCH 6/7] Usage zero as language id for FormatMessageW() --- library/std/src/sys/windows/os.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/windows/os.rs b/library/std/src/sys/windows/os.rs index 2329426ad1df2..58afca088ef9a 100644 --- a/library/std/src/sys/windows/os.rs +++ b/library/std/src/sys/windows/os.rs @@ -25,10 +25,6 @@ pub fn errno() -> i32 { /// Gets a detailed string description for the given error number. pub fn error_string(mut errnum: i32) -> String { - // This value is calculated from the macro - // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT) - let langId = 0x0800 as c::DWORD; - let mut buf = [0 as c::WCHAR; 2048]; unsafe { @@ -56,13 +52,13 @@ pub fn error_string(mut errnum: i32) -> String { flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS, module, errnum as c::DWORD, - langId, + 0, buf.as_mut_ptr(), buf.len() as c::DWORD, ptr::null(), ) as usize; if res == 0 { - // Sometimes FormatMessageW can fail e.g., system doesn't like langId, + // Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId, let fm_err = errno(); return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})"); } From 07ff87bf735e8e811e5cb5aed13424d4a7bc7d0f Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sat, 19 Aug 2023 08:46:37 +0100 Subject: [PATCH 7/7] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 7c3904d6c3ed5..80eca0e58fb2f 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 7c3904d6c3ed54e8a413023519b55a536ad44d5b +Subproject commit 80eca0e58fb2ff52c1e94fc191b55b37ed73e0e4