Question:
This is a recent regression, starting with when is set, in my case to where I have prepared a locally built sysroot (that's ), then rustc now assumes it can find the linker in the sysroot, which does not work. See for some more details. It is new to me that the sysroot is supposed to contain the linker as well, is that expected behavior? Also the error message in that case is really unhelpful.^^ Maybe rustc should check that the path it sets for actually exists before starting ?
Yes. The blog post has a summary of that PR
That blog post doesn't mention the term "sysroot" so it doesn't help with my issue.
FWIW what I would have expected is that rustc searches for the linker binary somewhere around . Isn't that how we find some other things as well that are usually installed with rustc by rustup?
How do you handle windows-gnu? Imo this also uses a self-contained linker by default.
No idea. CI passes on Windows, whatever github gives us when we say .
Yeah the rust-lld linker has been in the sysroot since , is used by default in e.g. some of the wasm and aarch64 targets, and rustc had flags to opt-into using it since that PR. What is new is that it is now used by nightlies we distribute. bootstrap puts it in the sysroot when is true (and it's now the default on x64 linux under certain conditions), so you can also set that when -ing if you want it. It works with or without download-ci-llvm.
We resolve the sysroot from rustc driver, not current executable.
Yes, the surprise is just that the linker is searched in the sysroot and thus affected by --sysroot, rather than being searched directly. But I guess this is working as intended, I just need to add some more stuff to these custom sysroots then.
This broke cargo's CI since the build-std tests try to verify that nothing in the sysroot is required. Would it be possible to change it so that it will only require rust-lld if it exists in the sysroot (similar to windows-gnu and other targets)?
I don't know what we do on windows-gnu but we can do something similar, yes. I'll open a PR.
FWIW I managed to add tests for windows-gnu and they work like a charm. So no copying of files seems to be required there. Though I do recall xargo copying some things for windows-gnu so maybe I am not testing enough... but my tests do involve building a small program against the sysroot and running it, so maybe those files are just not needed any more.
We actually hit a binutils linker bug last week on windows-gnu (not windows-gnullvm), and the linker flavor there is gnu-cc, so do these targets really use rust-lld by default?
How does this work with cross-compilation -- I assume we are always taking the host sysroot even when building for another target? To me that seems like a sign that this shouldn't be part of the sysroot, it should be part of the rustc distribution. The sysroot is for target-related things.
In particular, I would expect that if I set to a folder that only contains a sysroot for some foreign target, then that should work if I also set appropriately (and use the right linker and everything). But currently that will then likely fail as it tries to search the host target in the folder, and with it will instead silently fall back to the slow linker.
They do use a self-contained linker from sysroot by default, but not rust-lld. We ship from binutils for those targets.
Thanks for the clarification. That explains why there's no existence check (and your 2nd hack for older GCCs in that other issue :). Locally, it was just using mingw's ld probably because of $PATH differences.
Linkers are generally target-dependent, so it's pretty reasonable to ship them in target sysroot, I guess. rust-lld is just applicable to a wide range of targets by being a cross-linker. Also there's no target vs host separation for sysroot in rustc right now, there's just one sysroot. Maybe there's some space for improvements here, it's just not many people use to notice any issues.
I still hope to migrate both rust-lld and mingw linker to the common directory layout scheme based on .
rust-lld is just applicable to a wide range of targets by being a cross-linker. If I'm on macOS and want to build for a Linux target, then the binary shipped in the sysroot is going to be completely useless to me. So in that sense shipping them in the target sysroot seems pointless. (Of course our cross-compile story is not great so such cross-building will hardly ever work, but it demonstrates the fundamental issue I was pointing out.) Even when I am on and building for I probably want to use a 64bit program for the linking, and not a binary shipped in the i686 sysroot -- this is e.g. how Firefox is (or was) built as 4GB of RAM (the maximum accessible to 32bit programs) are just not enough for linking. Given that these are binaries that need to be run on the host (i.e. the machine where the build happens), IMO the only sensible location is together with the other host stuff, i.e., where lives.
Ah I think I understand. That's right, and on macOS we wouldn't look for in the "x8664-unknown-linux-gnu sysroot" . You can try this locally on a helloworld (look for the path to ), from with a target:
Oh, so we always assume that contains a sysroot for the host and the current target. That's news to me as well (and Miri certainly doesn't guarantee it). But the fallback in your PR should solve that as well, I think.

codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected <ins> codegen_ssa_self_contained_linker_missing = the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot </ins> codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link


Question:
This is a recent regression, starting with when is set, in my case to where I have prepared a locally built sysroot (that's ), then rustc now assumes it can find the linker in the sysroot, which does not work. See for some more details. It is new to me that the sysroot is supposed to contain the linker as well, is that expected behavior? Also the error message in that case is really unhelpful.^^ Maybe rustc should check that the path it sets for actually exists before starting ?
Yes. The blog post has a summary of that PR
That blog post doesn't mention the term "sysroot" so it doesn't help with my issue.
FWIW what I would have expected is that rustc searches for the linker binary somewhere around . Isn't that how we find some other things as well that are usually installed with rustc by rustup?
How do you handle windows-gnu? Imo this also uses a self-contained linker by default.
No idea. CI passes on Windows, whatever github gives us when we say .
Yeah the rust-lld linker has been in the sysroot since , is used by default in e.g. some of the wasm and aarch64 targets, and rustc had flags to opt-into using it since that PR. What is new is that it is now used by nightlies we distribute. bootstrap puts it in the sysroot when is true (and it's now the default on x64 linux under certain conditions), so you can also set that when -ing if you want it. It works with or without download-ci-llvm.
We resolve the sysroot from rustc driver, not current executable.
Yes, the surprise is just that the linker is searched in the sysroot and thus affected by --sysroot, rather than being searched directly. But I guess this is working as intended, I just need to add some more stuff to these custom sysroots then.
This broke cargo's CI since the build-std tests try to verify that nothing in the sysroot is required. Would it be possible to change it so that it will only require rust-lld if it exists in the sysroot (similar to windows-gnu and other targets)?
I don't know what we do on windows-gnu but we can do something similar, yes. I'll open a PR.
FWIW I managed to add tests for windows-gnu and they work like a charm. So no copying of files seems to be required there. Though I do recall xargo copying some things for windows-gnu so maybe I am not testing enough... but my tests do involve building a small program against the sysroot and running it, so maybe those files are just not needed any more.
We actually hit a binutils linker bug last week on windows-gnu (not windows-gnullvm), and the linker flavor there is gnu-cc, so do these targets really use rust-lld by default?
How does this work with cross-compilation -- I assume we are always taking the host sysroot even when building for another target? To me that seems like a sign that this shouldn't be part of the sysroot, it should be part of the rustc distribution. The sysroot is for target-related things.
In particular, I would expect that if I set to a folder that only contains a sysroot for some foreign target, then that should work if I also set appropriately (and use the right linker and everything). But currently that will then likely fail as it tries to search the host target in the folder, and with it will instead silently fall back to the slow linker.
They do use a self-contained linker from sysroot by default, but not rust-lld. We ship from binutils for those targets.
Thanks for the clarification. That explains why there's no existence check (and your 2nd hack for older GCCs in that other issue :). Locally, it was just using mingw's ld probably because of $PATH differences.
Linkers are generally target-dependent, so it's pretty reasonable to ship them in target sysroot, I guess. rust-lld is just applicable to a wide range of targets by being a cross-linker. Also there's no target vs host separation for sysroot in rustc right now, there's just one sysroot. Maybe there's some space for improvements here, it's just not many people use to notice any issues.
I still hope to migrate both rust-lld and mingw linker to the common directory layout scheme based on .
rust-lld is just applicable to a wide range of targets by being a cross-linker. If I'm on macOS and want to build for a Linux target, then the binary shipped in the sysroot is going to be completely useless to me. So in that sense shipping them in the target sysroot seems pointless. (Of course our cross-compile story is not great so such cross-building will hardly ever work, but it demonstrates the fundamental issue I was pointing out.) Even when I am on and building for I probably want to use a 64bit program for the linking, and not a binary shipped in the i686 sysroot -- this is e.g. how Firefox is (or was) built as 4GB of RAM (the maximum accessible to 32bit programs) are just not enough for linking. Given that these are binaries that need to be run on the host (i.e. the machine where the build happens), IMO the only sensible location is together with the other host stuff, i.e., where lives.
Ah I think I understand. That's right, and on macOS we wouldn't look for in the "x8664-unknown-linux-gnu sysroot" . You can try this locally on a helloworld (look for the path to ), from with a target:
Oh, so we always assume that contains a sysroot for the host and the current target. That's news to me as well (and Miri certainly doesn't guarantee it). But the fallback in your PR should solve that as well, I think.

let self_contained_linker = self_contained_cli || self_contained_target; if self_contained_linker && !sess.opts.cg.link_self_contained.is_linker_disabled() { <ins> let mut linker_path_exists = false; </ins> for path in sess.get_tools_search_paths(false) { <ins> let linker_path = path.join("gcc-ld"); linker_path_exists |= linker_path.exists(); </ins> cmd.arg({ let mut arg = OsString::from("-B"); <del> arg.push(path.join("gcc-ld")); </del> <ins> arg.push(linker_path); </ins> arg }); } <ins> if !linker_path_exists { // As a sanity check, we emit an error if none of these paths exist: we want // self-contained linking and have no linker. sess.dcx().emit_fatal(errors::SelfContainedLinkerMissing); } </ins> } // 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of


Question:
This is a recent regression, starting with when is set, in my case to where I have prepared a locally built sysroot (that's ), then rustc now assumes it can find the linker in the sysroot, which does not work. See for some more details. It is new to me that the sysroot is supposed to contain the linker as well, is that expected behavior? Also the error message in that case is really unhelpful.^^ Maybe rustc should check that the path it sets for actually exists before starting ?
Yes. The blog post has a summary of that PR
That blog post doesn't mention the term "sysroot" so it doesn't help with my issue.
FWIW what I would have expected is that rustc searches for the linker binary somewhere around . Isn't that how we find some other things as well that are usually installed with rustc by rustup?
How do you handle windows-gnu? Imo this also uses a self-contained linker by default.
No idea. CI passes on Windows, whatever github gives us when we say .
Yeah the rust-lld linker has been in the sysroot since , is used by default in e.g. some of the wasm and aarch64 targets, and rustc had flags to opt-into using it since that PR. What is new is that it is now used by nightlies we distribute. bootstrap puts it in the sysroot when is true (and it's now the default on x64 linux under certain conditions), so you can also set that when -ing if you want it. It works with or without download-ci-llvm.
We resolve the sysroot from rustc driver, not current executable.
Yes, the surprise is just that the linker is searched in the sysroot and thus affected by --sysroot, rather than being searched directly. But I guess this is working as intended, I just need to add some more stuff to these custom sysroots then.
This broke cargo's CI since the build-std tests try to verify that nothing in the sysroot is required. Would it be possible to change it so that it will only require rust-lld if it exists in the sysroot (similar to windows-gnu and other targets)?
I don't know what we do on windows-gnu but we can do something similar, yes. I'll open a PR.
FWIW I managed to add tests for windows-gnu and they work like a charm. So no copying of files seems to be required there. Though I do recall xargo copying some things for windows-gnu so maybe I am not testing enough... but my tests do involve building a small program against the sysroot and running it, so maybe those files are just not needed any more.
We actually hit a binutils linker bug last week on windows-gnu (not windows-gnullvm), and the linker flavor there is gnu-cc, so do these targets really use rust-lld by default?
How does this work with cross-compilation -- I assume we are always taking the host sysroot even when building for another target? To me that seems like a sign that this shouldn't be part of the sysroot, it should be part of the rustc distribution. The sysroot is for target-related things.
In particular, I would expect that if I set to a folder that only contains a sysroot for some foreign target, then that should work if I also set appropriately (and use the right linker and everything). But currently that will then likely fail as it tries to search the host target in the folder, and with it will instead silently fall back to the slow linker.
They do use a self-contained linker from sysroot by default, but not rust-lld. We ship from binutils for those targets.
Thanks for the clarification. That explains why there's no existence check (and your 2nd hack for older GCCs in that other issue :). Locally, it was just using mingw's ld probably because of $PATH differences.
Linkers are generally target-dependent, so it's pretty reasonable to ship them in target sysroot, I guess. rust-lld is just applicable to a wide range of targets by being a cross-linker. Also there's no target vs host separation for sysroot in rustc right now, there's just one sysroot. Maybe there's some space for improvements here, it's just not many people use to notice any issues.
I still hope to migrate both rust-lld and mingw linker to the common directory layout scheme based on .
rust-lld is just applicable to a wide range of targets by being a cross-linker. If I'm on macOS and want to build for a Linux target, then the binary shipped in the sysroot is going to be completely useless to me. So in that sense shipping them in the target sysroot seems pointless. (Of course our cross-compile story is not great so such cross-building will hardly ever work, but it demonstrates the fundamental issue I was pointing out.) Even when I am on and building for I probably want to use a 64bit program for the linking, and not a binary shipped in the i686 sysroot -- this is e.g. how Firefox is (or was) built as 4GB of RAM (the maximum accessible to 32bit programs) are just not enough for linking. Given that these are binaries that need to be run on the host (i.e. the machine where the build happens), IMO the only sensible location is together with the other host stuff, i.e., where lives.
Ah I think I understand. That's right, and on macOS we wouldn't look for in the "x8664-unknown-linux-gnu sysroot" . You can try this locally on a helloworld (look for the path to ), from with a target:
Oh, so we always assume that contains a sysroot for the host and the current target. That's news to me as well (and Miri certainly doesn't guarantee it). But the fallback in your PR should solve that as well, I think.

pub struct MsvcMissingLinker; #[derive(Diagnostic)] <ins> #[diag(codegen_ssa_self_contained_linker_missing)] pub struct SelfContainedLinkerMissing; #[derive(Diagnostic)] </ins> #[diag(codegen_ssa_check_installed_visual_studio)] pub struct CheckInstalledVisualStudio;


Question:
This is a recent regression, starting with when is set, in my case to where I have prepared a locally built sysroot (that's ), then rustc now assumes it can find the linker in the sysroot, which does not work. See for some more details. It is new to me that the sysroot is supposed to contain the linker as well, is that expected behavior? Also the error message in that case is really unhelpful.^^ Maybe rustc should check that the path it sets for actually exists before starting ?
Yes. The blog post has a summary of that PR
That blog post doesn't mention the term "sysroot" so it doesn't help with my issue.
FWIW what I would have expected is that rustc searches for the linker binary somewhere around . Isn't that how we find some other things as well that are usually installed with rustc by rustup?
How do you handle windows-gnu? Imo this also uses a self-contained linker by default.
No idea. CI passes on Windows, whatever github gives us when we say .
Yeah the rust-lld linker has been in the sysroot since , is used by default in e.g. some of the wasm and aarch64 targets, and rustc had flags to opt-into using it since that PR. What is new is that it is now used by nightlies we distribute. bootstrap puts it in the sysroot when is true (and it's now the default on x64 linux under certain conditions), so you can also set that when -ing if you want it. It works with or without download-ci-llvm.
We resolve the sysroot from rustc driver, not current executable.
Yes, the surprise is just that the linker is searched in the sysroot and thus affected by --sysroot, rather than being searched directly. But I guess this is working as intended, I just need to add some more stuff to these custom sysroots then.
This broke cargo's CI since the build-std tests try to verify that nothing in the sysroot is required. Would it be possible to change it so that it will only require rust-lld if it exists in the sysroot (similar to windows-gnu and other targets)?
I don't know what we do on windows-gnu but we can do something similar, yes. I'll open a PR.
FWIW I managed to add tests for windows-gnu and they work like a charm. So no copying of files seems to be required there. Though I do recall xargo copying some things for windows-gnu so maybe I am not testing enough... but my tests do involve building a small program against the sysroot and running it, so maybe those files are just not needed any more.
We actually hit a binutils linker bug last week on windows-gnu (not windows-gnullvm), and the linker flavor there is gnu-cc, so do these targets really use rust-lld by default?
How does this work with cross-compilation -- I assume we are always taking the host sysroot even when building for another target? To me that seems like a sign that this shouldn't be part of the sysroot, it should be part of the rustc distribution. The sysroot is for target-related things.
In particular, I would expect that if I set to a folder that only contains a sysroot for some foreign target, then that should work if I also set appropriately (and use the right linker and everything). But currently that will then likely fail as it tries to search the host target in the folder, and with it will instead silently fall back to the slow linker.
They do use a self-contained linker from sysroot by default, but not rust-lld. We ship from binutils for those targets.
Thanks for the clarification. That explains why there's no existence check (and your 2nd hack for older GCCs in that other issue :). Locally, it was just using mingw's ld probably because of $PATH differences.
Linkers are generally target-dependent, so it's pretty reasonable to ship them in target sysroot, I guess. rust-lld is just applicable to a wide range of targets by being a cross-linker. Also there's no target vs host separation for sysroot in rustc right now, there's just one sysroot. Maybe there's some space for improvements here, it's just not many people use to notice any issues.
I still hope to migrate both rust-lld and mingw linker to the common directory layout scheme based on .
rust-lld is just applicable to a wide range of targets by being a cross-linker. If I'm on macOS and want to build for a Linux target, then the binary shipped in the sysroot is going to be completely useless to me. So in that sense shipping them in the target sysroot seems pointless. (Of course our cross-compile story is not great so such cross-building will hardly ever work, but it demonstrates the fundamental issue I was pointing out.) Even when I am on and building for I probably want to use a 64bit program for the linking, and not a binary shipped in the i686 sysroot -- this is e.g. how Firefox is (or was) built as 4GB of RAM (the maximum accessible to 32bit programs) are just not enough for linking. Given that these are binaries that need to be run on the host (i.e. the machine where the build happens), IMO the only sensible location is together with the other host stuff, i.e., where lives.
Ah I think I understand. That's right, and on macOS we wouldn't look for in the "x8664-unknown-linux-gnu sysroot" . You can try this locally on a helloworld (look for the path to ), from with a target:
Oh, so we always assume that contains a sysroot for the host and the current target. That's news to me as well (and Miri certainly doesn't guarantee it). But the fallback in your PR should solve that as well, I think.

PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")]) } <ins> /// Returns a path to the target's `bin` folder within its `rustlib` path in the sysroot. This is /// where binaries are usually installed, e.g. the self-contained linkers, lld-wrappers, LLVM tools, /// etc. pub fn make_target_bin_path(sysroot: &Path, target_triple: &str) -> PathBuf { let rustlib_path = rustc_target::target_rustlib_path(sysroot, target_triple); PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("bin")]) } </ins> #[cfg(unix)] fn current_dll_path() -> Result<PathBuf, String> { use std::ffi::{CStr, OsStr};


Question:
This is a recent regression, starting with when is set, in my case to where I have prepared a locally built sysroot (that's ), then rustc now assumes it can find the linker in the sysroot, which does not work. See for some more details. It is new to me that the sysroot is supposed to contain the linker as well, is that expected behavior? Also the error message in that case is really unhelpful.^^ Maybe rustc should check that the path it sets for actually exists before starting ?
Yes. The blog post has a summary of that PR
That blog post doesn't mention the term "sysroot" so it doesn't help with my issue.
FWIW what I would have expected is that rustc searches for the linker binary somewhere around . Isn't that how we find some other things as well that are usually installed with rustc by rustup?
How do you handle windows-gnu? Imo this also uses a self-contained linker by default.
No idea. CI passes on Windows, whatever github gives us when we say .
Yeah the rust-lld linker has been in the sysroot since , is used by default in e.g. some of the wasm and aarch64 targets, and rustc had flags to opt-into using it since that PR. What is new is that it is now used by nightlies we distribute. bootstrap puts it in the sysroot when is true (and it's now the default on x64 linux under certain conditions), so you can also set that when -ing if you want it. It works with or without download-ci-llvm.
We resolve the sysroot from rustc driver, not current executable.
Yes, the surprise is just that the linker is searched in the sysroot and thus affected by --sysroot, rather than being searched directly. But I guess this is working as intended, I just need to add some more stuff to these custom sysroots then.
This broke cargo's CI since the build-std tests try to verify that nothing in the sysroot is required. Would it be possible to change it so that it will only require rust-lld if it exists in the sysroot (similar to windows-gnu and other targets)?
I don't know what we do on windows-gnu but we can do something similar, yes. I'll open a PR.
FWIW I managed to add tests for windows-gnu and they work like a charm. So no copying of files seems to be required there. Though I do recall xargo copying some things for windows-gnu so maybe I am not testing enough... but my tests do involve building a small program against the sysroot and running it, so maybe those files are just not needed any more.
We actually hit a binutils linker bug last week on windows-gnu (not windows-gnullvm), and the linker flavor there is gnu-cc, so do these targets really use rust-lld by default?
How does this work with cross-compilation -- I assume we are always taking the host sysroot even when building for another target? To me that seems like a sign that this shouldn't be part of the sysroot, it should be part of the rustc distribution. The sysroot is for target-related things.
In particular, I would expect that if I set to a folder that only contains a sysroot for some foreign target, then that should work if I also set appropriately (and use the right linker and everything). But currently that will then likely fail as it tries to search the host target in the folder, and with it will instead silently fall back to the slow linker.
They do use a self-contained linker from sysroot by default, but not rust-lld. We ship from binutils for those targets.
Thanks for the clarification. That explains why there's no existence check (and your 2nd hack for older GCCs in that other issue :). Locally, it was just using mingw's ld probably because of $PATH differences.
Linkers are generally target-dependent, so it's pretty reasonable to ship them in target sysroot, I guess. rust-lld is just applicable to a wide range of targets by being a cross-linker. Also there's no target vs host separation for sysroot in rustc right now, there's just one sysroot. Maybe there's some space for improvements here, it's just not many people use to notice any issues.
I still hope to migrate both rust-lld and mingw linker to the common directory layout scheme based on .
rust-lld is just applicable to a wide range of targets by being a cross-linker. If I'm on macOS and want to build for a Linux target, then the binary shipped in the sysroot is going to be completely useless to me. So in that sense shipping them in the target sysroot seems pointless. (Of course our cross-compile story is not great so such cross-building will hardly ever work, but it demonstrates the fundamental issue I was pointing out.) Even when I am on and building for I probably want to use a 64bit program for the linking, and not a binary shipped in the i686 sysroot -- this is e.g. how Firefox is (or was) built as 4GB of RAM (the maximum accessible to 32bit programs) are just not enough for linking. Given that these are binaries that need to be run on the host (i.e. the machine where the build happens), IMO the only sensible location is together with the other host stuff, i.e., where lives.
Ah I think I understand. That's right, and on macOS we wouldn't look for in the "x8664-unknown-linux-gnu sysroot" . You can try this locally on a helloworld (look for the path to ), from with a target:
Oh, so we always assume that contains a sysroot for the host and the current target. That's news to me as well (and Miri certainly doesn't guarantee it). But the fallback in your PR should solve that as well, I think.

) } <del> /// Returns a list of directories where target-specific tool binaries are located. </del> <ins> /// Returns a list of directories where target-specific tool binaries are located. Some fallback /// directories are also returned, for example if `--sysroot` is used but tools are missing /// (#125246): we also add the bin directories to the sysroot where rustc is located. </ins> pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> { <del> let rustlib_path = rustc_target::target_rustlib_path(&self.sysroot, config::host_triple()); let p = PathBuf::from_iter([ Path::new(&self.sysroot), Path::new(&rustlib_path), Path::new("bin"), ]); if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] } </del> <ins> let bin_path = filesearch::make_target_bin_path(&self.sysroot, config::host_triple()); let fallback_sysroot_paths = filesearch::sysroot_candidates() .into_iter() .map(|sysroot| filesearch::make_target_bin_path(&sysroot, config::host_triple())); let search_paths = std::iter::once(bin_path).chain(fallback_sysroot_paths); if self_contained { // The self-contained tools are expected to be e.g. in `bin/self-contained` in the // sysroot's `rustlib` path, so we add such a subfolder to the bin path, and the // fallback paths. search_paths.flat_map(|path| [path.clone(), path.join("self-contained")]).collect() } else { search_paths.collect() } </ins> } pub fn init_incr_comp_session(&self, session_dir: PathBuf, lock_file: flock::Lock) {


Question:
For example, from (And many more.) I think this is due to Should we just drop these from ?
cc

("avx512bw", Unstable(sym::avx512_target_feature)), ("avx512cd", Unstable(sym::avx512_target_feature)), ("avx512dq", Unstable(sym::avx512_target_feature)), <del> ("avx512er", Unstable(sym::avx512_target_feature)), </del> ("avx512f", Unstable(sym::avx512_target_feature)), ("avx512fp16", Unstable(sym::avx512_target_feature)), ("avx512ifma", Unstable(sym::avx512_target_feature)), <del> ("avx512pf", Unstable(sym::avx512_target_feature)), </del> ("avx512vbmi", Unstable(sym::avx512_target_feature)), ("avx512vbmi2", Unstable(sym::avx512_target_feature)), ("avx512vl", Unstable(sym::avx512_target_feature)),


Question:
For example, from (And many more.) I think this is due to Should we just drop these from ?
cc

println!("avx512bw: {:?}", is_x86_feature_detected!("avx512bw")); println!("avx512cd: {:?}", is_x86_feature_detected!("avx512cd")); println!("avx512dq: {:?}", is_x86_feature_detected!("avx512dq")); <del> println!("avx512er: {:?}", is_x86_feature_detected!("avx512er")); </del> println!("avx512f: {:?}", is_x86_feature_detected!("avx512f")); println!("avx512ifma: {:?}", is_x86_feature_detected!("avx512ifma")); <del> println!("avx512pf: {:?}", is_x86_feature_detected!("avx512pf")); </del> println!("avx512vbmi2: {:?}", is_x86_feature_detected!("avx512vbmi2")); println!("avx512vbmi: {:?}", is_x86_feature_detected!("avx512vbmi")); println!("avx512vl: {:?}", is_x86_feature_detected!("avx512vl"));


Question:
For example, from (And many more.) I think this is due to Should we just drop these from ?
cc

LL |     cfg!(target_feature = "zebra"); |          ^^^^^^^^^^^^^^^^^^^^^^^^ | <del> = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, and `bmi2` and 188 more </del> <ins> = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, and `bulk-memory` and 186 more </ins> = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: 27 warnings emitted


Question:
For example, from (And many more.) I think this is due to Should we just drop these from ?
cc

LL |     target_feature = "_UNEXPECTED_VALUE", |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | <del> = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` </del> <ins> = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `extended-const`, `f`, `f16c`, `f32mm`, `f64mm`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `unaligned-scalar-mem`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, and `zkt` </ins> = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`


Question: () Like and the other ABIs, should not trigger and for non-FFI-safe types. Related: , ; tracking issue . No response No response_

} fn is_internal_abi(&self, abi: SpecAbi) -> bool { <del> matches!(abi, SpecAbi::Rust | SpecAbi::RustCall | SpecAbi::RustIntrinsic) </del> <ins> matches!( abi, SpecAbi::Rust | SpecAbi::RustCall | SpecAbi::RustCold | SpecAbi::RustIntrinsic ) </ins> } /// Find any fn-ptr types with external ABIs in `ty`.


Question: () Like and the other ABIs, should not trigger and for non-FFI-safe types. Related: , ; tracking issue . No response No response_

<ins> //@ check-pass #![feature(rust_cold_cc)] // extern "rust-cold" is a "Rust" ABI so we accept `repr(Rust)` types as arg/ret without warnings. pub extern "rust-cold" fn f(_: ()) -> Result<(), ()> { Ok(()) } extern "rust-cold" { pub fn g(_: ()) -> Result<(), ()>; } fn main() {} </ins>


Question:
When downloading the (and variant) target, the that ships with the compiler is broken: Upon further inspection, the symbols are indeed built for x86-64 and not LoongArch: It's not clear what causes this, but contains no corresponding definitions for . This issue appears related, in that it would catch whatever causes this:
cc

AR_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-ar  CXX_loongarch64_unknown_linux_gnu=loongarch64-unknown-linux-gnu-g++ <ins> # We re-use the Linux toolchain for bare-metal, because upstream bare-metal # target support for LoongArch is only available from GCC 14+. # # See: https://github.com/gcc-mirror/gcc/commit/976f4f9e4770 ENV CC_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-gcc  AR_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-ar  CXX_loongarch64_unknown_none=loongarch64-unknown-linux-gnu-g++  CFLAGS_loongarch64_unknown_none="-ffreestanding -mabi=lp64d"  CXXFLAGS_loongarch64_unknown_none="-ffreestanding -mabi=lp64d"  CC_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-gcc  AR_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-ar  CXX_loongarch64_unknown_none_softfloat=loongarch64-unknown-linux-gnu-g++  CFLAGS_loongarch64_unknown_none_softfloat="-ffreestanding -mabi=lp64s -mfpu=none"  CXXFLAGS_loongarch64_unknown_none_softfloat="-ffreestanding -mabi=lp64s -mfpu=none" </ins> ENV HOSTS=loongarch64-unknown-linux-gnu <ins> ENV TARGETS=$HOSTS ENV TARGETS=$TARGETS,loongarch64-unknown-none ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat </ins> ENV RUST_CONFIGURE_ARGS  --enable-extended


Question:
When downloading the (and variant) target, the that ships with the compiler is broken: Upon further inspection, the symbols are indeed built for x86-64 and not LoongArch: It's not clear what causes this, but contains no corresponding definitions for . This issue appears related, in that it would catch whatever causes this:
cc

--enable-profiler  --disable-docs <del> ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS </del> <ins> ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $TARGETS </ins>


Question:
When downloading the (and variant) target, the that ships with the compiler is broken: Upon further inspection, the symbols are indeed built for x86-64 and not LoongArch: It's not clear what causes this, but contains no corresponding definitions for . This issue appears related, in that it would catch whatever causes this:
cc

ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi ENV TARGETS=$TARGETS,i686-unknown-freebsd ENV TARGETS=$TARGETS,x86_64-unknown-none <del> ENV TARGETS=$TARGETS,loongarch64-unknown-none ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat </del> ENV TARGETS=$TARGETS,aarch64-unknown-uefi ENV TARGETS=$TARGETS,i686-unknown-uefi ENV TARGETS=$TARGETS,x86_64-unknown-uefi


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: alloc <addrand dealloc <addris printed Instead, this happened: only alloc <addris printed <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: forgets that it's been initialized with an allocator, and always deletes the node with the global allocator. There seems to be one more place where this happens in the same file. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
claim

unsafe { self.current = unlinked_node.as_ref().next; self.list.unlink_node(unlinked_node); <del> let unlinked_node = Box::from_raw(unlinked_node.as_ptr()); </del> <ins> let unlinked_node = Box::from_raw_in(unlinked_node.as_ptr(), &self.list.alloc); </ins> Some(unlinked_node.element) } }


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: alloc <addrand dealloc <addris printed Instead, this happened: only alloc <addris printed <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: forgets that it's been initialized with an allocator, and always deletes the node with the global allocator. There seems to be one more place where this happens in the same file. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
claim

if (self.pred)(&mut node.as_mut().element) { // `unlink_node` is okay with aliasing `element` references. self.list.unlink_node(node); <del> return Some(Box::from_raw(node.as_ptr()).element); </del> <ins> return Some(Box::from_raw_in(node.as_ptr(), &self.list.alloc).element); </ins> } } }


Question:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: alloc <addrand dealloc <addris printed Instead, this happened: only alloc <addris printed <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: forgets that it's been initialized with an allocator, and always deletes the node with the global allocator. There seems to be one more place where this happens in the same file. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
claim

assert_eq!(unsafe { DROPS }, 8); } <ins> #[test] fn test_allocator() { use core::alloc::AllocError; use core::alloc::Allocator; use core::alloc::Layout; use core::cell::Cell; struct A { has_allocated: Cell<bool>, has_deallocated: Cell<bool>, } unsafe impl Allocator for A { fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> { assert!(!self.has_allocated.get()); self.has_allocated.set(true); Global.allocate(layout) } unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) { assert!(!self.has_deallocated.get()); self.has_deallocated.set(true); unsafe { Global.deallocate(ptr, layout) } } } let alloc = &A { has_allocated: Cell::new(false), has_deallocated: Cell::new(false) }; { let mut list = LinkedList::new_in(alloc); list.push_back(5u32); list.remove(0); } assert!(alloc.has_allocated.get()); assert!(alloc.has_deallocated.get()); } </ins>


Question:
The DEFAULTMINSTACK_SIZE is the default stack size assigned when creating a thread. This value varies across different platforms. The issue is that there isn't enough explanation as to why these values are different, and users might not realize that the stack size can vary. Recently, I was running existing Windows code on a WASI target, and I kept encountering font decoding failures. Since it worked correctly on Windows, I suspected WASI's instability and spent considerable time debugging. After several days, I discovered that the root cause was the stack size: WASI has a very small stack size of 4KB, while Windows has a much larger stack size of 2MB. Once I forcibly increased the thread's stack size, all issues were resolved. I felt quite frustrated that such a simple reason caused the problem. Although this is my personal experience, I believe that rather than setting different default stack sizes for different platforms without a compelling reason, it would be better to have a consistent stack size across all platforms in Rust. However, I acknowledge that this suggestion might not be very effective because the required memory can vary depending on the instruction set or architecture. I would like to discuss this matter further.
Different platforms have different useful minimum stack sizes. I have no idea why only 4KiB is reserved on wasi.
In my opinion, this isn't an issue of "inconsistency" this is an issue of a target having an absurdly low value, period. Please open a PR to raise it.
What are the criteria for determining that? Since I don't know, I can't tell whether the 4KB for WASI is inappropriate or not, and I also can't open a PR because I don't know the appropriate value.
...a zillion insanely low-level minutiae like how big the registers are, mostly. an article that might help: as that article explains, the smallest thread stack size of all platforms that I'm aware of, aside from the ones in our repo that only ask for 4096 bytes, is 64KiB. the current 4096 bytes boundary has caused you significant pain so it seems sensible to raise it to at least that much, then fool around and see how it works.
having done some review of our platform code, I am pretty sure 4096 bytes was just picked as the "unsupported" value and platforms that initially lacked thread support, like wasm32-wasi, just inherited that value.
I understand. The differences between the platforms are indeed huge..! Before proceeding, I would like to hear the opinion or history from Alex Crichton, the main maintainer of the wasi target. , could you please share your thoughts on this issue?
I commented a bit on but I've no recollection for the current value for wasi. I suspect it was a number of historical accidents that led to this, and stack sizes should definitely be larger than 4k by default on wasi. Thanks for the issue

} } <del> pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; </del> <ins> pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024; </ins> impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements


Question:
The DEFAULTMINSTACK_SIZE is the default stack size assigned when creating a thread. This value varies across different platforms. The issue is that there isn't enough explanation as to why these values are different, and users might not realize that the stack size can vary. Recently, I was running existing Windows code on a WASI target, and I kept encountering font decoding failures. Since it worked correctly on Windows, I suspected WASI's instability and spent considerable time debugging. After several days, I discovered that the root cause was the stack size: WASI has a very small stack size of 4KB, while Windows has a much larger stack size of 2MB. Once I forcibly increased the thread's stack size, all issues were resolved. I felt quite frustrated that such a simple reason caused the problem. Although this is my personal experience, I believe that rather than setting different default stack sizes for different platforms without a compelling reason, it would be better to have a consistent stack size across all platforms in Rust. However, I acknowledge that this suggestion might not be very effective because the required memory can vary depending on the instruction set or architecture. I would like to discuss this matter further.
Different platforms have different useful minimum stack sizes. I have no idea why only 4KiB is reserved on wasi.
In my opinion, this isn't an issue of "inconsistency" this is an issue of a target having an absurdly low value, period. Please open a PR to raise it.
What are the criteria for determining that? Since I don't know, I can't tell whether the 4KB for WASI is inappropriate or not, and I also can't open a PR because I don't know the appropriate value.
...a zillion insanely low-level minutiae like how big the registers are, mostly. an article that might help: as that article explains, the smallest thread stack size of all platforms that I'm aware of, aside from the ones in our repo that only ask for 4096 bytes, is 64KiB. the current 4096 bytes boundary has caused you significant pain so it seems sensible to raise it to at least that much, then fool around and see how it works.
having done some review of our platform code, I am pretty sure 4096 bytes was just picked as the "unsupported" value and platforms that initially lacked thread support, like wasm32-wasi, just inherited that value.
I understand. The differences between the platforms are indeed huge..! Before proceeding, I would like to hear the opinion or history from Alex Crichton, the main maintainer of the wasi target. , could you please share your thoughts on this issue?
I commented a bit on but I've no recollection for the current value for wasi. I suspect it was a number of historical accidents that led to this, and stack sizes should definitely be larger than 4k by default on wasi. Thanks for the issue

pub struct Thread(!); <del> pub const DEFAULT_MIN_STACK_SIZE: usize = 4096; </del> <ins> pub const DEFAULT_MIN_STACK_SIZE: usize = 64 * 1024; </ins> impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: could not find allocation for alloc3', 'error: internal compiler error: could not find allocation for alloc3' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evalstaticinitializer] evaluating initializer of static [analysis] running analysis passes on this crate -- label +F-extern_types
Regression in nightly-2024-05-23 cc :thinking:
Anyway it doesn't seem to affect the test.
This is not a recent regression, here's a reproducer on stable:
But why?^^ lol XD its just side effect of the fuzzing I guess :D

use std::hash::Hash; use super::{ <del> err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, CheckInAllocMsg, </del> <ins> err_ub, format_interp_error, machine::AllocMap, throw_ub, AllocId, AllocKind, CheckInAllocMsg, </ins> GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar, ValueVisitor, };


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: could not find allocation for alloc3', 'error: internal compiler error: could not find allocation for alloc3' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evalstaticinitializer] evaluating initializer of static [analysis] running analysis passes on this crate -- label +F-extern_types
Regression in nightly-2024-05-23 cc :thinking:
Anyway it doesn't seem to affect the test.
This is not a recent regression, here's a reproducer on stable:
But why?^^ lol XD its just side effect of the fuzzing I guess :D

Ub(PointerOutOfBounds { .. }) => DanglingPtrOutOfBounds { ptr_kind }, <del> // This cannot happen during const-eval (because interning already detects // dangling pointers), but it can happen in Miri. </del> Ub(PointerUseAfterFree(..)) => DanglingPtrUseAfterFree { ptr_kind, },


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: could not find allocation for alloc3', 'error: internal compiler error: could not find allocation for alloc3' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evalstaticinitializer] evaluating initializer of static [analysis] running analysis passes on this crate -- label +F-extern_types
Regression in nightly-2024-05-23 cc :thinking:
Anyway it doesn't seem to affect the test.
This is not a recent regression, here's a reproducer on stable:
But why?^^ lol XD its just side effect of the fuzzing I guess :D

} } <del> // Mutability check. </del> <ins> // Dangling and Mutability check. let (size, _align, alloc_kind) = self.ecx.get_alloc_info(alloc_id); if alloc_kind == AllocKind::Dead { // This can happen for zero-sized references. We can't have *any* references to non-existing // allocations though, interning rejects them all as the rest of rustc isn't happy with them... // so we throw an error, even though this isn't really UB. // A potential future alternative would be to resurrect this as a zero-sized allocation // (which codegen will then compile to an aligned dummy pointer anyway). throw_validation_failure!(self.path, DanglingPtrUseAfterFree { ptr_kind }); } </ins> // If this allocation has size zero, there is no actual mutability here. <del> let (size, _align, _alloc_kind) = self.ecx.get_alloc_info(alloc_id); </del> if size != Size::ZERO { let alloc_actual_mutbl = mutability(self.ecx, alloc_id); // Mutable pointer to immutable memory is no good.


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: could not find allocation for alloc3', 'error: internal compiler error: could not find allocation for alloc3' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evalstaticinitializer] evaluating initializer of static [analysis] running analysis passes on this crate -- label +F-extern_types
Regression in nightly-2024-05-23 cc :thinking:
Anyway it doesn't seem to affect the test.
This is not a recent regression, here's a reproducer on stable:
But why?^^ lol XD its just side effect of the fuzzing I guess :D

} const FOO: &() = { <del> //~^ ERROR encountered dangling pointer </del> <ins> //~^ ERROR it is undefined behavior to use this value </ins> let y = (); unsafe { Foo { y: &y }.long_live_the_unit } };


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: could not find allocation for alloc3', 'error: internal compiler error: could not find allocation for alloc3' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evalstaticinitializer] evaluating initializer of static [analysis] running analysis passes on this crate -- label +F-extern_types
Regression in nightly-2024-05-23 cc :thinking:
Anyway it doesn't seem to affect the test.
This is not a recent regression, here's a reproducer on stable:
But why?^^ lol XD its just side effect of the fuzzing I guess :D

<del> error: encountered dangling pointer in final value of constant </del> <ins> error[E0080]: it is undefined behavior to use this value </ins> --> $DIR/dangling-alloc-id-ice.rs:12:1 | LL | const FOO: &() = { <del> | ^^^^^^^^^^^^^^ </del> <ins> | ^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { HEX_DUMP } </ins> error: aborting due to 1 previous error <ins> For more information about this error, try `rustc --explain E0080`. </ins>


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: could not find allocation for alloc3', 'error: internal compiler error: could not find allocation for alloc3' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evalstaticinitializer] evaluating initializer of static [analysis] running analysis passes on this crate -- label +F-extern_types
Regression in nightly-2024-05-23 cc :thinking:
Anyway it doesn't seem to affect the test.
This is not a recent regression, here's a reproducer on stable:
But why?^^ lol XD its just side effect of the fuzzing I guess :D

<ins> // Strip out raw byte dumps to make comparison platform-independent: //@ normalize-stderr-test "(the raw bytes of the constant) (size: [0-9]*, align: [0-9]*)" -> "$1 (size: $$SIZE, align: $$ALIGN)" //@ normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*A(LLOC)?[0-9]+(+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" //@ normalize-stderr-test "HEX_DUMPs*ns*HEX_DUMP" -> "HEX_DUMP" pub struct Wrapper; pub static MAGIC_FFI_REF: &'static Wrapper = unsafe { //~^ERROR: it is undefined behavior to use this value std::mem::transmute(&{ let y = 42; y }) }; fn main() {} </ins>


Question:
<!-- ICE: Rustc '' 'error: internal compiler error: could not find allocation for alloc3', 'error: internal compiler error: could not find allocation for alloc3' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evalstaticinitializer] evaluating initializer of static [analysis] running analysis passes on this crate -- label +F-extern_types
Regression in nightly-2024-05-23 cc :thinking:
Anyway it doesn't seem to affect the test.
This is not a recent regression, here's a reproducer on stable:
But why?^^ lol XD its just side effect of the fuzzing I guess :D

<ins> error[E0080]: it is undefined behavior to use this value --> $DIR/dangling-zst-ice-issue-126393.rs:7:1 | LL | pub static MAGIC_FFI_REF: &'static Wrapper = unsafe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (use-after-free) | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { HEX_DUMP } error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

variant_index: VariantIdx, ) -> InterpResult<'tcx, Option<(ScalarInt, usize)>> { match self.layout_of(ty)?.variants { <del> abi::Variants::Single { .. } => Ok(None), </del> <ins> abi::Variants::Single { .. } => { // The tag of a `Single` enum is like the tag of the niched // variant: there's no tag as the discriminant is encoded // entirely implicitly. If `write_discriminant` ever hits this // case, we do a "validation read" to ensure the the right // discriminant is encoded implicitly, so any attempt to write // the wrong discriminant for a `Single` enum will reliably // result in UB. Ok(None) } </ins> abi::Variants::Multiple { tag_encoding: TagEncoding::Direct,


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

