diff --git a/compiler/rustc_middle/src/dep_graph/graph.rs b/compiler/rustc_middle/src/dep_graph/graph.rs index 2ce01ab4c6650..0d515ed82bc89 100644 --- a/compiler/rustc_middle/src/dep_graph/graph.rs +++ b/compiler/rustc_middle/src/dep_graph/graph.rs @@ -826,7 +826,13 @@ impl DepGraph { where F: FnOnce() -> String, { - let dep_node_debug = &self.data.as_ref().unwrap().dep_node_debug; + // Early queries (e.g., `-Z query-dep-graph` on empty crates) can reach here + // before the graph is initialized. Return early to prevent an ICE. + let data = match &self.data { + Some(d) => d, + None => return, + }; + let dep_node_debug = &data.dep_node_debug; if dep_node_debug.borrow().contains_key(&dep_node) { return; diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index e3fc9bfee49c4..994f7d17c5c41 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -136,19 +136,24 @@ impl<'tcx> Value<'tcx> { ty::Ref(_, inner_ty, _) => match inner_ty.kind() { // `&str` can be interpreted as raw bytes ty::Str => {} - // `&[u8]` can be interpreted as raw bytes - ty::Slice(slice_ty) if *slice_ty == tcx.types.u8 => {} + // `&[T]` can be interpreted as raw bytes if elements are `u8` + ty::Slice(_) => {} // other `&_` can't be interpreted as raw bytes _ => return None, }, - // `[u8; N]` can be interpreted as raw bytes - ty::Array(array_ty, _) if *array_ty == tcx.types.u8 => {} + // `[T; N]` can be interpreted as raw bytes if elements are `u8` + ty::Array(_, _) => {} // Otherwise, type cannot be interpreted as raw bytes _ => return None, } // We create an iterator that yields `Option` - let iterator = self.to_branch().into_iter().map(|ct| Some(ct.try_to_leaf()?.to_u8())); + let iterator = self.to_branch().into_iter().map(|ct| { + (*ct) + .try_to_value() + .and_then(|value| (value.ty == tcx.types.u8).then_some(value)) + .and_then(|value| value.try_to_leaf().map(|leaf| leaf.to_u8())) + }); // If there is `None` in the iterator, then the array is not a valid array of u8s and we return `None` let bytes: Vec = iterator.collect::>>()?; diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs index 03650615e25a6..40d61de50aaf2 100644 --- a/library/core/src/convert/num.rs +++ b/library/core/src/convert/num.rs @@ -198,11 +198,11 @@ macro_rules! impl_float_from_bool { /// # Examples /// ``` $($(#[doc = $doctest_prefix])*)? - #[doc = concat!("let x: ", stringify!($float)," = false.into();")] + #[doc = concat!("let x = ", stringify!($float), "::from(false);")] /// assert_eq!(x, 0.0); /// assert!(x.is_sign_positive()); /// - #[doc = concat!("let y: ", stringify!($float)," = true.into();")] + #[doc = concat!("let y = ", stringify!($float), "::from(true);")] /// assert_eq!(y, 1.0); $($(#[doc = $doctest_suffix])*)? /// ``` @@ -343,11 +343,11 @@ macro_rules! impl_try_from_integer_for_bool { /// # Examples /// /// ``` - #[doc = concat!("assert_eq!(0_", stringify!($int), ".try_into(), Ok(false));")] + #[doc = concat!("assert_eq!(bool::try_from(0_", stringify!($int), "), Ok(false));")] /// - #[doc = concat!("assert_eq!(1_", stringify!($int), ".try_into(), Ok(true));")] + #[doc = concat!("assert_eq!(bool::try_from(1_", stringify!($int), "), Ok(true));")] /// - #[doc = concat!("assert!(<", stringify!($int), " as TryInto>::try_into(2).is_err());")] + #[doc = concat!("assert!(bool::try_from(2_", stringify!($int), ").is_err());")] /// ``` #[inline] fn try_from(i: $int) -> Result { diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 98b21781e0915..edf0127a665e3 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -670,6 +670,17 @@ pub fn home_dir() -> Option { /// /// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] / /// [`GetTempPath`][GetTempPath], which this function uses internally. +/// Specifically, for non-SYSTEM processes, the function checks for the +/// following environment variables in order and returns the first path found: +/// +/// 1. The path specified by the `TMP` environment variable. +/// 2. The path specified by the `TEMP` environment variable. +/// 3. The path specified by the `USERPROFILE` environment variable. +/// 4. The Windows directory. +/// +/// When called from a process running as SYSTEM, +/// [`GetTempPath2`][GetTempPath2] returns `C:\Windows\SystemTemp` +/// regardless of environment variables. /// /// Note that, this [may change in the future][changes]. /// diff --git a/library/std/src/random.rs b/library/std/src/random.rs index 3994c5cfaf6f4..a18dcf98ec7fc 100644 --- a/library/std/src/random.rs +++ b/library/std/src/random.rs @@ -37,7 +37,7 @@ use crate::sys::random as sys; /// Horizon, Cygwin | `getrandom` /// AIX, Hurd, L4Re, QNX | `/dev/urandom` /// Redox | `/scheme/rand` -/// RTEMS | [`arc4random_buf`](https://docs.rtems.org/branches/master/bsp-howto/getentropy.html) +/// RTEMS | [`arc4random_buf`](https://docs.rtems.org/branches/main/bsp-howto/getentropy.html) /// SGX | [`rdrand`](https://en.wikipedia.org/wiki/RDRAND) /// SOLID | `SOLID_RNG_SampleRandomBytes` /// TEEOS | `TEE_GenerateRandom` diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs index 7d54bc9aff131..533810387d770 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/pal/uefi/os.rs @@ -2,7 +2,6 @@ use r_efi::efi::protocols::{device_path, loaded_image_device_path}; use super::{helpers, unsupported_err}; use crate::ffi::{OsStr, OsString}; -use crate::marker::PhantomData; use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; use crate::path::{self, PathBuf}; use crate::{fmt, io}; @@ -38,16 +37,37 @@ pub fn chdir(p: &path::Path) -> io::Result<()> { if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } -pub struct SplitPaths<'a>(!, PhantomData<&'a ()>); +pub struct SplitPaths<'a> { + data: crate::os::uefi::ffi::EncodeWide<'a>, + must_yield: bool, +} -pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> { - panic!("unsupported") +pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> { + SplitPaths { data: unparsed.encode_wide(), must_yield: true } } impl<'a> Iterator for SplitPaths<'a> { type Item = PathBuf; + fn next(&mut self) -> Option { - self.0 + let must_yield = self.must_yield; + self.must_yield = false; + + let mut in_progress = Vec::new(); + for b in self.data.by_ref() { + if b == PATHS_SEP { + self.must_yield = true; + break; + } else { + in_progress.push(b) + } + } + + if !must_yield && in_progress.is_empty() { + None + } else { + Some(PathBuf::from(OsString::from_wide(&in_progress))) + } } } diff --git a/library/std/tests/env.rs b/library/std/tests/env.rs index b53fd69b7070b..9d624d5592ce7 100644 --- a/library/std/tests/env.rs +++ b/library/std/tests/env.rs @@ -59,6 +59,23 @@ fn split_paths_unix() { assert!(check_parse("/:/usr/local", &mut ["/", "/usr/local"])); } +#[test] +#[cfg(target_os = "uefi")] +fn split_paths_uefi() { + use std::path::PathBuf; + + fn check_parse(unparsed: &str, parsed: &[&str]) -> bool { + split_paths(unparsed).collect::>() + == parsed.iter().map(|s| PathBuf::from(*s)).collect::>() + } + + assert!(check_parse("", &mut [""])); + assert!(check_parse(";;", &mut ["", "", ""])); + assert!(check_parse(r"fs0:\", &mut [r"fs0:\"])); + assert!(check_parse(r"fs0:\;", &mut [r"fs0:\", ""])); + assert!(check_parse(r"fs0:\;fs0:\boot\", &mut [r"fs0:\", r"fs0:\boot\"])); +} + #[test] #[cfg(unix)] fn join_paths_unix() { diff --git a/tests/ui/const-generics/mgca/array_elem_type_mismatch.rs b/tests/ui/const-generics/mgca/array_elem_type_mismatch.rs new file mode 100644 index 0000000000000..b15f90acb477e --- /dev/null +++ b/tests/ui/const-generics/mgca/array_elem_type_mismatch.rs @@ -0,0 +1,10 @@ +//! Regression test for +#![expect(incomplete_features)] +#![feature(adt_const_params, generic_const_parameter_types, min_generic_const_args)] +fn foo() {} + +fn main() { + foo::<_, { [0, 1u8, 2u32, 8u64] }>(); + //~^ ERROR the constant `2` is not of type `u8` + //~| ERROR the constant `8` is not of type `u8` +} diff --git a/tests/ui/const-generics/mgca/array_elem_type_mismatch.stderr b/tests/ui/const-generics/mgca/array_elem_type_mismatch.stderr new file mode 100644 index 0000000000000..f98dbf1e311ba --- /dev/null +++ b/tests/ui/const-generics/mgca/array_elem_type_mismatch.stderr @@ -0,0 +1,14 @@ +error: the constant `2` is not of type `u8` + --> $DIR/array_elem_type_mismatch.rs:7:16 + | +LL | foo::<_, { [0, 1u8, 2u32, 8u64] }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `u32` + +error: the constant `8` is not of type `u8` + --> $DIR/array_elem_type_mismatch.rs:7:16 + | +LL | foo::<_, { [0, 1u8, 2u32, 8u64] }>(); + | ^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `u64` + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.rs b/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.rs new file mode 100644 index 0000000000000..efc21808787b1 --- /dev/null +++ b/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.rs @@ -0,0 +1,10 @@ +#![expect(incomplete_features)] +#![feature(adt_const_params, min_generic_const_args)] + +struct ArrWrap; + +fn main() { + let _: ArrWrap<{ [1_u8] }> = ArrWrap::<{ [1_u16] }>; + //~^ ERROR: mismatched types + //~| ERROR the constant `1` is not of type `u8` +} diff --git a/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.stderr b/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.stderr new file mode 100644 index 0000000000000..4105f314f7974 --- /dev/null +++ b/tests/ui/const-generics/mgca/wrapped_array_elem_type_mismatch.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/wrapped_array_elem_type_mismatch.rs:7:34 + | +LL | let _: ArrWrap<{ [1_u8] }> = ArrWrap::<{ [1_u16] }>; + | ------------------- ^^^^^^^^^^^^^^^^^^^^^^ expected `*b"\x01"`, found `[1]` + | | + | expected due to this + | + = note: expected struct `ArrWrap<*b"\x01">` + found struct `ArrWrap<[1]>` + +error: the constant `1` is not of type `u8` + --> $DIR/wrapped_array_elem_type_mismatch.rs:7:46 + | +LL | let _: ArrWrap<{ [1_u8] }> = ArrWrap::<{ [1_u16] }>; + | ^^^^^^^ expected `u8`, found `u16` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/dep-graph/query-dep-graph-empty.rs b/tests/ui/dep-graph/query-dep-graph-empty.rs new file mode 100644 index 0000000000000..360dfd7f1126a --- /dev/null +++ b/tests/ui/dep-graph/query-dep-graph-empty.rs @@ -0,0 +1,7 @@ +//@ build-pass +//@ compile-flags: -Zquery-dep-graph --crate-type lib +//@ edition: 2021 + +// This file is intentionally left empty to reproduce issue #153199. +// rustc used to ICE when generating a dependency graph for an empty file +// because early queries would panic when unwrapping an uninitialized graph.