Question: let mut buf = [0; 2]; self.code_points.next().map(|code_point| { <del> let c = unsafe { char::from_u32_unchecked(code_point.value) }; let n = c.encode_utf16(&mut buf).len(); </del> <ins> let n = char::encode_utf16_raw(code_point.value, &mut buf).len(); </ins> if n == 2 { self.extra = buf[1]; }

The following program causes UB: Miri says: The problem is this code: This calls unless the new code point is in , but what about surrogates in ? This code is unchanged since its introduction in I am not sure what the intended safety contract of is. That method is not marked but clearly should be -- it calls . So my guess is the safety precondition is that must not be part of a surrogate pair, but the thing is, calls it without actually ensuring that condition. The condition it does ensure is that the codepoint is not in , but that does not help.
is excluded from Unicode scalar values a.k.a. , but it’s fine as a Unicode code point. I think this bug is not in the contract of (which is private anyway) but in its implementation, namely going through . The fix is to either duplicate the logic of into , or (to avoid duplication) move that logic to a new function in libcore that takes a parameter and that is called by both and . This function would need to be public because is in a different crate, but it should be prema-unstable and .
I would classify the priority of this bug as low. Although this call to is UB, I expect Miri checking for it explicitly is the only case where that has any consequence in today’s implementation: behaves as expected (for the purpose of WTF-8) in the surrogate range and does not exploit this UB The "layout" of in rustc excludes values beyond but not surrogates:
By the way, the docs at feel insufficient: Which values are invalid? Similarly, and say that represents Unicode Scalar values, but I couldn’t find it documented anywhere that constructing an out of range is Undefined Behavior rather than "merely" a logic bug. Is this specified elsewhere? What is the closest we have to a written down normative resource that specifies what is or isn’t UB in the the Rust language? (For APIs I assume this is the responsibility of their respective doc-comments.)
I agree the impact is low, but it's not just Miri -- this blocks , which is how I discovered the problem. That would be
But then what is "unchecked" about it? Elsewhere in that file the code is careful not to construct a from a without checking for surrogates: That made me assume the author was aware that surrogates in are UB.


Question: let mut buf = [0; 2]; self.code_points.next().map(|code_point| { <del> let c = unsafe { char::from_u32_unchecked(code_point.value) }; let n = c.encode_utf16(&mut buf).len(); </del> <ins> let n = char::encode_utf16_raw(code_point.value, &mut buf).len(); </ins> if n == 2 { self.extra = buf[1]; }

The type contains a (generalized-UTF-8-encoded) sequence of code point (including potentially surrogates) that doesn’t form a surrogate pair. doesn’t check for surrogate pairs. is a public method that is documented as returning a scalar value, therefore excluding all surrogates. Ok I looked into it, there are three different people involved. The original code in 2014 was YOLO Later in 2014, moved to duplicating logic instead. In 2015, PR which first imported WTF-8 support in libstd deduplicated that logic by adding a function that takes . (I knew that approach sounded familiar…) In 2016, PR changed the signature of and in passing removed . It made use + instead, presumably in the middle of updating many callers other.
Okay, so the fix would be to revert the part of that removed ?
That or copy into . I find them both not great, so meh.
Even with that done, there's still UB in another testcase: This is converting something to a before calling -- so probably the same issue as the above, just for a different encoding.


Question: #![omit_gdb_pretty_printer_section] <del> // ignore-android: FIXME(#10381) </del> // min-lldb-version: 310 // aux-build:cross_crate_spans.rs

Triggers an LLVM assertion when targeting Android:
Something that works on any host (i.e. you needn’t compile libstd for android to repro):
As the error says, isn't a supported calling convention for the ARM target in LLVM. Not really much we can do from the rustc side unless we want to error early based on cc/target combinations. In any case, it should not crash.
I'm hitting this when I tried to run tests for 1.10.0 on arm64 (aarch64-unknown-linux-gnu). The build succeeds otherwise. I'm just adding and to for the time being.
Neither example crashes today. Closing, since I don't see any good opportunity for a test here (it'd have to be something like and that's probably not worth it). With (original example): Updated example:


Question: /// If the hash of the input doesn't match or no input is supplied via None, /// it is interpreted as an error and the corresponding enum variant is set. /// The return value signifies whether some kind of source is present. <del> pub fn add_external_src(&self, src: Option<String>) -> bool { </del> <ins> pub fn add_external_src<F>(&self, get_src: F) -> bool where F: FnOnce() -> Option<String> { </ins> if *self.external_src.borrow() == ExternalSource::AbsentOk { <ins> let src = get_src(); </ins> let mut external_src = self.external_src.borrow_mut(); if let Some(src) = src { let mut hasher: StableHasher<u128> = StableHasher::new();

In investigating I was generating some source code, and using the shell script listed in we can see: That's a lot of time to expand a crate that doesn't have any macros in it!
cc you may be interested in this!
A looks like almost all the time is spent in In which case, cc
Apparently most time is spent
called ~38k times
Since we need to build the module graph and resolve imports during expansion for macros 2.0, we must construct node ids and def ids throughout expansion (i.e. interleaved arbitrarily many times until we hit fix-point). Ideally we'd keep running totals of the time spent assigning node ids, assigning def ids, etc. for more accurate profiling information within the expansion step.
in theory though isn't the fixed point for this crate the crate itself? (e.g. there's no macros here). Or are the def ids persisted for the rest of compilation, so "blaming" expansion isn't quite correct here?
Yeah, the def ids are persisted for the rest of compilation. We could move the "first round" of def id collection (in which we collect the raw, unexpanded source) outside of expansion, but that would introduce more code complexity and wouldn't count the time we spend collecting def ids for AST that comes from macro expansions.
Ah ok, nah it seems fine! I think there's a number of cases where is attributing time in the wrong place nowadays... Still it seems odd that 30-50k invocations of this function would take so long to execute?
Do I understand this correctly that all DefIds generated are actually used, right? There are no "temporary" DefIds? Each of these invocations creates a Blake2 hasher. I'd be interested how the performance looks with other hashing algorithms. I'd like to switch to something faster anyway:
Are you sure this isn't the other quadratic case fixed in ?
It may very well be! Feel free to close this w/ that PR landing, I'll verify to be sure but I'd imagine you're correct in that it's fixed by
er, didn't mean to close just yet


Question: /// If the hash of the input doesn't match or no input is supplied via None, /// it is interpreted as an error and the corresponding enum variant is set. /// The return value signifies whether some kind of source is present. <del> pub fn add_external_src(&self, src: Option<String>) -> bool { </del> <ins> pub fn add_external_src<F>(&self, get_src: F) -> bool where F: FnOnce() -> Option<String> { </ins> if *self.external_src.borrow() == ExternalSource::AbsentOk { <ins> let src = get_src(); </ins> let mut external_src = self.external_src.borrow_mut(); if let Some(src) = src { let mut hasher: StableHasher<u128> = StableHasher::new();

A of Servo's crate shows a huge amount of time (46 seconds!) in name resolution. It turns out that is calling , specifically . That's a lot of unused imports! Sure enough if we create a synthetic file locally with this script: we find: That's a lot of time spent processing unused imports! The slowdown here isn't quite the same as the style crate, unfortunately. The style crate only has ~7k unused imports, which apparently takes it 48s in that profile. In any case the intent here is clear, lots of unused imports seem to slow down compilation, and the crate looks to have a lot of unused imports!
cc
We could address this quickly by just emitting the first 10 unused imports warnings and then warning that there are more unused imports not shown.
I can never deal with more than 10 lints at a time anyway myself, so seems like a reasonable solution to me!
Dumping out a ton of warnings is useful when you're hooked into an IDE and you can see them as e.g. green squiggles under the offending text as opposed to 10k lines on a terminal.
I think the reason is slow is because it calls , which does this: I don't think we want to read source files multiple times like that.
Thank you for looking into Servo compile times Alex, and great find here! Could you CC me or someone from the Servo team for Servo-related issues? Thanks.
Can do!
In general I've always wanted the lint system to avoid even running in blocks. Currently the lint system runs all lints in parallel on the tree. This is great since it means we only traverse it once, and the cost of the traversal is consolidated. We don't need to reduce that cost itself (which is nice because then we don't have to worry about inside ). Most lints do not maintain state. The lint framework has the capability to do so, and we use this a couple times in Clippy, but most lints are , so they won't notice if or whatever isn't called in a region of . The "allowness" of a lint is tied to where in the tree the lint traversal is, not the span emitted by the lint.


Question: /// If the hash of the input doesn't match or no input is supplied via None, /// it is interpreted as an error and the corresponding enum variant is set. /// The return value signifies whether some kind of source is present. <del> pub fn add_external_src(&self, src: Option<String>) -> bool { </del> <ins> pub fn add_external_src<F>(&self, get_src: F) -> bool where F: FnOnce() -> Option<String> { </ins> if *self.external_src.borrow() == ExternalSource::AbsentOk { <ins> let src = get_src(); </ins> let mut external_src = self.external_src.borrow_mut(); if let Some(src) = src { let mut hasher: StableHasher<u128> = StableHasher::new();

It's perfectly possible to a block of code and have the lint still be emit there because a different block of code (where it is ) hit the lint but emitted a span it got from elsewhere. We've had trouble with this before in clipyp iirc. All of this enables this proposal: If we had a specialized trait for this, then when we have an we can turn off calling lint methods entirely, and when there's a turn it on again. It doesn't even have to be a trait, really, it could just be a defaulted fake-static method (until happens) on LateLintPass. I suspect this will get significant speedups for crates like Style. I may_ be able to take a crack at this if y'all think this is a good approach.
It occurs to me that a boolean check per lint each tree node might actually end up being more expensive? I'll have look at this code closer. Might be possible to make this fast by having a second array of trait objects which only contains the active lint passes.
It seems like we do a large enough amount of work that the whole "vector of active lints" stuff won't really be necessary. However, I just realized that this bug is not during the lint pass but during the resolution phase (which defers linting to the actual lint pass). This won't be able to help, though we can fix it by doing the spantosnippet in the actual lint and then making this optimization. So in that case I suspect this optimization is unnecessary. In general we've rarely had performance issues with lints in clippy (which has way more lints than rustc), and we've been pretty careful to measure impact there. Still, if folks think this optimization can help, let me know.


Question: <ins> #![feature(const_generics)] #![allow(incomplete_features)] struct Test(*const usize); type PassArg = (); unsafe extern "C" fn pass(args: PassArg) { println!("Hello, world!"); } impl Test { pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline::<Args, IDX, FN> as _ } unsafe extern "C" fn trampiline< Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { FN(args) } } fn main() { let x = Test(); x.call_me::<PassArg, 30, pass>() } </ins>

I've tried reducing this but wasn't really able to so far. I might try again some other time. The code below currently ICEs on Nightly (). When trying to reproduce locally for the backtrace, I had an older Nightly first () where this actually didn't crash the compiler, so it's apparently a regression. <details<summary<strongBacktrace</strong</summary<p</p</details
This is my first time using cargo-bisect-rustc and it's fantastic. It identified the regression as... searched nightlies: from nightly-2020-02-13 to nightly-2020-05-14 regressed nightly: nightly-2020-03-20 searched commits: from to regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.5.2</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details
is a rollup commit. The only PR which was part of that and (to me) looks like it could have caused this issue is .
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.


Question: <ins> #![feature(const_generics)] #![allow(incomplete_features)] struct Test(*const usize); type PassArg = (); unsafe extern "C" fn pass(args: PassArg) { println!("Hello, world!"); } impl Test { pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline::<Args, IDX, FN> as _ } unsafe extern "C" fn trampiline< Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { FN(args) } } fn main() { let x = Test(); x.call_me::<PassArg, 30, pass>() } </ins>

produces: <details</detailsIt should not be possible to access the type parameter in the type of the const parameter. cc Thanks to for .
Hi, I am new to rust compiler development and have decided to try to fix this issue to get started. If I understand the const-generics RFC correctly, type parameters can not be used in a const generic parameter because it cannot be ensured that the actual types have the "structural match" property. However, checking reveals that fn pointers (as well as raw pointers and empty arrays) always support structural matching, regardless of the types used within. My question is: is there another reason why const generic parameters are not allowed to use type parameters? If so, I think an additional check has to be to .
Actually, I think I may have interpreted. It looks like this example is intended to work to me. cc just to clarify.
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.


Question: <ins> #![feature(const_generics)] #![allow(incomplete_features)] struct Test(*const usize); type PassArg = (); unsafe extern "C" fn pass(args: PassArg) { println!("Hello, world!"); } impl Test { pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline::<Args, IDX, FN> as _ } unsafe extern "C" fn trampiline< Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { FN(args) } } fn main() { let x = Test(); x.call_me::<PassArg, 30, pass>() } </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. -- <!-- 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. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p
Probably related to
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.


Question: <ins> #![feature(const_generics)] #![allow(incomplete_features)] struct Test(*const usize); type PassArg = (); unsafe extern "C" fn pass(args: PassArg) { println!("Hello, world!"); } impl Test { pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) { //~^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline::<Args, IDX, FN> as _ } unsafe extern "C" fn trampiline< Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { FN(args) } } fn main() { let x = Test(); x.call_me::<PassArg, 30, pass>() } </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. -- <!-- 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. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p
Depends on const generics in type dependent paths afaict. See for more info. EDIT: Also depends on const generics with generic types. Merging does not close this issue
Triage: the feature was removed by and the ICE no longer occurs with the latest nightly.
Adding the following as a test might still be useful, even if it only errors with "using function pointers as const parameters is forbidden":


Question: #[stable(feature = "unicode_encode_char", since = "1.15.0")] #[inline] pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] { <del> let mut code = self as u32; // SAFETY: each arm checks whether there are enough bits to write into unsafe { if (code & 0xFFFF) == code && !dst.is_empty() { // The BMP falls through (assuming non-surrogate, as it should) *dst.get_unchecked_mut(0) = code as u16; slice::from_raw_parts_mut(dst.as_mut_ptr(), 1) } else if dst.len() >= 2 { // Supplementary planes break into surrogates. code -= 0x1_0000; *dst.get_unchecked_mut(0) = 0xD800 | ((code >> 10) as u16); *dst.get_unchecked_mut(1) = 0xDC00 | ((code as u16) & 0x3FF); slice::from_raw_parts_mut(dst.as_mut_ptr(), 2) } else { panic!( "encode_utf16: need {} units to encode U+{:X}, but the buffer has {}", from_u32_unchecked(code).len_utf16(), code, dst.len(), ) } } </del> <ins> encode_utf16_raw(self as u32, dst) </ins> } /// Returns `true` if this `char` has the `Alphabetic` property.


Question: #[stable(feature = "unicode_encode_char", since = "1.15.0")] #[inline] pub fn encode_utf16(self, dst: &mut [u16]) -> &mut [u16] { <del> let mut code = self as u32; // SAFETY: each arm checks whether there are enough bits to write into unsafe { if (code & 0xFFFF) == code && !dst.is_empty() { // The BMP falls through (assuming non-surrogate, as it should) *dst.get_unchecked_mut(0) = code as u16; slice::from_raw_parts_mut(dst.as_mut_ptr(), 1) } else if dst.len() >= 2 { // Supplementary planes break into surrogates. code -= 0x1_0000; *dst.get_unchecked_mut(0) = 0xD800 | ((code >> 10) as u16); *dst.get_unchecked_mut(1) = 0xDC00 | ((code as u16) & 0x3FF); slice::from_raw_parts_mut(dst.as_mut_ptr(), 2) } else { panic!( "encode_utf16: need {} units to encode U+{:X}, but the buffer has {}", from_u32_unchecked(code).len_utf16(), code, dst.len(), ) } } </del> <ins> encode_utf16_raw(self as u32, dst) </ins> } /// Returns `true` if this `char` has the `Alphabetic` property.


Question: .lifetime_ribs .iter() .rev() <del> .take_while(|rib| !matches!(rib.kind, LifetimeRibKind::Item)) </del> <ins> .take_while(|rib| { !matches!(rib.kind, LifetimeRibKind::Item | LifetimeRibKind::ConstParamTy) }) </ins> .flat_map(|rib| rib.bindings.iter()) .map(|(&ident, &res)| (ident, res)) .filter(|(ident, _)| ident.name != kw::UnderscoreLifetime)

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- 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. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
searched nightlies: from nightly-2023-02-17 to nightly-2023-02-19 regressed nightly: nightly-2023-02-18 searched commit range: regressed commit: - -cc <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.6</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details


Question: ///   both arguments were negative, then it is -0.0. Subtraction `a - b` is ///   regarded as a sum `a + (-b)`. /// <del> /// For more information on floating point numbers, see [Wikipedia][wikipedia]. </del> <ins> /// For more information on floating-point numbers, see [Wikipedia][wikipedia]. </ins> /// /// *[See also the `std::f32::consts` module](crate::f32::consts).* ///

Pointed out by in the float docs are using the term "arithmetic" operations in a few places, but that term is never defined. Furthermore, the new NaN docs probably should use that term as well when discussing which operations the NaN rules apply to (instead of "non-bitwise floating point operations" which they use currently). By "arithmetic operations", the docs likely mean all operations except for unary , , , , , and .


Question: "num_cpus", "ordslice", "racer", <del> "rand 0.6.1", </del> <ins> "rand 0.7.0", </ins> "rayon", "regex", "rls-analysis",

Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool rls no longer builds. A follow-up PR to the repository is needed to fix the fallout. cc do you think you would have time to do the follow-up work? If so, that would be great! cc the PR reviewer, and nominating for compiler team prioritization.


Question: AR_x86_64_pc_solaris=x86_64-pc-solaris2.10-ar  CC_x86_64_pc_solaris=x86_64-pc-solaris2.10-gcc  CXX_x86_64_pc_solaris=x86_64-pc-solaris2.10-g++  <ins> AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar  CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc  CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++  </ins> CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-8  CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-8  AR_x86_64_fortanix_unknown_sgx=ar

removed the alias of to , but as far as I can tell did not remove the target itself. After inquiring on Zulip, it was pointed out that the target was demoted to tier three, meaning builds are no longer provided. It appears this was done with no discussion, warning, or even a mention in the release notes. Given that the target hasn't been around for that long (I think? feel free to tell me I'm wrong), I think this change should be reverted. My CI unexpectedly failed after being unable to download the target, and the only solution that wouldn't involve a notable increase in complexity of the CI script is to outright remove the checks for Solaris/Illumos — a let loss for everyone. cc
I think my feeling right now is that we should likely re-enable the sun-solaris target alongside the pc-solaris, I don't think that should be a major problem for CI times or similar. I will see if we can do this in time for 1.52.1, but if it ends up being harder than expected, I think it's likely that either a) we'll push it out to a 1.52.2 release later in the cycle, or simply leave it to 1.53. For the time being, tagging as 1.53.
I will note that the change itself is fine, of course, it's the suddenness and unexpectedness of it that caught me by surprise.
I think it is likely true that we'll eventually drop the sun target, but it does seem like we should communicate that change better at least. Certainly the newly merged target tier policy suggests just that:
It is not clear to me what the impact of was. In particular, the produced target was not changed in , but I guess the target definition is sort of for pc... I think I am not sufficiently confident in moving in a particular direction here - and a full revert does not seem quite right either - so I will likely say this should be left for at least 1.52.2 or 1.53.0. cc as well, who reviewed
Removal of the older target was certainly not my intent; if that happened due to , I am sorry. Both and are there and both targets are usable when compiling with , but I guess that change to one of files might have resulted in artifacts necessary for no longer being available.


Question: AR_x86_64_pc_solaris=x86_64-pc-solaris2.10-ar  CC_x86_64_pc_solaris=x86_64-pc-solaris2.10-gcc  CXX_x86_64_pc_solaris=x86_64-pc-solaris2.10-g++  <ins> AR_x86_64_sun_solaris=x86_64-sun-solaris2.10-ar  CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc  CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++  </ins> CC_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-gcc-8  CXX_armv7_unknown_linux_gnueabi=arm-linux-gnueabi-g++-8  AR_x86_64_fortanix_unknown_sgx=ar

I created , which I believe should bring back the ability to the old target.
Reopening to track the illumos target work. I'm not sure it's a release blocker, but would like to not lose sight.
The remaining bug in this issue -- the change in the compiler used to build illumos to be based on a -pc- triple, not -sun- here is not a release blocker.
Realistically I don't think there's anything actionable here, so I'm going to go ahead and close this.


Question: <ins> // edition:2018 use std::sync::{Arc, Mutex}; pub async fn f(_: ()) {} pub async fn run() { let x: Arc<Mutex<()>> = unimplemented!(); f(*x.lock().unwrap()).await; } </ins>

rustc+cargo 1.40.0 Debian testing packages report the following ICE (which does not go away after a cargo clean): It can be reproduced by trying to build against
Can you try this on nightly?
Once the ICEBreakers-CleanupCrew is announced (which I think will be happening very soon), we should advertise this bug on it (at least the reduction to MCVE part of it); see
triage: P-high for initial investigation (i.e. identifying actual severity), removing nomination.
ping icebreakers-cleanup-crew
Hey Cleanup Crew ICE-breakers! This bug has been identified as a good "Cleanup ICE-breaking candidate". In case it's useful, here are some [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 [instructions]: https://rust- cc
Note that when I had a go at building on my Mac laptop, it failed with this message: This is due to in the source crate: So if you are on a Mac laptop, it may or may not be worth your effort to investigate this. (It is probably easy to work around, but I figure I'd let people know up front.)
Oops, right, you'll want to just drop that line. It shouldn't have any other effect, its only there due to (at least previously, based on my super-cursory read) libstd calling regular fsync() on OSX, which historically, well, didn't fsync.
I looked at this a bit more. I see the ICE on stable and beta. I do not see the ICE on nightly.


Question: <ins> // edition:2018 use std::sync::{Arc, Mutex}; pub async fn f(_: ()) {} pub async fn run() { let x: Arc<Mutex<()>> = unimplemented!(); f(*x.lock().unwrap()).await; } </ins>

On nightly, I instead get the following error: <details<summaryClick here to see error diagnostics</summary</details
Possibly associated: Possibly associated: I am not seeing the ICE in: searched nightlies: from nightly-2019-10-01 to nightly-2019-11-01 regressed nightly: nightly-2019-10-08 searched commits: from to regressed commit: source code: built against <details<summaryCOLLAPSIBLE ERROR STACKTRACE</summary<p</detailssearched nightlies: from nightly-2019-11-01 to nightly-2020-01-31 fixed nightly: nightly-2019-12-08 searched commits: from to fix commit: source code: built against Possibly here: -
Reduced for in the crate (still depends on ):
This is happening somewhere in item-bodies checking, if I remove the body of with the error goes away.
Ok, I don't have more time to spend on this, I pushed some deletions to
Got it down to two files, but they have to be in different crates: : :
A little smaller: : : <details<summarybacktrace</summary</details
This is a duplicate of , judging by the error message and the fact that I just confirmed as the fixing commit for the reduced example that I created over there. modify labels to -E-needs-mcve.


Question: <ins> // edition:2018 use std::sync::{Arc, Mutex}; pub async fn f(_: ()) {} pub async fn run() { let x: Arc<Mutex<()>> = unimplemented!(); f(*x.lock().unwrap()).await; } </ins>

Take the following code: Attempting to compile this results in the following: I think the compiler should fail with something along the lines of "you attempted to use a complex type () where I expected an immediate".
edit: not sure if these symptoms are the same, but here's what I stumbled across. The following code generates a similar result for me: The and struct seem to be required, else the ICE is not triggered. Output
No longer reproduces:


Question: <ins> // edition:2018 use std::sync::{Arc, Mutex}; pub async fn f(_: ()) {} pub async fn run() { let x: Arc<Mutex<()>> = unimplemented!(); f(*x.lock().unwrap()).await; } </ins>

We handle intrinsics in an odd way, we "inline" them in the current crate, and this might be a symptom of that twisted logic.
intrinsic-ABI functions should probably be disallowed as function pointers. That is, you should only be allowed to call them. This is the current situation, as calls to intrinsics actually just generate code at the call site.
That's not the problem, really, I believe we already have code to generate the shims. The problem is that we don't resolve intrinsics sanely and we rely on the ABI in the type, instead of always dealing with the paths to them and whatnot.
I don't think we have code for creating the shims, even. It's more that the ABI isn't actually defined anywhere, and we use an alternate callee to avoid generating an actual call.
We haven't had code for generating shims around intrinsics for a long time. As alludes to, this is because in almost all cases the actual function would be one or two instructions long. This is consistent with how C/C++ compilers handle intrinsics, generating code inline. Best I can tell, whether or not a given intrinsic can be used as a function in C is dependent on the intrinsic in question.
No longer ICEs ()
It requires now.
Ah, ok. Still no longer ICEs, but fails with a linker error (), if the distinction matters.
I think this has been fixed -- marking as E-needstest. Did you mean to self-assign this?
This seems like it could be made into an easy issue for newcomers.
This is now caught by .


Question: <ins> // edition:2018 use std::sync::{Arc, Mutex}; pub async fn f(_: ()) {} pub async fn run() { let x: Arc<Mutex<()>> = unimplemented!(); f(*x.lock().unwrap()).await; } </ins>

rustc just crashes with no useful errors. I guess you're not supposed to be able to do this anyway and it works if either are const instead of static but it shouldn't crash. Tested with latest nightly and 1.0.0-beta.2 on windows 64-bit.
No longer crashes:
E-needstest.
Triage: not aware of any tests being .
It seems that the E0394 error was removed in and the tests were moved from compile-fail and ui/error-codes to run-pass.


Question: E0242, // internal error looking up a definition E0245, // not a trait //  E0246, // invalid recursive type <ins> //  E0247, </ins> //  E0319, // trait impls for defaulted traits allowed just for structs/enums E0320, // recursive overflow during dropck E0328, // cannot implement Unsize explicitly

rustc crashes when compiling the following source code. I expect this to compile or report error. Instead the compiler crashed.
Reduced testcase:
This also causes an ICE with the latest nightly:
Any update on the issue. Please let me know if you need more information. Thanks


Question: <ins> #![feature(inherent_associated_types)] #![allow(incomplete_features)] // Check that we don't crash when printing inherent projections in diagnostics. struct Foo<T>(T); impl<'a> Foo<fn(&'a ())> { type Assoc = &'a (); } fn main(_: for<'a> fn(Foo<fn(&'a ())>::Assoc)) {} //~ ERROR `main` function has wrong type </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- 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. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
cc is this fixed by one of your PRs? This looked like it might be , but while was bisected to this one was bisected to , not sure what to make of it :thinking:
Yes, this issue is fixed in (ice → errors): <details<summarystderr</summary</detailsI'm not sure why the bisection points differ, they all share the same root cause. It doesn't really matter though. Btw, I saw about another new reproducer but I dismissed it as irrelevant since I assumed it required , too (I did run it but didn't notice I could omit that flag). Sorry about that. Thanks for opening a separate issue because now we actually have 2 beautiful regression tests for the bug fixed in ! So let's not close this issue then but wait for to get merged and then I will open a separate PR with the regression tests & assign you. claim


Question: { eprintln!( " <del> Couldn't find required command: ninja You should install ninja, or set `ninja=false` in config.toml in the `[llvm]` section. </del> <ins> Couldn't find required command: ninja (or ninja-build) You should install ninja as described at <https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages>, or set `ninja = false` in the `[llvm]` section of `config.toml`. Alternatively, set `download-ci-llvm = true` in that `[llvm]` section to download LLVM rather than building it. </ins> " ); std::process::exit(1);

I'm trying to build the compiler for the first time, following the instructions at https://rustc-dev- One of: documentation at https://rustc-dev- explaining how to install , or documentation at https://rustc-dev- saying to set in the section of , or to be installed automatically by , or to be set automatically by default by ; and a solution for the error.
Here's the backtrace:
Adding an section with to in the root does not appear to make any difference:
The next thing I tried was to uninstall and install , which resulted in this error instead:
You can set if you don't want to play with llvm.
I do want to potentially play with (especially, instrument) llvm. Removing the section, doing and running again fixed it. ( gave me a hint that this might be useful thing to try, since was under the directory.) I also installed the Debian package; I don't know whether that was necessary/relevant.
Yes, this is what fixed it - I don't know what the cargo package you installed is, but the Debian package is the one rustbuild expects. Hmm, I would rather have bootstrap tell you that directly when it gives an error that ninja isn't found, that seems more helpful (and easier to keep up to date). Are you interested in making a PR for that? :)
The error checking for this lives in
Yes I can make a PR for that.
describes how to install ninja packages on a variety of platforms, so I'll have the error message link to that.
One thing I'm confused about is that adding to was not sufficient to fix the problem originally. I would have expected that to work regardless of whether ninja was installed.
I tried reproducing it. Without ninja installed there's a proper warning message. Editing then makes things build with gnu make . Imo the main thing that could use improvement is to autodetect whether ninja is available or not and set that flag automatically. Unless we want to encourage the use of ninja by default for fast builds.
Yes, it's intentionally semi-required to encourage it's use, as it gives a much better experience (though these days most people are not building LLVM, I hope).


Question: } } <ins> let inner = (self.inner)(); </ins> let prev = unsafe { <del> let prev = self.inner.get(); self.inner.set(t as *const T as *mut T); </del> <ins> let prev = inner.get(); inner.set(t as *const T as *mut T); </ins> prev }; <del> let _reset = Reset { key: &self.inner, val: prev }; </del> <ins> let _reset = Reset { key: inner, val: prev }; </ins> cb() }

There is an  in the scoped TLS module, which allows for sharing of data that wasn't meant to be shared. An unqualified should only_ be used when provides some sort of threadsafe locking mechanism. and do not. This lets us, for example, clone an or between threads, in safe code: Here, we have clones from different threads being interleaved, which can cause unsafety if there's a race on the refcount. We could also cause unsafety with a , or any other non-Sync type. basically lets us share across threads even if . I put the sleeps in there because somehow without them the routines are run serially. Note that this is not a problem with the API. I'm using here because to exploit one needs to be able to share across threads, and has an additional bound which doesn't satisfy. Any usable API will probably have to make the assumption that . Nor is this a problem with , since it can be done with , too. Solution: Make it ... I think. I'm not familiar with this API, and I'm not sure why it's even in the first place.
cc
cc This seems concerning: this is designed to be thread-local, so that e.g. storing a works (which would be safe, if it were guaranteed to stay on one thread). However currently requires unconditionally, hence this overly-accepting impl.
Qualifying the impl with breaks scoped TLS for (see the associated PR); because becomes no longer and thus can't be stuffed inside a static.
I believe the only way statics can be safe is by requiring the absence of Sync. That may sound odd, but consider the following: - sending thread-local references across threads is memory unsafe even with no interior mutability a static with no interior mutability is almost entirely useless, certainly not a common case non- containers offering interior mutabilities are cheaper and preferred to ones, where they can be used The main issue is actually within the libstd TLS implementation: is a wrapper for getters so it's unaffected by it, but may live in a static or a global one, depending on whether the platform natively supports TLS or not. -ing a across threads is actually safe on the architectures which do not have native TLS support. However, allowing it on some architectures and not on others is undesirable. Should use an accessor model like ?


Question: } } <ins> let inner = (self.inner)(); </ins> let prev = unsafe { <del> let prev = self.inner.get(); self.inner.set(t as *const T as *mut T); </del> <ins> let prev = inner.get(); inner.set(t as *const T as *mut T); </ins> prev }; <del> let _reset = Reset { key: &self.inner, val: prev }; </del> <ins> let _reset = Reset { key: inner, val: prev }; </ins> cb() }

