Question: base.cpu = "yonah".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); <del> base.link_env.extend(super::apple_base::macos_link_env("i686")); </del> base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved base.stack_probes = StackProbeType::Call;

For coreaudio, if it really requires APIs from 11.0+, that seems a bit recent/limiting for a library that's existed since forever on macOS. If the authors were unaware of this, has revealed that they need to do more work to attain backwards compatibility. There will be more breakage like it, but it is the good kind, because anyone using newer Apple APIs should be aware of their minimum platform requirement, just as Xcode forces you to be.
Hmm, this change had more impact than I thought. to determine which minimum Macos version to pass as part of the target triple to LLVM and to ld via by looking at the various command line options and environment variables that have accumulated over the years. If nothing is specified, it apparently defaults to the minimum of the specified in the SDKROOTs and the host Macos version . I think ideally we should probably try to mimic this behavior somewhat so we don't confront users with having to set , while they don't have to do it using clang. Not sure how we can easily accomplish this though.
Actually, that makes a lot of sense, thanks! I fully agree that it's better to catch these issues when developing (instead of later, when users complain that the application doesn't work on their older system)! I've opened to fix the linking in , and would fix the linking in .
Note that this is a breaking change for macOS users, before, they didn't have to specify , now they do. Furthermore, they have no easy way to find out that they need to (they just get a confusing linker error)! Additionally, the affected crates (that we know about) are quite widely used (at least half of all Rust games depend on and/or ), and have not yet fixed the issue, nor yet released updated versions which includes these fixes. And even when this has been done, it will take time before users have run and received working versions (can probably be helped along by yanking the affected versions). I don't really know the procedure for this, but I would like to propose reverting (at least from the current beta) to give the affected crates more time to update. Again, I really do agree with the change, I just also want to minimize the breakage macOS users will experience from upgrading Rust.


Question: base.cpu = "yonah".to_string(); base.max_atomic_width = Some(64); base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); <del> base.link_env.extend(super::apple_base::macos_link_env("i686")); </del> base.link_env_remove.extend(super::apple_base::macos_link_env_remove()); // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved base.stack_probes = StackProbeType::Call;

Like I wrote I think ideally we should match clang's behavior and thus fall back to the default of the currently configured Macos SDK. That would mean looking at the property of the in the currently configured SDK. Unfortunately I don't really see a reliable way to do get the path to that without running .
I think we should revert the change until you find a way to do this - it seems to be causing a lot of breakage and my understanding is the goal was just to turn a runtime error into a link time error.
Oh sure. I am not against a revert until that is sorted out. I will open a PR. claim
reopening as this is a beta-regression, and we keep those open until beta fix lands (or we explicitly decline to fix).
Backport merged.
Just for reference, the linking in the noted crates have since been fixed: , ,
I root-caused this a little bit more today, sharing my findings: The problem can be reproduced with and the following file: Weirdly enough, if you remove the linking to , everything links fine. I think this is actually a bug in , it seems like: The linker is reading the symbol tables from and to try to figure out where comes from. When reading , it sees that it has a few "", which includes , which is where the symbol actually comes from (well, nowadays from , but that is re-exported from ). But when reading , it finds the symbol , which is intended to indicate that "when linking on older platforms, use instead" But instead, it ends up making it seem like is actually the real , and does not expose , so the linking fails. Again, I believe this to be a linker bug because the problem does not happen with (try passing ).


Question: .push((myname, Some(plain_summary_line(item.doc_value())))); } <del> for (_, items) in &mut map { items.sort(); </del> <ins> if self.shared.sort_modules_alphabetically { for (_, items) in &mut map { items.sort(); } </ins> } map }

Instead it should use the order that appear in the crate file. Even better, it should allow adding section headers (with a description) between them. Hypothetically: And get something like this: This would make both the source code and the documentation more accessible as the modules would be presented in a comprehensible order, with some description of each related group of modules. Edit: Rename issue to reflect that this isn't an either-or. Alphabetical order is useful, but so is programmer-specified order (to make the code accessible for newcomers) and Rustdoc should support both - see the thread below.
Shouldn't related modules be nested in submodules rather than logically ordered in the source? Finding things in long non-ordered lists is a real pain.
Yeah, I'm going to vote "alphabetical".
Hmmm. I pretty sure I put a comment here, and now its gone. Strange. Anyway. Here it goes again. Alphabetical order == random order. That's great when you know what you are looking for and just want to find it. When coming to a new non-trivial code base, being presented the content in random order is just about the worst possible way to access it. Nested modules allow us to group related modules together, and that's a good thing. If you have a long list of modules, certainly, group them. But this doesn't solve the problem. You now have a TOC where each level is randomized, which is still inaccessible. Searching for a function or module by name is an important use case, sure. But being able to access a new code base is as important, if not more so. Looking up a name in a short non-alphabetized list (at each level) isn't too hard, and one can always compensate for the lack of an alphabetical index by using ^F. Trying to understand a system presented in random order is next to impossible, and one can not compensate for the lack of a comprehensible order in a large system. If there was a way to specify the order of the entries in each level, which we agree should only contain "a few" entries, then the TOC would become accessible. If one could even add a bit of annotation for each level, so much the better.


Question: .push((myname, Some(plain_summary_line(item.doc_value())))); } <del> for (_, items) in &mut map { items.sort(); </del> <ins> if self.shared.sort_modules_alphabetically { for (_, items) in &mut map { items.sort(); } </ins> } map }

The annotated TOC would serve as a very accessible way for a newcomer to understand the code base. And, this doesn't rule out also generating an alphabetically sorted reference index, beside the TOC. All good books do both - a TOC in reasonable order and an index for looking up data by name. We shouldn't have to choose, we should be able to get both. So, I misnamed the issue. It should be "Rustdoc shouldn't list modules only alphabetically".
Agreed. Can someone rename the title?
Rename done.
Visiting for triage. Minor, but still an issue.
Triage, still listed alphabetically. Here's a sample source file: !


Question: [tlgba]: http://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/ [ro]: http://www.rustaceans.org/ [rctd]: ./src/test/COMPILER_TESTS.md <del> [cheatsheet]: https://buildbot.rust-lang.org/homu/ </del> <ins> [cheatsheet]: https://buildbot2.rust-lang.org/homu/ </ins>

This page isn’t working is currently unable to handle this request. HTTP ERROR 503
The bot got moved at some point; try Are there some docs that need to be updated?
Or how about made 302 redirect to the new target url?
Are there some docs that need to be updated? There are few references to the old address in the rust repo, including (all can be found by searching "buildbot").
Fixed the broken link in so I'm going to remove the issue tag here. It would be nice if there was a or something that was a GitHub Pages site that had an for and whatever else relevant resources for maintaining the queue. It'd be easy to change if the homu link changes again in the future.
I on IRC how to do this awhile ago, and I believe they're still basically applicable today. If anyone would like to help implement this and still has questions please just let me know!


Question: <del> Subproject commit 2adc39f27b7fd2d06b3d1d470827928766731a1d </del> <ins> Subproject commit fccb2398248802a268fcda544ff3945247ef2119 </ins>

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


Question: #[link_name = "llvm.sqrt.f32"] fn sqrt(x: f32) -> f32; //~^ ERROR linking to LLVM intrinsics is experimental <del> //~| HELP add #![feature(link_llvm_intrinsics)] to the crate attributes </del> } fn main(){

Steps to reproduce: The output of is: does as suggested by the message, but that fails too (as expected): Proposed fix: in the beta and stable channels (i.e. whenever is forbidden), the message that suggests adding should not be shown. (Clean up the test case with .) CC
Gonna milestone this real quick, as it seems quite important.
I might be able to whip up a quick fix, though I'm not 100% sure about testing it properly ... (I've never actually tried building something for a non-dev release channel before...)
after chatting with it seems like I have a patch, building it now
gonna leave to it
Hello good Rust folks :smile: Before the beta, I used which is in . Is there any way to use this trait during the beta ? I'm not sure how I can get the code to compile. Thanks for any tip / hints you can offer :+1:
Hi Commenting on random unrelated issues is usually not the right thing to do. You should rather open a new issue, or ask on . But to answer your question anyway, that trait only has : … and is stable and can be used on beta. So I’d recommend you copy/paste the trait into your code, or make a function.
Thanks for taking the time to answer. I appreciate it. I don't see how this is unrelated. This is related, since the code I'm talking about used to compile with and the compiler suggests to do that, during the beta period. Thanks for your tip on copying the function :+1: I guess I'll just do that if nothing better is available and change this again when the trait is stable.
This specific issue is about fixing one of the compiler’s error message, not about fixing code that triggers that error. It really helps everyone to keep discussions on topic.
Alright. I understand. I'll make sure to open a new issue or go on StackOverflow next time if appropriate. Thanks again :+1:
This doesn't seem to be properly fixed in the beta channel. I'm still being recommended to add in the errors, and then told it's not available in the beta channel. Rust version: The code I used (snappy example in the docs with the extra addition on the first line:
This happened after Beta release.


Question: #[link_name = "llvm.sqrt.f32"] fn sqrt(x: f32) -> f32; //~^ ERROR linking to LLVM intrinsics is experimental <del> //~| HELP add #![feature(link_llvm_intrinsics)] to the crate attributes </del> } fn main(){