// We consider three kinds of enums, each demanding a different // treatment of their layout computation: <del> // 1. enums that are uninhabited // 2. enums for which all but one variant is uninhabited // 3. enums with multiple inhabited variants </del> <ins> // 1. enums that are uninhabited ZSTs // 2. enums that delegate their layout to a variant // 3. enums with multiple variants </ins> match layout.variants() { <del> _ if layout.abi.is_uninhabited() => { // Uninhabited enums are usually (always?) zero-sized. In // the (unlikely?) event that an uninhabited enum is // non-zero-sized, this assert will trigger an ICE, and this // code should be modified such that a `layout.size` amount // of uninhabited bytes is returned instead. // // Uninhabited enums are currently implemented such that // their layout is described with `Variants::Single`, even // though they don't necessarily have a 'single' variant to // defer to. That said, we don't bother specifically // matching on `Variants::Single` in this arm because the // behavioral principles here remain true even if, for // whatever reason, the compiler describes an uninhabited // enum with `Variants::Multiple`. assert_eq!(layout.size, Size::ZERO); </del> <ins> Variants::Single { .. } if layout.abi.is_uninhabited() && layout.size == Size::ZERO => { // The layout representation of uninhabited, ZST enums is // defined to be like that of the `!` type, as opposed of a // typical enum. Consequently, they cannot be descended into // as if they typical enums. We therefore special-case this // scenario and simply return an uninhabited `Tree`. </ins> Ok(Self::uninhabited()) } Variants::Single { index } => { <del> // `Variants::Single` on non-uninhabited enums denotes that </del> <ins> // `Variants::Single` on enums with variants denotes that </ins> // the enum delegates its layout to the variant at `index`. layout_of_variant(*index) } Variants::Multiple { tag_field, .. } => { // `Variants::Multiple` denotes an enum with multiple <del> // inhabited variants. The layout of such an enum is the // disjunction of the layouts of its tagged variants. </del> <ins> // variants. The layout of such an enum is the disjunction // of the layouts of its tagged variants. </ins> // For enums (but not coroutines), the tag field is // currently always the first field of the layout.


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

