Question: // and about 2 * (len1 + len2) comparisons in the worst case // while `extend` takes O(len2 * log(len1)) operations // and about 1 * len2 * log_2(len1) comparisons in the worst case, <del> // assuming len1 >= len2. </del> <ins> // assuming len1 >= len2. For larger heaps, the crossover point // no longer follows this reasoning and was determined empirically. </ins> #[inline] fn better_to_rebuild(len1: usize, len2: usize) -> bool { <del> 2 * (len1 + len2) < len2 * log2_fast(len1) </del> <ins> let tot_len = len1 + len2; if tot_len <= 2048 { 2 * tot_len < len2 * log2_fast(len1) } else { 2 * tot_len < len2 * 11 } </ins> } if better_to_rebuild(self.len(), other.len()) {

To simulate more expensive comparisons I've made a benchmark where each comparison involves some global atomic operations. Below that I've included a benchmark with ten times the number of items in the heaps in total (an order of magnitude more than that makes the benchmark very slow). The trends remain similar. ! ! The original implementation ( and ) seems to base its choice for heuristic mostly on the expectation it is a reasonable heuristic. However, I think reasoning from the worst-case scenario (O(n log(m))) is pessimistic for the method as a large number of es require only one or two comparisons (instead of log(m)) before ending up in the bottom two layers (that contain 75% of all items in the end). Maybe for even larger heaps the method actually is advantageous again, but I'm not sure how to determine a heuristic for that. <details<summaryChanged code for atomic benchmark</summary</details
Ah, I missed that. That indeed limits the opportunities to realize its advantage. The x-axis still says 50k though? First we would need a benchmark demonstrating that advantage anyway.
Only for the first image, that one has the same number of elements as before but a more expansive comparison implementation. The x-axis of the second image goes up to 500k, that one has normal "cheap" integer comparison but a larger number of items in the heaps. Certainly.
Naively, when I look at the graphs in the OP what I see isn't that extend is always going to be better -- the slopes seem to be clearly different, though two graphs with different scales and extra lines makes that comparison harder than it ought to be -- but that the current heuristic is doing a bad job of accounting for constant factors when picking the switchover point. Why isn't the answer here just use a number other than two in the heuristic?
Here's the two lines from a different measurement of the same benchmark in the same graph. It has a weird jump between and (artifact?), that's why included the more messy pictures initially. ! The slopes are indeed very different, and extrapolating them would lead to a crossover point. However, this crossover point can never actually be reached because you can't extrapolate beyond the rightmost data point.


Question: // and about 2 * (len1 + len2) comparisons in the worst case // while `extend` takes O(len2 * log(len1)) operations // and about 1 * len2 * log_2(len1) comparisons in the worst case, <del> // assuming len1 >= len2. </del> <ins> // assuming len1 >= len2. For larger heaps, the crossover point // no longer follows this reasoning and was determined empirically. </ins> #[inline] fn better_to_rebuild(len1: usize, len2: usize) -> bool { <del> 2 * (len1 + len2) < len2 * log2_fast(len1) </del> <ins> let tot_len = len1 + len2; if tot_len <= 2048 { 2 * tot_len < len2 * log2_fast(len1) } else { 2 * tot_len < len2 * 11 } </ins> } if better_to_rebuild(self.len(), other.len()) {

The benchmark is set up such that two heaps are merged, one containing x elements and the other 100,000 - x. The rightmost data point at x = 50,000 corresponds to merging two equally sized heaps. The data point that would be to the right of that (x = 52,500) would give the same result as the data point to the left (x = 47,500) because both involve merging a heap of 47,500 and 52,500 elements and the heaps are swapped in one of them to make sure the smaller heap is append to the larger one. In other words, beyond the rightmost data point the slopes change (become negative) and the data would mirror the data to the left of that point (which is why I didn't include it). The crossover point is thus only reachable (in this benchmark) if you'd remove the swap-optimization (theoretically I mean, practically that would worsen performance, or course). The TLDR is that it appears the number would have to be such that the condition always evaluates to . On another note, I've now also benchmarked merging very large heaps (100 million elements after merge), and is always more favorable there as well. !
Just tried the benchmark with changes from PR and scores significantly better. The heuristic could still be improved though. !
Thanks for the update to remind me about this One thing that I'd missed last time: ing from the contents of a can never hit the worst case (needing to bubble to the root every time), since it's being extended by something that's in roughly-descending order. Do you want to wait on before looking at more?
I think for now it would be better to wait and/or work towards a better heuristic (even though can perform better, it's still up to 25% slower when the second heap is much smaller). PS/Disclaimer: I'm the author of and not a reviewer, so I may be a little biased, however the benchmarks should speak for themself. Would be nice someone else could confirm my claims
Nice performance improvements in , just a pity it makes determining the switchover heuristic more difficult ;). I ran the benchmark again with and on my machine it also improves 's performance enough that it's the faster method when merging larger heaps.


Question: // and about 2 * (len1 + len2) comparisons in the worst case // while `extend` takes O(len2 * log(len1)) operations // and about 1 * len2 * log_2(len1) comparisons in the worst case, <del> // assuming len1 >= len2. </del> <ins> // assuming len1 >= len2. For larger heaps, the crossover point // no longer follows this reasoning and was determined empirically. </ins> #[inline] fn better_to_rebuild(len1: usize, len2: usize) -> bool { <del> 2 * (len1 + len2) < len2 * log2_fast(len1) </del> <ins> let tot_len = len1 + len2; if tot_len <= 2048 { 2 * tot_len < len2 * log2_fast(len1) } else { 2 * tot_len < len2 * 11 } </ins> } if better_to_rebuild(self.len(), other.len()) {

I guess it doesn't make much sense to merge as-is because of that. I'll have a look if I can determine a better heuristic based on the improved performance.
In order to determine the new switchover point, I ran some benchmarks for heaps of different lengths. For a constant total heap length (heap length after the operation), the execution time has an (approximately) linear relationship with the length of the smaller heap. This means the data can be fitted with a least-squares linear fit: ! The blue line is the rebuild strategy, and purple the extend strategy. The green vertical line indicates the intersection of the fitted lines, i.e. where the switchover between strategies should ideally be. The red vertical line indicates the switchover point using the current heuristic. The fits for all the different other lengths can be found in the collapsible section at the end of this comment. I've plotted the location of the ideal switchover point as a function of the total heap length (the current heuristic is not a smooth curve because it uses a fast but inexact log2): ! I think a couple points are noteworthy: The current heuristic is quite close to the ideal point for smaller heaps. The switchover point stays roughly constant (when considered as a percentage as in the graph above) for heap lengths 1000 to . For larger heaps, the ideal switchover point rises again, which is not reflected in the current heuristic. I am not sure how to best model a heuristic for larger heaps, especially because for the power-of-2 heaps show it drops again for the two largest heaps. However, I think it should be fairly straightforward to improve the current heuristic by setting a lower bound on the switchover point: This results in the green curve in the graph above. It is closer to the ideal switchover point in all cases, but for larger heaps it is still suboptimal. I'd love to hear ideas on how to improve the heuristic further for larger heaps. <details<summaryImages of all fits</summaryIn all graphs, blue is the rebuild strategy and purple the extend strategy. The dots indicate raw data points and the line is a least-squares linear fit. The green vertical line indicates the intersection of the fitted lines, i.e. where the switchover between strategies should ideally be.


Question: // and about 2 * (len1 + len2) comparisons in the worst case // while `extend` takes O(len2 * log(len1)) operations // and about 1 * len2 * log_2(len1) comparisons in the worst case, <del> // assuming len1 >= len2. </del> <ins> // assuming len1 >= len2. For larger heaps, the crossover point // no longer follows this reasoning and was determined empirically. </ins> #[inline] fn better_to_rebuild(len1: usize, len2: usize) -> bool { <del> 2 * (len1 + len2) < len2 * log2_fast(len1) </del> <ins> let tot_len = len1 + len2; if tot_len <= 2048 { 2 * tot_len < len2 * log2_fast(len1) } else { 2 * tot_len < len2 * 11 } </ins> } if better_to_rebuild(self.len(), other.len()) {

The red vertical line indicates the current switchover point. ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! </details


Question: } _ => token.span, }, <del> Some(tree) => tree.span(), None => colon_span, </del> <ins> // Invalid, return a nice source location _ => colon_span.with_lo(start_sp.lo()), </ins> } } <del> Some(tree) => tree.span(), None => start_sp, </del> <ins> // Whether it's none or some other tree, it doesn't belong to // the current meta variable, returning the original span. _ => start_sp, </ins> }; result.push(TokenTree::MetaVarDecl(span, ident, None));