We'll see the effect of this patch in 1.0 and afterwards Beta, etc.
Whoops, I thought this made it in before beta. Thanks!
are there plans to release updates to the beta channel within a given 6 weeks cycle? Either this one or in the future.
I'm certain there will be updates; see discussion from last night here:
So how does one fix this error? I'm a new user of the rust library and I can't seem to use the collections library during the beta due to this problem. Given this git issue is a top google result, it would be nice if there were a solution here. Edit: Looks like the solution is to switch to the rust nightly. Is the entire collections library off-limits in the beta?
by design, you have access to the parts of that are re-exported from (and are stable).


Question: <ins> // Rustdoc shouldn't display `mut` in function arguments, which are // implementation details. Regression test for #81289. #![crate_name = "foo"] pub struct Foo; // @count foo/struct.Foo.html '//*[@class="impl-items"]//*[@class="method"]' 2 // @!has - '//*[@class="impl-items"]//*[@class="method"]' 'mut' impl Foo { pub fn foo(mut self) {} pub fn bar(mut bar: ()) {} } // @count foo/fn.baz.html '//*[@class="rust fn"]' 1 // @!has - '//*[@class="rust fn"]' 'mut' pub fn baz(mut foo: Foo) {} </ins>

Rustdoc on [nightly documents][1] methods have signature of as while it only has to document it as . ! On [rustdoc stable][2], things are normal: ! : Version 1.49.0 ( 2020-12-29) [1]: [2]:
I'd like to investigate this :)
searched nightlies: from nightly-2020-12-29 to nightly-2021-01-22 regressed nightly: nightly-2021-01-09 searched commits: from to regressed commit: This regressed in , so this is probably caused by
This also affects Where will generate:
So a few observations: which displays mutability in patterns, causing to be displayed the mechanism for detecting and eliding works by , but as returns instead of , the comparison fails and displays the type.
I see two path to solving this bug: an option for to not display the mutability in patterns revert cc what do you think?
I would prefer to go for 1, there's no reason to have two completely different functions for pretty-printing.
Assigning and removing as in the prioritization working group.
(now a beta regression)


Question: // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. <del> match self.opts.optimize { config::OptLevel::No => 16, _ => 1, // FIXME(#46346) this should be 16 } </del> <ins> 16 </ins> } /// Returns whether ThinLTO is enabled for this compilation

I'm opening this up to serve as a tracking issue for enabling multiple codegen units in release mode by default. I've written up a before but the tl;dr; is that multiple codegen units enables us to run optimization/code generation in parallel, making use of all available computing resources often speeding up compilations by more than 2x. Historically this has not been done due to claims of a loss in performance, but the is intended to assuage such concerns. The most viable route forward seems to be to enable multiple CGUs and ThinLTO at the same time in release mode. Blocking issues: [x] Enable for libstd on all platforms - - - - Potential blockers/bugs: - -
cc
Presumably this will remain a stable compiler flag, but what else will change by default? Is the plan to make this only affect , or is the plan to also make this affect ? Do we want to make continue to use only a single CGU, to hedge against regressions for people who are already willing to trade off compiler time for runtime?
I would specifically propose that any opt level greater than 1 uses 16 codegen units and ThinLTO enabled by default for those 16 codegen units.
This is very interesting. One would think that ThinLTO-driven inlining should always have to do less work when our much more conservative pre-LLVM inlining. But that doesn't always seem to be the case, as in the . Most tests on the seem to profit though. Overall it's still not a clear picture to me.
was that comment meant for a different thread? I forget which one as well though, so I'll respond here! As a "quick benchmark" I compiled the regex test suite with 16 CGUs + ThinLTO and then toggled inlining in all CGUs on/off. Surprisingly inlining in all CGUs was 5s faster to compile, and additionally . In those timings is where inlining is only in one CGU, where is inlining in all CGUs. One benchmark, , got twice as slow!
Yeah, the comment was in response to (rust-doom) but since that was closed already, I put it here.


Question: // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. <del> match self.opts.optimize { config::OptLevel::No => 16, _ => 1, // FIXME(#46346) this should be 16 } </del> <ins> 16 </ins> } /// Returns whether ThinLTO is enabled for this compilation

Regarding the compilation time difference between pre- and post-trans inlining, my hypothesis would be that sometimes pre-trans inlining will lead to more code being eliminated early on (as in the case of regex apparently) and sometimes it will have the opposite effect. I suspect that there's room for improvement by tuning which LLVM passes we run specifically for ThinLTO. Or do we do that already?
Heh it's true yeah, I'd imagine that there's always room for improvement in pass tuning in Rust :). Right now we perform (afaik) 0 customization of any pass manager in LLVM. All of the normal optimization passes, LTO optimization passes, and ThinLTO optimization passes are all the same as what's in LLVM itself.
I wanted to also take the time and tabulate all the results from the to make sure it's all visibile in one place. Note that all the timings below are comparing a release build to a release build with 16 CGUs and ThinLTO enabled Improvements All of the following compile times improved, sorted by most improved to least improved Regressions The following crates regressed in compile times, sorted from smallest regression to largest alexcrichton's attempt to reproduce the regressions Here I attempt to reproduce the regressions on my own machine with Unfortunately the only regression I was able to reproduce was the rust-belt regression. I'll be looking more into that.
Looking into , one interesting thing I've found is that the crate takes longer to compile with ThinLTO than it would otherwise. Looking at it appears that one codegen unit in this crate takes 99% of the time in LLVM. This codegen unit appears to be basically entirely dominated by . Almost all of the benefit of multiple codegen units is spreading out the work across all CPUs. Enabling ThinLTO to avoid losing any perf is fundamentally doing more work than what's already happening at , but we get speedups across the board in most cases. If we have one huge CGU, split it in two, and work on those in parallel then we've got 50% of the original time to run ThinLTO (in a perfect world). If ThinLTO takes more than 50% of the time then we'd have a build time regression, but that's almost never happening.


Question: // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. <del> match self.opts.optimize { config::OptLevel::No => 16, _ => 1, // FIXME(#46346) this should be 16 } </del> <ins> 16 </ins> } /// Returns whether ThinLTO is enabled for this compilation

What's happening here is that we have one huge CGU, but when we split it up we still have one huge CGU. This means that the CGU which may take ~1% less time in LLVM only gives us a tiny sliver of a window to run ThinLTO passes. In the case of the crate this means that adding ThinLTO passes is an overall build time regression. So generalizing even further, I think that enabling ThinLTO and multiple CGUs by default is going to regress compile time performance in any crate where our paritioning implementation doesn't actually partition very well. In the case of we've got one huge function which hogs almost all the optimization time (I think) and the entire crate is basically dominated by that one function. I would be willing to conclude, however, that such a situation is likely quite rare. Almost all other crates in the ecosystem will benefit from the partitioning which should basically evenly split up a crate. maybe you have thoughts on this though?
Thank you so much for collecting and analyzing such a large amount of data, Your conclusions make sense to me. Unevenly distributed CGU sizes are also a problem for incremental compilation; e.g. the test sees 90% CGU re-use, yet compile time is almost the same as from-scratch. In the non-incremental case it might be an option to detect the problematic case right after partitioning and then switch to non-LTO mode? I'm not sure it's worth the extra complexity though. For cases where there is one big CGU but that CGU contains multiple functions, we should be able to rather easily redistribute functions to other CGUs. We'd only need a metric for the size of a . The number of MIR instructions might be a sufficient heuristic here. That would not help for but it might help for other crates. In conclusion, judging from the table above, I think we should make the default sooner rather than later. Open questions I see: What to do about ? I would have thought that it would always be a clear win to disable this when ThinLTO is enabled but that doesn't seem to be the case. Are there hardware configurations where this never is a win? E.g. should we default to traditional compilation if ?


Question: // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. <del> match self.opts.optimize { config::OptLevel::No => 16, _ => 1, // FIXME(#46346) this should be 16 } </del> <ins> 16 </ins> } /// Returns whether ThinLTO is enabled for this compilation

FWIW, as the author of , which is a made-for-fun Piston game, I am more than happy to take a small compile regression when it seems like vast majority of crates get huge real-time improvements!
This seems like a good thing to have in our back pocket, but I'm also wary of trying to do this by default. For example the case is one where we may wish to disable ThinLTO but the one massive function could also critically rely on a function in a different CGU being inlined? That sort of case would be difficult for us to determine... In any case though I agree that we probably don't need the complexity just yet so I think we can defer this for later. Agreed! So far all the crate's I've seen the O(instructions) has been quite a good metric for "how long this takes in all LLVM-related passes", so counting MIR sounds reasonable to me as well. Again though I also feel like this is ok to have in our back pocket. I'd want dig more into the minor change example, I'm curious how awry the CGU distribution is there and whether a heuristic like this would help. Quite surprisingly I've yet to see any data that it's beneficial to compile time in release mode or doesn't hurt runtime. (all data is that it hurts both compile time and runtime performance!) That being said we're seeing such big wins from ThinLTO on big projects today that we can probably just save this as a possible optimization for the future. On the topic of inline functions I recently dug up again (later closed in favor of , but the latter may no longer be true today). I suspect that may "fix" quite a bit of the compile time issue here without coming at a loss of performance? In any case possibly lots of interesting things we could do there. Also a good question! I find this to be a difficult one, however, because the CGU number will affect the output artifact, which means that if we do this sort of probing it'll be beneficial for performance but come at the cost of more difficult deterministic builds. You'd have to specify the CGUs manually or build on the same-ish hardware to get a deterministic build I think? I think though that if you have 1 CPU then this is universaly a huge regression.