Then the actual borrow of a static is an implementation detail and happens on the thread where the key is used, not where it was itself borrowed.
"I believe the only way #[threadlocal] statics can be safe is by requiring the absence of ." This is wrong, I think. For example, one might use thread local data for intrusive linked lists of hazard pointers. They would be thread local but might still be (one can guarantee existence with scoped threads or in certain circumstances where threads are bound to cores). That said you can obviously come up with other representations. In any case, I've mostly come around to believing that we need a separate lifetime (not just for this, but for things like ensuring that can't catch an error in a thread that changes thread local data, violating exception safety).
Based on what wrote, it seems like the TLS interface requires a that only allows non- data and is still accessible like one. One idea I had of how to enable this in todays Rust is to make generate a unit like struct instead of a . That struct would be and have a impl: According to this could also help with , but I'm not familiar enough with the TLS API in general to really reason about this.
I was expecting the impl to target an intermediary type, not the contents themselves. and have their own APIs to deal with. You would still be about to use the TLS API provided by libstd with thread-safe data, it's just the low-level which would have the requirement. Ideas of thread-local lifetimes predate the removal of from , and I'm not sure how relevant they are anymore. I'm also conflating thread-safe data access and thread lifetime... but how long does a thread live? What would unify with? Actually, there's an... easy solution for this. Somehow we were blinded by language semantics, but their details are fluid. It is trivial to make borrows of behave like borrows of an arbitrary rvalue, allowing the resulting reference to be passed down, but not returned. That would ensure that the the thread is just as alive for such borrows as it is for stack ones. would still require a like has, because it may not be when native TLS is supported. But both their APIs are compatible with such a change.
Wouldn't that limit the usability of thread locals in some cases, though?