Y(Uninhabited), } <ins> enum MultipleUninhabited { X(u8, Uninhabited), Y(Uninhabited, u16), } </ins> fn main() { assert_transmutable::<Uninhabited>(); assert_transmutable::<SingleInhabited>(); assert_transmutable::<SingleUninhabited>(); <ins> assert_transmutable::<MultipleUninhabited>(); </ins> }


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

} // Non-ZST uninhabited types are, nonetheless, uninhabited. <del> fn yawning_void() { </del> <ins> fn yawning_void_struct() { </ins> enum Void {} struct YawningVoid(Void, u128);


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted } <ins> // Non-ZST uninhabited types are, nonetheless, uninhabited. fn yawning_void_enum() { enum Void {} enum YawningVoid { A(Void, u128), } const _: () = { assert!(std::mem::size_of::<YawningVoid>() == std::mem::size_of::<u128>()); // Just to be sure the above constant actually evaluated: assert!(false); //~ ERROR: evaluation of constant value failed }; // This transmutation is vacuously acceptable; since one cannot construct a // `Void`, unsoundness cannot directly arise from transmuting a void into // anything else. assert::is_maybe_transmutable::<YawningVoid, u128>(); assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted } </ins> // References to uninhabited types are, logically, uninhabited, but for layout // purposes are not ZSTs, and aren't treated as uninhabited when they appear in // enum variants.


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed <del> --> $DIR/uninhabited.rs:65:9 </del> <ins> --> $DIR/uninhabited.rs:63:9 </ins> | LL |         assert!(false); <del> |         ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:65:9 </del> <ins> |         ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:63:9 | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $DIR/uninhabited.rs:87:9 | LL |         assert!(false); |         ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:87:9 </ins> | = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