Question: // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. <del> match self.opts.optimize { config::OptLevel::No => 16, _ => 1, // FIXME(#46346) this should be 16 } </del> <ins> 16 </ins> } /// Returns whether ThinLTO is enabled for this compilation

With one CPU we'd split the preexisting one huge CGU into N different ones, probably take roughly the same amount of time to opimize those, and then tack on ThinLTO and more optimization passes. My guess is that with one CPU we'd easily see 50% regressions. With 2+ CPUs however I'd probably expect to see benefits to compile time. Anything giving us twice the resources to churn the cgus more quickly should quickly start seeing wins in theory I think. For now though the deterministic builds wins me over in terms of leaving this as-is for all hardware configurations. That and I doubt anyone's compiling Rust on single-core machines nowadays!
One thing I think that's also worth pointing out is that up to this point we've mostly been measuring the runtime of an entire . That's actually, I believe, the absolute worst case scenario for where ThinLTO will provide benefit. Despite this, it's showing huge improvements for lots of projects! The benefit of ThinLTO and multiple CGUs is leveraging otherwise idle parallelism on the build machine. It's overall increasing the amount of work the compiler does. For a from scratch, though, you typically already have tons of crates compiling for the first half of the build in parallel. In that sense there's not actually any idle parallelism. Put another way, ThinLTO and multiple CGUs should only be beneficial for builds which dont have many crates compiling in parallel for long parts of the build. If a build is 100% parallel for the entire time then ThinLTO will likely regress compile time performance. Now you might realize, however, that one very common case where you're only building one crate is in an incremental build! Typically if you do an incremental build you're only building a handful of crates, often serially. In that sense I think that there's some massive wins of ThinLTO + multiple CGUs in incremental builds rather than entire crate builds. Although improving both is of course great as well :)
For deterministic builds you have to do some extra configuration anyway (e.g. path remapping) so I would not consider that a blocker. And I guess there are single core VMs around somewhere.


Question: // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. <del> match self.opts.optimize { config::OptLevel::No => 16, _ => 1, // FIXME(#46346) this should be 16 } </del> <ins> 16 </ins> } /// Returns whether ThinLTO is enabled for this compilation

But all of this is such a niche case that I don't really care MIR-only RLIBs should put us into a pretty good spot regarding this, so I'm quite confident that we're on the right path overall.
That's really interesting. For incremental compilation enabled the situation might be different (because pre-trans inlining hurts re-use) but for the non-incremental case it sounds like it's pretty clear what to do.
Yeah, maybe we should revisit this at some point. Although I have to say the current solution of only and symbols and nothing in between is really nice and simple.
Hm yeah that's a good point about needing configuration anyway for deterministic builds. It now seems like a more plausible route to take! Also that's a very interesting apoint about incremental and inlining on our own end... Maybe we should dig more into those ThinLTO runtime regressions at some point! Also yeah I don't really want to change how we trans inline functions just yet, I do like the simplicity too :)
out of curiosity how did you figure out this and which function it was. I've wanted to look into why the webrender build is so slow and would welcome tips.
oh sure I'd love to explain! So I originally found as a problematic crate when compiling rust-belt as it just took awhile and I decided to dig deeper. I checked out the crate and ran: That drops in the current directory, and opening that up I see: ! The graph here isn't always the easiest to read, but we've clearly got two huge bars, both of which correspond to taking a huge amount of time for that one CGU (first is optimization, second is ThinLTO + codegen). Next I ran: and that command dumps a bunch of IR files into . Our interesting CGU is so I opened up (we sure do love our long filenames). Inside that file it was 70k lines and some poking around showed that one function was 66k lines of IR. I sort of forget now how at this point I went from that IR to determining there was a huge function in there though...
I don't know if this is the right place, but I think it should be considered whether the symbol issues reported in the Nightly section here: should be considered a blocker or not.


Question: // As a result 16 was chosen here! Mostly because it was a power of 2 // and most benchmarks agreed it was roughly a local optimum. Not very // scientific. <del> match self.opts.optimize { config::OptLevel::No => 16, _ => 1, // FIXME(#46346) this should be 16 } </del> <ins> 16 </ins> } /// Returns whether ThinLTO is enabled for this compilation

The tl;dr is that certain versions of llvm, (i've seen this on 3.8, and whatever llvm rustc nightly uses) appends seemingly random garbage to the end of some names, e.g. we get: instead of: This knocks the debuginfo out of sync (it doesn't have the garbage appended). I've been able to repro this with clang3.8 for c++ files as well (haven't tested on other llvm), and switching to 5.0 seems to have fixed the issue. I don't know if its within reach, but perhaps we should attempt upgrading to llvm 5.0 before releasing this on stable? Note I understand this is for release mode, but i see this in debug mode on rustc nightly right now as well...


Question: <ins> #![feature(extern_types)] pub mod aaaaaaa { extern { pub type MyForeignType; } impl MyForeignType { pub fn my_method() {} } } </ins>

There are bad (404) links in search results with nightly rustdoc. E.g. go to and then click the result. This leads to which does not exist. Cc
Actually, this issue seems to exist even on stable -- somehow it went unnoticed for quite a while, it seems.
I think it's because we are badly handling a reexport/type alias.
I think this is a duplicate of


