Question: /// /// # Examples ///  /// Converts an Option<[String]> into an Option<[usize]>, preserving /// the original. The [`map`] method takes the `self` argument by value, consuming the original, /// so this technique uses `as_ref` to first take an `Option` to a reference /// to the value inside the original.   /// Calculates the length of an Option<[String]> as an Option<[usize]> /// without moving the [`String`]. The [`map`] method takes the `self` argument by value, /// consuming the original, so this technique uses `as_ref` to first take an `Option` to a /// reference to the value inside the original.  /// /// [`map`]: Option::map /// [String]: ../../std/string/struct.String.html "String"  /// [`String`]: ../../std/string/struct.String.html "String"  /// /// ``` /// let text: Option<String> = Some("Hello, world!".to_string());

url: function: asref() Examples: Perhaps I'm just confused, but shouldn't that say: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
Transferring to the rust-lang/rust repository, as that is where the standard library documentation is. I think it is trying to illustrate the conversion from → → . The text is just eliding the middle step, and explaining where it is starting from and where it is finishing.
No, that seems fine; what confuses you (or leads you to the &str conclusion)? I could follow but not . Perhaps you're thinking the impl on would make the contain or such?
I guess I'm extremely confused then. If I have an , what good does an do me? If I have &Some( "fubar" ), how does that translate to a usize? Is it giving me the length of the string or it's pointer in memory? Neither seems useful nor relevant to the description of "Converts from &Option<Tto Option<&T.".
You can call . just describes the example code's functionality, not 's. It's showing one of the ways you could use .
Okay, sorry, I understand now that comment is talking about the upcoming example instead of discussing as_ref() in general. In order to help others not experience the same confusion I did, perhaps I could suggest a tweak to the wording, such as: ?
memory address
claim