Question: } } <ins> let inner = (self.inner)(); </ins> let prev = unsafe { <del> let prev = self.inner.get(); self.inner.set(t as *const T as *mut T); </del> <ins> let prev = inner.get(); inner.set(t as *const T as *mut T); </ins> prev }; <del> let _reset = Reset { key: &self.inner, val: prev }; </del> <ins> let _reset = Reset { key: inner, val: prev }; </ins> cb() }

e.g., wouldn't that make it difficult to have a thread local point to another thread local? Maybe I just have to think about it. (BTW, I'm aware we're just talking about the low-level API :)).
in a , borrows are , I didn't even think of that. First off, a global static shouldn't be allowed to borrow a static. And in general, having borrows in a is going to be difficult to support, except for non- data, because they would be right now. We could disallow borrows or we could give some kind of scope to those borrows. Which makes me think, as a compromise between a lifetime and , there could be a pseudo-(rvalue)-scope. Combined with the ability to leave out in globals' type (or not having a type at all), the scope should bubble up into users of those statics. They would behave as if they were borrowed before everything else in the function where they're used, but still not (and they can't be returned from functions).
There's a few intertwined issues here at play, so I just want to quickly summarize the way I see things: This does not affect as it which has an , which while sound should be fixed, allowing removal of the block for . A borrow of a static should not yield something with the lifetime, as that is clearly not sound. I'm not sure I follow why we might require the types in a are not , I haven't quite followed that. Due the cross-platform requirements of std, however, I believe the best solution here is to use the same strategy as with an indirect accessor to ensure the semantics are the same across platforms that have and those that don't (where a normal is used).
triage: P-medium This is an unstable API so it's not super-high priority to fix, but we should defnitely fix!
requiring that a is not is an easy way to ensure that a borrow of it, while , cannot escape the current thread. I've changed my mind and prefer an rvalue borrow semantic for , but it still is the case that and use non- statics (ignoring the workarounds for ). If was supported everywhere, having rvalue borrow semantics wouldn't hurt the std TLS API (aside from stability issues with ), as the access patterns are already through anonymous lifetimes (references passed to closures).


Question: } } <ins> let inner = (self.inner)(); </ins> let prev = unsafe { <del> let prev = self.inner.get(); self.inner.set(t as *const T as *mut T); </del> <ins> let prev = inner.get(); inner.set(t as *const T as *mut T); </ins> prev }; <del> let _reset = Reset { key: &self.inner, val: prev }; </del> <ins> let _reset = Reset { key: inner, val: prev }; </ins> cb() }