Here's some code incorrectly defining a macro, because it's missing a fragment specifier. Here's the error message rustc gives me: It's potentially confusing that the error points to the source after the name with the missing fragment specifier. Especially in a complicated macro, it would be better if it pointed to the item which was actually missing the fragment specifier. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Some more context at


Question: <ins> #![feature(fn_traits, unboxed_closures)] fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} struct Compose<F,G>(F,G); impl<T,F,G> FnOnce<(T,)> for Compose<F,G> where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { type Output = G::Output; extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { (self.1)((self.0)(x)) } } fn bad<T>(f: fn(&'static str) -> T) { test(Compose(f, |_| {})); //~ ERROR: mismatched types } fn main() {} </ins>

Reproduction branch: When applying the change from the last commit I get a panic in my code during the call to . <details<summaryBacktrace</summary</details
Cannot reproduce on my linux. Can you provide a small ? Is that possible? Maybe without all the externals :/
I can reproduce a very similar problem (appears to involve the same origin and failing assertion of ) compiling rust-lang/regex with and compiler flags: For me, setting to 2 or greater is required to present this failure. <details<summarybacktrace</summary<code<preRUSTBACKTRACE=1 cargo build Compiling regex v1.1.2 (/home/kent/rust/regex) thread 'rustc' panicked at 'assertion failed: bpos.tou32() = () + as u32', stack backtrace: 0: std::sys::unix::backtrace::tracing::imp::unwindbacktrace at 1: std::syscommon::backtrace::print at 2: std::panicking::defaulthook::{{closure}} at at 3: std::panicking::defaulthook at 4: rustc::util::common::panichook 5: std::panicking::rustpanicwithhook at 6: std::panicking::beginpanic 7: syntax::sourcemap::SourceMap::bytepostofilecharpos 8: syntax::sourcemap::SourceMap::lookupcharpos 9: <rustccodegenssa::mir::FunctionCx<'a, 'tcx, Bx::scopemetadataforloc 10: <rustccodegenssa::mir::FunctionCx<'a, 'tcx,


Question: <ins> #![feature(fn_traits, unboxed_closures)] fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} struct Compose<F,G>(F,G); impl<T,F,G> FnOnce<(T,)> for Compose<F,G> where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { type Output = G::Output; extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { (self.1)((self.0)(x)) } } fn bad<T>(f: fn(&'static str) -> T) { test(Compose(f, |_| {})); //~ ERROR: mismatched types } fn main() {} </ins>

Bx::debugloc 11: rustccodegenssa::mir::codegenmir 12: rustccodegenssa::base::codegeninstance 13: rustccodegenssa::monoitem::MonoItemExt::define 14: rustccodegenllvm::base::compilecodegenunit::modulecodegen 15: rustc::depgraph::graph::DepGraph::withtask 16: rustccodegenllvm::base::compilecodegenunit 17: rustccodegenssa::base::codegencrate 18: <rustccodegenllvm::LlvmCodegenBackend as rustccodegenutils::codegenbackend::CodegenBackend::codegencrate 19: rustc::util::common::time 20: rustcdriver::driver::phase4codegen 21: rustcdriver::driver::compileinput::{{closure}} 22: <std::thread::local::LocalKey<T::with 23: rustc::ty::context::TyCtxt::createandenter 24: rustcdriver::driver::compileinput 25: rustcdriver::runcompilerwithpool 26: <scopedtls::ScopedKey<T::set 27: rustcdriver::runcompiler 28: syntax::withglobals 29: rustmaybecatchpanic at 30: <F as alloc::boxed::FnBox<A::callbox 31: std::sys::unix::thread::Thread::new::threadstart at at at 32: <unknown33: clone query stack during panic: end of query stack error: internal compiler error: unexpected panic note: the compiler unexpectedly panicked. this is a bug. note: we would appreciate a bug report: note: rustc 1.34.0-nightly ( 2019-02-26) running on x86_64-unknown-linux-gnu note: compiler flags: -Z mir-opt-level=2 -C debuginfo=2 -C incremental --crate-type lib </pre</code</details
With the help of , I've found a tiny test that reproduces this crash on Linux and Mac:
Got another one: <details</detailsHappens when compiling regex tests with and calling on every span found in the mir of the functions needing codegen.
According to glaicer, the ICE from this example has been gone.
can you confirm that your example does not crash on nightly anymore?


Question: <ins> #![feature(fn_traits, unboxed_closures)] fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} struct Compose<F,G>(F,G); impl<T,F,G> FnOnce<(T,)> for Compose<F,G> where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { type Output = G::Output; extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { (self.1)((self.0)(x)) } } fn bad<T>(f: fn(&'static str) -> T) { test(Compose(f, |_| {})); //~ ERROR: mismatched types } fn main() {} </ins>

Has been fixed in
is likely the part of the rollup fixing it.
Shouldn't a testcase be instead of closing this?
A similar crash that still happens:


Question: <ins> #![feature(fn_traits, unboxed_closures)] fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} struct Compose<F,G>(F,G); impl<T,F,G> FnOnce<(T,)> for Compose<F,G> where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { type Output = G::Output; extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { (self.1)((self.0)(x)) } } fn bad<T>(f: fn(&'static str) -> T) { test(Compose(f, |_| {})); //~ ERROR: mismatched types } fn main() {} </ins>

I realize it's kinda nonsensical, but here:
Why didn't WF catch this?
That's because only checks statics/constants.
Still reproducible with .
This ought to be a mostly easy fix. The problem is that the well formedness check, which ought to be rejected this code, is ignoring things in an : They fall through to this `` case: We would need to add support for the HIR item: which in turn has a number of items: which are defined here: presumably we want the to check that the types of are well-formed, roughly analogous to how we current check normal static items: (We probably want similar checks on foreign item fns, though?) One tricky part might be compatibility, we may need to turn this into a compatibility lint in case there is lots of broken code in the wild.
I am trying to fix this bug, and need help moving forward. function is modified to accept a and a , yet it doesn't report any additional errors and the ICE prevails. Test file: Commit: Should I create a pull request or is it too early?
Looks like suggestions are incomplete ( does not require ). Also, I left a comment on your commit about how you can avoid adding . I suspect the only reason regular s are required to be is they have an initializer (and that, not the type, requires ), i.e. for we have these errors:
Oddly, the PR that were previously posted to fix this (PR , following on PR ) was subsequently closed as inactive ... but the bug itself seems like it may have been resolved in the meantime?
I'm going to assume this was fixed. Tagging as E-needstest, but if someone wants to take the time, it'd be even better to bisect to where this was fixed, and see if a regression test for this was at that time.
Compiler no longer panics, tested with


Question: /// A type that allows convenient usage of a UDP stream connected to one /// address via the `Reader` and `Writer` traits. <ins> /// /// # Note /// /// This structure has been deprecated because `Reader` is a stream-oriented API but UDP /// is a packet-oriented protocol. Every `Reader` method will read a whole packet and /// throw all superfluous bytes away so that they are no longer available for further /// method calls. #[deprecated] </ins> pub struct UdpStream { socket: UdpSocket, connected_to: SocketAddr

change this to something more appropriate. This was introduced in commit when still returned . This should either block until a message from the correct sender arrives or return an error.


Question: continue; } <ins> // HACK: `async fn() -> Self` in traits is "ok"... // This is not really that great, but it's similar to why the `-> Self` // return type is well-formed in traits even when `Self` isn't sized. if let ty::Param(param_ty) = *proj_term.kind() && param_ty.name == kw::SelfUpper && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(_)) && opaque.in_trait { continue; } </ins> let proj_ty = Ty::new_projection(cx.tcx, proj.projection_ty.def_id, proj.projection_ty.args); // For every instance of the projection type in the bounds,