Question: if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) { self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named); <del> if let LifetimeRes::Param { param, .. } = res { </del> <ins> if let LifetimeRes::Param { param, binder } = res { </ins> match self.lifetime_uses.entry(param) { Entry::Vacant(v) => { debug!("First use of {:?} at {:?}", res, ident.span);

<!-- 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: explanation suggestion compiles: Instead, this happened: explanation Suggestion does not compile: ` <!-- 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. --:


Question: B: TrustedRandomAccess + Iterator, { fn new(a: A, b: B) -> Self { <del> let len = cmp::min(a.size(), b.size()); Zip { a, b, index: 0, len } </del> <ins> let a_len = a.size(); let len = cmp::min(a_len, b.size()); Zip { a, b, index: 0, len, a_len } </ins> } #[inline]

Here is called for potential side effects until , ignoring however that it could have already been called in with those indexes. that demonstrates how this can be exploited to get two mutable references to the same data and cause an use-after-free bug.
Assigning as part of the .
The gift that keeps on giving Maybe it is time to get rid of as it exists today and replace it with a ? One that imposes the additional requirement on the caller that it must bring the iterator back into a safe state after it is done iterating. The upside would be eliminating a lot of code in and enabling the same optimization for and similar sources. While the downside would be that external iteration (i.e. loops and manual calls to ) would cease to benefit from optimizations and only internal iteration methods (including ) would continue to do so.
I don't know, I feel like that would just make more complex to upheld the invariants. IMO a good improvement over the current would be separating forward and backward iteration, this way it becomes easier to keep track of the state and I think would also make it possible to implement them for
I don't see how separating the forward and backward state would help with a drop implementation. The issue is that the source () currently does not have access to that state, instead the consumer drives the iteration by direct access through and never informs the source about it.
It would help because it allows the source iterator to keep track of its state by updating it when the method is called. Anyway, looks like someone already and it resulted in worse optimizations, but maybe LLVM got better in the meantime, or maybe that implementation could have been better. Anyway I don't think this is the right place to discuss this, a topic on zulip would probably be better.
https://rust-


Question: let mut head = self.head.index.load(Ordering::Acquire); let mut block = self.head.block.load(Ordering::Acquire); <ins> // If we're going to be dropping messages we need to synchronize with initialization if head >> SHIFT != tail >> SHIFT { // The block can be null here only if a sender is in the process of initializing the // channel while another sender managed to send a message by inserting it into the // semi-initialized channel and advanced the tail. // In that case, just wait until it gets initialized. while block.is_null() { backoff.spin_heavy(); block = self.head.block.load(Ordering::Acquire); } } </ins> unsafe { // Drop all messages between head and tail and deallocate the heap-allocated blocks. while head >> SHIFT != tail >> SHIFT {

The unbounded channel implementation from can segfault due to what looks like a race condition when dropping channel senders and receivers. You can find a repro at Unfortunately it is not minimal at all, since it depends on the timely-dataflow crate, which is the actual channel user. I hope it is still self-contained enough that people familiar with the channel implementation can run it and use it as a starting point for debugging. Run the example like this: On some machines it will segfault after some time, e.g.: The segfault happens inside , as visible in the gdb backtrace below. The same segfault also happens with . You can reproduce this by reverting the second-to-last commit on the repro branch. I understand that is a port of , so that's not surprising. : I can reproduce the segfault on nightly as well. The segfault is not reproducible on all machines! We were able to reproduce it on: a c5.2xlarge EC2 instance running Ubuntu an AMD Threadripper Thinkpad running Debian an Intel i5-8250U Dell XPS 13 running Arch Linux It doesn't seem to reproduce on: an M1 MacBook Pro Also note that the repro is using more and more memory over time. That is because the different worker threads create and drop dataflows at different speeds and timely-dataflow keeps per-dataflow communication state (including channels) around until the last worker has dropped the dataflow. It is possible to avoid that by adding a that lets late workers catch up, but in my experience that also stops the segfault from happening. <details<summaryBacktrace</summary<p</p</details
Here are the results of some initial investigation I have been doing. I used , but I assume the results will apply to the std port as well: The segfault happens in . In the linked line, is a null pointer, and so is . It seems like there is an inconsistency between the channel's and . is pointing to nothing while points to a block. I observed the following variable assignments at the time of the segfault: If I change all the atomic orderings in to , the segfault still occurs. This suggests that the issue is not caused by the usage of too-weak orderings. If I add an after , it is triggered under the repro.


Question: let mut head = self.head.index.load(Ordering::Acquire); let mut block = self.head.block.load(Ordering::Acquire); <ins> // If we're going to be dropping messages we need to synchronize with initialization if head >> SHIFT != tail >> SHIFT { // The block can be null here only if a sender is in the process of initializing the // channel while another sender managed to send a message by inserting it into the // semi-initialized channel and advanced the tail. // In that case, just wait until it gets initialized. while block.is_null() { backoff.spin_heavy(); block = self.head.block.load(Ordering::Acquire); } } </ins> unsafe { // Drop all messages between head and tail and deallocate the heap-allocated blocks. while head >> SHIFT != tail >> SHIFT {

This is where the sender is advancing and it seems plausible that this is the place where the inconsistency between and described above is introduced. I couldn't figure out why becomes a null pointer. The same method makes sure that the head is allocated previously, so some other thread must set it to null after the check.
cc
This suggests that the issue is not caused by the usage of too-weak orderings. I wouldn't be so quick to write off an ordering issue, the race condition could require stronger synchronization to fix (e.g. fences).
The segfault did occur (after about 5 minutes of runtime) on my Macbook Pro with an Intel Core i7 processor running macOS 13.3 and rustc 1.68.2. So whatever is causing this, it's not exclusive to Linux.
I have a feeling the issue is to do with a CAS failure when updating the tail not synchronizing with the update to head. If the thread that actually makes the update is preempted, the second thread might continue with the assumption that head has been updated, which might matter if it quickly writes to the entire block and the channel is disconnected before the head is ever touched. I haven't verified if this is possible, but it would be extremely rare if it is, which explains why this issue hasn't been hit before.


Question: <ins> - // MIR for `main` before DeadStoreElimination + // MIR for `main` after DeadStoreElimination fn main() -> () { let mut _0: ();                      // return place in scope 0 at $DIR/place_mention.rs:+0:11: +0:11 let mut _1: (&str, &str);            // in scope 0 at $DIR/place_mention.rs:+3:18: +3:36 scope 1 { } bb0: { StorageLive(_1);                 // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 _1 = (const "Hello", const "World"); // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 // mir::Constant // + span: $DIR/place_mention.rs:8:19: 8:26 // + literal: Const { ty: &str, val: Value(Slice(..)) } // mir::Constant // + span: $DIR/place_mention.rs:8:28: 8:35 // + literal: Const { ty: &str, val: Value(Slice(..)) } PlaceMention(_1);                // scope 0 at $DIR/place_mention.rs:+3:18: +3:36 StorageDead(_1);                 // scope 0 at $DIR/place_mention.rs:+3:36: +3:37 _0 = const ();                   // scope 0 at $DIR/place_mention.rs:+0:11: +4:2 return;                          // scope 0 at $DIR/place_mention.rs:+4:2: +4:2 } } </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: You need edition 2015 or 2018 to reproduce this. `
Looks to me like the problem is that doesn't realize that a makes the place not dead.
The bug is . is a nonuse, but should get the same treatment as a . I feel obligated to mention that I have repeatedly warned that these bugs are going to happen. We should really stop using in optimizations. It was written for borrowck. (To be clear: I am as much at fault for this as anyone, I originally wrote this code).
I was wondering why always has strangely unhelpful information for optimizations...
Why is this not just a bug in PlaceContext assignment?
See my comment in the PR - in general, my understanding is that the definition of placecontext is what it is because that's what makes sense in some other part of the compiler. If we start changing placecontext now to have the information that's useful to optimizations, I worry we'll just end up making those parts of the compiler buggy


Question: target = if let Some(cached_block) = free_data.cached_block { cached_block } else { <del> let t = build_free(tcx, cfg, unit_temp, free_data, target); free_data.cached_block = Some(t); t </del> <ins> let into = cfg.start_new_cleanup_block(); cfg.terminate(into, build_free(tcx, unit_temp, free_data, target)); free_data.cached_block = Some(into); into </ins> } };

This generates the following (broken) MIR: As you can see, is dropped but never written to (AFAIK this should be OK because of zeroing) but the boxes are never freed.
cc
EDIT: I wasn’t looking closely enough, it is indeed broken.
This is a problem on latest master ()


Question: // frames above our current position. let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE; <ins> // When using libgreen, one of the first things that we do is to turn off // the SIGPIPE signal (set it to ignore). By default, some platforms will // send a *signal* when a EPIPE error would otherwise be delivered. This // runtime doesn't install a SIGPIPE handler, causing it to kill the // program, which isn't exactly what we want! // // Hence, we set SIGPIPE to ignore when the program starts up in order to // prevent this problem. #[cfg(windows)] fn ignore_sigpipe() {} #[cfg(unix)] fn ignore_sigpipe() { use std::libc; use std::libc::funcs::posix01::signal::signal; unsafe { assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1); } } ignore_sigpipe(); </ins> rt::init(argc, argv); let mut exit_code = None; let mut main = Some(main);

Scripts to reproduce Steps to reproduce: Output:  Backtrace: None Exit code: 141 Version:
What are you expecting to happen? When you send a TERM signal to a process without a registered handler, it terminates promptly. The runtime currently doesn't register any TERM/INT handlers, that's up to you.
I was expecting the runtime to return some upon requesting an action from a defunct process. I also tried polling the state of the defunct process using (as mentioned in the ), but this returned as well. Even if the runtime dosn't "catch" the SIG{TERM,INT}, is it not possible at all to or return in any of the two cases mentioned above?
Oh whoops, sorry! I had my understanding backwards, and apparently this isn't a bug on OSX which caused more confusion for me. Anyway, closing as a dupe of , it's the same cause.
Oh wow, I've done it again. I'm sorry, again! I apologize for not investigating more thoroughly. This is indeed separate from


Question: /// /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal /// notation, divided by `.` (this is called "dot-decimal notation"). <del> /// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943]. </del> <ins> /// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which /// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943]. </ins> /// /// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 /// [`FromStr`]: crate::str::FromStr

According to the , "The four octets are in decimal notation, divided by . (this is called 'dot-decimal notation'). Notably, octal numbers and hexadecimal numbers are not allowed per IETF RFC 6943"; however the parsing of the violates the "strict" form mentioned in —this form is what prohibits octal and hexadecimal numbers—meanwhile the conforms to it. IETF RFC 6943 Section 3.1.1. states: If the af argument of inetpton() is AFINET, the src string shall be in the standard IPv4 dotted-decimal form: where "ddd" is a one to three digit decimal number between 0 and The inetpton() function does not accept other formats (such as the octal numbers, hexadecimal numbers, and fewer than four numbers that inetaddr() accepts). As shown above, inetpton() uses what we will refer to as the "strict" form of an IPv4 address literal. Some platforms also use the strict form with getaddrinfo() when the AINUMERICHOST flag is passed to it. I tried this code: I expected to see this happen: both s not causing a panic since the first has an octet represented by more than three base-10 numbers despite the requirement per RFC 6943 stating each octet be a "one to three digit decimal number". The second is valid per RFC 6943 since it is a string of exactly 4 octets separated by where each octet is a "one to three digit decimal number". Instead, this happened: Both lines cause a panic. : : <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details
I believe that the second input () is not valid, since the spec explicitly says that octal numbers are disallowed, and is an octal number in the loose form. The example in the RFC for an octal number is , which parses to if you use octal, but if you use decimal. If you instead have it parse it always as , that means that bad things can happen, such as different tools interpreting as different things.


Question: /// /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal /// notation, divided by `.` (this is called "dot-decimal notation"). <del> /// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943]. </del> <ins> /// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which /// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943]. </ins> /// /// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 /// [`FromStr`]: crate::str::FromStr

If you read the source code where the ipv4 address is parsed, it specifically disallows that: Regarding , the documentation only says that the disallowing of hexadecimal and octal numbers are according to IETF RFC 6943, and does not say anything about only allowing three digits. Also, four or more zeroes are an edge case, and thus the only numbers that can be parsed there with more than three digits, due to the disallowing of octal numbers apart from .
From the :
I'm confused by these comments. Padded zeros is not unique to the base-8 numeral system. Base-2, Base-3, etc. all have the property of having an infinite number of padded zeros with the convention being to truncate them all. After all is also valid in base-8, base-9, etc. The documentation is quite clear that the octets are to be interpreted in base-10 though, so this problem of how to interpret the octets is solved. Consequently the last octet in is interpreted as 1 in base-10 for the same reason the first octet in is interpreted as 127 in base-10 and not some other value (e.g., 87 in base-10) namely because the documentation says so. After all objecting to on the grounds that the last octet could be in base-8—again, all of the octets there could be in base-8—doesn't apply to the fact that is also rejected by the parsing algorithm since clearly each of those octets are not in base-8 since is not a symbol in the base-8 numeral system. This is of course nothing more than a consequence of incorrectly assuming padded 0s means base-8. The inconsistent treatment of 0 (in base-10) is also a consequence of this incorrect assumption. Why is 0 (in base-10) allowed to be represented by one or more s, but 1 (in base-10) cannot have padded s? There is nothing special about the syntactic representation of 0 (in base-10) that warrants this inconsistent treatment. To me the solution is clear: more strictly follow IETF RFC 6943 and enforce that each octet be one-to-three digits in length.


Question: /// /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal /// notation, divided by `.` (this is called "dot-decimal notation"). <del> /// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943]. </del> <ins> /// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which /// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943]. </ins> /// /// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 /// [`FromStr`]: crate::str::FromStr

One could even follow a stricter format and require that there be no padded s at all—since the RFC doesn't actually specify that. This would then lead to consistent behavior (that's also more easily predictable since it follows a well-established convention) in that both and will either be accepted (since they both follow RFC 6943) or rejected (if a stricter form is required that requires the minimal number of digits necessary to represent each octet).
This is not an incorrect assumption, as octal numbers in the loose format are specified by the number having a leading zero. (See for the PR that banned octal numbers) This is an implementation detail in the way that it checks for leading zeroes: it checks if the number starts with a zero and rejects it if the resultant parsed number is not zero.
So we are re-defining how mathematics defines numeral systems? Saying that is in base-8 (i.e., octal) because of the leading makes no sense since none of those symbols except exist in that system. Rust certainly doesn't treat the in base-8 here: . Also the documentation clearly states that each octet is in "decimal notation". Suddenly treating the octet as base-8 is a clear contradiction to the documentation.
Using leading zeros to designate octal literals is a fairly common convention. In other languages like JS and C, . Rust doesn't have that as an octal prefix because it is confusing. When using leading zeros to indicate octal numbers, isn't a valid number at all (in the same way that isn't a valid base-10 number).
So it sounds like the documentation needs to be modified. It is confusing (because it is contradictory to reality) to say that each octet is in decimal notation when the actual implementation requires each octet to be either base-10 or base-8 where the latter is assumed when there are leading s and the value is not 0—at which point any positive-integer amount of s are allowed—and furthermore error when any octet is interpreted as base-8. Seems much easier to both document and comprehend to simply require at most 3 decimal digits for each octet and either forbid leading s (including for the integer 0) or allow leading s (including ).
"The actual implementation" is relevant only insofar as its behavior is externally observable.


Question: /// /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal /// notation, divided by `.` (this is called "dot-decimal notation"). <del> /// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943]. </del> <ins> /// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which /// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943]. </ins> /// /// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 /// [`FromStr`]: crate::str::FromStr

And -- correct me if I'm wrong -- in every case where the function succeeds, it (behaves as if it) interprets all digits in decimal, right? So I'd say it is correct to say that everything is "in decimal notation". The only weird bit is that is accepted, but is not. This is strange, but not in contradiction with saying things are "in decimal notation".
When the documentation says the "four octets are in decimal notation", that is effectively a definition which in turn can be phrased as a logical biconditional. In this case, the logical biconditional I formed in my head was something like: "a will be parsed into an iff it is a sequence of exactly 4 base-10 numbers delimited by a ". Only one of those directions is true: if an is produced from parsing a , then the was a sequence of exactly 4 base-10 numbers delimited by a . The other direction, which is observable via a parsing failure, is not true as can be seen with something like . That is a sequence of exactly 4 base-10 numbers delimited by a , but it leads to a parsing failure. As was discovered in the discussion , it sounds like "decimal notation" as used in the documentation is not what it has meant my entire life nor what it means in a lot of areas in Rust. Specifically, any number that has leading s is not a base-10 number but in fact a base-8 number. With this modified definition of "decimal"; then my counterexample, , is in fact not a counterexample since each of those octets are not in "decimal" notation but in fact base-8. Even more perplexing as stated by is that "a lone 0 is technically octal as well in C, not that it matters" which means the definition of "decimal" used in the documentation is neither the mathematical definition nor the C definition—since something like is successfully parsed despite each of those octets being in base-8 per the C definition.
That's true in C. (Specifically, it is how C converts series of digits to numbers. "Numbers" don't have leading 0s, numbers are elements of the set of integers. The representation of a number as a string of digits can have leading 0s.


Question: /// /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal /// notation, divided by `.` (this is called "dot-decimal notation"). <del> /// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943]. </del> <ins> /// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which /// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943]. </ins> /// /// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 /// [`FromStr`]: crate::str::FromStr

At least that's how I think the term is usually used when one needs to be precise about series of digits vs. the thing they represent.) However, it's not true for this function. Any number that has leading 0s is rejected by this function. This fact about C was brought up only to explain why leading 0s are rejected. No base-8 occurs anywhere in the behavior of this function. If you disagree, please show an input-output pair for this function which demonstrates that base 8 is used. (The code inside the function doesn't matter, of course. Only its observable behavior does.) I really don't understand why you keep insisting that this function has anything to do with base 8. I think it might be because of some quirk in how it is implemented, but unobservable implementation details are irrelevant. As a mathematician you should be even more used to this than most programmers, since the usual way of defining mathematical functions consists entirely of input-output pairs, there is not even such a thing as an "implementation"... but I am digressing. ;) Even mathematically speaking, the sequence of digits "0" represents the same number in any base system. So, in a very precise formal sense, "not that it matters" is accurate. A base is just a way to convert a series of digits into a number, and for series of digits consisting only of 0s, the result is always the same. The definition of "decimal" used in the documentation exactly matches the mathematical definition. The documentation just fails to mention that there is an additional restriction, namely that no leading 0s are accepted (except if all digits of an octet are 0). However, it remains the case that if an input is accepted by this function, then all octets are interpreted as decimal -- and moreover, all decimal representations without leading 0s are accepted by this function.
Saying a definition matches exactly with another definition before subsequently changing the definition by adding other restrictions does not make sense to me. Does the definition of an even integer "match exactly" with the definition of an integer? No. Adding or removing restrictions to a definition changes the definition. So the fact that leading s is not allowed means we are not talking about mathematical base-10.


Question: /// /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal /// notation, divided by `.` (this is called "dot-decimal notation"). <del> /// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943]. </del> <ins> /// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which /// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943]. </ins> /// /// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 /// [`FromStr`]: crate::str::FromStr

If I define a function that takes an integer and it errors any time the integer is not even; however the documentation of that function makes no mention of that seems very problematic. I would not defend such documentation by saying "my definition of integer matches exactly with the definition of the mathematical definition of an integer except I also require the integer to be divisible by 2". My documentation should very clearly define what I mean by "integer", or better, simply state "even integer".
Okay, I guess I should have said that it is strictly a restriction of the mathematical definition (a subset, if you take the graph view of a function). But it doesn't disagree on any inputs where it is defined. Your talking about base 8 makes it sound like sometimes it is not matching the base 10 function even when it does produce a result (but matches the base 8 function instead), and it took a quite a lot of time to realize that is not what happens. Moreover, the subset still contains the full graph of the inverse of the full "base 10" function where you always pick the shortest representation (i.e., the most common "serialization" function of numbers into base 10 representation). So unlike your "even" example it is a pretty reasonable parsing function still. There are only some "non-canonical" representations being rejected.
Well, I think we are talking in circles at this point honestly, lol. While I would agree my example is a more extreme example of documentation failure since conflating the definition of "even integer" with "integer" is more absurd than conflating the definition of "base-10 in the shortest representation (with the exception of 0 which is allowed any non-negative integer amount of leading 0s)" with "base-10", both examples suffer from the fact that additional failures occur than otherwise would occur based on the exact definition of the term that is used (in my example "integer" and in this example "decimal"). For me, as I mentioned in the other discussion, this really is not me being "pedantic". I wrote code based on the documentation that ended being invalid since I (mis-)interpreted "decimal" to be more general than what it actually means in this context.


Question: /// /// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal /// notation, divided by `.` (this is called "dot-decimal notation"). <del> /// Notably, octal numbers and hexadecimal numbers are not allowed per [IETF RFC 6943]. </del> <ins> /// Notably, octal numbers (which are indicated with a leading `0`) and hexadecimal numbers (which /// are indicated with a leading `0x`) are not allowed per [IETF RFC 6943]. </ins> /// /// [IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1 /// [`FromStr`]: crate::str::FromStr

Ideally, in my opinion at least, that should not happen especially since it is not that much additional effort to more properly document what certain terms mean even if that means just adding one or two more examples highlighting parsing failures (or successes) that one (like myself) would not expect.
We already agree that the docs need to be improved. :) The rest of this discussion is then mostly philosophical and not going to lead to a productive outcome, so maybe we better stop it. ;)


Question: match memchr::memrchr(b'n', buf) { Some(i) => { let n = try!(self.inner.write(&buf[..i + 1])); <del> if n != i + 1 { return Ok(n) } try!(self.inner.flush()); </del> <ins> if n != i + 1 || self.inner.flush().is_err() { // Do not return errors on partial writes. return Ok(n); } </ins> self.inner.write(&buf[i + 1..]).map(|i| n + i) } None => self.inner.write(buf),

can return an error after a partial write if flushing the inner fails (). It should instead return , ignoring the error. I originally thought this problem was systematic so I audited stdlib. Apparently it isn't... See below. The write trait guarantees: However, this is violated all over stdlib. For example, if is written to a , the could write , try to flush, and then return an error due to a failed flush. However, has been written violating the spec. IMO, the solution is to return for partial writes and drop the error (if any). This should be safe because of write's write-xor-error guarantee. If the error was transient, the caller never needs to know. Otherwise, they will will learn of it on the next write. Here's everything in the stdlib that implements write (and should be audited): [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [x] in [ ] in (buggy) [x] in (buggy but unfixable and deprecated). [x] in [x] in [x] in [ ] in (panics on partial write) [x] in [x] in [x] in
Note: this could, e.g., theoretically cause to write on interrupt.
Ok. Actually, it turns out that only and are really problematic. on windows is bad but at least it's acknowledged in the code with a ...
So, is actually correct (I misread some of the code). This is just a bug in , nothing more.
Nice effort to audit it all!


Question: = help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date <del> error[E0658]: the `#[pointee]` attribute is an experimental feature --> $DIR/feature-gate-derive-smart-pointer.rs:5:22 | LL | struct MyPointer<'a, #[pointee] T: ?Sized> { |                      ^^^^^^^^^^ | = note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information = help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date </del> error[E0658]: use of unstable library feature 'derive_smart_pointer' --> $DIR/feature-gate-derive-smart-pointer.rs:1:5 |

https://crater- https://crater- cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
cc
label F-derivesmartpointer
Thread on zulip: https://rust-
claim
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: let mut late_depth = 0; let mut scope = self.scope; let mut crossed_anon_const = false; let result = loop { match *scope { Scope::Body { s, .. } => {

<!-- 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
minimized
Bisected to :sweatsmile:


Question: <ins> #[derive(PartialEq, Eq)] enum X { A, B, C, } fn main() { let x = X::A; let y = Some(X::A); match (x, y) { //~^ ERROR non-exhaustive patterns: `(A, Some(A))`, `(A, Some(B))`, `(B, Some(B))` and 2 //~| more not covered (_, None) => false, (v, Some(w)) if v == w => true, (X::B, Some(X::C)) => false, (X::B, Some(X::A)) => false, (X::A, Some(X::C)) | (X::C, Some(X::A)) => false, }; } </ins>

A small demo: . I expected to see this happen The usual error message indicating that patterns and are not covered. Instead, this happened Patterns and are detected as not covered. :
If you add the suggested arms, it will in fact detect the other ones as missing. It is expected that is detected as not covered since the match guard is not taken into account when checking exhaustiveness (and couldn't be, since it's an arbitrary expression).
Closing as expected behavior.
Wouldn't you then expect that it mentions , , , and as not covered? Or is the number of outputs always restricted to two? In that case, I think it would be useful to indicate that some patterns might be missing, e.g.:
Yeah that's true


Question: extern "C" { pub fn LLVMRustInstallFatalErrorHandler(); <ins> pub fn LLVMRustDisableSystemDialogsOnCrash(); </ins> // Create and destroy contexts. pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context;

The Windows CI build with LLVM assertions enabled recently hung without an error message. It turned out to be an LLVM assertion failure resulting in a dialog which needed to be acknowledged, see According to the such a dialog is always displayed, but that is not the whole truth. Apparently can be used to customize assertion failure handling. We should definitely make assertions failures exit with error after printing failure information to stderr instead of displaying a dialog and hanging. label O-windows
Could this be part of why we're getting so many hangs in the CI?
That was responsible for four stuck builds recently. I don't think it was responsible for many timed out builds before that.
Posted with a possible solution.


Question: expected: Expectation) { check_expr_has_type(fcx, cond_expr, ty::mk_bool()); <ins> // Disregard "castable to" expectations because they // can lead us astray. Consider for example `if cond // {22} else {c} as u8` -- if we propagate the // "castable to u8" constraint to 22, it will pick the // type 22u8, which is overly constrained (c might not // be a u8). In effect, the problem is that the // "castable to" expectation is not the tightest thing // we can say, so we want to drop it in this case. // The tightest thing we can say is "must unify with // else branch". Note that in the case of a "has type" // constraint, this limitation does not hold. // If the expected type is just a type variable, then don't use // an expected type. Otherwise, we might write parts of the type // when checking the 'then' block which are incompatible with the // 'else' branch. let expected = match expected.only_has_type() { ExpectHasType(ety) => { match infer::resolve_type(fcx.infcx(), Some(sp), ety, force_tvar) { Ok(rty) if !ty::type_is_ty_var(rty) => ExpectHasType(rty), _ => NoExpectation } } _ => NoExpectation }; check_block_with_expected(fcx, then_blk, expected); let then_ty = fcx.node_ty(then_blk.id); </ins> let branches_ty = match opt_else_expr { Some(ref else_expr) => { <del> // Disregard "castable to" expectations because they // can lead us astray. Consider for example `if cond // {22} else {c} as u8` -- if we propagate the // "castable to u8" constraint to 22, it will pick the // type 22u8, which is overly constrained (c might not // be a u8). In effect, the problem is that the // "castable to" expectation is not the tightest thing // we can say, so we want to drop it in this case. // The tightest thing we can say is "must unify with // else branch". Note that in the case of a "has type" // constraint, this limitation does not hold. // If the expected type is just a type variable, then don't use // an expected type. Otherwise, we might write parts of the type // when checking the 'then' block which are incompatible with the // 'else' branch. let expected = match expected.only_has_type() { ExpectHasType(ety) => { match infer::resolve_type(fcx.infcx(), Some(sp), ety, force_tvar) { Ok(rty) if !ty::type_is_ty_var(rty) => ExpectHasType(rty), _ => NoExpectation } } _ => NoExpectation }; check_block_with_expected(fcx, then_blk, expected); let then_ty = fcx.node_ty(then_blk.id); </del> check_expr_with_expectation(fcx, &**else_expr, expected); let else_ty = fcx.expr_ty(&**else_expr); infer::common_supertype(fcx.infcx(),

I apologize in advance if this is a separate issue. With the map() generic function from the tutorial: That code gives a nice error message: However, remove the assignment and what should be the same error message becomes:
Yes, that is unrelated to this issue. You're seeing an expected type mismatch error since the return type of main() is () and your samples result in two different non-() results.
Thanks I was one hour into learning Rust when I came across this. I understand what is going on now. I still think the error message could be improved to mention that "expected " is referring to the return type of main(). That simple clue could help people not as familiar with Rust to remember the semicolon rule to turn a statement into an expression.
Not critical for 0.7, but improving error messages is always good. Nominating for milestone 5.
declined. this is bad but it's not a blocker.
Confirmed that the situation is unchanged.
This is still an issue.
Bug triage. Still an issue.
Very, very small change:


Question: E0701: include_str!("./error_codes/E0701.md"), E0704: include_str!("./error_codes/E0704.md"), E0705: include_str!("./error_codes/E0705.md"), <ins> E0706: include_str!("./error_codes/E0706.md"), </ins> E0712: include_str!("./error_codes/E0712.md"), E0713: include_str!("./error_codes/E0713.md"), E0714: include_str!("./error_codes/E0714.md"),

we currently emit We should tell people that trait functions are not possible , and possibly point them to . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Created


Question: // don't create labels for compiler-generated spans Some(_) => None, None => { <del> let (span, suggestion) = suggest_ampmut( self.infcx.tcx, local_decl, opt_assignment_rhs_span, *opt_ty_info, ); </del> <ins> let (span, suggestion) = if name != kw::SelfLower { suggest_ampmut( self.infcx.tcx, local_decl, opt_assignment_rhs_span, *opt_ty_info, ) } else { match local_decl.local_info.as_deref() { Some(LocalInfo::User(ClearCrossCrate::Set( mir::BindingForm::Var(mir::VarBindingForm { opt_ty_info: None, .. }), ))) => { suggest_ampmut_self(self.infcx.tcx, local_decl) } // explicit self (eg `self: &'a Self`) _ => suggest_ampmut( self.infcx.tcx, local_decl, opt_assignment_rhs_span, *opt_ty_info, ), } }; </ins> Some((true, span, suggestion)) } }

Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should look like: <!-- If the problem is not self-explanatory, please provide a rationale for the change. --is not a valid argument; it needs to be either or . For some reason this problem only happens when the function is async.
This is the same diagnostic you get when mutably dereferencing let-bindings that are : So it seems like this has to do with the fact that ast_lowering emits a binding when desugaring. I wonder if we can get the name of the variable when emitting this diagnostic, and special-case when it .
Another (possibly related?) bug: doesn't have the suggestion if it's in an async block:
Same with closures. I would probably classify that as a separate bug, since the original bug has to do specifically with desugaring, and the latter has to do with closure/generator captures.
Thanks for the report and getting a PR up so quickly! label +AsyncAwait-Triaged +AsyncAwait-Polish
Another similar error, not related to async this time: isn't valid Rust.


Question: /// Was the origin of the `span` from a scrutinee expression? /// /// Otherwise there is no scrutinee and it could be e.g. from the type of a formal parameter. <del> origin_expr: bool, </del> <ins> origin_expr: Option<&'tcx hir::Expr<'tcx>>, </ins> /// The span giving rise to the `expected` type, if one could be provided. /// /// If `origin_expr` is `true`, then this is the span of the scrutinee as in:

<!-- 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: The current output is: <!-- The following is not always necessary. --Ideally the output should suggest to the user that they need to initialize the enum variant's value in order to use the . <!-- 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 --
Can you give the output of what it should look like?
It should probably look similar to the suggestion given for and So I guess sth. like: Edit: Or instead of saying “to instantiate this tuple variant” we could say “to call this function” like it's done for the erroneous snippet (where is a ).
claim
commit the fix


Question: [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git <del> branch = rustc/18.0-2024-02-13 </del> <ins> branch = rustc/18.1-2024-05-19 </ins> shallow = true [submodule "src/doc/embedded-book"] path = src/doc/embedded-book

I get a segfault when I try to run on the following code: I see the same behavior with the latest nightly . I see no error with 1.77.0 or earlier. It also works fine on Linux, and on an older Intel Macbook. I also updated to the latest XCode to make sure all parts of my toolchain were up to date. Doing so did not make the segfault go away.
The problem disappears if I turn off incremental compilation by adding this to the :
I believe this bisects to LLVM 18 from cc
We are hitting an LLVM assertion:
Could someone please run and then repeat the rustc command with and share the bitcode files?
I can reproduce it, and I will try to reduce it.
Upstream issue: Reduced:
It has already been backported to LLVM 18: label +llvm-fixed-upstream


Question: [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git <del> branch = rustc/18.0-2024-02-13 </del> <ins> branch = rustc/18.1-2024-05-19 </ins> shallow = true [submodule "src/doc/embedded-book"] path = src/doc/embedded-book

<!-- 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. --This bug is spotted jointly by and We tried this code (minimized by and I expected to see this happen: The program should exit without error. Instead, this happened: segmentation fault. Notice that the code will pass . (). The error is reproducible with larger than . The error seems to be related, as does not reproduce the bug. There seems to be no bug in LLVM IR. noticed that produces different asm compared with the one in the ELF output. Notice that we encountered an ICE while exploring the code (for now, we are not sure whether the ICE is related to SEGV, we can file a separate report for ICE if needed). Basically, invoking the rustc consecutively, one will get (cleaning up the directory can help): <!-- 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. --Both nightly and stable versions are affected :
may be running into
This started on stable in 1.73, and bisects to : A couple notes, when using cargo: incremental compilation is not enabled on release builds for people who opt into optimizing dependencies even in debug builds: incremental compilation is not enabled for dependencies either, only local crates It would be interesting to see exactly what impacts codegen here when enabling incremental compilation of a single session (but at the same time, it seems probable that not many users should encounter this issue in the more common configurations?).
Some additional context: the code is largely related to ecow. In case people compile typst/ecow related code with incremental build and level 1 optimization enabled and run into segmentation fault, this should be the bug behind it.
So the error happens just from adding , without there actually being a previous incremental cache there? Wow. Cc Seems likely that the LLVM 17 update is involved. Cc
I can confirm that this reproduces with an empty cache -- which should be good news in terms of debugging the issue. I'm pretty sure this is a ThinLTO-related bug and incremental somehow configures CGUs and LLVM settings in a way that triggers the bug. The segfault does not reproduce when compiling with .


Question: [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git <del> branch = rustc/18.0-2024-02-13 </del> <ins> branch = rustc/18.1-2024-05-19 </ins> shallow = true [submodule "src/doc/embedded-book"] path = src/doc/embedded-book

Running the miscompiled binary in gdb (with ) gives:
Yeah, that would crash...
I think this is a minimal reproducer: We infer that the result of this function is nonnull...
Upstream issue:
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: } let source_string = match file.get_line(line.line_index - 1) { <del> Some(s) => s, </del> <ins> Some(s) => replace_tabs(&*s), </ins> None => return Vec::new(), };

The code that truncates long lines doesn't take (hard) tabs into account, so the lines printed are off. Example code: Gives the following error: If you use four spaces instead of each tab it works as expected: cc and cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I thought we were already accounting for tabs, but looking we rely on which considers to not have a width, which we then assume to be 1.
claim


Question: import_id: Option<LocalDefId>, ) { debug!("visiting item {:?}", item); <ins> if self.inside_body { // Only impls can be "seen" outside a body. For example: // // ``` // struct Bar; // // fn foo() { //     impl Bar { fn bar() {} } // } // Bar::bar(); // ``` if let hir::ItemKind::Impl(impl_) = item.kind && // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. impl_.of_trait.is_none() { self.add_to_current_mod(item, None, None); } return; } </ins> let name = renamed.unwrap_or(item.ident.name); let tcx = self.cx.tcx;

<!-- 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. --Consider the following code is local to and inaccessible, and should not be documented. Instead, rustdoc currently documents the module at the same level as . <!-- 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. --: </details
cc does this have to do with those changes you made to item collection?
Very likely. I won't be able to fix it until next week though. EDIT: I suspect it broke from
I just realized that this is broken on stable, too, so I think the cause may be older than that?
Oh. I'm at least happy to realize that I didn't break it recently. Thanks for the report. Will fix it monday.


Question: <ins> // check-pass // aux-build:test-macros.rs // compile-flags: -Z span-debug // // Regression test for issue #76182 // Tests that we properly handle patterns with a leading vert #![no_std] // Don't load unnecessary hygiene information from std extern crate std; extern crate test_macros; #[test_macros::print_attr] fn main() { match () { | () => () } } </ins>

The following code: is currently pretty-printed as: If this occurs in a macro invocation, it leads to an instance of
Extra info (but it boils down to what said): Using I get the following log: Rendered diff:
This applies to all trailing separators in theory (except that the separator is leading rather than trailing in this case), but in other cases the difference is fixed up by fuzzy comparison in .


Question: fn is_expr_delims_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool { followed_by_block && match inner.kind { <del> ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true, </del> <ins> ExprKind::Ret(_) | ExprKind::Break(..) => true, </ins> _ => parser::contains_exterior_struct_lit(&inner), } }

This produces a lint: But removing the parentheses produces an error. This bug was already mentioned in , but that issue is lost in feature-request purgatory since it asks for the version without parentheses to be allowed. I'm opening this issue to track the incorrect lint specifically. (Edit: Fixed the example.) <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim Will wait for to get merged before this is fixed though.


Question: fn is_expr_delims_necessary(inner: &ast::Expr, followed_by_block: bool) -> bool { followed_by_block && match inner.kind { <del> ast::ExprKind::Ret(_) | ast::ExprKind::Break(..) => true, </del> <ins> ExprKind::Ret(_) | ExprKind::Break(..) => true, </ins> _ => parser::contains_exterior_struct_lit(&inner), } }

The following code fails to compile (): The compiler error is: Adding parentheses or braces, it will compile fine: The same issue happens with other constructs such as:
cc
I believe the error is expected here, the same as with : Which also needs to be to compile. That said, the warning to remove the necessary parens is definitely wrong. EDIT: Hmm, I might be wrong, actually. The following compiles, which surprised me: as does this: So maybe the parser restriction is only for struct literals, not for keyword-introduced expressions.
Yeah I think is the better comparison here so it's probably a bug.
This is exactly what a thought. I didn't know that this:
For , hmmm... well, I can't come up with a truly devastating example, but eliminating the parentheses could hurt diagnostics.


Question: fs::write(&self.path, self.hash.as_deref().unwrap_or(b"")) } } <ins> #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrtBeginEnd { pub target: TargetSelection, } impl Step for CrtBeginEnd { type Output = PathBuf; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/llvm-project/compiler-rt/lib/crt") } fn make_run(run: RunConfig<'_>) { run.builder.ensure(CrtBeginEnd { target: run.target }); } /// Build crtbegin.o/crtend.o for musl target. fn run(self, builder: &Builder<'_>) -> Self::Output { let out_dir = builder.native_dir(self.target).join("crt"); if builder.config.dry_run { return out_dir; } let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c"); let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c"); if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o")) && up_to_date(&crtend_src, &out_dir.join("crtendS.o")) { return out_dir; } builder.info("Building crtbegin.o and crtend.o"); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); if let Some(ar) = builder.ar(self.target) { cfg.archiver(ar); } cfg.compiler(builder.cc(self.target)); cfg.cargo_metadata(false) .out_dir(&out_dir) .target(&self.target.triple) .host(&builder.config.build.triple) .warnings(false) .debug(false) .opt_level(3) .file(crtbegin_src) .file(crtend_src); // Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt // Currently only consumer of those objects is musl, which use .init_array/.fini_array // instead of .ctors/.dtors cfg.flag("-std=c11") .define("CRT_HAS_INITFINI_ARRAY", None) .define("EH_USE_FRAME_REGISTRY", None); cfg.compile("crt"); t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o"))); t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o"))); out_dir } } </ins>

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: fs::write(&self.path, self.hash.as_deref().unwrap_or(b"")) } } <ins> #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrtBeginEnd { pub target: TargetSelection, } impl Step for CrtBeginEnd { type Output = PathBuf; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/llvm-project/compiler-rt/lib/crt") } fn make_run(run: RunConfig<'_>) { run.builder.ensure(CrtBeginEnd { target: run.target }); } /// Build crtbegin.o/crtend.o for musl target. fn run(self, builder: &Builder<'_>) -> Self::Output { let out_dir = builder.native_dir(self.target).join("crt"); if builder.config.dry_run { return out_dir; } let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c"); let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c"); if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o")) && up_to_date(&crtend_src, &out_dir.join("crtendS.o")) { return out_dir; } builder.info("Building crtbegin.o and crtend.o"); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); if let Some(ar) = builder.ar(self.target) { cfg.archiver(ar); } cfg.compiler(builder.cc(self.target)); cfg.cargo_metadata(false) .out_dir(&out_dir) .target(&self.target.triple) .host(&builder.config.build.triple) .warnings(false) .debug(false) .opt_level(3) .file(crtbegin_src) .file(crtend_src); // Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt // Currently only consumer of those objects is musl, which use .init_array/.fini_array // instead of .ctors/.dtors cfg.flag("-std=c11") .define("CRT_HAS_INITFINI_ARRAY", None) .define("EH_USE_FRAME_REGISTRY", None); cfg.compile("crt"); t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o"))); t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o"))); out_dir } } </ins>

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: fs::write(&self.path, self.hash.as_deref().unwrap_or(b"")) } } <ins> #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrtBeginEnd { pub target: TargetSelection, } impl Step for CrtBeginEnd { type Output = PathBuf; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/llvm-project/compiler-rt/lib/crt") } fn make_run(run: RunConfig<'_>) { run.builder.ensure(CrtBeginEnd { target: run.target }); } /// Build crtbegin.o/crtend.o for musl target. fn run(self, builder: &Builder<'_>) -> Self::Output { let out_dir = builder.native_dir(self.target).join("crt"); if builder.config.dry_run { return out_dir; } let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c"); let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c"); if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o")) && up_to_date(&crtend_src, &out_dir.join("crtendS.o")) { return out_dir; } builder.info("Building crtbegin.o and crtend.o"); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); if let Some(ar) = builder.ar(self.target) { cfg.archiver(ar); } cfg.compiler(builder.cc(self.target)); cfg.cargo_metadata(false) .out_dir(&out_dir) .target(&self.target.triple) .host(&builder.config.build.triple) .warnings(false) .debug(false) .opt_level(3) .file(crtbegin_src) .file(crtend_src); // Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt // Currently only consumer of those objects is musl, which use .init_array/.fini_array // instead of .ctors/.dtors cfg.flag("-std=c11") .define("CRT_HAS_INITFINI_ARRAY", None) .define("EH_USE_FRAME_REGISTRY", None); cfg.compile("crt"); t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o"))); t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o"))); out_dir } } </ins>

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: fs::write(&self.path, self.hash.as_deref().unwrap_or(b"")) } } <ins> #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrtBeginEnd { pub target: TargetSelection, } impl Step for CrtBeginEnd { type Output = PathBuf; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/llvm-project/compiler-rt/lib/crt") } fn make_run(run: RunConfig<'_>) { run.builder.ensure(CrtBeginEnd { target: run.target }); } /// Build crtbegin.o/crtend.o for musl target. fn run(self, builder: &Builder<'_>) -> Self::Output { let out_dir = builder.native_dir(self.target).join("crt"); if builder.config.dry_run { return out_dir; } let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c"); let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c"); if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o")) && up_to_date(&crtend_src, &out_dir.join("crtendS.o")) { return out_dir; } builder.info("Building crtbegin.o and crtend.o"); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); if let Some(ar) = builder.ar(self.target) { cfg.archiver(ar); } cfg.compiler(builder.cc(self.target)); cfg.cargo_metadata(false) .out_dir(&out_dir) .target(&self.target.triple) .host(&builder.config.build.triple) .warnings(false) .debug(false) .opt_level(3) .file(crtbegin_src) .file(crtend_src); // Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt // Currently only consumer of those objects is musl, which use .init_array/.fini_array // instead of .ctors/.dtors cfg.flag("-std=c11") .define("CRT_HAS_INITFINI_ARRAY", None) .define("EH_USE_FRAME_REGISTRY", None); cfg.compile("crt"); t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o"))); t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o"))); out_dir } } </ins>

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: fs::write(&self.path, self.hash.as_deref().unwrap_or(b"")) } } <ins> #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrtBeginEnd { pub target: TargetSelection, } impl Step for CrtBeginEnd { type Output = PathBuf; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/llvm-project/compiler-rt/lib/crt") } fn make_run(run: RunConfig<'_>) { run.builder.ensure(CrtBeginEnd { target: run.target }); } /// Build crtbegin.o/crtend.o for musl target. fn run(self, builder: &Builder<'_>) -> Self::Output { let out_dir = builder.native_dir(self.target).join("crt"); if builder.config.dry_run { return out_dir; } let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c"); let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c"); if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o")) && up_to_date(&crtend_src, &out_dir.join("crtendS.o")) { return out_dir; } builder.info("Building crtbegin.o and crtend.o"); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); if let Some(ar) = builder.ar(self.target) { cfg.archiver(ar); } cfg.compiler(builder.cc(self.target)); cfg.cargo_metadata(false) .out_dir(&out_dir) .target(&self.target.triple) .host(&builder.config.build.triple) .warnings(false) .debug(false) .opt_level(3) .file(crtbegin_src) .file(crtend_src); // Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt // Currently only consumer of those objects is musl, which use .init_array/.fini_array // instead of .ctors/.dtors cfg.flag("-std=c11") .define("CRT_HAS_INITFINI_ARRAY", None) .define("EH_USE_FRAME_REGISTRY", None); cfg.compile("crt"); t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o"))); t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o"))); out_dir } } </ins>

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: fs::write(&self.path, self.hash.as_deref().unwrap_or(b"")) } } <ins> #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrtBeginEnd { pub target: TargetSelection, } impl Step for CrtBeginEnd { type Output = PathBuf; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/llvm-project/compiler-rt/lib/crt") } fn make_run(run: RunConfig<'_>) { run.builder.ensure(CrtBeginEnd { target: run.target }); } /// Build crtbegin.o/crtend.o for musl target. fn run(self, builder: &Builder<'_>) -> Self::Output { let out_dir = builder.native_dir(self.target).join("crt"); if builder.config.dry_run { return out_dir; } let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c"); let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c"); if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o")) && up_to_date(&crtend_src, &out_dir.join("crtendS.o")) { return out_dir; } builder.info("Building crtbegin.o and crtend.o"); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); if let Some(ar) = builder.ar(self.target) { cfg.archiver(ar); } cfg.compiler(builder.cc(self.target)); cfg.cargo_metadata(false) .out_dir(&out_dir) .target(&self.target.triple) .host(&builder.config.build.triple) .warnings(false) .debug(false) .opt_level(3) .file(crtbegin_src) .file(crtend_src); // Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt // Currently only consumer of those objects is musl, which use .init_array/.fini_array // instead of .ctors/.dtors cfg.flag("-std=c11") .define("CRT_HAS_INITFINI_ARRAY", None) .define("EH_USE_FRAME_REGISTRY", None); cfg.compile("crt"); t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o"))); t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o"))); out_dir } } </ins>

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: fs::write(&self.path, self.hash.as_deref().unwrap_or(b"")) } } <ins> #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrtBeginEnd { pub target: TargetSelection, } impl Step for CrtBeginEnd { type Output = PathBuf; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path("src/llvm-project/compiler-rt/lib/crt") } fn make_run(run: RunConfig<'_>) { run.builder.ensure(CrtBeginEnd { target: run.target }); } /// Build crtbegin.o/crtend.o for musl target. fn run(self, builder: &Builder<'_>) -> Self::Output { let out_dir = builder.native_dir(self.target).join("crt"); if builder.config.dry_run { return out_dir; } let crtbegin_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtbegin.c"); let crtend_src = builder.src.join("src/llvm-project/compiler-rt/lib/crt/crtend.c"); if up_to_date(&crtbegin_src, &out_dir.join("crtbegin.o")) && up_to_date(&crtend_src, &out_dir.join("crtendS.o")) { return out_dir; } builder.info("Building crtbegin.o and crtend.o"); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); if let Some(ar) = builder.ar(self.target) { cfg.archiver(ar); } cfg.compiler(builder.cc(self.target)); cfg.cargo_metadata(false) .out_dir(&out_dir) .target(&self.target.triple) .host(&builder.config.build.triple) .warnings(false) .debug(false) .opt_level(3) .file(crtbegin_src) .file(crtend_src); // Those flags are defined in src/llvm-project/compiler-rt/lib/crt/CMakeLists.txt // Currently only consumer of those objects is musl, which use .init_array/.fini_array // instead of .ctors/.dtors cfg.flag("-std=c11") .define("CRT_HAS_INITFINI_ARRAY", None) .define("EH_USE_FRAME_REGISTRY", None); cfg.compile("crt"); t!(fs::copy(out_dir.join("crtbegin.o"), out_dir.join("crtbeginS.o"))); t!(fs::copy(out_dir.join("crtend.o"), out_dir.join("crtendS.o"))); out_dir } } </ins>

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:


Question: } } <del> /// Checks `#[doc(hidden)]` attributes. Returns `true` if valid. fn check_doc_hidden( &self, attr: &Attribute, meta_index: usize, meta: &NestedMetaItem, hir_id: HirId, target: Target, ) -> bool { if let Target::AssocConst | Target::AssocTy | Target::Method(MethodKind::Trait { body: true }) = target { let parent_hir_id = self.tcx.hir().get_parent_item(hir_id); let containing_item = self.tcx.hir().expect_item(parent_hir_id); if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = containing_item.kind { let meta_items = attr.meta_item_list().unwrap(); let (span, replacement_span) = if meta_items.len() == 1 { (attr.span, attr.span) } else { let meta_span = meta.span(); ( meta_span, meta_span.until(match meta_items.get(meta_index + 1) { Some(next_item) => next_item.span(), None => match attr.get_normal_item().args { MacArgs::Delimited(DelimSpan { close, .. }, ..) => close, _ => unreachable!(), }, }), ) }; // FIXME: #[doc(hidden)] was previously erroneously allowed on trait impl items, // so for backward compatibility only emit a warning and do not mark it as invalid. self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, span, |lint| { lint.build("`#[doc(hidden)]` is ignored on trait impl items") .warn( "this was previously accepted by the compiler but is  being phased out; it will become a hard error in  a future release!", ) .note( "whether the impl item is `doc(hidden)` or not  entirely depends on the corresponding trait item", ) .span_suggestion( replacement_span, "remove this attribute", "", Applicability::MachineApplicable, ) .emit(); }); } } true } </del> /// Checks that an attribute is *not* used at the crate level. Returns `true` if valid. fn check_attr_not_crate_level( &self,