Maybe a combined strategy, where borrows of statics are iff the data is not (and rvalue-like otherwise), might work better and would require fewer changes to the std TLS implementation.
Right, but returning a borrow with a lifetime for a global is unsafe for other reasons (the lifetime of the thread is not ).
how can it be abused without sending it to a different thread?
The actual values themselves do not have a lifetime, so it can be a source of unsafety to advertise otherwise. For example you could stick a into a TLS value with a destructor, but when the destructor runs that pointer could be invalid.


Question: <ins> error[E0185]: method `example` has a `&self` declaration in the impl, but not in the trait --> $DIR/argument_number_mismatch_ice.rs:8:5 | LL |     fn example(val: ()); |     -------------------- trait method declared without `&self` ... LL |     fn example(&self, input: &i32) { |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl error[E0594]: cannot assign to `*input`, which is behind a `&` reference --> $DIR/argument_number_mismatch_ice.rs:10:9 | LL |         *input = self.0; |         ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written error: aborting due to 2 previous errors Some errors have detailed explanations: E0185, E0594. For more information about an error, try `rustc --explain E0185`. </ins>

<!-- 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): 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: [mirborrowck] borrow-checking [analysis] running analysis passes on this crate --
cc
label +D-diagnostic-infra -needs-triage


Question: <ins> // Doc links in `Trait`'s methods are resolved because it has a local impl. // aux-build:issue-103463-aux.rs extern crate issue_103463_aux; use issue_103463_aux::Trait; pub struct LocalType; impl Trait for LocalType { fn method() {} } fn main() {} </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --Nightly 2022-08-11 worked fine, trying to upgrade from it. : <details<summary<strongBacktrace</strong</summary<p</p</details
, same rustc version
label E-needs-mcve -T-compiler +T-rustdoc
Error: Label needs-mcve can only be set by Rust team members Please file an issue on GitHub at if there's a problem with this bot, or reach out on on Zulip.
I don't have a MCVE but the same problem on the same nightly version happens with a dependency of . Sounds awfully similar to also involving deps, but that one's definitely fixed.
Pinging since they're the last one who worked on this. Maybe you have an idea?
Somewhat minimal example: Removing the impl avoids the bug.
This happens with beta too:
Fixed in