When using the flag, I stumbled upon a warning that I don't understand and assume to be a bug/missed implementation. If this is the intended behavior, could anyone please explain why? This is simplified code that generates the warning: But when adding a type restriction on self (in this case Sized)_ the warning does not appear anymore. <!-- 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. --:
This is in fact a bug.
Update: This issue is still present, and has now sneaked into stable with the release of ; as such I'm updating the title to reflect that.
This is similar to the bug report
This isn't the same bug. This just has to do with a false warning of the lint.
on this, also encountering this bug
Also encountering with


Question: // panicking thread consumes at least 2 bytes of address space. static GLOBAL_PANIC_COUNT: AtomicUsize = AtomicUsize::new(0); <ins> // Return the state of the ALWAYS_ABORT_FLAG and number of panics. // // If ALWAYS_ABORT_FLAG is not set, the number is determined on a per-thread // base (stored in LOCAL_PANIC_COUNT), i.e. it is the amount of recursive calls // of the calling thread. // If ALWAYS_ABORT_FLAG is set, the number equals the *global* number of panic // calls. See above why LOCAL_PANIC_COUNT is not used. </ins> pub fn increase() -> (bool, usize) { <del> ( GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed) & ALWAYS_ABORT_FLAG != 0, </del> <ins> let global_count = GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed); let must_abort = global_count & ALWAYS_ABORT_FLAG != 0; let panics = if must_abort { global_count & !ALWAYS_ABORT_FLAG } else { </ins> LOCAL_PANIC_COUNT.with(|c| { let next = c.get() + 1; c.set(next); next <del> }), ) </del> <ins> }) }; (must_abort, panics) </ins> } pub fn decrease() {

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I am trying to fix it so that Rust's stdlib prevents unwinding, or allocating, in the child, after a fork on Unix (including in ). That is . (Allocation after fork of a multithreaded program is UB in several libcs.) I a new test case, Unfortunately this test fails, but just on Android: I have few good theories as to why. I wrote some speculations: I think this probably needs attention from an Android expert to try to repro and fix this issue. I suspect it's a problem with the library rather than the tests. The worst case is that it might be a general UB bug in Android Rust programs using or . I'm filing this issue here to try to ask for help again, since writing in doesn't seem like a particularly good way of getting the attention of Android folks. If we can't get a resolution, reluctantly, I guess I will disable that test on Android so that my MR can go through. The current situation is quite a hazard (see eg "panic! in Command child forked from non-main thread results in exit status 0") I will try to explain what the test does and what the symptoms seem to mean: The test file has a custom global allocator, whose purpose is to spot allocations in the child after fork. That global allocator has an atomic variable which is supposed to contain either zero (initially, meaning it's not engaged yet) or the process's pid. Whenever an allocator method is called, we read the atomic and, if it is not zero, we check it against . If it doesn't match we <strike</strike. The test enters , and engages the stunt allocator, recording the program's pid. Each call to (which is called from and therefore from ) produces output from . We see only one of these, so this must be the first test, . The test uses to fork. In the child, it calls (my new function to disable panic unwinding). It then panics (using the provided closure). This ought to result in the program dying with (or maybe or ). The parent collects the child's exit status. For the first test case, we run .


Question: // panicking thread consumes at least 2 bytes of address space. static GLOBAL_PANIC_COUNT: AtomicUsize = AtomicUsize::new(0); <ins> // Return the state of the ALWAYS_ABORT_FLAG and number of panics. // // If ALWAYS_ABORT_FLAG is not set, the number is determined on a per-thread // base (stored in LOCAL_PANIC_COUNT), i.e. it is the amount of recursive calls // of the calling thread. // If ALWAYS_ABORT_FLAG is set, the number equals the *global* number of panic // calls. See above why LOCAL_PANIC_COUNT is not used. </ins> pub fn increase() -> (bool, usize) { <del> ( GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed) & ALWAYS_ABORT_FLAG != 0, </del> <ins> let global_count = GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed); let must_abort = global_count & ALWAYS_ABORT_FLAG != 0; let panics = if must_abort { global_count & !ALWAYS_ABORT_FLAG } else { </ins> LOCAL_PANIC_COUNT.with(|c| { let next = c.get() + 1; c.set(next); next <del> }), ) </del> <ins> }) }; (must_abort, panics) </ins> } pub fn decrease() {

This extracts the signal number from it and checks that it is as expected. On other systems this works. In the failing test, this test fails. The assertion on fails. Meaning, the child did die of a signal but the signal number wasn't the one expected. The previous debug print shows that the raw wait status (confusingly described by Rust stdlib as an "exit status") is <strike</strike. Usually, a bare number like that in a wait status is a signal number, and indeed that seems to be the case here since is . On Linux (and most Unices), is and 10 is . Ie, it seems that the child tried to allocate memory, despite my efforts to make sure that panicking does not involve allocation. Weirdly, a more-portable test case which uses and does not insist on specific signal numbers passes. It's definitely my stunt allocator which is tripping here, because when I changed it to use instead of , the failing test case signal number changed too.
modify labels +O-android +T-libs-impl
<strike provided an explanation here I still think there is a bug here but it is not Android-specific. I have a WIP branch to try to address it, so I think it's probably best if I close this issue and submit that as an MR when it's ready.</strike
My first guesses were right. In where I changed the stunt allocator to use , we see this:
I found a memory allocation with a patched Miri: With this code:
Apparently, the thread locals aren't working as expected. I think the child after fork is being treated as a new thread, and then the thread local storage has to be re-created. I think the surviving thread in the fork should inherit all the thread-locals from the forking thread in the parent.
But I just tested the code after , so there's no "new thread" or "parent" here...
Oh! Yes. You are right. Evidently the first use of this thread-local allocates. Presumably that would happen on a new thread as well as on the initial thread. Having panic rely on thread-locals, and thread-locals rely on the allocator, seems unfortunate. Having panic allocate is not good, especially when actually it's just trying to abort precisely to avoid this.


Question: // panicking thread consumes at least 2 bytes of address space. static GLOBAL_PANIC_COUNT: AtomicUsize = AtomicUsize::new(0); <ins> // Return the state of the ALWAYS_ABORT_FLAG and number of panics. // // If ALWAYS_ABORT_FLAG is not set, the number is determined on a per-thread // base (stored in LOCAL_PANIC_COUNT), i.e. it is the amount of recursive calls // of the calling thread. // If ALWAYS_ABORT_FLAG is set, the number equals the *global* number of panic // calls. See above why LOCAL_PANIC_COUNT is not used. </ins> pub fn increase() -> (bool, usize) { <del> ( GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed) & ALWAYS_ABORT_FLAG != 0, </del> <ins> let global_count = GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed); let must_abort = global_count & ALWAYS_ABORT_FLAG != 0; let panics = if must_abort { global_count & !ALWAYS_ABORT_FLAG } else { </ins> LOCAL_PANIC_COUNT.with(|c| { let next = c.get() + 1; c.set(next); next <del> }), ) </del> <ins> }) }; (must_abort, panics) </ins> } pub fn decrease() {