The warning by claims that on an impl item is ignored by rustdoc, but it isn't necessarily. The warning says: which is not true in the following repro: This warning is a false positive. Rustdoc does pay attention to this attribute. For the code above, the rendered documentation of and looks like: <table<tr<td<img src="https://user-" height="185"</td<td<img src="https://user-" height="300"</td</tr</tableAfter removing the supposedly unused attribute and rendering again, the "nasty uninteresting type" that we wanted not shown is going to get rendered on both pages: <table<tr<td<img src="https://user-" height="185"</td<td<img src="https://user-" height="300"</td</tr</table( :


Question: } } <del> /// Checks `#[doc(hidden)]` attributes. Returns `true` if valid. fn check_doc_hidden( &self, attr: &Attribute, meta_index: usize, meta: &NestedMetaItem, hir_id: HirId, target: Target, ) -> bool { if let Target::AssocConst | Target::AssocTy | Target::Method(MethodKind::Trait { body: true }) = target { let parent_hir_id = self.tcx.hir().get_parent_item(hir_id); let containing_item = self.tcx.hir().expect_item(parent_hir_id); if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = containing_item.kind { let meta_items = attr.meta_item_list().unwrap(); let (span, replacement_span) = if meta_items.len() == 1 { (attr.span, attr.span) } else { let meta_span = meta.span(); ( meta_span, meta_span.until(match meta_items.get(meta_index + 1) { Some(next_item) => next_item.span(), None => match attr.get_normal_item().args { MacArgs::Delimited(DelimSpan { close, .. }, ..) => close, _ => unreachable!(), }, }), ) }; // FIXME: #[doc(hidden)] was previously erroneously allowed on trait impl items, // so for backward compatibility only emit a warning and do not mark it as invalid. self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, span, |lint| { lint.build("`#[doc(hidden)]` is ignored on trait impl items") .warn( "this was previously accepted by the compiler but is  being phased out; it will become a hard error in  a future release!", ) .note( "whether the impl item is `doc(hidden)` or not  entirely depends on the corresponding trait item", ) .span_suggestion( replacement_span, "remove this attribute", "", Applicability::MachineApplicable, ) .emit(); }); } } true } </del> /// Checks that an attribute is *not* used at the crate level. Returns `true` if valid. fn check_attr_not_crate_level( &self,