Question: <ins> pub trait Bar: Super<SuperAssoc: Bound> {} pub trait Super { type SuperAssoc; } pub trait Bound {} </ins>

<!-- 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: This compiles fine, however if crateb is a separate crate instead of a local module_, it errors with: This is not fixed by the next solver (). <!-- 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. --:
I was able to narrow this down even further:
yep yep makes sense i'll fix it, sorry


Question: fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> { let mut b = [0; 2]; <del> let mut amt = 0; while amt < b.len() { match r.read(&mut b[amt..])? { 0 => return Err(io::Error::new(io::ErrorKind::Other, "end of file")), n => amt += n, } } </del> <ins> r.read_exact(&mut b)?; </ins> Ok((b[0] as u16) | ((b[1] as u16) << 8)) } <ins> fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> { let mut b = [0; 4]; r.read_exact(&mut b)?; Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24)) } </ins> fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> { match r.bytes().next() { Some(s) => s,

does not emit color output when running under a tmux session with set correctly to (supported by the latest versions of ncurses) even with when is set to . On the machine in question (macOS) the term file for is installed and returns the following: Per cargo should be invoking rustc with the flag, and indeed, returns 'Option color given more than once. Executing also does not produce color output, but does.
I have a similar bug on Archlinux. I used to get colored output on this system, but that recently stopped working for rustc. (Cargo is still fine for me.) If I add in and run in , I get Result::unwrap()Err/lib/terminfo/x/xterm-256colorncursesNEWS file does mention a new (incompatible) file format with a different magic number: Could rustc switch to whatever Cargo uses for colored terminal output?
A work-around for my machine was temporarily downgrading the packages, and copying the old file to .
Yes rustc should be able to switch at any time
Thanks for the workaround!
Changing from to also seems to work as a temporary workaround. (note: this may affect other terminal applications)
Another work-around if you're using sh: This sets to a possibly incorrect value, but limits its impact to only the output of a command.
That worked for me as well. I had no colour with . I downgraded to , which was what I had in , and now I have colour again.
I have a similar issue: In my regular terminal emulator (not tmux), there are no colors from rustc (as executed with ), colors from cargo itself are working fine. The default setting for there is: . The problem is fixed by setting to . Inside tmux however, colors work just fine, there seems to be by default.
Colors are fixed in the latest nightly (thanks to o/)
This is fixed for me in today’s nigthly, presumably by
With the current nightly I still have no colors with and have to use as a work around. What might still be broken?
Terminal colors are still broken with . however, does use colors, so there's clearly still a discrepancy between how and use termcolor
It works fine for me with ncurses 6.1, even rustup has colors again since the last version .


Question: fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> { let mut b = [0; 2]; <del> let mut amt = 0; while amt < b.len() { match r.read(&mut b[amt..])? { 0 => return Err(io::Error::new(io::ErrorKind::Other, "end of file")), n => amt += n, } } </del> <ins> r.read_exact(&mut b)?; </ins> Ok((b[0] as u16) | ((b[1] as u16) << 8)) } <ins> fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> { let mut b = [0; 4]; r.read_exact(&mut b)?; Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24)) } </ins> fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> { match r.bytes().next() { Some(s) => s,

I’d like to note though that things like destroy this for some reason (even if is set). It took me some time to figure that out
I'm using ncurses 6.1 on Fedora 28 and everything appears to be working fine except for test colors. In mentioned that a bit tricky due to how the build works, but we can always tackle that later. What is the barrier to migrating libtest from to ? For now, it's leaving my test output looking like this. !
I have an in-progress patch for libtest but I ran into I'm guessing that's the build issue that is referring to. I don't know how linking libtest works, but I'm happy to try to fix the build if someone can point me in the right direction.


Question: <ins> // run-rustfix fn main() { for _ in 0..=255 as u8 {} //~ ERROR range endpoint is out of range for _ in 0..=(255 as u8) {} //~ ERROR range endpoint is out of range } </ins>

<!-- 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: printing all numbers from 0 to 255 (inclusive) Instead, this happened: : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
The error is correct, 256 is indeed out of range for u8. You need to use .
You can run that code if you want, by allowing the lint: if you do you'll see that it will print nothing because the overflows and becomes , so it's which is empty. Examples like this where allowing the literal overflow would do something you don't want are exactly why this lint is deny-by-default
I've renamed this issue because the lint is correct. If there's anything to be done here, it would be to add a range-specific suggestion for this situation to help guide towards the correct code.
claim


Question: }, lt_op: |region| { match region { <del> // ignore static regions ty::ReStatic => region, </del> <ins> // Skip static and bound regions: they don't // require substitution. ty::ReStatic | ty::ReLateBound(..) => region, </ins> _ => { trace!("checking {:?}", region); for (subst, p) in opaque_defn.substs.iter().zip(&generics.params) {

cc
Am I correct in assuming that this should not compile, but report an error about returning a reference to the local variable ? Or is the self-borrowing generator part what makes this work? so the is part of the generator struct and the is the yielded thing? I'll try pretty printing to the expanded HIR, since I'm not sure what's going on there
Expanded version:
No, this should definitely compile. isn't yielded, but yes, it's a local variable inside the generator (that references another local variable in the generator).
Hmm, so because the generator contains references, it has lifetimes, but these lifetimes actually refer to the generator again? Do we have a special kind of lifetime that we use for this? We should just ignore those generator lifetimes for existential types.
There's no special lifetime afaik (cc
We should ignore all bound regions. Function pointers have the same issue:


Question: // ensure struct variants get warning for their fields enum IJK { <del> I, //~ ERROR variant is never used </del> <ins> I, //~ ERROR variant is never constructed </ins> J { a: String, b: i32, //~ ERROR field is never used c: i32, //~ ERROR field is never used }, <del> K //~ ERROR variant is never used </del> <ins> K //~ ERROR variant is never constructed </ins> }

I was changing some code from integer constants to a proper enum and was greeted by the following warning: The warning sounded weird to me because I was pattern-matching on that damn variant in various places of the code; but I was pointed out to the fact that I wasn't actually creating that value. Maybe the warning should be rewritten to explicitly mention value creation? Cc
cc that looks like your thing
duplicate of
Yup! Closing in favor of that.


Question: <ins> // run-rustfix pub enum struct Range { //~^ ERROR `enum` and `struct` are mutually exclusive Valid { begin: u32, len: u32, }, Out, } fn main() { } </ins>

<!-- 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. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: <!-- Please provide a link to --The current output is: <!-- The following is not always necessary. --Ideally the output should look like: Highlight to the user that the keywords and are mutually exclusive. Replace with . <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. 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. The output might also be different depending on the Edition. --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim


Question: <del> Subproject commit d1ddc34c4b23468f6d2bf553084834b104e16dde </del> <ins> Subproject commit 8b6b5014fdad3a750f7242a6bfdcad83619498d4 </ins>

<!-- 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 on AVR (arduino Uno = atmega328p) with opt-level="z": I expected to see this happen: Instead, this happened: An alternate code that emits the correct output is This compiler error is corrupting the pixel stream transmitted via SPI to an ST7789 display from an Arduino Uno. What appears to be happening is that instead of the bytes being swapped, the LSB is being copied to the MSB. I do not have the expertise to decompile and examine the assembly code. : The malfunction also occurs with . The full code can be cloned from <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Since I looked it up, here's the expected/actual in hex, which makes the bug more clear: input: expected: actual:
Hi, Could you please check with ? It feels like a bug nonetheless, but I'm curious about the result
Also: claim
I'm analyzing the codegen bug - simplest reproduction so far:
Got it! The simplest reproduction: This prints ( in hex) instead of ( in hex), because the generated binary accidentally overwrites the high-order byte with the low-order one: ! After calling ( on the screenshot), the returned number - ( in hex) - gets stored into r23:r24 (you can see that r23=0x39, r24=0x30, and AVR being little-endian means the number is reconstructed from r24 first, r23 second). expects its parameter to be stored in , so right before calling , the codegen has a simple job: move into ; and that's where the bug comes into play. What the code generator says is: ... which always sets and to the same value () - what it should generate instead is: Overall, that's an omission on the LLVM's side (when moving register pairs, it should consider whether the registers are overlapping or not) - I'll try to prepare a patch Edit:
I just updated to nightly-2022-07-08 and some weirdness I was seeing with seems to have been fixed.


Question: <del> Subproject commit d1ddc34c4b23468f6d2bf553084834b104e16dde </del> <ins> Subproject commit 8b6b5014fdad3a750f7242a6bfdcad83619498d4 </ins>

Under nightly-2022-05-10 I would see this in the serial log: Under nightly-2022-07-08 I get It also fixed the problems I was having with the st7789 crate that led me to file this bug.


Question: wShowWindow: 0, cbReserved2: 0, lpReserved2: ptr::null_mut(), <del> hStdInput: c::INVALID_HANDLE_VALUE, hStdOutput: c::INVALID_HANDLE_VALUE, hStdError: c::INVALID_HANDLE_VALUE, </del> <ins> hStdInput: ptr::null_mut(), hStdOutput: ptr::null_mut(), hStdError: ptr::null_mut(), </ins> } }

<!-- 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: App P: App C: Build this in Windows. Since has "windows" subsystem, it will create no console window (i.e. no process). Since is a console app, when the process is created, I expect to see one console window that prints "Hello World" infinitely. App creates its console window but no text is printed. In Windows, spawn() eventually calls to with a , whose  is hard coded to . Additionally, it also with , and set them to the . Since app uses "windows" subsystem, it does not have console. stdout is always . Combining with in causes the unexpected behavior. If I make a call to with same parameters except a "zeroed" , it exhibits the correct behavior. spawn() should only conditionally set the flag if it can obtain those device handles, and never set any of those handles . Like this (pseudo code): <!-- 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. --:
I think this will need a T-libs-api decision as the current documentation for  (and stdin/stderr) is: I would guess that this "inherit by default" is why it's implemented the way it is. But perhaps there's some wiggle room with what it means to inherit handles that don't exist so we can change it. In either case it would be good to have some way to use platform default behaviour here. label -T-libs +T-libs-api
That's exactly my point. If there is nothing to inherit in the first place, just inherit nothing. The current behavior () is simply wrong. I believe fixing it doesn't violate the current specification.
Basically, currently there are only two options when handling the stdout/stderr: inherit or pipe. I think there should be a third option: isolated - make the child handle its console by itself. For example, if user calls and , he basically says "the parent process doesn't care about the child's output". It is the same as the "windows" subsystem case above. In this case, the flag should never be set, regardless if or is called.


Question: wShowWindow: 0, cbReserved2: 0, lpReserved2: ptr::null_mut(), <del> hStdInput: c::INVALID_HANDLE_VALUE, hStdOutput: c::INVALID_HANDLE_VALUE, hStdError: c::INVALID_HANDLE_VALUE, </del> <ins> hStdInput: ptr::null_mut(), hStdOutput: ptr::null_mut(), hStdError: ptr::null_mut(), </ins> } }