LL | |         }> | |__________^ required by this bound in `is_maybe_transmutable` <del> error[E0277]: `()` cannot be safely transmuted into `yawning_void::Void` </del> <ins> error[E0277]: `()` cannot be safely transmuted into `yawning_void_struct::Void` </ins> --> $DIR/uninhabited.rs:49:41 | LL |     assert::is_maybe_transmutable::<(), Void>(); <del> |                                         ^^^^ `yawning_void::Void` is uninhabited </del> <ins> |                                         ^^^^ `yawning_void_struct::Void` is uninhabited | note: required by a bound in `is_maybe_transmutable` --> $DIR/uninhabited.rs:10:14 | LL |       pub fn is_maybe_transmutable<Src, Dst>() |              --------------------- required by a bound in this function LL |       where LL |           Dst: BikeshedIntrinsicFrom<Src, { |  ______________^ LL | |             Assume { LL | |                 alignment: true, LL | |                 lifetimes: true, ...  | LL | |             } LL | |         }> | |__________^ required by this bound in `is_maybe_transmutable` error[E0277]: `()` cannot be safely transmuted into `yawning_void_enum::Void` --> $DIR/uninhabited.rs:71:41 | LL |     assert::is_maybe_transmutable::<(), Void>(); |                                         ^^^^ `yawning_void_enum::Void` is uninhabited </ins> | note: required by a bound in `is_maybe_transmutable` --> $DIR/uninhabited.rs:10:14


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