Just wanted to add that this is also affecting , but in a different way: <img width="500" src="https://user-"The isn't there at all without the : <img width="500" src="https://user-"Based on the above, this isn't correct: it actually hides the entire thing, at least for associated constants.
In your case, it's inherent associated items being accidentally flagged which is which was meaning the most recent nightly should not have your issue anymore. Sorry for the inconvenience. The longer I look this lint, the less I like it.


Question: &base_segments[base_segments.len()-2], base_segments.last().unwrap()) } <del> Def::Mod(id) => { </del> <ins> Def::Mod(..) => { </ins> // Used as sentinel by callers to indicate the `<T>::A::B::C` form. // FIXME(#22519) This part of the resolution logic should be // avoided entirely for that form, once we stop needed a Def

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: mod predecessors; mod query; pub mod tcx; <ins> pub mod terminator; pub use terminator::*; </ins> pub mod traversal; mod type_foldable; pub mod visit;

moved the file to over 3k LOC, but I didn't fix it there and instead just annotated the file so tidy ignores it. We should probably split the mir types into separate submodules by the way they are used in MIR. I think we can start by pulling out e.g. terminators and all their sub-types to a submodule <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim Will be interested in picking this up


Question: .try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub) .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings)); self.r.record_partial_res(pat.id, PartialRes::new(res)); <ins> self.r.record_pat_span(pat.id, pat.span); </ins> } PatKind::TupleStruct(ref path, ref sub_patterns) => { self.smart_resolve_path(

The following code... the following error and warning: The warning says that is not used but it clearly is, just not properly. This error is normally easier to spot when using the proper casing for constants, but that might not always be the case. Perhaps in this instance, we should look for other items with the exact same name and point out that the user is trying to use a constant as a type. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Every single one of these errors should point at similarly named things of the wrong namespace.
Do you know where in the code this is coming from?
running the following will tell you where the error is being emitted: From there the place you might want to start looking at is , which is a bit hard to follow at the moment (I'm doing a slight clean up of that method at the moment), but should be reasonably straight forward to add another check for this case to that pile :)
claim
Can I take this issue?
Yes feel free to take it, I removed my assignment.
I’m going to be tied up until May, feel free to take this issue:pray:
Hey I'm looking to get to know the Rust codebase better and contribute to the project - would love to take a crack at this issue!
claim


Question: <ins> // build-pass // aux-build:issue-97708-aux.rs extern crate issue_97708_aux; use issue_97708_aux::TaskStub; static TASK_STUB: TaskStub = TaskStub::new(); 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. --Github: Repro: Reproduces in: Stable Linux - rustc 1.61.0 ( 2022-05-18) Nightly Linux - rustc 1.63.0-nightly ( 2022-06-02) <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
I'll see if I can make a smaller repro case
So, the minimal repro case is MUCH smaller: in : In : Which points to these code chunks: This seems to work in the tests for , so it seems like the ICE only triggers when used from an external trait. Additionally, this ICE does NOT trigger in .
CC
Yeah, this seems to occur specifically when trying to compile an external crate that calls this function. Lib tests inside the crate that call the function don't ICE, but adding an integration test (outside of the crate's compilation unit) does trigger the ICE:
If the function is made , the ICE no longer occurs. For example, this commit does not ICE:
prioritize
, if the functions are made but placed in a private module, they get culled again, triggering the ICE:
It also appears that if you move the functions out of the , AND mark them as , the ICE is also abated. See this PR for addressing:
For folks joining now/as a TL;DR, the offending code is basically this: The function produces a value, that gets created in a static: Which gets loaded into a static in user code: It LOOKS like somehow the two original functions (declared inside a private, const fn; inside a private type), are getting culled, which means that when the static (in another compilation unit) goes to be created, the MIR for those functions are missing.
This is likely a disagreement between . Though I don't know much about codegen.
Anyways I think I have a fix, though I am not certain it's the right one. In any case, I at least have a minimized UI test for rustc devs who know codegen better than me. PR incoming.


Question: [[package]] name = "compiler_builtins" <del> version = "0.1.114" </del> <ins> version = "0.1.117" </ins> source = "registry+https://github.com/rust-lang/crates.io-index" <del> checksum = "eb58b199190fcfe0846f55a3b545cd6b07a34bdd5930a476ff856f3ebcc5558a" </del> <ins> checksum = "a91dae36d82fe12621dfb5b596d7db766187747749b22e33ac068e1bfc356f4a" </ins> dependencies = [ "cc", "rustc-std-workspace-core",

I do not have minimised code. This was a sudden CI build failure on nightly for aarch64-unknown-linux-musl () Note that this is a cross compile using cross-rs. It fails on rust version 1.82.0-nightly ( 2024-07-29) but works on 1.82.0-nightly ( 2024-07-28). Needless to say it also works perfectly fine on stable. The error is reproducible on rebuild and locally with cross-rs. It is not reproducible with cargo-zigbuild interestingly enough. I also checked that the version of cross-rs didn't change between the successful and failing builds (no new releases of that project since february). The only change between the successful and failing CI runs were a typo fix to an unrelated CI pipeline (the release one, so it didn't even run yet). As such I'm forced to conclude that the blame lies with Rustc. Steps to reproduce: I expected to see this happen: Compilation successful (as it is with stable for same target, or with -gnu and nightly) Instead, this happened () It most recently worked on: 1.82.0-nightly ( 2024-07-28) (or stable 1.80.0 or beta 1.81.0, take your pick for triaging) :
cc (of cross-rs fame) in case he has any insight on this regression
I have hit the same issue in a similar situation. Cross compiling to aarch64-unknown-linux-musl from x86_64 linux in a Github CI pipeline using cross-rs. Link to pipeline failing logs:
Seems rune isn't needed based on the comment by Updated the title.
This is probably
WG-prioritization assigning priority (). label -I-prioritize +P-high
Yeah that's probably it. We used to build the C version of those symbols but switched to Rust versions with the compiler builtins update. Unfortunately we can't enable them on all platforms because LLVM has crashes, and the logic that would allow optional configuration is apparently not working.


Question: [[package]] name = "compiler_builtins" <del> version = "0.1.114" </del> <ins> version = "0.1.117" </ins> source = "registry+https://github.com/rust-lang/crates.io-index" <del> checksum = "eb58b199190fcfe0846f55a3b545cd6b07a34bdd5930a476ff856f3ebcc5558a" </del> <ins> checksum = "a91dae36d82fe12621dfb5b596d7db766187747749b22e33ac068e1bfc356f4a" </ins> dependencies = [ "cc", "rustc-std-workspace-core",

After that part is fixed, we will need to enable the symbols on all platforms where is f128 (which includes aarch64), since these errors probably come from here I think anyone who needs a quick workaround can add to their dependencies to get the symbols directly, as described near the top of Note that this requires nightly.
Is it possible to add a dependency conditionally based on if it is nightly? (In a specific range of dates even?) I cannot and will not depend on nightly, but I do test my code on nightly in CI (in order to find breakages like this early). For now I just disabled that nightly build on aarch64 musl.
Same for me. Not using cross-rs though. Logs are here:
Same for me, both using as host toolchain and cross compiling.
Looks like it is happening now too for x86_64.
Not for my projects, so you should probably provide a reproducer on x86-64 GNU if possible, since that is a tier 1 platform (unlike Aarch64 on Musl). Or is this about some other x8664 variation that is also tier 2?
Woops, sorry, the x86_64 build failed too, but then i looked at the aarch64 build logs :) which still fail.


Question: } match self.parse_expr_res(Restrictions::CONST_EXPR, None) { Ok(expr) => { <del> if token::Comma == self.token.kind || self.token.kind.should_end_const_arg() { </del> <ins> // Find a mistake like `MyTrait<Assoc == S::Assoc>`. if token::EqEq == snapshot.token.kind { err.span_suggestion( snapshot.token.span, "if you meant to use an associated type binding, replace `==` with `=`", "=".to_string(), Applicability::MaybeIncorrect, ); let value = self.mk_expr_err(start.to(expr.span)); err.emit(); return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })); } else if token::Comma == self.token.kind || self.token.kind.should_end_const_arg() { </ins> // Avoid the following output by checking that we consumed a full const arg: // help: expressions must be enclosed in braces to be used as const generic //       arguments

<!-- 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: Playground: I expected to see this happen: The error message should indicate that the should be a single . Instead, this happened: The error message gives no hint of the correct syntax. It gives two errors, neither of which are helpful: This error is unhelpful because it says "expected one of or ", but is also allowed. Also, the suggestion to use curly braces is a red herring. This error is unhelpful because I am not specifying const arguments; I'm specifying associated types. Rust version according to 1.53.0
cc


Question: LL |     f: i32, |     ^^^^^^ <del> error: aborting due to 3 previous errors </del> <ins> error: field is never read: `y` --> $DIR/write-only-field.rs:28:9 | LL |         y: bool, |         ^^^^^^^ error: field is never read: `u` --> $DIR/write-only-field.rs:58:9 | LL |         u: u32, |         ^^^^^^ error: field is never read: `v` --> $DIR/write-only-field.rs:59:9 | LL |         v: u32, |         ^^^^^^ error: aborting due to 6 previous errors </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. --Here's a reduced test-case from Firefox source code: Compiling that program warns with: Which is obviously not true. <!-- 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. --:
Seems like this is a regression from .
cc
Oops, sorry! Technically, field is, in fact, never read. What went wrong is is written and read through other ways. I think restricting the lint to non-reference fields should work, and will submit a PR to do so quickly. Please double check whether my thinking is correct.
Ah, yeah, I somehow thought that the macro was needed to trigger the bug but it is not. That sounds good. Writes to mutable references have side effects so doing that seems ok.
Would that also cover this case here, in the idna crate? (The field is a reference to an type, which is in fact returned to the caller of .)
Yeah, I think it's the same.
Ah, this was closed, but the bug leaked into beta (as mentioned in ) while the fix is only in nightly. Reopening and tagging as stable-to-beta regression
Assigning and removing .
As noted on , we're going to resolve the beta issue by reverting PR on beta (which I have assigned myself to take care of).
This was a regression affecting beta 1.51, closing this.