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

When using process::Command on Windows, environment variable names must be case-preserving but case-insensitive #85270

Merged
merged 2 commits into from
Jul 4, 2021

Conversation

ChrisDenton
Copy link
Member

When using Command to set the environment variables, the key should be compared as uppercase Unicode but when set it should preserve the original case.

Fixes #85242

@rust-highfive
Copy link
Collaborator

r? @Mark-Simulacrum

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 13, 2021
@ChrisDenton
Copy link
Member Author

I've moved the test to the right place. Sorry about that.

@ChrisDenton ChrisDenton changed the title Windows enviroment variables on process::Comamnd should be case-preserving but comparing must be case-sensitive Windows enviroment variables on process::Comamnd should be case-preserving but comparing must be case-insensitive May 13, 2021
@rust-log-analyzer

This comment has been minimized.

@ChrisDenton ChrisDenton changed the title Windows enviroment variables on process::Comamnd should be case-preserving but comparing must be case-insensitive When using process::Command on Windows, environment variable names must be case-preserving but case-insensitive May 14, 2021
fn iter_uppercase<T: Iterator<Item = u16>>(iter: T) -> impl Iterator<Item = u32> {
char::decode_utf16(iter).flat_map(|cp| match cp {
Err(e) => CodeUnits::Unit(Some(e.unpaired_surrogate())),
Ok(cp) => CodeUnits::Iter(cp.to_uppercase()),
Copy link
Contributor

@CDirkx CDirkx May 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked and to_uppercase is not always correct: 'ß'.to_uppercase() == "SS", but the following fails

set_var("ß", "something");
var("SS").unwrap() // panic: Err<NotPresent>

I can't find anything about in official documentation, but from tests I did I suspect Windows uses simple case folding (for context see Unicode Technical Report #21 Case Mappings Section 1.3, simple case folding is the unicode case folding algorithm, but restricted to code points that don't expand under upper/lower casing like ß). I also checked if any normalization or locale-dependent behavior was happening, but that doesn't appear to be the case: é and (e + acute accent combining character) are different keys and nothing changed around i/I on the Turkish locale (https://en.wikipedia.org/wiki/Dotted_and_dotless_I).

Not sure what the best way to use case folding in std would be (if that is even what Windows is indeed using). There are crates like unicode-rs/rust-caseless implementing case folding, but I couldn't find any that also implements the simple variant.

Edit: Windows does not use Unicode case folding, but instead has a different uppercase implementation: see the comment below.
Edit2: It does appear to be based on reverse unicode folding, but with some unique particularities, see https://github.com/ChrisDenton/Windows-case

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm yeah, that is a problem. I think the only way to resolve this properly is to use the OS's own function for this. So in the next commit I've replaced my implementation with a Windows API call and expanded the testing slightly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked through the docs some more:

File paths and environment variables should be compared using StringComparison.OrdinalIgnoreCase [1]. Comparisons made using OrdinalIgnoreCase are behaviorally the composition of two calls: calling ToUpperInvariant on both string arguments, and doing a comparison using Ordinal [2]. A comparison using Ordinal is just a comparison based on the numerical value of each utf16 code unit [3].

So the original approach was conceptually correct, but Windows apparently handles converting to uppercase differently than rust (I haven't yet found anywhere how ToUpperInvariant is actually implemented 🙁). I agree with the approach to instead just use the Windows API.

(As an aside, with the relevant Windows API added a future possibility for std would be to expose case insensitive functionality with a std::os extension trait, for example for correctly comparing paths case insensitively.)

[1] https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#choosing-a-stringcomparison-member-for-your-method-call
[2] https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings#stringtoupper-and-stringtolower
[3] https://docs.microsoft.com/en-us/dotnet/api/system.stringcomparison?view=net-5.0#System_StringComparison_Ordinal

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add this conclusion, why CompareStringOrdinal is used, in a comment in the code?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-ou-se I've added a comment (based on CDirkx's) to briefly explain how comparing environment keys works and thus why CompareStringOrdinal is used.

@Mark-Simulacrum
Copy link
Member

@rustbot ping windows

It sounds like there's some differences between Rust's case-conversion and the one used by Windows - see this comment #85270 (comment) -- I'm wondering if some windows folks can weigh in on the right thing for us to do here for comparison.

I think it sounds like @ChrisDenton this PR is actually solving two different problems right now, right? We're currently exposing the case-converted (i.e., to_ascii_uppercase) environment variable names through std's APIs, which is loosely the decoupling intended by the first commit here. Then, the second question is whether to_ascii_uppercase is actually the right function to call (sounds like no), and what that function should be.

@rustbot
Copy link
Collaborator

rustbot commented May 14, 2021

Hey Windows Group! This bug has been identified as a good "Windows candidate".
In case it's useful, here are some instructions for tackling these sorts of
bugs. Maybe take a look?
Thanks! <3

cc @arlosi @danielframpton @gdr-at-ms @kennykerr @luqmana @lzybkr @nico-abram @retep998 @rylev @sivadeilra @wesleywiser

@rustbot rustbot added the O-windows Operating system: Windows label May 14, 2021
@ChrisDenton
Copy link
Member Author

ChrisDenton commented May 15, 2021

To sum up where we are at now, there were two problems with the original code, before this PR:

  1. It ASCII uppercased environment variable keys. It should have left them as-is.
  2. The uppercasing was (possibly) done so that looking up environment variables by key would be case-insensitive. The problem with this is that Windows uses a variant of Unicode casing rules to do key comparisons, not just ASCII uppercasing.

My first attempt to fix this was to remove the original uppercasing and use Rust's Unicode functions to compare (and only to compare) the strings. As CDirkx has shown, this was wrong because Windows uses what it calls "ordinal" comparisons in this context. This ordinal comparison is documented as testing for "binary equality, not linguistic equality" though I'm a bit fuzzy on what that means for casing.

So now I'm using the Windows API function CompareStringOrdinal to do the comparison, which appears to do what the OS expects.

@ChrisDenton
Copy link
Member Author

Ok so I investigated this further and I'm now even more confident that using the system APIs is the right one. Elsewhere I have figured out the case-folding algorithm for my system, but it's odd and can vary a bit depending on the OS version. Therefore asking the OS to compare strings is, I think, the best approach.

@CDirkx should I squish my commits to make my changes clearer?

@CDirkx
Copy link
Contributor

CDirkx commented May 19, 2021

I was going to comment that this behavior should be documented somewhere on the process::Command docs, but it already is:

Note that environment variable names are case-insensitive (but case-preserving) on Windows, and case-sensitive on all other platforms.

(https://doc.rust-lang.org/std/process/struct.Command.html#method.env)

@CDirkx
Copy link
Contributor

CDirkx commented May 19, 2021

PR looks good to me, @ChrisDenton could you squash the commits?

@CDirkx
Copy link
Contributor

CDirkx commented May 19, 2021

@Mark-Simulacrum this looks ready for review (although I'm not from the Windows group). This PR addresses two problems:

  • Env keys on Windows are case-insensitive, but case-preserving. The original implementation stored the make_ascii_uppercased key, making the derived Ord implementation effectively case-insensitive (although not completely correct, see the second point), but not preserving case. This PR stores the key as given, instead adding a manual case-insensitive Ord implementation, thus preserving case.
  • The way keys are compared is changed because just uppercasing and comparing is not sufficient, Windows has complex case-folding rules, based on an older version of Unicode case folding, but with additional custom mappings. Instead of re-implementing this functionality in std and possibly getting it wrong, the Windows API CompareStringOrdinal with bIgnoreCase = TRUE is used. This does have some costs however, OsString is a Vec<u8> and Windows API calls expect *const u16. To avoid having to convert (which requires an allocation) every time the BTreeMap might compare keys, both the original OsString and the converted UTF16-encoded Vec<u16> are stored in the key, resulting in a bit more memory use. I don't expect this to be an issue however.

So in conclusion, this PR makes sure that the code actually matches what is already in the documentation, implementing case-preserving and correct case-insensitivity:

Note that environment variable names are case-insensitive (but case-preserving) on Windows, and case-sensitive on all other platforms.

(https://doc.rust-lang.org/std/process/struct.Command.html#method.env)

@Mark-Simulacrum
Copy link
Member

r=me on the implementation. This is technically going to break any user expecting the to_uppercase behavior on Windows, right? e.g., previously env("Cargo_incremental", "1") would set CARGO_INCREMENTAL, but now won't. Seems like an unlikely situation but we'll likely want to FCP and relnotes if we land this.

@Mark-Simulacrum Mark-Simulacrum added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label May 26, 2021
@CDirkx
Copy link
Contributor

CDirkx commented May 26, 2021

I don't think there would really be such an expectation. The docs already stated that on Windows env vars are case-preserving and in general that is what Windows users would expect. I would consider the current implementation a bug, as the to_uppercase doesn't preserve case and thus does not match the documentation.

There is however indeed the small change of breaking changes; the OS will handle "CARGO_INCREMENTAL" and "Cargo_incremental" the same but applications might not.

@Mark-Simulacrum
Copy link
Member

I agree that the current implementation is a bug. That doesn't necessarily mean we can 'just' break things for users regardless, though. @rust-lang/libs, would someone care to weigh in here? I don't know if an FCP is in order, but as this is technically a breaking change it seems potentially appropriate.

@Mark-Simulacrum Mark-Simulacrum removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 26, 2021
@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jun 26, 2021
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Jul 1, 2021
@ChrisDenton
Copy link
Member Author

ChrisDenton commented Jul 2, 2021

Ok, the failure is being addressed here: rust-lang/cargo#9646

If I'm understanding right the problem was that cargo:

  1. It always spawns itself
  2. In doing so it sets an environment variable, using env, which caused Rust to upper case all environment variables
  3. It had Windows specific tests that assumed lower cased environment variables would always be converted to upper case (which was previously true for cargo itself because of 1 and 2).

If this PR goes ahead I think the release notes should emphasize that, on Windows, using env with Command would previously cause all environment variables to be ASCII-uppercased.

bors added a commit to rust-lang/cargo that referenced this pull request Jul 2, 2021
Temporarily disable windows env test.

This temporarily disables the `target_in_environment_contains_lower_case` test on Windows until rust-lang/rust#85270 gets into nightly.  That PR changes it so that env vars are case-preserved on Windows.  My intent is that after that is in nightly, we can remove the windows-specific code in `Config`, and this test should work the same on all platforms.

Closes #9630
@ehuss
Copy link
Contributor

ehuss commented Jul 3, 2021

@bors r=m-ou-se

@bors

This comment has been minimized.

@bors
Copy link
Contributor

bors commented Jul 3, 2021

📌 Commit a200c01 has been approved by m-ou-se

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 3, 2021
@bors
Copy link
Contributor

bors commented Jul 4, 2021

⌛ Testing commit a200c01 with merge 1540711...

@bors
Copy link
Contributor

bors commented Jul 4, 2021

☀️ Test successful - checks-actions
Approved by: m-ou-se
Pushing 1540711 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jul 4, 2021
@bors bors merged commit 1540711 into rust-lang:master Jul 4, 2021
@rustbot rustbot added this to the 1.55.0 milestone Jul 4, 2021
@ChrisDenton ChrisDenton deleted the win-env-case branch July 8, 2021 11:44
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Nov 20, 2021
Pkgsrc changes:
 * Bump bootstrap kit version to 1.55.0.
 * Adjust patches as needed, some no longer apply (so removed)
 * Update checksum adjustments.
 * Avoid rust-llvm on SunOS
 * Optionally build docs
 * Remove reference to closed/old PR#54621

Upstream changes:

Version 1.56.1 (2021-11-01)
===========================

- New lints to detect the presence of bidirectional-override Unicode
  codepoints in the compiled source code ([CVE-2021-42574])

[CVE-2021-42574]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42574

Version 1.56.0 (2021-10-21)
========================

Language
--------

- [The 2021 Edition is now stable.][rust#88100]
  See [the edition guide][rust-2021-edition-guide] for more details.
- [The pattern in `binding @ pattern` can now also introduce new bindings.]
  [rust#85305]
- [Union field access is permitted in `const fn`.][rust#85769]

[rust-2021-edition-guide]:
  https://doc.rust-lang.org/nightly/edition-guide/rust-2021/index.html

Compiler
--------

- [Upgrade to LLVM 13.][rust#87570]
- [Support memory, address, and thread sanitizers on aarch64-unknown-freebsd.]
  [rust#88023]
- [Allow specifying a deployment target version for all iOS targets][rust#87699]
- [Warnings can be forced on with `--force-warn`.][rust#87472]
  This feature is primarily intended for usage by `cargo fix`, rather than
  end users.
- [Promote `aarch64-apple-ios-sim` to Tier 2\*.][rust#87760]
- [Add `powerpc-unknown-freebsd` at Tier 3\*.][rust#87370]
- [Add `riscv32imc-esp-espidf` at Tier 3\*.][rust#87666]

\* Refer to Rust's [platform support page][platform-support-doc] for more
information on Rust's tiered platform support.

Libraries
---------

- [Allow writing of incomplete UTF-8 sequences via stdout/stderr on Windows.]
  [rust#83342]
  The Windows console still requires valid Unicode, but this change allows
  splitting a UTF-8 character across multiple write calls. This allows, for
  instance, programs that just read and write data buffers (e.g. copying a file
  to stdout) without regard for Unicode or character boundaries.
- [Prefer `AtomicU{64,128}` over Mutex for Instant backsliding protection.]
  [rust#83093]
  For this use case, atomics scale much better under contention.
- [Implement `Extend<(A, B)>` for `(Extend<A>, Extend<B>)`][rust#85835]
- [impl Default, Copy, Clone for std::io::Sink and std::io::Empty][rust#86744]
- [`impl From<[(K, V); N]>` for all collections.][rust#84111]
- [Remove `P: Unpin` bound on impl Future for Pin.][rust#81363]
- [Treat invalid environment variable names as non-existent.][rust#86183]
  Previously, the environment functions would panic if given a
  variable name with an internal null character or equal sign (`=`).
  Now, these functions will just treat such names as non-existent
  variables, since the OS cannot represent the existence of a
  variable with such a name.

Stabilised APIs
---------------

- [`std::os::unix::fs::chroot`]
- [`UnsafeCell::raw_get`]
- [`BufWriter::into_parts`]
- [`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]
  These APIs were previously stable in `std`, but are now also available
  in `core`.
- [`Vec::shrink_to`]
- [`String::shrink_to`]
- [`OsString::shrink_to`]
- [`PathBuf::shrink_to`]
- [`BinaryHeap::shrink_to`]
- [`VecDeque::shrink_to`]
- [`HashMap::shrink_to`]
- [`HashSet::shrink_to`]

These APIs are now usable in const contexts:

- [`std::mem::transmute`]
- [`[T]::first`][`slice::first`]
- [`[T]::split_first`][`slice::split_first`]
- [`[T]::last`][`slice::last`]
- [`[T]::split_last`][`slice::split_last`]

Cargo
-----

- [Cargo supports specifying a minimum supported Rust version in Cargo.toml.]
  [`rust-version`]
  This has no effect at present on dependency version selection.
  We encourage crates to specify their minimum supported Rust
  version, and we encourage CI systems that support Rust code to
  include a crate's specified minimum version in the text matrix
  for that crate by default.

Compatibility notes
-------------------

- [Update to new argument parsing rules on Windows.][rust#87580]
  This adjusts Rust's standard library to match the behavior of the standard
  libraries for C/C++. The rules have changed slightly over time, and this PR
  brings us to the latest set of rules (changed in 2008).
- [Disallow the aapcs calling convention on aarch64][rust#88399]
  This was already not supported by LLVM; this change surfaces this lack of
  support with a better error message.
- [Make `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` warn by default][rust#87385]
- [Warn when an escaped newline skips multiple lines.][rust#87671]
- [Calls to `libc::getpid` / `std::process::id` from `Command::pre_exec`
  may return different values on glibc <= 2.24.][rust#81825]
  Rust now invokes the `clone3` system call directly, when available,
  to use new functionality available via that system call. Older
  versions of glibc cache the result of `getpid`, and only update
  that cache when calling glibc's clone/fork functions, so a direct
  system call bypasses that cache update. glibc 2.25 and newer no
  longer cache `getpid` for exactly this reason.

Internal changes
----------------
These changes provide no direct user facing benefits, but represent
significant improvements to the internals and overall performance
of rustc and related tools.

- [LLVM is compiled with PGO in published x86_64-unknown-linux-gnu artifacts.]
  [rust#88069]
  This improves the performance of most Rust builds.
- [Unify representation of macros in internal data structures.][rust#88019]
  This change fixes a host of bugs with the handling of macros by the compiler,
  as well as rustdoc.

[`std::os::unix::fs::chroot`]: https://doc.rust-lang.org/stable/std/os/unix/fs/fn.chroot.html
[`Iterator::intersperse`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
[`Iterator::intersperse_with`]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.intersperse
[`UnsafeCell::raw_get`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.raw_get
[`BufWriter::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.BufWriter.html#method.into_parts
[`core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}`]: rust-lang/rust#84662
[`Vec::shrink_to`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.shrink_to
[`String::shrink_to`]: https://doc.rust-lang.org/stable/std/string/struct.String.html#method.shrink_to
[`OsString::shrink_to`]: https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html#method.shrink_to
[`PathBuf::shrink_to`]: https://doc.rust-lang.org/stable/std/path/struct.PathBuf.html#method.shrink_to
[`BinaryHeap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.BinaryHeap.html#method.shrink_to
[`VecDeque::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.shrink_to
[`HashMap::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.HashMap.html#method.shrink_to
[`HashSet::shrink_to`]: https://doc.rust-lang.org/stable/std/collections/hash_set/struct.HashSet.html#method.shrink_to
[`std::mem::transmute`]: https://doc.rust-lang.org/stable/std/mem/fn.transmute.html
[`slice::first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.first
[`slice::split_first`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_first
[`slice::last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.last
[`slice::split_last`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.split_last
[`rust-version`]: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field
[rust#87671]: rust-lang/rust#87671
[rust#86183]: rust-lang/rust#86183
[rust#87385]: rust-lang/rust#87385
[rust#88100]: rust-lang/rust#88100
[rust#86860]: rust-lang/rust#86860
[rust#84039]: rust-lang/rust#84039
[rust#86492]: rust-lang/rust#86492
[rust#88363]: rust-lang/rust#88363
[rust#85305]: rust-lang/rust#85305
[rust#87832]: rust-lang/rust#87832
[rust#88069]: rust-lang/rust#88069
[rust#87472]: rust-lang/rust#87472
[rust#87699]: rust-lang/rust#87699
[rust#87570]: rust-lang/rust#87570
[rust#88023]: rust-lang/rust#88023
[rust#87760]: rust-lang/rust#87760
[rust#87370]: rust-lang/rust#87370
[rust#87580]: rust-lang/rust#87580
[rust#83342]: rust-lang/rust#83342
[rust#83093]: rust-lang/rust#83093
[rust#88177]: rust-lang/rust#88177
[rust#88548]: rust-lang/rust#88548
[rust#88551]: rust-lang/rust#88551
[rust#88299]: rust-lang/rust#88299
[rust#88220]: rust-lang/rust#88220
[rust#85835]: rust-lang/rust#85835
[rust#86879]: rust-lang/rust#86879
[rust#86744]: rust-lang/rust#86744
[rust#84662]: rust-lang/rust#84662
[rust#86593]: rust-lang/rust#86593
[rust#81050]: rust-lang/rust#81050
[rust#81363]: rust-lang/rust#81363
[rust#84111]: rust-lang/rust#84111
[rust#85769]: rust-lang/rust#85769 (comment)
[rust#88490]: rust-lang/rust#88490
[rust#88269]: rust-lang/rust#88269
[rust#84176]: rust-lang/rust#84176
[rust#88399]: rust-lang/rust#88399
[rust#88227]: rust-lang/rust#88227
[rust#88200]: rust-lang/rust#88200
[rust#82776]: rust-lang/rust#82776
[rust#88077]: rust-lang/rust#88077
[rust#87728]: rust-lang/rust#87728
[rust#87050]: rust-lang/rust#87050
[rust#87619]: rust-lang/rust#87619
[rust#81825]: rust-lang/rust#81825 (comment)
[rust#88019]: rust-lang/rust#88019
[rust#87666]: rust-lang/rust#87666

Version 1.55.0 (2021-09-09)
============================

Language
--------
- [You can now write open "from" range patterns (`X..`), which will start
  at `X` and will end at the maximum value of the integer.][83918]
- [You can now explicitly import the prelude of different editions
  through `std::prelude` (e.g. `use std::prelude::rust_2021::*;`).][86294]

Compiler
--------
- [Added tier 3\* support for `powerpc64le-unknown-freebsd`.][83572]

\* Refer to Rust's [platform support page][platform-support-doc] for more
   information on Rust's tiered platform support.

Libraries
---------

- [Updated std's float parsing to use the Eisel-Lemire algorithm.][86761]
  These improvements should in general provide faster string parsing of floats,
  no longer reject certain valid floating point values, and reduce
  the produced code size for non-stripped artifacts.
- [`string::Drain` now implements `AsRef<str>` and `AsRef<[u8]>`.][86858]

Stabilised APIs
---------------

- [`Bound::cloned`]
- [`Drain::as_str`]
- [`IntoInnerError::into_error`]
- [`IntoInnerError::into_parts`]
- [`MaybeUninit::assume_init_mut`]
- [`MaybeUninit::assume_init_ref`]
- [`MaybeUninit::write`]
- [`array::map`]
- [`ops::ControlFlow`]
- [`x86::_bittest`]
- [`x86::_bittestandcomplement`]
- [`x86::_bittestandreset`]
- [`x86::_bittestandset`]
- [`x86_64::_bittest64`]
- [`x86_64::_bittestandcomplement64`]
- [`x86_64::_bittestandreset64`]
- [`x86_64::_bittestandset64`]

The following previously stable functions are now `const`.

- [`str::from_utf8_unchecked`]


Cargo
-----
- [Cargo will now deduplicate compiler diagnostics to the terminal when invoking
  rustc in parallel such as when using `cargo test`.][cargo/9675]
- [The package definition in `cargo metadata` now includes the `"default_run"`
  field from the manifest.][cargo/9550]
- [Added `cargo d` as an alias for `cargo doc`.][cargo/9680]
- [Added `{lib}` as formatting option for `cargo tree` to print the `"lib_name"`
  of packages.][cargo/9663]

Rustdoc
-------
- [Added "Go to item on exact match" search option.][85876]
- [The "Implementors" section on traits no longer shows redundant
  method definitions.][85970]
- [Trait implementations are toggled open by default.][86260] This should
  make the implementations more searchable by tools like `CTRL+F` in
  your browser.
- [Intra-doc links should now correctly resolve associated items (e.g. methods)
  through type aliases.][86334]
- [Traits which are marked with `#[doc(hidden)]` will no longer appear in the
  "Trait Implementations" section.][86513]


Compatibility Notes
-------------------
- [std functions that return an `io::Error` will no longer use the
  `ErrorKind::Other` variant.][85746] This is to better reflect that these
  kinds of errors could be categorised [into newer more specific `ErrorKind`
  variants][79965], and that they do not represent a user error.
- [Using environment variable names with `process::Command` on Windows now
  behaves as expected.][85270] Previously using envionment variables with
  `Command` would cause them to be ASCII-uppercased.
- [Rustdoc will now warn on using rustdoc lints that aren't prefixed
  with `rustdoc::`][86849]

[86849]: rust-lang/rust#86849
[86513]: rust-lang/rust#86513
[86334]: rust-lang/rust#86334
[86260]: rust-lang/rust#86260
[85970]: rust-lang/rust#85970
[85876]: rust-lang/rust#85876
[83572]: rust-lang/rust#83572
[86294]: rust-lang/rust#86294
[86858]: rust-lang/rust#86858
[86761]: rust-lang/rust#86761
[85769]: rust-lang/rust#85769
[85746]: rust-lang/rust#85746
[85305]: rust-lang/rust#85305
[85270]: rust-lang/rust#85270
[84111]: rust-lang/rust#84111
[83918]: rust-lang/rust#83918
[79965]: rust-lang/rust#79965
[87370]: rust-lang/rust#87370
[87298]: rust-lang/rust#87298
[cargo/9663]: rust-lang/cargo#9663
[cargo/9675]: rust-lang/cargo#9675
[cargo/9550]: rust-lang/cargo#9550
[cargo/9680]: rust-lang/cargo#9680
[cargo/9663]: rust-lang/cargo#9663
[`array::map`]: https://doc.rust-lang.org/stable/std/primitive.array.html#method.map
[`Bound::cloned`]: https://doc.rust-lang.org/stable/std/ops/enum.Bound.html#method.cloned
[`Drain::as_str`]: https://doc.rust-lang.org/stable/std/string/struct.Drain.html#method.as_str
[`IntoInnerError::into_error`]: https://doc.rust-lang.org/stable/std/io/struct.IntoInnerError.html#method.into_error
[`IntoInnerError::into_parts`]: https://doc.rust-lang.org/stable/std/io/struct.IntoInnerError.html#method.into_parts
[`MaybeUninit::assume_init_mut`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_mut
[`MaybeUninit::assume_init_ref`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.assume_init_ref
[`MaybeUninit::write`]: https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.write
[`Seek::rewind`]: https://doc.rust-lang.org/stable/std/io/trait.Seek.html#method.rewind
[`ops::ControlFlow`]: https://doc.rust-lang.org/stable/std/ops/enum.ControlFlow.html
[`str::from_utf8_unchecked`]: https://doc.rust-lang.org/stable/std/str/fn.from_utf8_unchecked.html
[`x86::_bittest`]: https://doc.rust-lang.org/stable/core/arch/x86/fn._bittest.html
[`x86::_bittestandcomplement`]: https://doc.rust-lang.org/stable/core/arch/x86/fn._bittestandcomplement.html
[`x86::_bittestandreset`]: https://doc.rust-lang.org/stable/core/arch/x86/fn._bittestandreset.html
[`x86::_bittestandset`]: https://doc.rust-lang.org/stable/core/arch/x86/fn._bittestandset.html
[`x86_64::_bittest64`]: https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bittest64.html
[`x86_64::_bittestandcomplement64`]: https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bittestandcomplement64.html
[`x86_64::_bittestandreset64`]: https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bittestandreset64.html
[`x86_64::_bittestandset64`]: https://doc.rust-lang.org/stable/core/arch/x86_64/fn._bittestandset64.html
bors added a commit to rust-lang/cargo that referenced this pull request Jan 14, 2023
Enable source_config_env test on Windows

This enables the `advaned_env::source_config_env` test on Windows. The issue with `Command` modifying the case of environment variables was fixed by rust-lang/rust#85270.
seritools added a commit to rust9x/rust that referenced this pull request Dec 29, 2023
mbilker pushed a commit to mbilker/rust that referenced this pull request Jul 17, 2024
seritools added a commit to rust9x/rust that referenced this pull request Nov 29, 2024
seritools added a commit to rust9x/rust that referenced this pull request Dec 1, 2024
seritools added a commit to rust9x/rust that referenced this pull request Dec 1, 2024
seritools added a commit to rust9x/rust that referenced this pull request Dec 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. merged-by-bors This PR was explicitly merged by bors. O-windows Operating system: Windows relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Windows std::env::vars() uppercases environment variables