Since is stored in which is not a thread-local, maybe the program could abort before using any thread-local.
It can't do that and also print the payload, because printing the payload might itself panic, and the recursive panic needs to be detected.
Maybe instead there should be a which can return None to mean "this thread-local variable has not been initialised".
I think it might be possible to use a to avoid the allocation.
Do thread-local always avoid the allocation? I think they fall back to regular thread-locals on platforms where avoiding allocations is not (easily) possible.
The version of looks basically same as the non- version when using , which will likely allocate here: Maybe the panic count could be stored directly in rather than on the heap. But is itself safe after ? If it tries to hold a lock or something it's possible to deadlock.
Should this only occur on Android? It happened on QNX as well (not yet upstreamed, work in progress so I don't trust it yet), but I can also reproduce it on with a simple patch (disables thread local storage): Would this be a target spec where we would expect to succeed?
Interesting. To be honest, I'm not sure. I do know that modern libc doctrine is that allocation after fork is UB. The test case is checking that we can safely panic after fork, and abort, without UB. This ought to work due to . I think that every failure of this test case is a real bug. Solving those bugs is not so easy because the machinery inside panic uses thread-local state which apparently is really super hard to make work without allocating or taking locks.
Yes, allocating memory is UB, same as working with mutexes. In case our setups are okay (i.e. having and using fork etc.), I also see this is a bug. Maybe we don't need to fix the issue with the thread-local state (if at all possible): calls to get the number recursive panics and if we . : determines using --works determines number recursive panics using TLS --allocates after --UB first: If it is true, it will always call -- the process will be killed very very soon by the OS In case of a recursion, a hardcoded-string is printed; otherwise additionally Do we really need to correctly determine a recursion, or can we allow "false positives"?


Question: // panicking thread consumes at least 2 bytes of address space. static GLOBAL_PANIC_COUNT: AtomicUsize = AtomicUsize::new(0); <ins> // Return the state of the ALWAYS_ABORT_FLAG and number of panics. // // If ALWAYS_ABORT_FLAG is not set, the number is determined on a per-thread // base (stored in LOCAL_PANIC_COUNT), i.e. it is the amount of recursive calls // of the calling thread. // If ALWAYS_ABORT_FLAG is set, the number equals the *global* number of panic // calls. See above why LOCAL_PANIC_COUNT is not used. </ins> pub fn increase() -> (bool, usize) { <del> ( GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed) & ALWAYS_ABORT_FLAG != 0, </del> <ins> let global_count = GLOBAL_PANIC_COUNT.fetch_add(1, Ordering::Relaxed); let must_abort = global_count & ALWAYS_ABORT_FLAG != 0; let panics = if must_abort { global_count & !ALWAYS_ABORT_FLAG } else { </ins> LOCAL_PANIC_COUNT.with(|c| { let next = c.get() + 1; c.set(next); next <del> }), ) </del> <ins> }) }; (must_abort, panics) </ins> } pub fn decrease() {

Instead of having UB, I think it would be fine to only check the number of overall current panics calls (as stored in ignoring ). If it is higher than 2, assume we have a recursion (results in false positives in case two or more threads panic at the same time). ==In case we have two panics going on in parallel by two threads there is the chance that we don't output , but it prevents UB. Also, when one thread calls it will often happen that the second thread will be killed soon and outputs nothing at all. In other cases (only one thread panics), there should be no difference. A change could look like that (high probability I've missed something!): This change passes all tests of for targets and QNX on AArch64.
Would you please try to test the fix above to check if it solves the issue on Android as well?
On most Unix it's UB to touch TLS after fork. Even if we have static TLS, accessing it might cause [^1] to be be called, and that function has paths where it allocates memory, takes locks, etc. That is, this is probably not a specific issue with QNX/Android. [^1]: At least on ELF, although I believe this is broadly true for Mach-O as well.


Question: <ins> error[E0644]: closure/coroutine type that references itself --> $DIR/cyclic_type_ice.rs:3:7 | LL |     f(f); |       ^ cyclic type of infinite size | = note: closures cannot capture themselves or take themselves as argument; this error may be the result of a recent compiler bug-fix, see issue #46062 <https://github.com/rust-lang/rust/issues/46062> for more information error[E0057]: this function takes 2 arguments but 1 argument was supplied --> $DIR/cyclic_type_ice.rs:3:5 | LL |     f(f); |     ^--- an argument is missing | note: closure defined here --> $DIR/cyclic_type_ice.rs:2:13 | LL |     let f = |_, _| (); |             ^^^^^^ help: provide the argument | LL |     f(/*  */, /*  */); |      ~~~~~~~~~~~~~~~~ error: aborting due to 2 previous errors Some errors have detailed explanations: E0057, E0644. For more information about an error, try `rustc --explain E0057`. </ins>

<!-- ICE: Rustc '' 'thread 'rustc' panicked at 'assertion failed: errors.isempty()'', 'thread 'rustc' panicked at 'assertion failed: errors.isempty()'' File: --auto-reduced (treereduce-rust): original: Version information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: [typeck] type-checking [analysis] running analysis passes on this crate --
cc