| |__________^ required by this bound in `is_maybe_transmutable` error[E0277]: `u128` cannot be safely transmuted into `DistantVoid` <del> --> $DIR/uninhabited.rs:70:43 </del> <ins> --> $DIR/uninhabited.rs:92:43 </ins> | LL |     assert::is_maybe_transmutable::<u128, DistantVoid>(); |                                           ^^^^^^^^^^^ at least one value of `u128` isn't a bit-valid value of `DistantVoid`


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed'', 'thread 'rustc' panicked at 'assertion failed'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [evaluateobligation] evaluating trait selection obligation [typeck] type-checking -- label +F-transmutability <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
Ah, it's an uninhabited non-ZST!
claim
I guess that answers my ;)

LL | |         }> | |__________^ required by this bound in `is_maybe_transmutable` <del> error: aborting due to 5 previous errors </del> <ins> error: aborting due to 7 previous errors </ins> Some errors have detailed explanations: E0080, E0277. For more information about an error, try `rustc --explain E0080`.


Question:
I worked out this minimal reproducible example from some code I've been working on. Changing almost anything about this causes the compiler crash to go away, which probably makes it a little hard to figure out what's going on here. I've checked and performing a release build, or a debug build with an opt level = 1 will cause the compiler to SIGSEGV. Clearing the target dir, switching between stable/nightly, reinstalling toolchains, updating my system etc. didn't have an effect. Occurs in both Stable and Nightly. : : No backtrace was output. Also attempted to enable LLVM assertions and saw no change in output. Increasing stack size, as per advice, had no effect.
rustc 1.77.0 compiles OK. rustc 1.78.0+ crashes.
Crash in TwoAddressInstructionPass, appears to still occur on LLVM main.
Upstream issue:

<del> Subproject commit e6a6470d1eb4c88fee4b1ea98cd8e0ac4a181c16 </del> <ins> Subproject commit c54cff0e6e4d1a0d0a2df7c1ce3d96cdd554763e </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'', 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [resolverforlowering_raw] getting the resolver for lowering --
I suspect this could be cc
what's the command line to reproduce it? I build nightly version and cannot reproduce it by only compiling the code. also I checked playground:
Ok, got it, we can not use 2021 edition in the command line.

if let Some(candidate) = candidates.get(0) { let path = { // remove the possible common prefix of the path <del> let start_index = (0..failed_segment_idx) .find(|&i| path[i].ident != candidate.path.segments[i].ident) </del> <ins> let len = candidate.path.segments.len(); let start_index = (0..=failed_segment_idx.min(len - 1)) .find(|&i| path[i].ident.name != candidate.path.segments[i].ident.name) </ins> .unwrap_or_default(); <del> let segments = (start_index..=failed_segment_idx) .map(|s| candidate.path.segments[s].clone()) .collect(); </del> <ins> let segments = (start_index..len).map(|s| candidate.path.segments[s].clone()).collect(); </ins> Path { segments, span: Span::default(), tokens: None } }; (


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'', 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [resolverforlowering_raw] getting the resolver for lowering --
I suspect this could be cc
what's the command line to reproduce it? I build nightly version and cannot reproduce it by only compiling the code. also I checked playground:
Ok, got it, we can not use 2021 edition in the command line.

<ins> error[E0583]: file not found for module `config` --> $DIR/suggest-import-ice-issue-127302.rs:3:1 | LL | mod config; | ^^^^^^^^^^^ | = help: to create the module `config`, create file "$DIR/config.rs" or "$DIR/config/mod.rs" = note: if there is a `mod config` elsewhere in the crate already, import it with `use crate::...` instead error: format argument must be a string literal --> $DIR/suggest-import-ice-issue-127302.rs:10:14 | LL |     println!(args.ctx.compiler.display()); |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: you might be missing a string literal to format with | LL |     println!("{}", args.ctx.compiler.display()); |              +++++ error[E0425]: cannot find value `args` in this scope --> $DIR/suggest-import-ice-issue-127302.rs:6:12 | LL |     match &args.cmd { |            ^^^^ not found in this scope | help: consider importing this function | LL + use std::env::args; | error[E0532]: expected unit struct, unit variant or constant, found module `crate::config` --> $DIR/suggest-import-ice-issue-127302.rs:7:9 | LL |         crate::config => {} |         ^^^^^^^^^^^^^ not a unit struct, unit variant or constant error: aborting due to 4 previous errors Some errors have detailed explanations: E0425, E0532, E0583. For more information about an error, try `rustc --explain E0425`. </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'', 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [resolverforlowering_raw] getting the resolver for lowering --
I suspect this could be cc
what's the command line to reproduce it? I build nightly version and cannot reproduce it by only compiling the code. also I checked playground:
Ok, got it, we can not use 2021 edition in the command line.

<ins> //@ revisions: edition2015 edition2021 mod config; //~ ERROR file not found for module fn main() { match &args.cmd { //~ ERROR cannot find value `args` in this scope crate::config => {} //~ ERROR expected unit struct, unit variant or constant, found module `crate::config` } println!(args.ctx.compiler.display()); //~^ ERROR format argument must be a string literal } </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'', 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [resolverforlowering_raw] getting the resolver for lowering --
I suspect this could be cc
what's the command line to reproduce it? I build nightly version and cannot reproduce it by only compiling the code. also I checked playground:
Ok, got it, we can not use 2021 edition in the command line.

<ins> error[E0433]: failed to resolve: unresolved import --> $DIR/suggest-import-issue-120074.rs:12:35 | LL |     println!("Hello, {}!", crate::bar::do_the_thing); |                                   ^^^ unresolved import | help: a similar path exists | LL |     println!("Hello, {}!", crate::foo::bar::do_the_thing); |                                   ~~~~~~~~ help: consider importing this module | LL + use foo::bar; | help: if you import `bar`, refer to it directly | LL -     println!("Hello, {}!", crate::bar::do_the_thing); LL +     println!("Hello, {}!", bar::do_the_thing); | error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0433`. </ins>


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'', 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [resolverforlowering_raw] getting the resolver for lowering --
I suspect this could be cc
what's the command line to reproduce it? I build nightly version and cannot reproduce it by only compiling the code. also I checked playground:
Ok, got it, we can not use 2021 edition in the command line.

<ins> //@ revisions: edition2015 edition2021 </ins> pub mod foo { pub mod bar { pub fn do_the_thing() -> usize {


Question:
<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'', 'thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1'' File: --auto-reduced (treereduce-rust): <details<summary<strongoriginal code</strong</summary<poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [resolverforlowering_raw] getting the resolver for lowering --
I suspect this could be cc
what's the command line to reproduce it? I build nightly version and cannot reproduce it by only compiling the code. also I checked playground:
Ok, got it, we can not use 2021 edition in the command line.

<del> error[E0433]: failed to resolve: unresolved import --> $DIR/suggest-import-issue-120074.rs:10:35 | LL |     println!("Hello, {}!", crate::bar::do_the_thing); |                                   ^^^ unresolved import | help: a similar path exists | LL |     println!("Hello, {}!", crate::foo::bar::do_the_thing); |                                   ~~~~~~~~ help: consider importing this module | LL + use foo::bar; | help: if you import `bar`, refer to it directly | LL -     println!("Hello, {}!", crate::bar::do_the_thing); LL +     println!("Hello, {}!", bar::do_the_thing); | error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0433`. </del>


Question:
The struct is meant to not be constructible. Also the behavior is incoherent between tuple structs (correct behavior) and named structs (incorrect behavior). Also, this is a regression, this didn't use to be the case. No response No response
label +F-never_Type +D-inconsistent
We will also get such warnings for private structs with fields of never type (): The struct is never constructed although it is not constructible. This behavior is expected and is not a regression. Did you meet any cases using this way in real world? For the incoherent behavior, we also have: This because we only skip positional ZST (PhantomData and generics), this policy is also applied for never read fields:
Can you elaborate in which sense it is expected? I can understand that it is expected given the current implementation of Rust. It seems between stable and nightly a new lint was implemented. This lint is expected for inhabited types. However it has false positives on inhabited types, i.e. types that are only meant for type-level usage (for example to implement a trait). I agree we should probably categorize this issue as a false positive of a new lint rather than a regression (technically). Thanks, I can see the idea behind it. I'm not convinced about it though, but it doesn't bother me either. So let's just keep this issue focused on the false positive rather than the inconsistent behavior.
How do you think about private structs with fields of never type?
I would consider it the same as public structs, because they can still be "constructed" at the type-level. So they are dynamic dead--code but not dead-code since they are used statically. It would be dead-code though if the type is never used (both in dynamic code and static code, i.e. types).
Actually, thinking about this issue, I don't think this is a false positive only for the never type. I think the whole lint is wrong. The fact that the type is empty is just a proof that constructing it at term-level is not necessary for the type to be "alive" (aka usable). This could also be the case with non-empty types. A lot of people just use unit types for type-level usage only (instead of empty types). So my conclusion would be that linting a type to be dead-code because it is never constructed is brittle as it can't be sure that the type is not meant to be constructed at term-level (and thus only used at type-level). Adding is not a solution because if the type is actually not used at all (including in types) then we actually want the warning. Here is an example: The same thing with a private struct: And now actual dead code:
I think a better way is: is usually used to do such things like just a proof. Maybe we can add a help for this case.
But I agree that we shouldn't emit warnings for pub structs with any fields of never type (and also unit type), this is an intentional behavior.
Oh yes good point. So all good to proceed with adding never type to the list of special types.
Thanks a lot for the quick fix! Once it hits nightly, I'll give it a try. I'm a bit afraid though that this won't fix the underlying problem of understanding which types are not meant to exist at runtime. For example, sometimes instead of using the never type, I also use empty enums such that I can give a name and separate identity to that type. Let's see if it's an issue. If yes, I guess ultimately there would be 2 options: Just use in those cases. Introduce a trait (or better name) for types that are not meant to exist at runtime like unit, never, and phantom types, but could be extended with user types like empty enums. I'll ping this thread again if I actually hit this issue.
I could test it (using nightly-2024-08-01) and . I just had to change a to in a crate where I didn't have already. Ultimately, is going to be a type alias for so maybe it's not worth supporting it. And thinking about empty enums, this should never be an issue for my particular usage, which is to build empty types. Because either the type takes no parameters in which case I use an empty enum directly. Or it takes parameters and I have to use a struct with fields, and to make the struct empty I also have to add a never field. So my concern in the previous message is not an issue for me.

} fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: LocalDefId) -> bool { <del> // treat PhantomData and positional ZST as public, // we don't want to lint types which only have them, // cause it's a common way to use such types to check things like well-formedness tcx.adt_def(id).all_fields().all(|field| { </del> <ins> let adt_def = tcx.adt_def(id); // skip types contain fields of unit and never type, // it's usually intentional to make the type not constructible let not_require_constructor = adt_def.all_fields().any(|field| { </ins> let field_type = tcx.type_of(field.did).instantiate_identity(); <del> if field_type.is_phantom_data() { return true; } let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit()); if is_positional && tcx .layout_of(tcx.param_env(field.did).and(field_type)) .map_or(true, |layout| layout.is_zst()) { return true; } field.vis.is_public() }) </del> <ins> field_type.is_unit() || field_type.is_never() }); not_require_constructor || adt_def.all_fields().all(|field| { let field_type = tcx.type_of(field.did).instantiate_identity(); // skip fields of PhantomData, // cause it's a common way to check things like well-formedness if field_type.is_phantom_data() { return true; } field.vis.is_public() }) </ins> } /// check struct and its fields are public or not,


Question:
The struct is meant to not be constructible. Also the behavior is incoherent between tuple structs (correct behavior) and named structs (incorrect behavior). Also, this is a regression, this didn't use to be the case. No response No response
label +F-never_Type +D-inconsistent
We will also get such warnings for private structs with fields of never type (): The struct is never constructed although it is not constructible. This behavior is expected and is not a regression. Did you meet any cases using this way in real world? For the incoherent behavior, we also have: This because we only skip positional ZST (PhantomData and generics), this policy is also applied for never read fields:
Can you elaborate in which sense it is expected? I can understand that it is expected given the current implementation of Rust. It seems between stable and nightly a new lint was implemented. This lint is expected for inhabited types. However it has false positives on inhabited types, i.e. types that are only meant for type-level usage (for example to implement a trait). I agree we should probably categorize this issue as a false positive of a new lint rather than a regression (technically). Thanks, I can see the idea behind it. I'm not convinced about it though, but it doesn't bother me either. So let's just keep this issue focused on the false positive rather than the inconsistent behavior.
How do you think about private structs with fields of never type?
I would consider it the same as public structs, because they can still be "constructed" at the type-level. So they are dynamic dead--code but not dead-code since they are used statically. It would be dead-code though if the type is never used (both in dynamic code and static code, i.e. types).
Actually, thinking about this issue, I don't think this is a false positive only for the never type. I think the whole lint is wrong. The fact that the type is empty is just a proof that constructing it at term-level is not necessary for the type to be "alive" (aka usable). This could also be the case with non-empty types. A lot of people just use unit types for type-level usage only (instead of empty types). So my conclusion would be that linting a type to be dead-code because it is never constructed is brittle as it can't be sure that the type is not meant to be constructed at term-level (and thus only used at type-level). Adding is not a solution because if the type is actually not used at all (including in types) then we actually want the warning. Here is an example: The same thing with a private struct: And now actual dead code:
I think a better way is: is usually used to do such things like just a proof. Maybe we can add a help for this case.
But I agree that we shouldn't emit warnings for pub structs with any fields of never type (and also unit type), this is an intentional behavior.
Oh yes good point. So all good to proceed with adding never type to the list of special types.
Thanks a lot for the quick fix! Once it hits nightly, I'll give it a try. I'm a bit afraid though that this won't fix the underlying problem of understanding which types are not meant to exist at runtime. For example, sometimes instead of using the never type, I also use empty enums such that I can give a name and separate identity to that type. Let's see if it's an issue. If yes, I guess ultimately there would be 2 options: Just use in those cases. Introduce a trait (or better name) for types that are not meant to exist at runtime like unit, never, and phantom types, but could be extended with user types like empty enums. I'll ping this thread again if I actually hit this issue.
I could test it (using nightly-2024-08-01) and . I just had to change a to in a crate where I didn't have already. Ultimately, is going to be a type alias for so maybe it's not worth supporting it. And thinking about empty enums, this should never be an issue for my particular usage, which is to build empty types. Because either the type takes no parameters in which case I use an empty enum directly. Or it takes parameters and I have to use a struct with fields, and to make the struct empty I also have to add a never field. So my concern in the previous message is not an issue for me.

#![forbid(dead_code)] #[derive(Debug)] <del> pub struct Whatever { //~ ERROR struct `Whatever` is never constructed </del> <ins> pub struct Whatever { </ins> pub field0: (), <del> field1: (), </del> <ins> field1: (), //~ ERROR fields `field1`, `field2`, `field3`, and `field4` are never read </ins> field2: (), field3: (), field4: (),