More importantly, this is de facto the default way of how a process is created in Windows. Defaulting to really makes me confused before reading the internal source code.
Not always. Parent process can still set those handles to something other than . For example, if you launch App P from IntelliJ it actually prints "Hello World!" in a loop but not in the spawned console which is empty, but in IntelliJ internal terminal. returns non invalid handle. This solution would make behaviour different depending on how you launch your app. Also, you can explicitly ask to create new console with even if your app already uses console subsystem. In this case you also likely want to avoid inheriting handles because you want output of the spawned process to be displayed in the new console, not in the existing one. This solution doesn't help with this.
I can't verify your statements since I don't have IntelliJ atm, but even it's true, isn't it IntelliJ setting up the console with maybe some special debugging API? How to you modify the code of P to achieve the same? And realistically speaking, do people actually do that with GUI apps? I think in this case, it's impossible to be 100% sure where the user wants the output at. New option might be the way to go.
Your prediction was dead-on, as it came true in While we can do this, as is proposing, it seems best here that we create a function, or set of functions, that explicitly handle this kind of situation rather than guessing.
Even with new APIs, we still need reasonable default behaviour. And the Command API is documented as inheriting handles by default. However, currently the API neglects the "no handle set" case entirely as that's not really a thing in POSIX or ISO C (well, you can close stdio but that's usually considered a Bad Thing unless you're being very very careful).


Question: // The first byte is special, only want bottom 5 bits for width 2, 4 bits // for width 3, and 3 bits for width 4 macro_rules! utf8_first_byte( <del> ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as uint) </del> <ins> ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32) </ins> ) // return the value of $ch updated with continuation byte $byte macro_rules! utf8_acc_cont_byte( <del> ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as uint) </del> <ins> ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32) </ins> ) static TAG_CONT_U8: u8 = 128u8; <ins> /// Converts a vector of bytes to a new utf-8 string. /// Any invalid utf-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER. /// /// # Example /// /// ```rust /// let input = bytes!("Hello ", 0xF0, 0x90, 0x80, "World"); /// let output = std::str::from_utf8_lossy(input); /// assert_eq!(output, ~"Hello uFFFDWorld"); /// ``` pub fn from_utf8_lossy(v: &[u8]) -> ~str { static REPLACEMENT: &'static [u8] = bytes!(0xEF, 0xBF, 0xBD); // U+FFFD in UTF-8 let mut i = 0u; let mut lastgood = 0u; let total = v.len(); fn unsafe_get(xs: &[u8], i: uint) -> u8 { unsafe { *xs.unsafe_ref(i) } } fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 { if i >= total { 0 } else { unsafe_get(xs, i) } } let mut res = with_capacity(total); while i < total { let i_ = i; let byte = unsafe_get(v, i); i += 1; macro_rules! error(() => { unsafe { if lastgood != i_ { raw::push_bytes(&mut res, v.slice(lastgood, i_)); } lastgood = i; raw::push_bytes(&mut res, REPLACEMENT); } }) if byte < 128u8 { // lastgood handles this } else { let w = utf8_char_width(byte); match w { 2 => { if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 { error!(); continue; } i += 1; } 3 => { match (byte, safe_get(v, i, total)) { (0xE0        , 0xA0 .. 0xBF) => (), (0xE1 .. 0xEC, 0x80 .. 0xBF) => (), (0xED        , 0x80 .. 0x9F) => (), (0xEE .. 0xEF, 0x80 .. 0xBF) => (), _ => { error!(); continue; } } i += 1; if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 { error!(); continue; } i += 1; } 4 => { match (byte, safe_get(v, i, total)) { (0xF0        , 0x90 .. 0xBF) => (), (0xF1 .. 0xF3, 0x80 .. 0xBF) => (), (0xF4        , 0x80 .. 0x8F) => (), _ => { error!(); continue; } } i += 1; if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 { error!(); continue; } i += 1; if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 { error!(); continue; } i += 1; } _ => { error!(); continue; } } } } unsafe { raw::push_bytes(&mut res, v.slice(lastgood, total)) }; res } </ins> /// Unsafe operations pub mod raw { use cast;

We need some way to interpret a as UTF-8, using the replacement character for invalid sequences instead of conditions. This would ideally be provided in the form of an .
Could we remove the current condition API in favour of this? It doesn't really seem to offer anything but failing, and we already have an API returning an .
I would be quite pleased if we could do that. Using the condition is rather awkward, and I would rather just have replacement chars myself.
This is a duplicate of , no?
And also the e-mail thread here I think is relevant:
This is an implementation of a mostly complete → UTF-8 decoder
It's only a duplicate if the intended resolution of is to use the replacement char instead of conditions, but it's unclear from the discussion if that's the plan.
I guess my thinking was that a maximally expressive condition-based solution would let one express a replacement char approach using conditions. But I don't actually favor doing that at this point. Or at least, I don't favor making that the only way to accomplish this, since I suspect a more specialized approach will be much nicer to use (both in terms of programmer convenience and in terms of efficiency). So okay, this is not a duplicate of .
Rust needs to support both fatal and replacement error handling modes, it should follow the WHATWG spec simonsapin has said (edit by is WHATWG spec.)
the fatal mode is already handled by the API
well, the current functions in str don't handle decoding buffers in chunks like the proposed encodings API. But yes, it does handle one-off decoding with 'fatal' error handling.
I think we need to improve/extend our API along the lines suggested here for 1.0. Nominating for P-backcompat-lang. (Arguably we could avoid the backwards compatibility hazard by offering a fail-only method for 1.0 and then adding an alternative entry point that provides the more flexible API supporting replacement characters in post 1.0. But I think this case is important enough that we should try to get the primary API method to provide both choices up front. That, or put dynamic fluid support in for representing the state of that choice.)
I submitted a PR for this last night, although I forgot there was an open issue too so I didn't link them. The PR is