Question: "concatenates all document attributes into one document attribute"), ("strip-private", passes::strip_private, "strips all private items from a crate which cannot be seen externally"), <ins> ("strip-priv-imports", passes::strip_priv_imports, "strips all private import statements (`use`, `extern crate`) from a crate"), </ins> ]; const DEFAULT_PASSES: &'static [&'static str] = &[

Rustdoc defaults to only documented things that are public, i.e. things that the user of a library would care about. This is a good default, but rustdoc can also be useful to people working on large crates by documenting these crates themselves. In that case, it’s preferable to also include private types, fields, functions, and methods. was about this use case, and was closed with this solution: We just tried this on . It’s better than before, but has the unexpected side effect that every item (including non- and the implicit prelude) and every (including the implicit ) is documented under “Reexports”. It can get pretty noisy: ! They’re technically part of the crate, but don’t provide useful information. Could rustdoc split up the pass into one that strips private and , and one for everything else?


Question: <ins> # only-linux # ignore-32bit -include ../tools.mk all: $(RUSTC) eh_frame-terminator.rs $(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788' objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator' </ins>

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


Question: <ins> # only-linux # ignore-32bit -include ../tools.mk all: $(RUSTC) eh_frame-terminator.rs $(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788' objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator' </ins>

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


Question: <ins> # only-linux # ignore-32bit -include ../tools.mk all: $(RUSTC) eh_frame-terminator.rs $(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788' objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator' </ins>

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


Question: <ins> # only-linux # ignore-32bit -include ../tools.mk all: $(RUSTC) eh_frame-terminator.rs $(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788' objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator' </ins>

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


Question: <ins> # only-linux # ignore-32bit -include ../tools.mk all: $(RUSTC) eh_frame-terminator.rs $(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788' objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator' </ins>

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


Question: <ins> # only-linux # ignore-32bit -include ../tools.mk all: $(RUSTC) eh_frame-terminator.rs $(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788' objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator' </ins>

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


Question: <ins> # only-linux # ignore-32bit -include ../tools.mk all: $(RUSTC) eh_frame-terminator.rs $(call RUN,eh_frame-terminator) | $(CGREP) '1122334455667788' objdump --dwarf=frames $(TMPDIR)/eh_frame-terminator | $(CGREP) 'ZERO terminator' </ins>

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


Question: <ins> // check-fail // dont-check-compiler-stdout // dont-check-compiler-stderr fn�a<e>(){fn�p(){e}} //~ ERROR unknown start of token: u{fffd} //~^ ERROR unknown start of token: u{fffd} //~^^ ERROR can't use generic parameters from outer function [E0401] //~^^^ WARN type parameter `e` should have an upper camel case name fn main(){} </ins>

I'm seeing an internal compiler error on the following input, found by : The ICE happens after correctly reporting the error "unknown start of token", so low priority. I guess that one part of the code treats as whitespace, while another part of the code treats it as not whitespace, causing a logic error with this input. Affected versions: nightly 2022-02-26 and beta 1.60.0-beta1 are affected, but stable 1.59.0 does not ICE. <details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Fixed by , different enough to the test that I'll mark as needs-test. But anybody feel free to close this if we don't generally add fuzzed inputs to tests


Question: <ins> error[E0308]: mismatched types --> $DIR/suggest-call-on-pat-mismatch.rs:7:12 | LL |     if let E::One(var1, var2) = var { |            ^^^^^^^^^^^^^^^^^^   --- this expression has type `fn(i32, i32) -> E {E::One}` |            | |            expected enum constructor, found `E` | = note: expected enum constructor `fn(i32, i32) -> E {E::One}` found enum `E` help: use parentheses to construct this tuple variant | LL |     if let E::One(var1, var2) = var(/* i32 */, /* i32 */) { |                                    ++++++++++++++++++++++ error[E0308]: mismatched types --> $DIR/suggest-call-on-pat-mismatch.rs:13:9 | LL |     let Some(x) = Some; |         ^^^^^^^   ---- this expression has type `fn(_) -> Option<_> {Option::<_>::Some}` |         | |         expected enum constructor, found `Option<_>` | = note: expected enum constructor `fn(_) -> Option<_> {Option::<_>::Some}` found enum `Option<_>` help: use parentheses to construct this tuple variant | LL |     let Some(x) = Some(/* value */); |                       +++++++++++++ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should suggest to the user that they need to initialize the enum variant's value in order to use the . <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. The output might also be different depending on the Edition. --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Can you give the output of what it should look like?
It should probably look similar to the suggestion given for and So I guess sth. like: Edit: Or instead of saying “to instantiate this tuple variant” we could say “to call this function” like it's done for the erroneous snippet (where is a ).
claim
commit the fix


Question: /// /// [`to_ascii_uppercase()`]: #method.to_ascii_uppercase #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] <del> #[rustc_const_unstable(feature = "const_make_ascii", issue = "130698")] </del> <ins> #[rustc_const_stable(feature = "const_make_ascii", since = "CURRENT_RUSTC_VERSION")] </ins> #[inline] <ins> #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))] </ins> pub const fn make_ascii_uppercase(&mut self) { *self = self.to_ascii_uppercase(); }

Feature gate: This is a tracking issue for marking the and methods in , , , and as "const." [x] Implementation for : [x] Implementation for : [x] Implementation for and : [x] Final comment period (FCP) [x] Stabilization PRNone yet.
fcp merge / have been stable in const since 1.52. / are unblocked now by the stabilization of
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.
Can the methods be included in this? Similarly const stable / since 1.52.
Yes, that sounds like a good idea. I'll try adding another PR later.
:bell: This is now entering its final comment period, as per the . :bell:
stabilises this.
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: > { after_tail: usize, after_head: usize, <del> iter: Iter<'a, T>, </del> <ins> ring: NonNull<[T]>, tail: usize, head: usize, </ins> deque: NonNull<VecDeque<T, A>>, <ins> _phantom: PhantomData<&'a T>, </ins> } impl<'a, T, A: Allocator> Drain<'a, T, A> { pub(super) unsafe fn new( after_tail: usize, after_head: usize, <del> iter: Iter<'a, T>, </del> <ins> ring: &'a [MaybeUninit<T>], tail: usize, head: usize, </ins> deque: NonNull<VecDeque<T, A>>, ) -> Self { <del> Drain { after_tail, after_head, iter, deque } </del> <ins> let ring = unsafe { NonNull::new_unchecked(ring as *const [MaybeUninit<T>] as *mut _) }; Drain { after_tail, after_head, ring, tail, head, deque, _phantom: PhantomData } </ins> } }

liballoc's fails when run in Miri. The error occurs in the call: is called with a as argument. contains contains a shared reference to a slice; that slice is thus marked as "must not be mutated for the entire duration of this function call". calls calls calls calls , which eventually drops the . calls to re-arrange stuff (I have not fully understood this yet), and in some cases this will end up writing to memory that the slice in points to. I am not sure what the best way to fix this is. We have to fix holding (indirectly) a shared reference to something that it'll mutate during its . The mutation is likely there for a reason, so I guess the shared reference has to go. (FWIW, this shared reference already caused other trouble, but that was fixed by ) Cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
yeah I guess just change it to and toss in a PhantomData for the borrow. shrug
You mean, change this in as well? Sure, that should work. In principle this reduces the precision of compiler analyses on .
ahh misread. maybe would just not use Iter then. depends on what the impl looks like now
But the first thing it does is which should exhaust the such that its is an empty slice. I suppose its pointer will still be somewhere in the deque's memory, but with length 0 it can't actually read anything. Is that not good enough to appease Miri?
No. This code still matches the pattern There is no notion of "exhausting" or "consuming" a shared reference. When you create a shared reference with a certain lifetime, you promise that until that lifetime ends, no mutation happens. here is mutable so you can change what the slice points to, but that has no effect at all on the guarantees that have been made about the value that was initially passed to . Now, lifetimes are an entirely static concept, so for Stacked Borrows a "lifetime" generally is "until the pointer is used for the last time".


Question: > { after_tail: usize, after_head: usize, <del> iter: Iter<'a, T>, </del> <ins> ring: NonNull<[T]>, tail: usize, head: usize, </ins> deque: NonNull<VecDeque<T, A>>, <ins> _phantom: PhantomData<&'a T>, </ins> } impl<'a, T, A: Allocator> Drain<'a, T, A> { pub(super) unsafe fn new( after_tail: usize, after_head: usize, <del> iter: Iter<'a, T>, </del> <ins> ring: &'a [MaybeUninit<T>], tail: usize, head: usize, </ins> deque: NonNull<VecDeque<T, A>>, ) -> Self { <del> Drain { after_tail, after_head, iter, deque } </del> <ins> let ring = unsafe { NonNull::new_unchecked(ring as *const [MaybeUninit<T>] as *mut _) }; Drain { after_tail, after_head, ring, tail, head, deque, _phantom: PhantomData } </ins> } }

However, for the special case of a reference being passed to a function, Stacked Borrows asserts that the "lifetime" will last at least as long as the function the reference is pointed to. (This is enforced by the "barriers" explained .) This is extremely useful for optimizations.
forward to . I wouldn't want to copy those.
Oh, I also didn't realize that doesn't actually shrink down to an empty slice -- it only updates its indexes. It would otherwise have to use two slices for the wrapped head and tail. So that full shared reference does still exist after the iterator is exhausted. (This also raises the validity question of having references to uninitialized data.) Could we base on instead? We could arrange to work through that mutable reference too, so there's no question of mutable aliasing.
That might work. However, must not access in that case -- that would be in conflict with the unique reference in .
Hmm, does need to be covariant over ? I guess would break that.
Actually this idea of "consuming a shared ref" is far from unique to ... the following code also errors in Miri:
As I understand it, Miri and stacked borrows should be "more powerful" than the Rust borrow checker, right? So, is this an example where Miri does not match what Rust allows or is this a bug in Rust that could lead to undefined behaviour in safe code? ()
-- I believe is admitting that example as something that should be allowed. But this issue with involves raw pointers, which rustc doesn't check at all, so miri is in uncharted waters here.
This is up for us all to decide. I can't tell you. ;) Not necessary. I have argued that / are problematic long before Stacked Borrows. The lifetimes there are, strictly speaking, wrong. I think it would be reasonable to rule that they have to use raw pointers.
FWIW here is a stand-alone version of the testcase to reproduce this with Miri (but it needs access to some private internals):
See for the issue about whether Stacked Borrows should allow such code or not. For now, with , Miri accepts this code again. So I am going to close the issue here. It still represents an interesting data point to inform what Stacked Borrows rules should be.


Question: > { after_tail: usize, after_head: usize, <del> iter: Iter<'a, T>, </del> <ins> ring: NonNull<[T]>, tail: usize, head: usize, </ins> deque: NonNull<VecDeque<T, A>>, <ins> _phantom: PhantomData<&'a T>, </ins> } impl<'a, T, A: Allocator> Drain<'a, T, A> { pub(super) unsafe fn new( after_tail: usize, after_head: usize, <del> iter: Iter<'a, T>, </del> <ins> ring: &'a [MaybeUninit<T>], tail: usize, head: usize, </ins> deque: NonNull<VecDeque<T, A>>, ) -> Self { <del> Drain { after_tail, after_head, iter, deque } </del> <ins> let ring = unsafe { NonNull::new_unchecked(ring as *const [MaybeUninit<T>] as *mut _) }; Drain { after_tail, after_head, ring, tail, head, deque, _phantom: PhantomData } </ins> } }

nods wisely just gotta stand still long enough for the spec to bend around you
;-) I don't think the decision is made either way, but for now with several counterexamples in libstd, it is not helpful for Miri to complain about this. Plus, this matches what we formalized in Coq; the basic optimizations that we considered so far are all fine with this change.
See there actually is a bug here right now, because we do emit for passed to a function. So what Miri found is actually UB in the LLVM IR that we are generating right now. Reopening for now, but maybe it makes more sense to treat this as a duplicate of
Smaller reproduction that I found in (a now closed dupe of this issue) that doesn't rely on VecDeque internals, that fails now with
re-enables the part of Stacked Borrows that got disabled (in parts) to work around the issue, before I knew that we actually have here and are risking real miscompilations.
claim


Question: use crate::io::ErrorKind; use crate::str; <del> // FIXME(#10380) these tests should not all be ignored on android. </del> <ins> #[cfg(target_os = "android")] fn shell_cmd() -> Command { Command::new("/system/bin/sh") } #[cfg(not(target_os = "android"))] fn shell_cmd() -> Command { Command::new("/bin/sh") } </ins> #[test] <del> #[cfg_attr(any(target_os = "vxworks", target_os = "android"), ignore)] </del> <ins> #[cfg_attr(any(target_os = "vxworks"), ignore)] </ins> fn smoke() { let p = if cfg!(target_os = "windows") { Command::new("cmd").args(&["/C", "exit 0"]).spawn() } else { <del> Command::new("true").spawn() </del> <ins> shell_cmd().arg("-c").arg("true").spawn() </ins> }; assert!(p.is_ok()); let mut p = p.unwrap();

To enable test on android bot and test/run-pass/rtio- It looks to me RtioProcess does not work properly on android.
logs are
Hm this may be an FFI issue with libuv. I realized during my uv rewrite that libuv is giving us an int64t exit status and we think it's a cint. Once lands this may be fixed.
Hmm, this issue number has propagated to several more tests that are cfg-disabled on android. (Some of which are now failing when I mixed in a Boehm/BDW conservative GC into the runtime, in particular .)
Also, has landed, so it would be good to determine if these tests now work on Android.
Triage: I have no idea how to test this, but a lot has changed in a year (especially the removal of green & libuv), so these may be magically fixed; if someone can check.
Triage: is gone, but all these tests in are still ignored for android.
I tried to run these tests with but they all failed with , which seems suspect (at least for the tests that invoke , , , etc.). Is there a better way to test? I have an android device available.


Question: LL | | /// Some docs. LL | | ...  | <del> LL | |     pub fn bar() {} </del> <ins> LL | |     } </ins> LL | | } | |_^ |

The lint seems to be erroneously complaining about missing documentation examples where local types implement foreign traits (both from 3rd party crates and the standard library). The example below should pass all checks as far as I can tell: However, running results in the following warnings: :
cc
I think the current lint behavior is correct. The issue here is on the core lib side. I opened to fix it.
Maybe the lint shouldn't warn when implementing a foreign trait? By the same rationale as
Hmmm... I have shared feelings here: if a trait doesn't provided documentation "by default", doesn't it make sense to complain about it on the implementors?
I guess if you can add docs on the implementation it makes sense - you have a way to fix it.
That's mainly my position yes. :)
Unfortunately, that drags with itself more issues. First of all, I have to implement said examples on all of the implementations I write. Second, I have to copy (and correctly maintain said copy) the original example-less documentation onto every instance so that it's not lost by the language server and/or . While this isn't entirely impossible, it's a huge chore, especially when you implement multiple traits on tens of types at a time. While could get its issues fixed, that hardly helps us with the rest of the crate ecosystem. As of now, I have about 300 warnings, and actually useful information just drowns in that flood.
You can disable the lint on a specific implementation in the worst case. However, the goal is to enforce more documentation through the ecosystem. If users start to complain about it to the crates' maintainers, I'm pretty sure the situation will improve pretty quickly.
I don't really like this approach - it should be fixable by you, not by bugging upstream maintainers. was saying something like that for I think.
You can fix it on your side by adding the examples yourself in your implementation. So on that on point, even if not the best, it's still possible.
I suppose in the worst case, I could fork the upstream project, add examples, and hope that it either gets merged or the developer doesn't cause too many conflicts so I can keep it up-to-date.


Question: LL | | /// Some docs. LL | | ...  | <del> LL | |     pub fn bar() {} </del> <ins> LL | |     } </ins> LL | | } | |_^ |

But even then, it takes a lot of back-and-forth, a lot of time and effort on both ends to get from my linter complaining about missing examples to a new crate release that fixes it - even if everything goes quick and smooth. There should at least be a way for me to temporarily ignore warnings coming from (or rather because of) 3rd party and standard library crates, so that - at the minimum - I can fix my own linting issues without having to comb through thousands of lines of all too similar lines of warnings every time I generate documentation for testing purposes.
on the implementation?
Like I said, you can ignore the lint on the implementations, or directly on a module if it only contains such cases. Adding a doesn't seem to be such a burden...
Let it be known that I was today days old when I learned that you can apply to a single block. I suppose that will have to suffice for now.
I strongly feel that we should not warn on foreign trait implementations here. Firstly, as said, a lint should be fixable by you. Yes, you can add examples yourself, but that isn't actually the real fix here in most cases. In most cases trait implementations are lightweight and you rarely document them, so you're not actually giving the user a "fix", you're asking them to do something they don't actually want to shut the lint up. That's not good, that is not the actual fix, the actual fix is asking people to fix it upstream, and we should not lint that downstream. "The lint can be ignored" is not good enough for normal situations -- if it was some weird confluence of situations, then, sure, but a foreign trait impl is an extremely normal thing to do.
Coming back on this after a while and I now agree with this issue: we shouldn't lint on foreign trait implementations. I'll send a fix in the following days.
I just tried locally and it seems like this issue has already been fixed. Closing it then.
we should still test that it behaves properly
I'll send a test if there isn't already one then.


Question: <ins> // check-pass // Regression test for issue #55099 // Tests that we don't incorrectly consider a lifetime to part // of the concrete type #![feature(type_alias_impl_trait)] trait Future { } struct AndThen<F>(F); impl<F> Future for AndThen<F> { } struct Foo<'a> { x: &'a mut (), } type F = impl Future; impl<'a> Foo<'a> { fn reply(&mut self) -> F { AndThen(|| ()) } } fn main() {} </ins>

Consider the following code (): This code doesn't compile because that all type parameters are in scope for the concrete type. This get fixed eventually, but for the time being, we can work around it using (rust-lang/rfcs; ): However, this pattern does not compose. This example fails to compile (): with the error I'm not entirely sure why this fails, but it seems like the code should be accepted? /cc
Or a somewhat simpler example with just a single existential ():
Maybe also tag with since it's related to existentials? And possibly (or is this terretority?)
Replacing with compiles fine.


Question: <del> Subproject commit 20da8f45c601d0eec8af8c0897abd536ad57951f </del> <ins> Subproject commit 71be6f62fa920c0bd10cdf3a29aeb8c6719a8075 </ins>

Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool rls no longer builds. A follow-up PR to the repository is needed to fix the fallout. cc do you think you would have time to do the follow-up work? If so, that would be great! cc the PR reviewer, and -- nominating for prioritization.
I'll make an update pr once the two prs currently in the clippy ci queue are merged
triage: P-medium. Removing nomination tag.


Question: <ins> warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe --> $DIR/repr-transparent-issue-87496.rs:8:18 | LL |     fn good17(p: TransparentCustomZst); |                  ^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: `#[warn(improper_ctypes)]` on by default = note: this struct contains only zero-sized fields note: the type is defined here --> $DIR/repr-transparent-issue-87496.rs:6:1 | LL | struct TransparentCustomZst(()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
modify labels: regression-from-stable-to-nightly Regressed in cc
Hmm, I don't think this is actually a regression. The MCVE triggers an error on stable and beta: and it seems like the requirements for were relaxed by such that this code should compile successfully on nightly.
Sorry, I forgot to re-check this issue before opening my PR. You can have a look at to avoid duplicate work, if it's not too late already...
Assigning priority as discussed in the of the Prioritization Working Group. label -I-prioritize +P-low


Question: | NonMutatingUseContext::Copy | NonMutatingUseContext::Inspect | NonMutatingUseContext::Move <ins> | NonMutatingUseContext::PlaceMention </ins> | NonMutatingUseContext::ShallowBorrow | NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::UniqueBorrow,

<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: You need edition 2015 or 2018 to reproduce this. `
Looks to me like the problem is that doesn't realize that a makes the place not dead.
The bug is . is a nonuse, but should get the same treatment as a . I feel obligated to mention that I have repeatedly warned that these bugs are going to happen. We should really stop using in optimizations. It was written for borrowck. (To be clear: I am as much at fault for this as anyone, I originally wrote this code).
I was wondering why always has strangely unhelpful information for optimizations...
Why is this not just a bug in PlaceContext assignment?
See my comment in the PR - in general, my understanding is that the definition of placecontext is what it is because that's what makes sense in some other part of the compiler. If we start changing placecontext now to have the information that's useful to optimizations, I worry we'll just end up making those parts of the compiler buggy


Question: // Check whether a span corresponding to a range expression is a // range literal, rather than an explicit struct or `new()` call. fn is_lit(sm: &SourceMap, span: &Span) -> bool { <del> let end_point = sm.end_point(*span); if let Ok(end_string) = sm.span_to_snippet(end_point) { !(end_string.ends_with('}') || end_string.ends_with(')')) } else { false } </del> <ins> sm.span_to_snippet(*span).map(|range_src| range_src.contains("..")).unwrap_or(false) </ins> }; match expr.kind {

Hi there! With this code (here's a ) The compiler reports this error message with a hint but the hint is incorrect due to missing parantheses in this case. The correct answer would be It works correctly when the second line in main is executed, where the range is provided directly. : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim


Question: // @has blanket_with_local.json "$.index[*][?(@.name=='Load')]" pub trait Load { <ins> // @has - "$.index[*][?(@.name=='load')]" </ins> fn load() {} <ins> // @has - "$.index[*][?(@.name=='write')]" fn write(self) {} </ins> } impl<P> Load for P { fn load() {} <ins> fn write(self) {} </ins> } // @has - "$.index[*][?(@.name=='Wrapper')]"

Interesingly, and shockingly If you remove and , this doesn't panic. <details<summaryWhats up with the diff? </summaryThe assetion format is differnt to usual as I've patch rustc with to make it readable, but this can also be repoduced with the latest nightly </details modify labels: +A-rustdoc-json +T-rustdoc
MCVE: One has while the other has - I bet one is going through HIR and the other is going through metadata, that could explain why the generic parameter matters.
I have a similar MCVE generated from , but the only item that differs in the assertion is the visibility: The left has a visibility of , and the right has a visibility of . A similar MCVE, with as a parameter, has as an input for the right side, but not for the left (and the / visibility issue):


Question: <ins> // Copyright 2015 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. pub fn main() { let command = "a"; match command { "foo" => println!("foo"), _     => println!("{}", command), } } </ins>

Hi, The rust optimiser or some other component is not behaving correctly resulting in wrong results. I have produced a small example here : This was reproduced on Mac yosemite: cargo 0.0.1-pre-nightly ( 2015-01-30 02:47:30 +0000) rustc 1.0.0-nightly ( 2015-02-03 14:56:32 +0000) and centos7 x64, rustc 1.0.0-nightly ( 2015-02-05 23:14:28 +0000) Please let me know if you need any more details.
Reduced test case: This segfaults with = 2 (on Linux x86-64, )
This goes back to at least 0.12 - though it prints garbage values instead of segfaulting. 0.11 seems unaffected.
I've done some hacky . I'm not seeing the original data in the IR. cc Is this another memcpy metadata bug? Or a lifetime intrinsic issue. EDIT: turns out , which is used here, calls on its arguments, as if it was certain they were temporaries that didn't outlive the call (which is wrong, in this case). Not sure if needs to create a temporary for the value it's trying to compare with a constant, or the lifetime intrinsic calls shouldn't be emitted for .
This has two parts. When I extended rustc to emit lifetime intrinsics, I chose to put a call to at the end of functions to mark arguments as dead that are passed by value on the stack. This allows LLVM to remove dead stores at the end of functions that it normally can't remove. This works because normally, the caller makes a copy of the value it passes in. Now, the call that match generates to compare the strings is to , which accepts two slices by-value, and slices are large enough to be passed on the stack. Thus, calls to are emitted. But, the call the match generates does not actually make copies of the slices, but passes in pointers to the original slices. That means that the call marks the original alloca as dead, and then things fall apart. Question: Do we want to drop the call for by-value on-stack arguments, or fix the call to eqslice to make copies? cc
just-a-bug; P-high, not 1.0 milestone.


Question: <ins> // Copyright 2015 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. #![crate_type = "lib"] #[macro_export] macro_rules! declare { () => ( pub fn aaa() {} pub mod bbb { use super::aaa; pub fn ccc() { aaa(); } } ) } </ins>

Macro definitions encoded to the metadata do not preserve the identifier style, thus certain paths break down.
Nice catch. I was afraid something like this would happen... Really a bug in pretty printing, as it doesn't preserve the ident style. This is what we get for hacking contextual lexer information into the token stream...
The original example now compiles fine, but then I'm not sure about tomaka/android-rs-glue. is this issue still relevant?
I didn't test myself, but reported that it's fixed.
Yeah it looks like this has been fixed, yay!


Question: } else if #[cfg(target_os = "hermit")] { #[path = "hermit.rs"] mod real_imp; <del> } else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] { #[path = "dummy.rs"] mod real_imp; </del> } else if #[cfg(target_env = "msvc")] { #[path = "seh.rs"] mod real_imp;

The and targets force panic=abort. said : This looks related to , which points at these now-merged LLVM changes: It's possible that we do not need to force panic=abort anymore for arm64 Windows as a result. What's the best way to determine if this is still required?
Theoretically the way to fix this issue is: First Next, run the build Finally, run the tests If that all passes, then the change can land! The tests may be able to be skipped, and some tests may fail, so it may be possible to switch the defaults and we can fixup bugs later. I don't personally have hardware to test these changes on myself, though.
I occasionally have access to a Windows arm64 laptop, so I'll try and get a rustc build going on it at some point.


Question: documentation: ~~~ <del> #[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png", </del> <ins> #[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", </ins> html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://static.rust-lang.org/doc/master")]; ~~~

It's currently very bright and distracting (IMO). (Sorry :( ) Current scheme, for future triage/comparison purposes: !
I think I should reconsider my career in graphic design.
I'm looking at this.
(The relevant file is , if you're lost. :) )
BTW I was wondering, why not just use for src line numbering? Probably more optimized/idiomatic in the browser.
Also, it's pretty much impossible to have consistency between rustdoc and the old codemirror (tutorial) since both parsers behave very differently. would it be possible to pass the standalone documentation through rustdoc?
Doesn't this mean every line is a new tag? Also, it possibly screws with copy-paste and making the formatting consistent. This bug is specifically about the colour scheme of rustdoc since it's so wild. Also, about using rustdoc for everything.
My preference for the highlighting scheme is bold for keywords, green for macros, red for strings (the current color is fine), gray for comments (would be nice if code within comments were highlighted). I'd also like to hear more suggestions before we change it.
Something I hacked up a few days ago: ! (The macro colour wasn't "optimised" at all.)
No, it would look like this: I think it would be better to use that since that's the browser native numberings. No it doesn't. The identifier of a list aren't inlined with the content. is an example.
Oh, awesome. It does seem like a good idea, if you can get that to work.
Another note: current rustdoc parsing could be improved, i.e. the "ident" class corresponds to variable names, function names, paths, parameters... could be more split if you ask me.
The highlighting is performed by just by the token types the lexer (with a little bit of extra logic for attributes, macros and $ non-terminals in macros) and so does not have that information.


Question: <ins> error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:3:1 | LL | #[rustc_layout_scalar_valid_range_start(u32::MAX)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:6:1 | LL | #[rustc_layout_scalar_valid_range_end(1, 2)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:9:1 | LL | #[rustc_layout_scalar_valid_range_end(a = "a")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute should be applied to a struct --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:12:1 | LL |   #[rustc_layout_scalar_valid_range_end(1)] |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | / enum E { LL | |     X = 1, LL | |     Y = 14, LL | | } | |_- not a struct error: aborting due to 4 previous errors </ins>

<!-- Thank you for finding an Internal Compiler Error! If possible, try to provide a minimal verifiable example. You can read "Rust Bug Minimization Patterns" for how to create smaller examples. --<!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
This isn't really a bug, it's just that it has bad diagnostics because it uses , which is a perma-unstable attribute. I would recommend against reporting bugs that need attributes unless they cause unsoundness.
MCVE:
Should I exclude all test programs that have a line starting with ? Thanks.
I don't personally feel comfortable setting a policy that we'll never fix ICEs with attributes, but they are definitely less likely to be bugs than other ICEs. Note that this isn't sufficient to catch programs that have an attribute, you can have arbitrary macros that play with conditional compilation, like . Catching and will probably hit the common cases, though (you may want to also include inner attributes).


Question: <ins> error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:3:1 | LL | #[rustc_layout_scalar_valid_range_start(u32::MAX)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:6:1 | LL | #[rustc_layout_scalar_valid_range_end(1, 2)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: expected exactly one integer literal argument --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:9:1 | LL | #[rustc_layout_scalar_valid_range_end(a = "a")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: attribute should be applied to a struct --> $DIR/invalid_rustc_layout_scalar_valid_range.rs:12:1 | LL |   #[rustc_layout_scalar_valid_range_end(1)] |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | / enum E { LL | |     X = 1, LL | |     Y = 14, LL | | } | |_- not a struct error: aborting due to 4 previous errors </ins>

Gives:
cc ICE-ing instead of user error on misuse seems somewhat okay given that it's an internal attribute, IMO.
agreed. We don't protect against mis-use of rustc internal attributes beyond making sure that you can't trivially create buggy code. I don't think we should put any effort into making this nicer to use and instead create the const-generic based replacement.


Question: pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>, macro_def_scopes: FxHashMap<Mark, DefId>, expansions: FxHashMap<DefIndex, Mark>, <del> keys_created: FxHashSet<DefKey>, </del> <ins> next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>, </ins> } // Unfortunately we have to provide a manual impl of Clone because of the

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


Question: pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>, macro_def_scopes: FxHashMap<Mark, DefId>, expansions: FxHashMap<DefIndex, Mark>, <del> keys_created: FxHashSet<DefKey>, </del> <ins> next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>, </ins> } // Unfortunately we have to provide a manual impl of Clone because of the

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


Question: pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>, macro_def_scopes: FxHashMap<Mark, DefId>, expansions: FxHashMap<DefIndex, Mark>, <del> keys_created: FxHashSet<DefKey>, </del> <ins> next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>, </ins> } // Unfortunately we have to provide a manual impl of Clone because of the

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


Question: <ins> // compile-pass #[deny(warnings)] enum Empty { } trait Bar<T> {} impl Bar<Empty> for () {} fn boo() -> impl Bar<Empty> {} fn main() { boo(); } </ins>

The following code gives "warning: enum is never used: ": This regressed pretty recently. cc
27.0 does not warn, 1.28.0 does.
triage: P-medium; This seems like a papercut that should be easy to work-around (at least if one isn't using ...).
switched to P-high after prompting from
whoops forgot to tag with T-compiler in time for the meeting...
assigning to
I'm grabbing this, I think I broke it and it should be easy to fix


Question: } Some(BacktraceStyle::Off) => { if FIRST_PANIC.swap(false, Ordering::SeqCst) { <del> if let Some(path) = path { let _ = writeln!( err, "note: a backtrace for this error was stored at `{}`", path.display(), ); } else { let _ = writeln!( err, "note: run with `RUST_BACKTRACE=1` environment variable to display a  </del> <ins> let _ = writeln!( err, "note: run with `RUST_BACKTRACE=1` environment variable to display a  </ins> backtrace" <del> ); } </del> <ins> ); </ins> } } // If backtraces aren't supported or are forced-off, do nothing.

slightly increased default binary size (checked on x8664-pc-windows-msvc), the reason is now code unconditionally includes File::open (~ 2kb out of 130) and friends. can be tracked back by new imports of , for where is Originally posted by in
cc
cc -- I'm surprised that didn't include any libs review in the first place, having modified the default panic hook. Maybe ought to be registering its own panic hook instead?
Size changed back to 123kb.


Question: "x86_64-pc-windows-gnu", ]; <del> static TOOLSTATE: &str = "https://raw.githubusercontent.com/rust-lang-nursery/rust-toolstate/master/history/linux.tsv"; </del> #[derive(Serialize)] #[serde(rename_all = "kebab-case")] struct Manifest {

Seems like no nightly was released today. That might be related to Unfortunately I don't think I have access to the logs. Cc
Logs are missing on the server, let me start a manual release...
Well that is odd. You wouldn't know what commit is is using? ( file in the tarball, if I recall correctly.)
Is there a way for me to download the "dist" artifacts for better testing? Right now I am manually grabbing a bunch of files from https://s3-us-west- (and we only get dir listing for alt builds there it seems so I am using those). That's not very convenient at all.
Apparently not all commits are pushed to toolstate ( vs ), for example the latest one () is missing in toolstate .
Reverting the cause in the meantime --
Alternatively we could land which will just skip of the toolstate is not found. That installs a toolchain based on these artifacts, but I don't think it gives me access to the tarballs. FTR, for now I did So we are only committing when the toolstate changed? Ouch. That kills my entire approach :(
It should print the URLs it's downloading though, and you can use to avoid it actually downloading stuff.


Question: <ins> # Rustdoc in-doc settings Rustdoc's HTML output includes a settings menu, and this chapter describes what each setting in this menu does. It can be accessed by clicking on the gear button (<i class="fa fa-cog" aria-hidden="true"></i>) in the upper right. ## Changing displayed theme It is possible to change the theme. If you pick the "system preference", you will be able to see two new sub-menus: "Preferred light theme" and "Preferred dark theme". It means that if your system preference is set to "light", then rustdoc will use the theme you selected in "Preferred light theme". ## Auto-hide item contents for large items If the type definition contains more than 12 items, and this setting is enabled, it'll collapse them by default. You can see them by clicking on the `[+]` button to expand them. A good example of this setting in use can be seen in the [`Iterator`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) doc page: ![Collapsed long item](../images/collapsed-long-item.png) ## Auto-hide item methods' documentation If enabled, this setting will collapse all trait implementations blocks. It is convenient if you just want an overview of all the methods available. You can still see a method's documentation by expanding it. ## Auto-hide trait implementation documentation If enabled, this setting will collapse all trait implementations blocks (you can see them in the "Trait Implementations" section). It is convenient if you just want an overview of all the trait implemented on a type. You can still see a trait implementation's associated items by expanding it. Example: ![Collapsed trait implementations](../images/collapsed-trait-impls.png) ## Directly go to item in search if there is only one result If this setting is enabled, you will directly be taken to the result page if your search only returned one element. Useful if you know exactly what you're looking for and want to be taken there directly and not waste time selecting the only search result. ## Show line numbers on code examples If enabled, this setting will add line numbers to the code examples in the documentation. It provides a visual aide for the code reading. ## Disable keyboard shortcuts If this setting is enabled, the keyboard shortcuts will be disabled. It's useful in case some of these shortcuts are already used by a web extension you're using. To see the full list of the rustdoc keyboard shortcuts, you can open the help menu (the button with the question mark on the left of the setting menu button). </ins>

Rustdoc has accumulated a handful of settings that users can toggle as they read docs, but we don't document them anywhere. It would be ideal if we had some documentation about these options in the Rustdoc Book that described their functionality better than the short descriptions shown on the settings page itself. !
I don't mind picking this up, unless you want to do this yourself! I do however have some questions!: The Rustdoc book you mean is right? Do you suggest adding a new section to this book or would you include it in an already existing section? What do you believe is not clear / elaborated enough in the short descriptions? I do not know the specific details of each switch are there any side-effects that are not in the short description?
Triage: no changes. The rustdoc book is that one, ! I am not a rustdoc maintainer these days (cc ) but I would probably make a new section. While the short description is good, I think it would make sense to show the options in slightly more detail, for example, maybe a before/after.
Bit of a late reply :) Do you have something to add to this? Otherwise I will follow what Steve said!