Question: <ins> error: mismatched closing delimiter: `}` --> $DIR/mismatched-delimiter-corner-case-issue-127868.rs:4:42 | LL | fn main() { |           - closing delimiter possibly meant for this LL |     let a = [[[[[[[[[[[[[[[[[[[[1, {, (, [,; |                                          ^ unclosed delimiter LL | } | ^ mismatched closing delimiter error: this file contains an unclosed delimiter --> $DIR/mismatched-delimiter-corner-case-issue-127868.rs:6:52 | LL | fn main() { |           - unclosed delimiter LL |     let a = [[[[[[[[[[[[[[[[[[[[1, {, (, [,; |             -----                  - this delimiter might not be properly closed... |             ||||| |             ||||another 16 unclosed delimiters begin from here |             |||unclosed delimiter |             ||unclosed delimiter |             |unclosed delimiter |             unclosed delimiter LL | } | - ...as it matches this but it has different indentation LL | |                                                   ^ error: aborting due to 2 previous errors </ins>

In my Fedora installation ended up being a corrupted file. It took me hours to realize, given that the output does not bring any clarity to it. rustc should really have ratelimit detection or something to detect corrupted file instead and inform about this to the user. !
This indeed seems quite confusing; and counter-productive to try to show this blob of errors. Would you be able to provide us with a reproducible example of the issue? Or if you still have it the corrupted file. labels +T-compiler +A-diagnostics +D-verbose +D-confusing +S-needs-repro -needs-triage
So this a problem because I unfortunately deleted the trashed file before someone told me that I should report this as a bug. I regret that I did not store it :-/ BUT I recalled that it was probably for reason a long string of ANSI escape codes. So I did a test string: This creates somewhat similar output as I got, except probably the string was a bit longer in my case.
OK doubling that starts to be almost perfect match:
! ... I'm considering T-shirt design ;-) Made by me and rustc. EDIT: and rendered by excellent terminal emulator foot
Somehow rustc should be able to detect corrupted file in cargo's source repository (or whatever it is called). It was pretty bizarre sight when I encountered this by accident.
Thanks for the repro. label -S-needs-repro
Yeah I mean it is really a huge corner case but it can happen in the case of data corruption (e.g. power outage in middle of write operation). I'd detect frequency of errors and maybe a threshold parameter when it is interpreted as corruption with a sane default value.
yeah, I believe this error comes out from the phase of lexing, which rustc are trying to find all the mismatched delimiters, maybe a threshold is ok for resolve it.


Question: <ins> error[E0573]: expected type, found variant `Ok` --> $DIR/issue-106062.rs:15:64 | LL |     async fn connection_handler(handler: impl Sized) -> Result<Ok, std::io::Error> { |                                                                ^^ not a type | help: try using the variant's enum | LL |     async fn connection_handler(handler: impl Sized) -> Result<core::result::Result, std::io::Error> { |                                                                ~~~~~~~~~~~~~~~~~~~~ LL |     async fn connection_handler(handler: impl Sized) -> Result<std::result::Result, std::io::Error> { |                                                                ~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error For more information about this error, try `rustc --explain E0573`. </ins>

The full repo is here: : </p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
For what it's worth, I can reproduce this issue with version 1.63.0, but it doesn't happen with 1.64.0 nor with the latest stable version 1.66.0.
The ICE disappeared in nightly-2022-07-01, which contains the following merges: [x] : ICEs [x] : ICEs [x] : ICEs [x] : ICEs [ ] [x] : ICEs
Here is it minified, and standalone-ed:
Triage: This has been fixed on the latest nightly, as reported, and needs a test to close.
claim


Question: #![feature(const_caller_location)] #![feature(const_cell_into_inner)] #![feature(const_discriminant)] <ins> #![cfg_attr(not(bootstrap), feature(const_eval_select))] </ins> #![feature(const_float_bits_conv)] #![feature(const_float_classify)] #![feature(const_fmt_arguments_new)]

Currently,  is not , since it uses with a non- check: can't be made , since it involves ptr-int cast to check the alignment: Recently intrinsic , it allows to run different code in CTFE and runtime. This, in turn, allows us to only make the alignment check in runtime and ignore it in the CTFE where it doesn't make much sense. See also: cc and (it seems like use of requires approval of all of the above teams) label +T-lang +T-libs +A-const-eval +A-const-fn
Another approach to make const would be to disable the checks altogether, but since we already have , that seems unreasonable.
cc opinions before we escalate to lang and libs?
If a new intrinsic was in the spirit of and , this could possibly provide a solution without . Something like:
It seems useless to be able to perform any align checks in constants. The CTFE catches invalid pointer dereferences anyways.
Yes, but we also want to catch invalid pointer dereferences when we are not in CTFE, hence the idea of the function/intrinsic.
So why not use ?
It doesn't catch insufficiently aligned pointers though.


Question: <del> // no-prefer-dynamic </del> // ignore-emscripten thread_local!(static FOO: Foo = Foo);

Right now on our bots we're basically in a state where if valgrind rpass tests are compiled dynamically they will all fail, but when compiled statically they will pass. I'm not really sure what's going on unfortunately, but this is either a bug in valgrind or a bug with us, and we should know precisely what it is to ensure something more sinister isn't lurking. Some links: - first pass at linking tests statically, fixed - another pass at linking all tests statically
All the failures seem to be within platform’s dynamic loader. Here’s a few things to try: updating kernel+glibc to the most recent versions (4.4-ish and 2.23-ish, respectively) help? downgrading kernel+glibc to some older version help? non-linux/non-glibc work correctly?
Any news/changes on this one ?


Question: /// that were given to the `panic!()` macro. /// /// See [`PanicInfo::message`]. <del> #[unstable(feature = "panic_info_message", issue = "66745")] </del> <ins> #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] </ins> pub struct PanicMessage<'a> { message: fmt::Arguments<'a>, }

was closed when stabilized the corresponding language feature, but we didn’t realize that it was also the tracking issue for this standard library feature: History: [x] Original tracking issue: [x] Discussion of payload vs message [x] Making .message() infallible: [x] Split core/std PanicInfo into two types: This made core::panic::PanicInfo::message() infallible. [x] Use opaque return type: [x] FCP [x] Stablization PR: Unresolved questions: [x] Should it be infallible? Yes, by making std::panic::PanicHookInfo a different type. [x] What should the return type be? or an opaque ? The first is simpler, but the latter allows a bit more flexibility for future changes.
Instead of making a PR go through the queue to fix the tracking issue, should we stabilize this method? fcp merge The doc-comment is slightly wrong or out of date. Its second line shoudl be removed. always creates a where is , regardless of the number of arguments given. In the single-argument case, that argument is required to have type . At first returning seemed unusual to me and I considered that we could make the method return instead, on the basis that calling its impl is almost the only useful thing to do with a . But has been stable and documented as the return type of since 1.0.0, so maybe it’s fine.
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [ ] [ ] [x] [x] [ ] [ ] [ ] Concerns: single-arg core::panic () Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
The module also links to that closed tracking issue. Let’s consider the pFCP above to also include stabilizing it. ( is stable.)
concern single-arg core::panic Should we change libcore’s macro so that its single-argument form creates a with a instead of one with a ?


Question: /// that were given to the `panic!()` macro. /// /// See [`PanicInfo::message`]. <del> #[unstable(feature = "panic_info_message", issue = "66745")] </del> <ins> #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] </ins> pub struct PanicMessage<'a> { message: fmt::Arguments<'a>, }

CC Pushing this idea further, it’s tempting to maybe remove entirely and instead have a whose dynamic type can be . But that doesn’t work because is a method of and is not .
I thought the point of the message field was that core can't make a payload since it can't allocate?
The struct is: Both the and fields involve borrowing. As far as is concerned, they could both be borrowing form a stack frame. (And as far as I understand they are, in practice today.) It’s in the case of unwinding that there’s an owned that can return, which requires allocating.
Based on the timing of it looks like you may have thoughts on this :)
Ah, goes into how and why the panic handler in libstd (which is called by if libstd is linked) ignores the it receives. We could probably change this but it gets tricky: while most implementations of for environments would be fine with receiving a borrowed payload, libstd wants to potentially take ownership and box it for unwinding.
I have zero recollection for why this is the way it is, and I'm not really particularly interested in doing all the archaeology to dig up why it is the way it is. I'm not a huge fan of just stabilizing things because they happen to be there, but I don't really see why we wouldn't want to stabilize this. If there were a reason to not stabilize this though an investigation would presumably turn that up, but I'm not up to do that investigation myself.
That’s totally fair. I’m confident that this was more likely forgotten than deliberately left unstable. If deliberate we would have kept the tracking issue open or made a new one for the remaining bits. This is what lead me to propose stabilization. Having dug a little more, and thanks to Ralf’s blog post, I think we may want at some point to revisit what data we expect to contain or not in various situation. In particular it could be interesting to extend to support payloads other than and make it closer to . Given those possibly-desirable changes, it may not be the time to add more constraints: fcp cancel
proposal cancelled.
Lol, I had no idea. ;) So, indeed, I was wondering if we could do something about the duality of the and fields in . I assume we cannot change the fact that the same type is used both of panic handlers and panic hooks.


Question: /// that were given to the `panic!()` macro. /// /// See [`PanicInfo::message`]. <del> #[unstable(feature = "panic_info_message", issue = "66745")] </del> <ins> #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] </ins> pub struct PanicMessage<'a> { message: fmt::Arguments<'a>, }

Concretely, I was thinking of adjusting somewhat like this: That would at least remove the need for the hack in . (The hack would likely move to instead, but that is a smaller hack IMO: the hack is now not encoded in the state of any more, just in its dynamic API.) I think this would retain all current functionality while clarifying the invariant of wrt. the payload (and explicitly calling the message a "payload"; right now it seems to be something that sits next to the payload which is inaccruate). But there are enough subtleties here that we'll only really know once someone implements this. With this change, the panic hook would always get a . We should likely provide a method somewhere in libstd to factor out this code: I was imagining something like an extension trait on with a type like . However, the panic hook is not the only place where that conversion is useful; another situation is code that caught a panic and wants to extract the message. I expect most instances of that to just handle payloads, not knowing that payloads are also common (that is certainly what happened when I wrote such code). So ideally we'd have a method that takes and returns , but I do not have a good idea where to put that. This is the hard part, as we cannot use . I wonder if we can use a take-based approach, similar to ? Conceptually, would put the panic into an , and somehow pass an to the panic handler, and the implementation of said handler could then the payload if it needs full ownership (like for unwinding). Except the panic handler cannot be generic, so it would have to be , which is not a thing. But with enough unsafe code we could re-implement something that behaves like that. I don't see any way to do this entirely safely; the panic handler that wants to take out the payload and put it somewhere needs to dynamically determine the size of the payload and arrange for there to be enough space. In liballoc, we could provide a safe wrapper for this that puts things into a , but in libcore, I don't think there is a safe API that we could provide to grab ownership.


Question: /// that were given to the `panic!()` macro. /// /// See [`PanicInfo::message`]. <del> #[unstable(feature = "panic_info_message", issue = "66745")] </del> <ins> #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] </ins> pub struct PanicMessage<'a> { message: fmt::Arguments<'a>, }

But maybe it is enough for the public API to expose ways to borrow the payload (should work for all non-unwinding handlers); if only libstd needs to take the payload (for unwinding) we could keep the unsafe part of the API internal. Also, we certainly do not want a panic hook to the payload out of its . At this point it seems to be quite a problem that panic hook and panic handler both use the same type. In fact, a panic handler likely wants a to be able to things without interior mutability. Is there any way we could make the attribute support both signatures, and then (based on the types of the methods) only -based implementations will actually be able to or the payload?
I agree, but it’s can easily be an inherent method of nor of because those are in libcore which doesn’t have access to . It feels slightly unfortunate that we’d need an extension trait just for this. I considered this yesterday and come to pretty much the same conclusions. To take ownership of a payload of unknown size through a non-generic API we pretty much heap allocation, which for libcore means something like receiving an , unsafely using , and returning that is to be passed to . It’s not pretty, but if only libcore and libstd deal with this internally maybe that’s ok? Is there a use case for a other than libstd’s to take ownership of the payload?
I was thinking of a slightly different API actually: Here, does to put the payload into caller-allocated storage; that storage must have (at least) size and align as given by . What I did not consider is how to get out the vtable, so maybe that higher-order approach is better.
We discussed this in the libs-api meeting today. We concluded that before stabilizing this, we need to make sure it works (doesn't return ) for std::panic!() as well. That is already the case with Rust 2021's std::panic!() (since it's identical to core::panic!() in this edition), but not for Rust 2015/2018's std::panic!(). Once that is fixed, we feel okay with returning a placeholder message for non-string panics (panics from or Rust 2015/2018's ), at which point the function can return an unconditionally, rather than an .


Question: /// that were given to the `panic!()` macro. /// /// See [`PanicInfo::message`]. <del> #[unstable(feature = "panic_info_message", issue = "66745")] </del> <ins> #[stable(feature = "panic_info_message", since = "CURRENT_RUSTC_VERSION")] </ins> pub struct PanicMessage<'a> { message: fmt::Arguments<'a>, }

(And also, should be returned by value, not by reference.)
Any progress on stabilization?
It would great to have this little feature.
Still nothing? What's missing?
can this be stabilized after was resolved in the pull request ?
Yes, soon, hopefully! I've updated the overview at the top of this tracking issue. The main question left before stabilization is the return type of the method. Should this return (as the unstable method does today), or should it return an opaque type that wraps that fmt::Arguments, so we can still change in the future? (In case we want to support different types of no_std panic, such as panicking with an Error or something.)
Can it return or so?
I would vote for an opaque type that would also implement .
Did that in this PR:
merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [ ] [x] [x] [x] [x] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.


Question: <ins> // force-host // no-prefer-dynamic #![crate_type = "proc-macro"] #![crate_name="some_macros"] extern crate proc_macro; use proc_macro::TokenStream; #[proc_macro_attribute] pub fn first(_attr: TokenStream, item: TokenStream) -> TokenStream { item // This doesn't erase the spans. } #[proc_macro_attribute] pub fn second(_attr: TokenStream, item: TokenStream) -> TokenStream { // Make a new `TokenStream` to erase the spans: let mut out: TokenStream = TokenStream::new(); out.extend(item); out } </ins>

crashes on nightly () and also on stable () with "nightly" features turned on via . It does not trigger on stable without flag. Here is the output I'm getting: I created a small repro case + here: (it only happens when there is a certain combination of procedural macros, so I cannot make it a single file).
The source code is: with crate being a procedural macro crate with:
Couple of things that are important here: only happens with two procedural macros. macro has to do that . attribute has to be , does not reproduce with anything else.
Just a heads-up: AFAIK if a bug only occurs on stable with (I understand that it is not the case here), then it should probably be disregarded, because isn't supposed to be used when not bootstrapping the compiler.
The bug itself reminds me of
it happens on nightly as well. That detail was included to give context that evidently the ICE has been present for longer than 12 weeks, I believe.
With the following patch in the linked repo, the output is not ideal, but preferable to the ICE: I'll take a look to see if we can somehow keep the span for the entire attr doc, or at worst pointing at the correct macro.
Changing the patch to be gives us which makes more sense but is missing a primary span. Edit: I see no way to recover the original span after its has been modified. I guess we already rely on proc macro writers to be nice when it comes to spans, so this is acceptable as well.


Question: /// # Example /// /// ```rust <ins> /// # #![allow(deprecated)] </ins> /// use url::Url; /// /// let raw = "https://username@example.com:8080/foo/bar?baz=qux#quz";

Users should use the cargo-ified Deprecate for a release or two then delete. cc
:+1:
Related:
I tried this: Hoping to deprecate the whole crate, but then building this program does not emit any warning: I expected a deprecation warning on the line. Is there another way to achieve this, or do I need to annotate individual items in the crate?
That should have worked, but you may need to remove the annotation above (they may be conflicting). I would also personally find it very helpful to annotate methods in particular what the path forward is (or just a general post about how to migrate).
Removing worked, thanks. Should this deprecation go through the RFC process, or can I assume that the team wants it since filed this issue? The documentation at explains how to use rust-url, and in particular the concept of relative v.s. non-relative URL schemes (e.g. vs ) which is a bit unusual. I believe this sufficient to make migration straightforward, but I’m obviously biased. Any feedback on the documentation is welcome. (I’ll make the deprecation message include the documentation’s URL, it seems more useful landing page than the github repo.)
Having an issue is sometimes considered a "todo item" rather than "everyone has approved this", you'll find both styles of issues on the issue tracker. We don't have much precedent for deprecating an in-tree crate, so we're forging new territory here. I'd like to start moving crates out of the repo, however, so I hope to have some more on this topic soon.


Question: sections[None] = [] section_order = [None] targets = {} <ins> top_level_keys = [] </ins> for line in open(rust_dir + '/config.toml.example').read().split("n"): <ins> if cur_section == None: if line.count('=') == 1: top_level_key = line.split('=')[0] top_level_key = top_level_key.strip(' #') top_level_keys.append(top_level_key) </ins> if line.startswith('['): cur_section = line[1:-1] if cur_section.startswith('target'):

The problem is that the configure script assumes that all keys are in a section and there are no top-level keys. This forces people to use instead: We should make it possible to set top-level keys through , both and . We should also update the line in the readme linked above to suggest instead of printf. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Mentoring instructions: look around I think the fix would be something like .
In the , from where exactly do we get the top-level keys? from the set function?
I'm not sure off the top of my head. How could you find out that information?
Hi are you still working on this?
do you think it's okay to unassign ? This issue is blocking as well.
Since there's no response from the assignee, I think you can take the issue. Are you still keen on working on this issue?
Yup I am interested! claim
Hi and thanks for mentoring! Assuming I run , I think will be 2. So I am not sure if this path would work. It seems like the first blocker is that does not contain or as keys. Should the approach be to expand with those keys? Or should we just allow / as special cases? I am guessing it's closer to the latter, since that might affect the definition of which searches for . Finally, I am a little confused what top-level keys mean - do they exclusively refer to [, ] ? Are there more?
I am able to expand when parsing to include and but I realise I may either have to make changes to or write a new method. Before I do that, I would like to understand how the configure script is commonly used. Could you give me some sample commands, say if I want to modify the field of llvm?
Shall we refactor the 2 top level keys under a section? this makes the parsing logic more consistent and unwieldy lol
you can take a look at for a complete example of what a configuration could look like. I think that would resolve most, if not all of your queries(: Hope this helps!
try running
Got it, thanks I put up a PR. This is kinda my first PR so would appreciate all the tips and advice!


Question: use crate::callee::{self, DeferredCallResolution}; <ins> use crate::errors::CtorIsPrivate; </ins> use crate::method::{self, MethodCallee, SelfSource}; use crate::rvalue_scopes; use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy};

I tried this code: I expected to see this happen: compilation should fail because the trait impl is defined outside of the module for the type but refers to its private field. Instead, this happened: this compiled successfully This reproduces on the playground for stable Rust, version 1.69.0:
Adding a main function and attempting to call the (playground link: ) raises the compilation error: !
This can be reproduced with cross-crate (e.i., any other crate can access the private field). This means that all encapsulations that take advantage of the field being private can be bypassed. (For example, if we change Vec to a tuple struct, the same thing as setlen could be done in safe code by abusing this bug.) label +I-unsound Also, this can be reproduced in all versions where is stable (e.i., 1.32+). It's a matter of how you initialize Foo. If you provide a constructor for Foo, you won't get a compile error:
Just for completeness, turning this into a segfault without external crates/just std:
label A-visibility
this has been unsound ever since in version 1.32
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: to rejecting hexadecimal IP addresses.][83652] The octal format can lead to confusion and potential security vulnerabilities and [is no longer recommended][ietf6943]. <ins> - [The added `BITS` constant may conflict with external definitions.][85667] In particular, this was known to be a problem in the `lexical-core` crate, but they have published fixes for semantic versions 0.4 through 0.7. To update this dependency alone, use `cargo update -p lexical-core`. </ins> Internal Only -------------

was re-stabilized in 1.53 after being backed out of 1.51 due to breakage, primarily in the lexical-core crate. This breakage has not been fixed, as far as I can tell, in a vast majority of crates: we're still seeing ~1300 regressions, majority of which are lexical-core in the . There was no discussion on the re-stabilization PR as to whether this level of breakage is acceptable. Comments on the original breakage issue suggest that 0.7.5 was published with a fix, but older versions (0.4, 0.5, 0.6) did not receive similar treatment. The majority of the breakage is in crates locked at 0.7.4; the other versions do share ~400 different crates amongst them, so I think it'd be good to try and help get those series patches as well.
cc Even with 0.7.5 out, it does look like it'll be some time before crates actually update lockfiles (if ever). We don't have a firm policy on whether cargo update being sufficient is "enough" that breakage is OK -- it's a new decision each time pretty much -- but this level of breakage is pretty bad. I guess there may not be much we can do -- IIRC a prelude trait for example adding BITS wouldn't help here, right? Those still introduce conflicts IIRC.
There’s no way around the symbol collision. I think it’s important that stabilize and I’d like us to get out of the way on that. I can take the list of broken crates and start walking it. I can also work on a backport on the older minor series; the reason I did not do so last time is that I was unfamiliar with ’s dependents and didn’t know whether the older series were still in use. What is the most complete course of action we can take to clear for stabilization? Should I yank the conflicting versions in each minor series? Alternatively, would it make sense, and is it even possible, to stabilize only in ?
I wouldn't worry about filing pull requests with 1300+ crates bumping lock files (in part because those are unlikely to get merged quickly). I do think getting patch releases out for each series would already be a significant step forward.


Question: to rejecting hexadecimal IP addresses.][83652] The octal format can lead to confusion and potential security vulnerabilities and [is no longer recommended][ietf6943]. <ins> - [The added `BITS` constant may conflict with external definitions.][85667] In particular, this was known to be a problem in the `lexical-core` crate, but they have published fixes for semantic versions 0.4 through 0.7. To update this dependency alone, use `cargo update -p lexical-core`. </ins> Internal Only -------------

I think yanking is likely not the right step to take at this time. In terms of stabilizing only with - no, that's not really possible. In theory we could stabilize with a different name to avoid all the breakage, but I doubt there's a great name...
The constant would have to be available everywhere, and stable everywhere, but one could think about adding a syntactic hack to interpret the syntax differently depending on the edition, similarly to how it was done for . That would have the desired effect of avoiding breakage on editions 2018 and before, but I'm not sure it's a good idea to double down on adding such hacks.
Attaching it to an edition would not only require compiler changes, but also a lint, a suggestion for rustfix, documentation, etc.
Indeed. Such a policy would be useful. If the decision is that that's fine, we might want to make crater update the lock files when something fails before it considers a crate broken. As another data point: also ignores the lock files and picks the latest matching version of everything.
I assumed the edition route was an infeasible idea but hey might as well get a “no” in writing. I’ll start cutting fixes for the minor series listed in the regression report this weekend.
Thank you! Let me know if I can help.
I'm wondering if we should have a in (just like ) that will make Rustc consider everything that was stabilized in a later version as still unstable. could add it to the uploaded crate if it's not explicitly set, and it makes it easier for crates to track an explicit MSRV.
did you get a chance to release new patch releases on each of the channels to avoid this breakage for the lexical crates, at least? I believe that was the plan but I haven't seen updates on this issue at least :)
Hi; I am so sorry for the radio silence; I have had quite the month since then. Fortunately, Alex Huszagh already did the patch-release issuance back in April. versions , , , and all appear to have the necessary disambiguation in place. These versions also do not appear in the regression report from Bors. I've also run on each of these releases with and passed, so these tips ought to be correct when the constants stabilize. I hope day-before isn't too late and I apologize again for the delay.


Question: to rejecting hexadecimal IP addresses.][83652] The octal format can lead to confusion and potential security vulnerabilities and [is no longer recommended][ietf6943]. <ins> - [The added `BITS` constant may conflict with external definitions.][85667] In particular, this was known to be a problem in the `lexical-core` crate, but they have published fixes for semantic versions 0.4 through 0.7. To update this dependency alone, use `cargo update -p lexical-core`. </ins> Internal Only -------------

If you're comfortable with a "run to un-break your project", then is ready.
No worries. We are planning to move ahead with a compat note indicating cargo update.
Just an FYI: this was fixed ~2 months ago, with , , and . It means that any branch used in the wild should be able to be updated to a compatible version now.


Question: <ins> error[E0658]: intrinsics are subject to change --> $DIR/incorrect-transmute.rs:5:8 | LL | extern "rust-intrinsic" fn transmute() {} |        ^^^^^^^^^^^^^^^^ | = help: add `#![feature(intrinsics)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0094]: intrinsic has wrong number of type parameters: found 0, expected 2 --> $DIR/incorrect-transmute.rs:5:37 | LL | extern "rust-intrinsic" fn transmute() {} |                                     ^ expected 2 type parameters error: intrinsic must be in `extern "rust-intrinsic" { ... }` block --> $DIR/incorrect-transmute.rs:5:40 | LL | extern "rust-intrinsic" fn transmute() {} |                                        ^^ error: aborting due to 3 previous errors Some errors have detailed explanations: E0094, E0658. For more information about an error, try `rustc --explain E0094`. </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. --(reduced) (original) <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Please try to minimize the example as much as possible:
claim
heads up that already put up a fix
Thanks Just want to add that some other intrinsics also ICE. For example: ICEs as well.
Interesting -- I wonder if we should perhaps fix this in a less specific way than . I wonder if we should instead detect that the declaration is not valid b/c has not been enabled in the crate... If not, then I'd be glad to review a PR that fixes whatever other intrinsics you find to make too many assumptions in the compiler.
Even adding does not prevent the ICE unfortunately. It happens in due to the wrong number of arguments e.g. here for : occurs for a lot of intrinsics in this file. I'm guessing all of them will ICE under the conditions in this issue. To fix it, we could extend what's done for in to all intrinsics, maybe leveraging this code to know how many args are expected for any given intrinsic:
I have opened
Looks like intrinsics are expected to ICE if used wrongly (see comment: ) so I opened has been rightly closed. But that mean that should also ICE in these conditions. However, in the present issue it was ICEing for the wrong reason i.e. out of bound access . So does the right thing by stopping that. However, IMHO it should not taint the context and let it go to MIR lowering and then let it ICE there. That keeps consistent with other intrinsics' behaviour as noted above. Thoughts & If you guys agree I can open a PR to remove the tainting.
See which takes a different approach
Nice!


Question: <ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // // compile-pass fn main() { let mut i = [1, 2, 3]; i[i[0]] = 0; i[i[0] - 1] = 0; } </ins>

This appears to now be fixed.
Neat! Just needs a test if there isn't one already.
There's , but I'm not sure if that qualifies as testing this in particular. If not, I can add one.
Marking as E-needstest. I don't think the test I linked previously really fits this case.


Question: CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); <ins> pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); </ins> }

I'm opening this up to serve as a tracking issue for enabling multiple codegen units in release mode by default. I've written up a before but the tl;dr; is that multiple codegen units enables us to run optimization/code generation in parallel, making use of all available computing resources often speeding up compilations by more than 2x. Historically this has not been done due to claims of a loss in performance, but the is intended to assuage such concerns. The most viable route forward seems to be to enable multiple CGUs and ThinLTO at the same time in release mode. Blocking issues: [x] Enable for libstd on all platforms - - - - Potential blockers/bugs: - -
cc
Presumably this will remain a stable compiler flag, but what else will change by default? Is the plan to make this only affect , or is the plan to also make this affect ? Do we want to make continue to use only a single CGU, to hedge against regressions for people who are already willing to trade off compiler time for runtime?
I would specifically propose that any opt level greater than 1 uses 16 codegen units and ThinLTO enabled by default for those 16 codegen units.
This is very interesting. One would think that ThinLTO-driven inlining should always have to do less work when our much more conservative pre-LLVM inlining. But that doesn't always seem to be the case, as in the . Most tests on the seem to profit though. Overall it's still not a clear picture to me.
was that comment meant for a different thread? I forget which one as well though, so I'll respond here! As a "quick benchmark" I compiled the regex test suite with 16 CGUs + ThinLTO and then toggled inlining in all CGUs on/off. Surprisingly inlining in all CGUs was 5s faster to compile, and additionally . In those timings is where inlining is only in one CGU, where is inlining in all CGUs. One benchmark, , got twice as slow!
Yeah, the comment was in response to (rust-doom) but since that was closed already, I put it here.


Question: CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); <ins> pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); </ins> }

Regarding the compilation time difference between pre- and post-trans inlining, my hypothesis would be that sometimes pre-trans inlining will lead to more code being eliminated early on (as in the case of regex apparently) and sometimes it will have the opposite effect. I suspect that there's room for improvement by tuning which LLVM passes we run specifically for ThinLTO. Or do we do that already?
Heh it's true yeah, I'd imagine that there's always room for improvement in pass tuning in Rust :). Right now we perform (afaik) 0 customization of any pass manager in LLVM. All of the normal optimization passes, LTO optimization passes, and ThinLTO optimization passes are all the same as what's in LLVM itself.
I wanted to also take the time and tabulate all the results from the to make sure it's all visibile in one place. Note that all the timings below are comparing a release build to a release build with 16 CGUs and ThinLTO enabled Improvements All of the following compile times improved, sorted by most improved to least improved Regressions The following crates regressed in compile times, sorted from smallest regression to largest alexcrichton's attempt to reproduce the regressions Here I attempt to reproduce the regressions on my own machine with Unfortunately the only regression I was able to reproduce was the rust-belt regression. I'll be looking more into that.
Looking into , one interesting thing I've found is that the crate takes longer to compile with ThinLTO than it would otherwise. Looking at it appears that one codegen unit in this crate takes 99% of the time in LLVM. This codegen unit appears to be basically entirely dominated by . Almost all of the benefit of multiple codegen units is spreading out the work across all CPUs. Enabling ThinLTO to avoid losing any perf is fundamentally doing more work than what's already happening at , but we get speedups across the board in most cases. If we have one huge CGU, split it in two, and work on those in parallel then we've got 50% of the original time to run ThinLTO (in a perfect world). If ThinLTO takes more than 50% of the time then we'd have a build time regression, but that's almost never happening.


Question: CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); <ins> pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); </ins> }

What's happening here is that we have one huge CGU, but when we split it up we still have one huge CGU. This means that the CGU which may take ~1% less time in LLVM only gives us a tiny sliver of a window to run ThinLTO passes. In the case of the crate this means that adding ThinLTO passes is an overall build time regression. So generalizing even further, I think that enabling ThinLTO and multiple CGUs by default is going to regress compile time performance in any crate where our paritioning implementation doesn't actually partition very well. In the case of we've got one huge function which hogs almost all the optimization time (I think) and the entire crate is basically dominated by that one function. I would be willing to conclude, however, that such a situation is likely quite rare. Almost all other crates in the ecosystem will benefit from the partitioning which should basically evenly split up a crate. maybe you have thoughts on this though?
Thank you so much for collecting and analyzing such a large amount of data, Your conclusions make sense to me. Unevenly distributed CGU sizes are also a problem for incremental compilation; e.g. the test sees 90% CGU re-use, yet compile time is almost the same as from-scratch. In the non-incremental case it might be an option to detect the problematic case right after partitioning and then switch to non-LTO mode? I'm not sure it's worth the extra complexity though. For cases where there is one big CGU but that CGU contains multiple functions, we should be able to rather easily redistribute functions to other CGUs. We'd only need a metric for the size of a . The number of MIR instructions might be a sufficient heuristic here. That would not help for but it might help for other crates. In conclusion, judging from the table above, I think we should make the default sooner rather than later. Open questions I see: What to do about ? I would have thought that it would always be a clear win to disable this when ThinLTO is enabled but that doesn't seem to be the case. Are there hardware configurations where this never is a win? E.g. should we default to traditional compilation if ?


Question: CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); <ins> pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); </ins> }

FWIW, as the author of , which is a made-for-fun Piston game, I am more than happy to take a small compile regression when it seems like vast majority of crates get huge real-time improvements!
This seems like a good thing to have in our back pocket, but I'm also wary of trying to do this by default. For example the case is one where we may wish to disable ThinLTO but the one massive function could also critically rely on a function in a different CGU being inlined? That sort of case would be difficult for us to determine... In any case though I agree that we probably don't need the complexity just yet so I think we can defer this for later. Agreed! So far all the crate's I've seen the O(instructions) has been quite a good metric for "how long this takes in all LLVM-related passes", so counting MIR sounds reasonable to me as well. Again though I also feel like this is ok to have in our back pocket. I'd want dig more into the minor change example, I'm curious how awry the CGU distribution is there and whether a heuristic like this would help. Quite surprisingly I've yet to see any data that it's beneficial to compile time in release mode or doesn't hurt runtime. (all data is that it hurts both compile time and runtime performance!) That being said we're seeing such big wins from ThinLTO on big projects today that we can probably just save this as a possible optimization for the future. On the topic of inline functions I recently dug up again (later closed in favor of , but the latter may no longer be true today). I suspect that may "fix" quite a bit of the compile time issue here without coming at a loss of performance? In any case possibly lots of interesting things we could do there. Also a good question! I find this to be a difficult one, however, because the CGU number will affect the output artifact, which means that if we do this sort of probing it'll be beneficial for performance but come at the cost of more difficult deterministic builds. You'd have to specify the CGUs manually or build on the same-ish hardware to get a deterministic build I think? I think though that if you have 1 CPU then this is universaly a huge regression.


Question: CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); <ins> pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); </ins> }

With one CPU we'd split the preexisting one huge CGU into N different ones, probably take roughly the same amount of time to opimize those, and then tack on ThinLTO and more optimization passes. My guess is that with one CPU we'd easily see 50% regressions. With 2+ CPUs however I'd probably expect to see benefits to compile time. Anything giving us twice the resources to churn the cgus more quickly should quickly start seeing wins in theory I think. For now though the deterministic builds wins me over in terms of leaving this as-is for all hardware configurations. That and I doubt anyone's compiling Rust on single-core machines nowadays!
One thing I think that's also worth pointing out is that up to this point we've mostly been measuring the runtime of an entire . That's actually, I believe, the absolute worst case scenario for where ThinLTO will provide benefit. Despite this, it's showing huge improvements for lots of projects! The benefit of ThinLTO and multiple CGUs is leveraging otherwise idle parallelism on the build machine. It's overall increasing the amount of work the compiler does. For a from scratch, though, you typically already have tons of crates compiling for the first half of the build in parallel. In that sense there's not actually any idle parallelism. Put another way, ThinLTO and multiple CGUs should only be beneficial for builds which dont have many crates compiling in parallel for long parts of the build. If a build is 100% parallel for the entire time then ThinLTO will likely regress compile time performance. Now you might realize, however, that one very common case where you're only building one crate is in an incremental build! Typically if you do an incremental build you're only building a handful of crates, often serially. In that sense I think that there's some massive wins of ThinLTO + multiple CGUs in incremental builds rather than entire crate builds. Although improving both is of course great as well :)
For deterministic builds you have to do some extra configuration anyway (e.g. path remapping) so I would not consider that a blocker. And I guess there are single core VMs around somewhere.


Question: CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); <ins> pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); </ins> }

But all of this is such a niche case that I don't really care MIR-only RLIBs should put us into a pretty good spot regarding this, so I'm quite confident that we're on the right path overall.
That's really interesting. For incremental compilation enabled the situation might be different (because pre-trans inlining hurts re-use) but for the non-incremental case it sounds like it's pretty clear what to do.
Yeah, maybe we should revisit this at some point. Although I have to say the current solution of only and symbols and nothing in between is really nice and simple.
Hm yeah that's a good point about needing configuration anyway for deterministic builds. It now seems like a more plausible route to take! Also that's a very interesting apoint about incremental and inlining on our own end... Maybe we should dig more into those ThinLTO runtime regressions at some point! Also yeah I don't really want to change how we trans inline functions just yet, I do like the simplicity too :)
out of curiosity how did you figure out this and which function it was. I've wanted to look into why the webrender build is so slow and would welcome tips.
oh sure I'd love to explain! So I originally found as a problematic crate when compiling rust-belt as it just took awhile and I decided to dig deeper. I checked out the crate and ran: That drops in the current directory, and opening that up I see: ! The graph here isn't always the easiest to read, but we've clearly got two huge bars, both of which correspond to taking a huge amount of time for that one CGU (first is optimization, second is ThinLTO + codegen). Next I ran: and that command dumps a bunch of IR files into . Our interesting CGU is so I opened up (we sure do love our long filenames). Inside that file it was 70k lines and some poking around showed that one function was 66k lines of IR. I sort of forget now how at this point I went from that IR to determining there was a huge function in there though...
I don't know if this is the right place, but I think it should be considered whether the symbol issues reported in the Nightly section here: should be considered a blocker or not.


Question: CU1: *mut *mut c_void, CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); <ins> pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); </ins> }

The tl;dr is that certain versions of llvm, (i've seen this on 3.8, and whatever llvm rustc nightly uses) appends seemingly random garbage to the end of some names, e.g. we get: instead of: This knocks the debuginfo out of sync (it doesn't have the garbage appended). I've been able to repro this with clang3.8 for c++ files as well (haven't tested on other llvm), and switching to 5.0 seems to have fixed the issue. I don't know if its within reach, but perhaps we should attempt upgrading to llvm 5.0 before releasing this on stable? Note I understand this is for release mode, but i see this in debug mode on rustc nightly right now as well...


Question: <ins> // run-rustfix struct Foo { first: Bar, _second: u32, _third: u32, } struct Bar { bar: C, } struct C { c: D, } struct D { test: E, } struct E { _e: F, } struct F { _f: u32, } fn main() { let f = F { _f: 6 }; let e = E { _e: f }; let d = D { test: e }; let c = C { c: d }; let bar = Bar { bar: c }; let fooer = Foo { first: bar, _second: 4, _third: 5 }; let _test = &fooer.c; //~^ ERROR no field let _test2 = fooer.test; //~^ ERROR no field } </ins>

I just encountered this output: We currently mention available fields when the field used isn't found. It would be nice if we peeked at the types for the available fields to see if any of them has any fields (including through deref) of the name we originally wanted. In this case, I would love to see the following output: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I'll work on this. claim
I was just about to open a PR when I saw that you claimed the issue. It's my fault for not claiming this issue myself obviously, so if you've already been investing time into this the issue its still yours, but if you haven't can I open a PR for this?
I've done nothing yet as I planned to work on this tomorrow morning, so this is yours :)
release-assignment
if you're still interested in contributing, it seems to me that might be similar in scope and section of the codebase you could work in.
Thank you.


Question: const _: u32 = recursive_expand!(); //~ ERROR: recursion limit reached while expanding `recursive_expand!` <del> fn main() {} </del> <ins> fn main() { // https://github.com/rust-lang/rust/issues/104414 match b"Included file contentsn" { include_bytes!("auxiliary/included-file.txt") => (), _ => panic!("include_bytes! in pattern"), } } </ins>

<!-- Thank you for filing a regression report! A regression is something that changed between versions of Rust but was not supposed to. Please provide a short summary of the regression, along with any information you feel is relevant to replicate it. --I tried this code: I expected to see this happen: code compiles and execute Instead, this happened: compilation fails with It most recently worked on: and <!-- Provide the version you are using that has the regression. --: <!-- Did the compiler crash? If so, please provide a backtrace. --<!-- If you know when this regression occurred, please add a line like below, replacing with one of stable, beta, or nightly. modify labels: +regression-from-stable-to-{channel} -regression-untriaged --used by . I suspect (but did not confirm) might be the cause of the breakage as it is a recent change on that area. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
cc
The code posted has a missing delimiter.
oops, fixed
claim
WG-prioritization assigning priority (). label -I-prioritize +P-high


Question: | ^^^^^^^^ error[E0603]: enum `Bar` is private <del> --> $DIR/struct-variant-privacy-xc.rs:6:33 </del> <ins> --> $DIR/struct-variant-privacy-xc.rs:7:33 </ins> | LL |         struct_variant_privacy::Bar::Baz { a: _a } => {} |                                 ^^^ private enum

<!-- 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
Seems to be the indicated function:
.
Assigning as discussed as part of the and removing . label -I-prioritize +P-medium
Oh this is ugly x) Reading the PR, the problem is that there are two ways to match a Box: via a box-pattern or via . But we can't know which will be used based on the type only. Current code assumes box-patterns, hence the error. The PR works because luckily all the fields of are private. If you tried pattern-matching within the module that defines , you'd get crazy results like (actually wouldn't even typecheck): We'll need to figure out a real solution when we implement generalized Deref patterns...
in that case we should open a new ticket for that work, tagged something like or something.


Question: /// # Examples /// /// ``` <del> /// #![feature(arc_unwrap_or_clone)] </del> /// # use std::{ptr, rc::Rc}; /// let inner = String::from("test"); /// let ptr = inner.as_ptr();

Feature gate: This is a tracking issue for . This feature adds methods to / to gain access to the contained value, by unwrapping if there is exactly one reference, or cloning otherwise. It is equivalent to cloning the inner value, but saves the clone operation if the caller has the only reference to the rc'd value. [x] Implementation: [ ] Final comment period (FCP) [ ] Stabilization PRThere seems to be consensus that the current name is good.
Apologies if this is the wrong place for this comment, feel free to delete. Is there a technical reason why is an associated function and not a method? If I have , I cannot call , but have to resort to which feels unwieldy.
it's because / are 'wrapper types' that implement . A lot of the methods are implemented as associated functions so they don't clash with method names on the . This makes it easier to change between different wrapper types like / etc without suddenly getting a name clash. Apologies if I'm using the wrong terminology but that's the gist of it.
That makes sense. Thanks for the explanation :)
sounds like a bad name to me: has a connotation of potentially panicking code in Rust. The other suggested names in all sound better to me. (Couldn't comment on the thread in IRLO as it has been closed.)
There is precedence for this pattern: for example.
True, I overlooked it.
I think this name is good, and it's easy for me to understand what it means. I'm really looking forward for this to be fcped and stabilized.
At $work we've been using the exact same implementation as the one used in nightly (), it works perfectly well
While I like the proposal very much (for it's convenience), I feel like I want to point out something that might be interesting as well in the future and is related: It's not possible to use where . In this case we have an , which is . However this is a conversion that is also very useful. It would be intersting to go from to . The other way is already possible, but this way is currently not possible, however there are sometimes cases where the count is known and converting back to a Box would be very useful. Consider wanting to remove an element from an for example.


Question: /// # Examples /// /// ``` <del> /// #![feature(arc_unwrap_or_clone)] </del> /// # use std::{ptr, rc::Rc}; /// let inner = String::from("test"); /// let ptr = inner.as_ptr();

The current way to do this is to clone the vec, remove an element and make a new Rc, even when an Rc is empty. I understand that there would need to be something like a first, but I just wanted to bring it up, so it's clear that there's potentially more things that could "unwrap" from an Rc.
Try this: The code above will copy vector if needed. (I didn't test the code)
Yes, good point, thanks for bringing it up. However a Vec is unfortunately another layer of indirection. Typically I have something like .
Is there something that still needs to be done before this can go to FCP? I just came across the need for this and noticed that the comments seem positive with confirmation that it works at $work for at least one commenter above, so am wondering what if anything is preventing it moving forward?
Pinging here for input. There seems to be consensus on stabilizing this. Can anyone start an FCP? I'd be happy to work on a stabilization PR (with some guidance)
fcp merge Both of these are already expressible on stable using the following incantation, which is exactly the standard library's implementation too: . The rationale for a dedicated method is that "I need a " is a common enough use case that it's worthwhile to have one easy function prominently available in the type's API doing the thing you most likely want to do in that scenario.
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [ ] [ ] No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
and others: is related
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.
I believe that can check off the stabilization?
And update the documentation as this seems to have been stabilized.


Question: /// # Examples /// /// ``` <del> /// #![feature(arc_unwrap_or_clone)] </del> /// # use std::{ptr, rc::Rc}; /// let inner = String::from("test"); /// let ptr = inner.as_ptr();

I am getting this:
Arc<strstores the string inline on the heap together with the strongcount and weak_count of the Arc. This means it has a different in-memory representation than Box<strand thus can't be converted into a Box<strwithout copying the contents. A Box<strto Arc<strconversion also copies the string contents into the Arc allocation.
I understand that. But moving elements from an Rc to a Vec is different from cloning. The opposite direction is already possible. This means that you can write , but not . I understand that moving is different from . This would probably need to be named something like Vec::frommovedrcorclone`.
GitHub deleted all my angle brackets. I was specifically talking about converting between string types because there's no difference between moving and cloning characters.


Question: error[E0658]: panicking in constants is unstable <del> --> $DIR/issue-76064.rs:1:17 </del> <ins> --> $DIR/issue-76064.rs:3:17 </ins> | <del> LL | struct Bug([u8; panic!(1)]); |                 ^^^^^^^^^ </del> <ins> LL | struct Bug([u8; panic!("panic")]); |                 ^^^^^^^^^^^^^^^ </ins> | = note: see issue #51999 <https://github.com/rust-lang/rust/issues/51999> for more information = help: add `#![feature(const_panic)]` to the crate attributes to enable

The panic payload of the macro (as passed on to ) is generic, but the CTFE panic support assumes it will always be an . This leads to ICEs: Cc
I guess we could support this, but we'd have to find some way to render the errors. Maybe we need to wait for const traits so we can require const Debug?
Alternatively constck could require the argument to have type .
also requires a
Yeah, the libcore panic machinery does not support non-format-string panics.
Aye, left out the latter of my message. is likely the most common argument to , and it's not unusual with e.g. ; so I agree that waiting for const traits before supporting any other arguments is reasonable.
Im hitting this ICE on stable without feature flag:
Hm indeed, that is interesting: any idea why we go on here after seeing an error? Does this kind of behavior mean any part of CTFE is reachable on stable somehow?
yes. We're not gating CTFE on whether there were stability (or any other static checks) failing. I've been abusing this since 1.0 to demo things on the stable compiler and never got around to fixing it. I don't even know if we have a tracking issue for it.
:rofl: So what would be a possible approach here? Replace such consts by early enough that their MIR never actually gets evaluated? We might as well use this issue, IMO...
That would require us to mutate all MIR and potentially even HIR. Other possible solutions: poison the mir Body if const checks fail (by adding a field like or by just nuking the body by replacing it with ) and thus make allow const evaluation to check if the mir Body failed the checks and bail out before doing anything make the have an field similar to
On second thought, let's leave this issue for the ICE, and make a new one for "we can trigger nightly-only const code on stable because we don't abort compilation early enough":
Given that this ICE is pre-existing, as shown by , can we un-block ? I'd really like to see const_panic stabilized, and this seems like a minor issue to be blocking on.
That comment is an example of accidentally partially exposing an unstable feature on stable -- a separate bug tracked in I don't see how that's an argument for shipping that feature on stable when it is broken.


Question: error[E0658]: panicking in constants is unstable <del> --> $DIR/issue-76064.rs:1:17 </del> <ins> --> $DIR/issue-76064.rs:3:17 </ins> | <del> LL | struct Bug([u8; panic!(1)]); |                 ^^^^^^^^^ </del> <ins> LL | struct Bug([u8; panic!("panic")]); |                 ^^^^^^^^^^^^^^^ </ins> | = note: see issue #51999 <https://github.com/rust-lang/rust/issues/51999> for more information = help: add `#![feature(const_panic)]` to the crate attributes to enable

In particular, applies to all unstable const features. Fixing this bug here is not even that hard I think: somewhere around here there needs to be a check that the argument has type . Re: , AFAIK that one is also blocked on figuring out how the diagnostics should look like, and a further concern (though maybe not blocking) is .
I guess that might make this a non-issue, where it is proposed also would require as first argument.
For reference: , which was recently merged. The plan is to fix the behaviour of in the Rust 2021 edition. Given that this ICE is listed as a blocker for , does this mean that stabilizing that will have to wait for the next edition?
No, because breaking changes are allowed to be made to unstable features without moving to a new edition; that's kinda the whole idea. The 2021 edition will effectively just extend the same restriction to all invocations, const context or not.
I'd like to tackle this but I'm not very experienced with the CTFE code. I get that we need to check from the that we've matched on in this branch and we need to match on the enum, but: For the first question, I see and that we probably want to check that the type of the tuple and that there's variants of that are , but do we stop the iteration when we get one that is a type? Is the projection list always guaranteed to terminate in a variant of that has a ? And once we have an instance of , do we just check that there's any_ projection in the list that has a ?
you can use to get the type of the . Then you can test its to be .


Question:
pub fn must_use(&self) -> bool { true }  /// hello /// ///
this is a warning
 /// /// done pub fn warning1() {} /// Checking there is no bottom margin if "warning" is the last element. /// ///
this is a warning
 pub fn warning2() {}  } impl AsRef<str> for Foo {

Following , we realized that rustdoc users would prefer to have a syntax extension rather than using plain HTML to have warning blocks. suggested the following: suggested: What do you think? cc
Personal Opinions: The first style will look fine for short forms, but I'm not sure for longer text. A possible syntax: Which to me pushes the text too far right. Not having any spacing, but just separating with newlines, seems hard to parse at a glance what is part of the WARNING, and prevents multiple line breaks inside the warning. Also, it's not as extensible. INFO can be , but if we ever want more extensions, they would increasingly possibly conflict with other things. The second style makes it immediately clear what is part of the block, and is unlikely to accidentally conflict if we ever want to add more block styles. It also supports multiple lines or inner blocks trivially. A final advantage is that it may support nested blocks, in case those ever come to be useful. Overall: I prefer the second form, both aesthetically and for future-proofing
I think I agree with in preferring the second form. I like the first form's simplicity, but it also seems surprising that is treated as a 'keyword' and will change the formatting of the docs.
That's why we have this debate. :stuckouttongue:
I personally actually prefer stabilizing a CSS class, I think we should do more of that, just because parsing can get annoying. But this is not that hard to parse anyway. The problem with is precisely that you can't scope it easily: what if you want to add code blocks? bullet points?
The problem with this is it ties rustdoc to the HTML backend; like I said nothing rustdoc currently does guarentees that it will generate HTML from the markdown. Changing that means that to make the JSON backend have the same info, we'd have to add a full HTML parser to rustdoc just to read the HTML in the markdown, because pulldown does not parse HTML for us. I really think we should avoid making the JSON backend a second-class citizen.
Also there's not much point to this if it's just a little CSS IMO, you can add that yourself with and it will look just as good and be more flexible since you can control the styles yourself.