Question: debug!("Checking must_not_suspend for {}", ty); match *ty.kind() { <del> ty::Adt(..) if ty.is_box() => { let boxed_ty = ty.boxed_ty(); let descr_pre = &format!("{}boxed ", data.descr_pre); </del> <ins> ty::Adt(_, args) if ty.is_box() => { let boxed_ty = args.type_at(0); let allocator_ty = args.type_at(1); </ins> check_must_not_suspend_ty( tcx, boxed_ty, hir_id, param_env, <del> SuspendCheckData { descr_pre, ..data }, </del> <ins> SuspendCheckData { descr_pre: &format!("{}boxed ", data.descr_pre), ..data }, ) || check_must_not_suspend_ty( tcx, allocator_ty, hir_id, param_env, SuspendCheckData { descr_pre: &format!("{}allocator ", data.descr_pre), ..data }, </ins> ) } ty::Adt(def, _) => check_must_not_suspend_def(tcx, def.did(), hir_id, data),

This code here has a potential issue: If the Box has a custom allocator, then that will not be checked at all. So whatever is used for, it ignores anything stored in custom allocators. It seems like this is just for a lint, so this is probably not critical, but I guess should still be fixed. Cc -- not sure whom else to ping for coroutine state machine transform things?
Cc (also a regular occurrence in this file's )
Lol sorry, I thought I had clicked enter on a comment but I must've not. Let me rewrite it. Yeah, this is approximately the level of urgency you determined. This code exists for an unstable lint, . I don't expect people to be writing , but technically they could.


Question: impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); // float -> float <del> impl_from!(f16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); </del> <ins> // FIXME(f16_f128): adding additional `From` impls for existing types breaks inference. See // <https://github.com/rust-lang/rust/issues/123824> </ins> impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);

After we started seeing the following compile failure: I repro'd this locally on but we have so we're fairly sure that it started with . Of the changes in that rollup is the only one that seemed to touch float stuff, but I'm not sure how adding some extra impls for and would break inference in this case.
cc is it possible that adding the the impls for / may have caused type inference regression here?
It must be, but I don't know why since wasn't touched. Also reproduced locally
When there is only one applicable impl it can guide inference, as soon as there are multiple it can't use those and instead goes to default-numeric-fallback which appears to be for floating point.
Correct.
Just coming to the same conclusion - the literal is getting guided to f32 on stable since that's the only type that fits the , but when there are more options it gets the default float literal type of f64
I'll put up a PR to remove these impls for now but what is the correct longer term fix? cc
label -needs-triage +A-inference +F-f16andf128
Race condition <img width="497" alt="image" src=""
I did not remove the feature label lol (it wasn't even in the list), welldone GitHub
Theoretically, type inference regressions are permitted as part of Rust's 1.0 stability guarantees. In practice, if the regressions are too bad, the changes usually get reverted and are subsequently blocked indefinitely iirc. However, we could make use of editions if the worst comes to the worst. See arrays & . I think we have something similar queued up for Rust 2024. On mobile, can't link.
I put a fix up at and opened to further discuss what we want to do here. Thanks for identifying this so quick!
if you get the chance, could you link some of the places that caused this failure? It would be good to have some references for how this behavior is being relied on in the wild.
that we caught it on. It's a pretty simple case (that type is just an type alias) and seems reasonable to break on an edition boundary (or even just on a release as long as there's a machine applicable suggestion to fix it).
Hi! I'm from the Bevy project.


Question: impl_from!(u32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); // float -> float <del> impl_from!(f16 => f32, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(f16 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); </del> <ins> // FIXME(f16_f128): adding additional `From` impls for existing types breaks inference. See // <https://github.com/rust-lang/rust/issues/123824> </ins> impl_from!(f16 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(f32 => f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")]); impl_from!(f32 => f128, #[stable(feature = "lossless_float_conv", since = "1.6.0")]);

We caught this bug with too, though the error originates from the crate (0.3.18).
Awesome, thanks for the report! I started a list of known regressions at , and there is a crater run going to figure out how best to deal with this behavior. The fix for this was merged so should be available on the next nightly (couple of hours?).


Question: { let start_len = buf.len(); let mut g = Guard { len: buf.len(), buf }; <del> let ret; </del> loop { if g.len == g.buf.len() { unsafe {

At line 393, the guard object's field is incremented by the value returned from a read implementation. If a questionable returns a value larger than the buffer size, it will take that value and set the length of the vector over the boundary. This bug is reachable from and . Here is a that demonstrates the bug. It segfaults with .
This is definitely broken - nice find. A simple fix would be to just add an in the drop impl: You can still get weird behavior in readtoendwithreservation, but it should be memory safe and it seems best to avoid a bunch of extra logic in the main loop.
It looks like the bug was introduced in
Assigning as and removing .


Question: lint_improper_ctypes_char_reason = the `char` type has no C equivalent lint_improper_ctypes_dyn = trait objects have no C equivalent <del> lint_improper_ctypes_enum_phantomdata = this enum contains a PhantomData field </del> lint_improper_ctypes_enum_repr_help = consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum

The function itself is considered FFI-safe and does not trigger the warning (). Its function pointer should also be allowed, to be consistent. Discovered on CI The original code has several more levels of indirection, but is also considered FFI-safe before. <details<summaryExtracted original code</summary</detailsAccording to CI logs, the warning occurs since rust 1.72.0-nightly ( 2023-07-03). Probably caused by . cc
Okay, so, I had a fix for this that just got rid of the regression, but I'm not sure that's the correct solution here - I think this is correct to be linting in the fn-ptr case and should be linting for the function case. is FFI-unsafe, but we allow a function to return because that's the default, but that doesn't mean that a within a type is okay (with the exception of a wrapper around the - because that's just returning , which we've already decided is okay). In the function case that works right now, that's being allowed because of this code.. ..which is there to support the case. However, it's not quite the right check. It doesn't actually check for ! It checks that the type - however nested - which was deemed FFI-unsafe is and that type is part of a return type. So any FFI-unsafe in a return type makes the entire return type FFI-safe - which is clearly incorrect. That's making the example below compile, which absolutely shouldn't. I've submitted , which makes this even more of a regression by making the function case fail too. We already had a simple "is it a unit" check, so I extended that to check for transparent newtype wrappers too, and removed the incorrect check.
This is unfortunate since I'm trying to return a where is likely to be . What should I do instead if I want to be FFI-safe with layout ?
I'm not so sure anymore after reading comment (). It's clear that some changes are required regardless - our current implementation wrong as demonstrated in the final example from my previous comment, but it's also inconsistent, in that this example... lint for the argument use of , but not the return use of , when really it should be both or neither. After my pull request, it's both.


Question: lint_improper_ctypes_char_reason = the `char` type has no C equivalent lint_improper_ctypes_dyn = trait objects have no C equivalent <del> lint_improper_ctypes_enum_phantomdata = this enum contains a PhantomData field </del> lint_improper_ctypes_enum_repr_help = consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum

With and without my pull request, when you change this to , it doesn't lint.
I'll nominate this issue so that it sees some discussion - see also and .
I posted some more info on zulip but it may also worth mentioning here. ZST is still zero-sized under repr(C), rather than FFI-unsafe.
The issue now also exists in beta. I also found uitests which seems to expect ZST to be FFI-safe, but ends in to suppress the warning and tests nothing.
We discussed this in today's meeting. We didn't have consensus that this should warn; at least some people thought the code in the top comment should continue to compile without warnings. We did have consensus that changing that (to warn) would need an FCP. So, we felt that we'd like to see a fix removing the warning applied to beta and nightly, and then separately if someone wants to propose that we change this to warn, we could evaluate that and do an FCP on it. But at the moment the temperature of the team seems to be that we don't have consensus for such an FCP.
WG-prioritization assigning priority (). label -I-prioritize +P-medium
labels -I-lang-nominated We rendered our opinion


Question: # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not # installed. <del> ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </del> <ins> ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft"  CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm"  CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp"  CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a"  CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </ins> CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc  CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc  CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc

Upstream issue: The version of used in the (and possibly the one too?) standard library has a bug where it will sometimes walk off the end of the segment containing the section and segfault. I've struggled to reproduce this except in some proprietary code, but the backtrace looks like: There's a proposed fix in the linked LLVM issue, which can possibly be patched into libunwind before building the musl target if taking an updated libunwind isn't possible.
I ran into this as well.
There doesn't seem to be any movement on the LLVM issue since I raised it, not even an assignee. Do you know if this is normal behaviour for them? Or if I've mis-raised the issue?
Running into this as well at OneSignal
I can reproduce this on latest stable on an open source project: On the second run of the final command, the background process will segfault.
After much investigation, I think there's two bugs here, one that LLVM's unwinder will consider unreadable memory as part of the section, and one that the rust compiler creates invalid (unusual?) unwind information. The crash is specifically happening when trying to find unwind information for the frame above (not but the "c-runtime" main. Since the frames above the C entry point are provided by the runtime (musl in this case), they are contained in / which, in rust's musl-targeting stdlib have been provided. The provided object files have no unwind information in them: This in and of itself isn't a huge problem, the code stops trying to unwind when it can't find unwind information for the next frame (), so it should stop after which would be fine. so long as we can safely fail to find the unwind information. The issue is that libunwind's logic for searching for FDE (frame description entry) for the parent frame is pretty all-encompassing and runs in many phases, and one of these crashes (sometimes) if there searched for address is not present in the unwind information).


Question: # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not # installed. <del> ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </del> <ins> ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft"  CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm"  CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp"  CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a"  CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </ins> CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc  CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc  CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc

At a high level the process looks like () Look for a "compact unwinding table" Look for "DWARF unwind information" Look for ARM EHABI unwind info Look for dynamically created DWARF unwind entries For Rust x8664 musl binaries, the compiler has provided DWARF unwind information, so we fall into the second bullet (): No compact encoding hint, so the first section isn't interesting Search the section for an index for the frame - not present Check the local cache in case we've seen this frame before - we haven't Scan the whole of the section for the address of interest - CRASH! Digging further, we see that the logic for scanning the sector looks like (): Read a length field If it's 0 stop, we're done - rustc never seems to generate this "end-of-information" marker Skip over CIE entries For non-CIE entries work out if the address we're looking for is in the range of the entry, if so we've got our FDE Jump forward by the length of the CFI entry In each loop we check that the newly found CIE entry is in a reasonable place (between and ). If it's not, bail out for safety and fail the lookup. Unfortunately, as in the linked issue originally is incorrectly set too big (it's set to which is almost always wrong) so the unwind code will step right off the end of the segment and into one of: (LSDA) - This starts with a signature that is approximately , which is bigger than the error introduced by the miscalculation, so (after failing to parse the LSDA as a CFI entry) it jumps forward out of the range and bails out because the of the "reasonable location" check I mentioned above. The gap before (if the did not have a length that's a multiple of 32 and thus there's padding between the sections). In this case when it tries to read the next entry one of three things happens: The padding bytes happen to have a large value (when interpreted as a ) and we're in a similar position to the case where there's no padding, fail to parse the CFI entry, try to jump to the next one, realise we're jumping out of the allowed range and bail out for safety.


Question: # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not # installed. <del> ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </del> <ins> ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft"  CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm"  CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp"  CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a"  CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </ins> CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc  CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc  CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc

The padding bytes are medium sized when interpreted as a , in this case, after the failed parse, the unwinder jumps far enough to be off the end of the loaded segment, but not far enough to be past the so the sanity check passes and the unwinder attempts to read the next CFI entry, reads a 32-bit number from an invalid address and... :boom: The padding bytes are small when interpreted as a , and the unwinder jumps into a random part of the LSDA and we're back in a situation that's functionally similar to when we're reading the padding bytes and the same three options are still applicable in the next lookup. So, what's the bug(s) here? LLVM is miscalculating the section length (the original issue) Rustc (or the linker?) doesn't include the marker at the end of Either of these would fix this issue, probably both should be done?
Ah, there's another possible route for the crash: If the LOAD segement is really big, the signature at the start of the LSDA might not be big enough to jump past leading to an invalid read and a :boom:
I've ran into this issue as well. What's the status of this?
I've been looking at a proper fix for this and neither of the two paths I proposed above are yeilding simple results: LLVM miscalculating the section length: The simple fix I proposed in the upstream issue allows the unwinder to read arbitrary parts of the LOAD segment before bailing, which might have unexpected effects A more complex fix needs to calculate the section length at runtime, which is tricky as sections don't exist at runtime... Neither the nor section contains a length field so we're not simply told the length Maybe read the executable off disk (look in ) and parse the section table? Might not be readable to the current user. Might not even exist (not sure if this is possible, can you create a linux executable from an in-memory image?) Add terminator entry to the end of the section This relies on the static linker's behaviour, which is a shame as allows you to bring your own linker and both seem inconsistent about whether they add terminator entries, sometimes they do, sometimes they don't This feels like something that rustc can't fix locally or rely on externally Another option would be for LLVM to skip walking the section if the lookup in the fails.


Question: # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not # installed. <del> ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </del> <ins> ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft"  CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm"  CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp"  CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a"  CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </ins> CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc  CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc  CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc

It's unlikely to ever reveal anything new, and it seems that this section is just un-walkable with any kind of reliability.
Here are two tested workarounds, neither very pretty, but both work: to your Cargo config a build, extract the link script from the linker verbose output the lines: .ehframe : ONLYIFRO { KEEP ((.ehframe)) (.ehframe.) } ... .ehframe : ONLYIFRW { KEEP ((.ehframe)) (.ehframe.) } them to: .ehframe : ONLYIFRO { KEEP ((.ehframe)) (.ehframe.) LONG(0x0) } ... .ehframe : ONLYIFRW { KEEP ((.ehframe)) (.ehframe.) LONG(0x0) } ( is the CIE terminator) off this script somewhere in Cargo config (probably under the Musl target) an object containing just the terminator: 2, Add to your Cargo config (probably under the Musl target)
Hi! Is this still an issue? If so, is there perhaps a simpler way to reproduce this than the instructions linked above?
The setup that's needed is: A large LOAD segment (the one containing and ) Specifically the section needs to be deep into the segment How deep it has to be is roughly determined by the first of the section So something like the following should trigger the fault: This builds a huge section, which lives before the section so should lead to the crash. Hedging words because I can't reproduce the issue on my development machine (I run out of RAM and get OOM-killered).
Hmm, that doesn't seem to be sufficient (tested on the current stable and nightly). I get this output when building and running this on Arch Linux: I also get the same output when using to capture the backtrace.
I noticed the wrong ehSectionEnd calculation independently and filed
It looks like the gcc driver on Alpine adds the file to the link, which includes a terminator in . It seems that the rustc driver doesn't add something like this? (LLVM has a that has an .ehframe terminator, so maybe that's relevant to rustc.)


Question: # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not # installed. <del> ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </del> <ins> ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft"  CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm"  CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp"  CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a"  CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </ins> CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc  CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc  CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc

FWIW, it looks like LLVM's LLD linker automatically adds a terminator to the end of .ehframe, even if one isn't present in the linker inputs, so that could be a workaround: I think libunwind should stop scanning .ehframe when it finds unwind info from .ehframehdr (i.e. the GNUEH_FRAME segment).
Rustc's musl-targeting link includes: I don't exactly know where the files come from (they're shipped with the compiler toolchain, e.g. mine are in ) but looking at the musl codebase, there's no terminator in : (Intriguingly there's also no in the musl codebase, suggesting Rustc gets these objects from somewhere else?)_ I wouldn't expect to see a or since the rustc musl target doesn't include a C++ runtime and musl libc doesn't define either of these objects for the C runtime either.
It looks like musl's crt1 is a C file, not assembly. crt/{S,r,}crt1.c When crtbegin and crtend were to LLVM (), there was some discussion about which project is responsible for which aspects of the CRT begin/end files. Apparently the status quo on Linux is that: the compiler (e.g. libgcc) provides crtbegin/crtend the libc provides crti/crte (and maybe crt1, too?) That is the case on my gLinux (i.e. Debian) system: /usr/lib/x8664-linux-gnu/crt[1ie].o all come from the libc6-dev:amd64 package /usr/lib/gcc/x8664-linux-gnu/9/{crtbegin.o,crtend.o} come from libgcc-9-dev:amd64 The .ehframe terminator is usually in crtend, which is part of libgcc (not glibc or musl). LLVM's compiler-rt also provides crtbegin/crtend files. The gcc and clang drivers link a crtend object even for C programs. On Alpine, the gcc driver links a libgcc crtend object. It looks like rustc typically invokes the driver, but when it's targeting musl, it enters a mode where it provides the start files explicitly, and in this mode, it doesn't include crtbegin/crtend. For Alpine, I see , , , and .


Question: # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not # installed. <del> ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </del> <ins> ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft"  CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm"  CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp"  CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a"  CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </ins> CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc  CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc  CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc

For rustc/glibc, I don't see any of those flags, so the cc driver uses the default CRT begin/end/i/n/1 files. I see that rustc documents a lot of this at The unwinder needs the .ehframe terminator, because the .ehframehdr search table is optional, and because .ehframehdr has the start address of .ehframe, but not its size. ( / ). I don't think it's reasonable to open the ELF file indicated by dlpiname -- in principle, that duplicates the work done by the loader, and I can think of many specific things that wouldn't work. (e.g. the vdso, the executable w/glibc, Android's androiddlopen_ext and ability to map DSOs from zip files, unlinked files, etc).
Using self-contained mode is not generally recommended for serious work. If the compiler heuristics enable it by default, then it can be explicitly disabled with , then gcc will be used for linking without and will find all the necessary CRT objects by itself. Then it's important to make sure that gcc for the right target (musl in this case) is used by rustc.
If the compiler heuristics enable it by default Here's a FIXME for improving the heuristic for musl targets:
Thanks for that, very interesting. I think there are two separate use cases for musl-targeting builds: an environment where there's a full "native musl" toolchain (like on Alpine etc) where I think you're correct that we shouldn't use and should let the toolchain sort it out for us though I can't see an easy way to tell if a real toolchain is available a generic linux environment where the goal is fully static binaries (for easy of redistribution/embedding in thin container images/etc.)


Question: # riscv targets currently do not need a C compiler, as compiler_builtins # doesn't currently have it enabled, and the riscv gcc compiler is not # installed. <del> ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </del> <ins> ENV CFLAGS_armv5te_unknown_linux_musleabi="-march=armv5te -marm -mfloat-abi=soft"  CFLAGS_arm_unknown_linux_musleabi="-march=armv6 -marm"  CFLAGS_arm_unknown_linux_musleabihf="-march=armv6 -marm -mfpu=vfp"  CFLAGS_armv7_unknown_linux_musleabihf="-march=armv7-a"  CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc  </ins> CC_mips_unknown_linux_musl=mips-openwrt-linux-gcc  CC_mips64el_unknown_linux_muslabi64=mips64el-linux-gnuabi64-gcc  CC_mips64_unknown_linux_muslabi64=mips64-linux-gnuabi64-gcc

where there's likely not a native toolchain and rustc is forced to work out the answers for itself (as an aside no longer works as the "linker" for musl targets, since it doesn't support which is enabled in rustc as of the last release) I'm worrying about the latter case and I think from above the fix for that is: to add the terminator in builds as well as ones and include it in the target package alongside the (so rustup etc fetch it) the link command rustc emits for the musl target to include before Some side questions: Does the above sound sensible to people? Do we need to include any of too? (I think not, but I'm no expert :shrug:) Do other targets need similar treatment? musl?
In the latter case it would make sense to me for rustc to invoke an actual linker (///etc) since at the moment it goes via a compiler but has to tell the compiler to not do anything and just to pass the link args to the linker anyway. This is off topic for this discussion though.
If we need to improve the self-contained mode specifically, then I think we can just ship the begin/end objects and link to them like gcc does obsoleting the comment cited in That appears to be the simplest solution. If that doesn't work out (e.g. due to licensing), then the necessary parts can be to and linked as , as you suggested above.
Which / objects were you thinking? 's? LLVM's? If you're right and it's the compiler that ships the begin/end then maybe it's right for to have it's own (though given that the link might contain code compiled by random compilers (from scripts) as well as compiled by , which is "the compiler" for the sake of this discussion)?
's? LLVM's? I don't know, but looks like they should be compatible. At least on Ubuntu both gcc and clang link to gcc's objects. The gcc ones can be just copied by rustbuild if the license allows, the LLVM ones can be used if we need to build them by ourselves (they are a part of compiler-rt).
adds crtbegin/crtend objects to Rust distribution and links to them in self-contained mode as was suggested in , so it should fix this issue.
I still have this problem with clang's compiler-rt: