a programming language that I am working on, and the VM is written in Rust. Up until Rust nightly 2018-08-17, everything works fine. Starting with the nightly from the 17th, I'm observing various crashes and different program behaviour. For example: On Windows it will either fail with a , or (more on this in a moment). On Linux . Note that the funny segfault output is because the command is started with Ruby, and Ruby installs its own segmentation fault handler. Locally it will usually fail with the same runtime error as observed in Windows above, but sometimes it will segfault. Sometimes it will panic because certain operations are performed using NULL pointers where this is not expected. The last nightly that did not suffer from these problems was Rust 2018-08-16. Stable Rust also works fine. When the segmentation faults happen, they are usually in different places. For example, for one segmentation fault the backtrace is as follows: 0x00007ffff7e12763 in intmalloc () from 0x00007ffff7e13ada in malloc () from 0x0000555555568e6b in alloc::alloc::alloc (layout=...) at <libinko::chunk::Chunk<T::new (capacity=3) at libinko::register::Register::new (amount=3) at libinko::executioncontext::ExecutionContext::fromblock (block=0x7fffdc0971e0, returnregister=Some = {...}) at libinko::vm::machine::Machine::run (self=<optimized out, process=<optimized out) at 0x0000555555568b7f in libinko::vm::machine::Machine::runwitherrorhandling (self=0x55555567d8c0, process=0x7ffff75fcbd0) at 0x00005555555c88a4 in libinko::vm::machine::Machine::startprimarythreads::{{closure}} (process=...) at <libinko::pool::PoolInner<T::process (self=<optimized out, index=0, closure=0x7ffff75fcc60) at 0x00005555555b739d in <libinko::pool::Pool<T::run::{{closure}} () at std::syscommon::backtrace::rustbeginshortbacktrace (f=...) at 0x00005555555cb0dc in std::thread::Builder::spawn::{{closure}}::{{closure}} () at <std::panic::AssertUnwindSafe<Fas core::ops::function::FnOnce<()::callonce (self=..., args=<optimized out) at std::panicking::try::docall (data=<optimized out) at 0x0000555555618a3a in rustmaybecatchpanic () at 0x00005555555ba39b in std::panicking::try (f=...) at std::panic::catchunwind (f=...) at std::thread::Builder::spawn::{{closure}} () at <F as alloc::boxed::FnBox<A::callbox (self=0x55555567db50, args=<optimized out) at 0x00005555556090db in LTdynLTCOutputRu20u20aGTasLTGT::callonce::h904fcd0dbdc71d4f () at std::syscommon::thread::startthread () at 0x00005555555f83b6 in std::sys::unix::thread::Thread::new::threadstart () at 0x00007ffff7f73a9d in startthread () from 0x00007ffff7e89a43 in clone () from While for another segfault the backtrace is instead: libinko::runtimepanic::displaypanic (process=0x7f, message="ObjectValue::asblock() called on a non block object") at 0x0000555555568baa in libinko::vm::machine::Machine::panic (self=0x55555567d8c0, process=0x7ffff71f8bd0, message="") at libinko::vm::machine::Machine::runwitherrorhandling (self=0x55555567d8c0, process=0x7ffff71f8bd0) at 0x00005555555c88a4 in libinko::vm::machine::Machine::startprimarythreads::{{closure}} (process=...) at <libinko::pool::PoolInner<T::process (self=<optimized out, index=4, closure=0x7ffff71f8c60) at 0x00005555555b739d in <libinko::pool::Pool<T::run::{{closure}} () at std::syscommon::backtrace::rustbeginshortbacktrace (f=...) at 0x00005555555cb0dc in std::thread::Builder::spawn::{{closure}}::{{closure}} () at <std::panic::AssertUnwindSafe<Fas core::ops::function::FnOnce<()::callonce (self=..., args=<optimized out) at std::panicking::try::docall (data=<optimized out) at 0x0000555555618a3a in rustmaybecatchpanic () at 0x00005555555ba39b in std::panicking::try (f=...) at std::panic::catchunwind (f=...) at std::thread::Builder::spawn::{{closure}} () at <F as alloc::boxed::FnBox<A::callbox (self=0x55555567e5d0, args=<optimized out) at 0x00005555556090db in LTdynLTCOutputRu20u20aGTasLTGT::callonce::h904fcd0dbdc71d4f () at std::syscommon::thread::startthread () at 0x00005555555f83b6 in std::sys::unix::thread::Thread::new::threadstart () at 0x00007ffff7f73a9d in startthread () from 0x00007ffff7e89a43 in clone () from And a third segfault: 0x0000555555568d84 in libinko::vm::machine::Machine::run (self=<optimized out, process=<optimized out) at 0x0000555555568b7f in libinko::vm::machine::Machine::runwitherrorhandling (self=0x55555567d8c0, process=0x7ffff6cf3bd0) at 0x00005555555c88a4 in libinko::vm::machine::Machine::startprimarythreads::{{closure}} (process=...) at <libinko::pool::PoolInner<T::process (self=<optimized out, index=10, closure=0x7ffff6cf3c60) at 0x00005555555b739d in <libinko::pool::Pool<T::run::{{closure}} () at std::syscommon::backtrace::rustbeginshortbacktrace (f=...) at 0x00005555555cb0dc in std::thread::Builder::spawn::{{closure}}::{{closure}} () at <std::panic::AssertUnwindSafe<Fas core::ops::function::FnOnce<()::callonce (self=..., args=<optimized out) at std::panicking::try::docall (data=<optimized out) at 0x0000555555618a3a in rustmaybecatchpanic () at 0x00005555555ba39b in std::panicking::try (f=...) at std::panic::catchunwind (f=...) at std::thread::Builder::spawn::{{closure}} () at <F as alloc::boxed::FnBox<A::callbox (self=0x55555567f590, args=<optimized out) at 0x00005555556090db in LTdynLTCOutputRu20u20aGTasLTGT::callonce::h904fcd0dbdc71d4f () at std::syscommon::thread::startthread () at 0x00005555555f83b6 in std::sys::unix::thread::Thread::new::threadstart () at 0x00007ffff7f73a9d in startthread () from 0x00007ffff7e89a43 in clone () from In case of the last segfault, it seems certain local variables that are used are NULL pointers, when this should be impossible. Debugging this in GDB proves to be quite difficult, as a variety of variables are reported as <optimized outeven when debugging symbols are included. For example, for the last backtrace the output of "info locals" is: The VM test suite passes, even when running . I'm wondering if perhaps code is optimised in the wrong way, and this is somehow not triggered in the test suite (certainly possible, code coverage is not 100%). Reproducing this is a bit weird. If we leave the code as-is, the segmentation faults rarely occur, instead the VM panics with the following: Stack trace (the most recent call comes last): 0: "", line 324, in "<block" 1: "", line 281, in "<lambda" 2: "", line 220, in "run" Process 1 panicked: ObjectValue::as_block() called on a non block object However, if we apply the following patch things will start to segfault really quick: Note that the last command requires Ruby 2.3 or newer. This will run the test suite of the standard library, which is where all the crashes happen rather frequently (probably because they run much more than the VM's own test suite).
There's a lot of questionable unsafe code in that project. For example, should really be marked as (same goes for . It's very likely that the cause of the issue is preexisting UB due to misuse of .
Simply marking functions as to my knowledge doesn't influence the compiler's code generation. Many of the unsafe operations are safe in practise, as they will only fail if (for example) the input bytecode is invalid. Tagging them as does nothing but make the code significantly more verbose. The various operations in the bytecode parser are there to convert sequences of bytes into particular types. To the best of my knowledge there is no stable way of converting a into say a , requiring you to use instead. The closest is but this: nightly the platform's endianness, instead of allowing you to specify which to use.
Yes, but marking a function as requires all call sites to opt into that unsafety, and the functions I mentioned all assume that their arguments are valid (and cause UB if not). This additional constraint on the arguments is expressed by marking the function and documenting the safety constraints. Check out the crate.
This wouldn't achieve much, as a lot would have to be marked unsafe as VMs and GCs inherently perform many operations Rust may consider unsafe. There are a few cases where I want to get rid of more risky code (e.g. the borrowing of you highlighted), but all of this feels rather offtopic since it's very project specific. I avoided it in the past because it also just used , so it didn't feel like much of an improvement. It appears this is no longer the case, so I'll take another look.
To better understand what is going on I dumped the MIR output using and (2018-08-18). After replacing a bunch of SHA hashes with placeholders (to reduce diff noise), I ended up with the exact same MIR before and after. Next I'll try LLVM IR.
It appears the LLVM IR uses a different order for things when using the different nightly versions. This generates a lot of diff noise, so I'm not sure how useful this information will be. I tried to clean it up a bit by replacing various SHA hashes with placeholders, but even then there is a lot of noise.
The ASM output was a bit easier to clean up, but there are still lots of differences. To be exact, reports: Again this is probably because of ordering. The new version has 99 lines more, but I'm really not sure if that's expected or not.
Using I found that nightly-2018-08-19 is the first version that introduces the regression, while nightly-2018-08-18 works fine. The commits included into the 18th nightly can be found at (if I got things right at least).
This hints at , which can change the behaviour of any latent UB, or , since your project uses in a few places.
I don't fully understand the first mentioned PR. What would I need to do to verify if that has any impact? For the second one, I'll see if I can somehow get my code to use a version of from before that PR, to see if it affects anything.
A custom version of probably isn't going to work. For example, I'm using Rayon which only implements its traits for the default :<
I ended up replacing all my uses of with to test if the VecDeque changes are to blame. I used LinkedList because its API is closest to VecDeque, making it easier to test things. When using LinkedList, my code runs fine. This suggests that the changes in may have somehow broken things. cc
The first PR changes details about the generated code that is passed to LLVM. In fact, it just removes unneeded information. The easiest way to check if it's at fault is to manually build the compiler from with the PR reverted. If the problem stops happening, it's at fault (or more likely, UB in your code is). It would also be helpful if you could reduce the code as much as possible so that we can get a few hundred line example that shows the issue.
Specifically, the patch I applied is:
I narrowed this down to the following file being broken by the changes: If I switch back to for this file, my code breaks. There are two possibilities here: was a bug before in my code that only somehow didn't get triggered before VecDeque changes themselves break things The Mailbox data structure has multiple threads accessing it concurrently. This is synchronised using a mutex of type (provided by parking_lot). The structure is broken up into essentially two parts: a synchronised external part, and an unsynchronised internal part. The internal part is only used by a single thread, while multiple threads can compete for the external part. For this reason the mutex is separate, so we don't need to synchronise both. Edit: I forgot, this is synchronised earlier on, preventing concurrent writes. I'll see if I can refactor this code a bit so it's safer, that way we can at least rule out my own code being the problem (or not).
Upon closer inspection, the VecDeque changes specifically affect , and I happen to use that in my Mailbox structure. Specifically, I have the following: I don't remember why this is using since is also a , probably I wrote this when not paying attention. Regardless, changing this to doesn't make any difference regarding the errors. Next I changed this code to the following: This is based on the old implementation of , which was: This then produces output like: This is a bit odd considering the implementation is the same as before, but at least now part of the program is running.
There was another place where I relied on . After also replacing that with the pattern my code now runs fine again, both on nightly and stable Rust. This suggests the failure is definitely due to the changes made to . Now to see if I can get this in a standalone example.
Good news: Thanks to the great investigation of and I think I found the reason for the segfault: the new calls which unsoundly creates mutable slices to uninitialized memory. I will try to send a fixing PR tomorrow.
Aha, thanks! I was looking at the code to see how I might be able to trigger this problem, but I hadn't made my way to just yet. Looking at the code, I'm not sure exactly how to trigger this reliably.
That could be it, nice find!
The problem AFAIK is that this function is triggering Undefined Behavior, and so can cause the program to segfault randomly, and so it may be difficult to reproduce it reliably.
I can verify that this is because of my PR. Minimal example that segfaults for me: And the reason for the segfault is apparent when run with simpler types This will print and continue in such a loop forever, printing the buffer over and over again. This happens because of line hitting an edge case when that causes head to be placed outside of the buffer. This can be fixed by changing that line to I think that is the only thing that is causing these segfaults.


here is the example: this example will compile well if you remove
Backtrace: `
Hmm I reproduced same ICE with next snippet without :
Smaller repro: Edit: AFAICT the problem is the existential assoc type is being made dependent on the type parameter of the trait method ('s in this repro, 's in the OP). So it would be a compile error if it weren't for the ICE.
compiles without ICE.
sorry it needs to be feature or used 2018 edition. Here is complete one which fails to compile regardless feature:
Right, 2015 doesn't hit the error until you actually try to use the type. Regardless, as I said in my previous comment, this code should be a compile error anyway regardless of edition, since it's trying to declare an associated type that depends on the type parameters of the trait method rather than the trait.
hey have you had a chance to look into this yet? Do you think you will be looking at it in the near term, or should we unassign you?
Removed my assignment. Unfortunately I'm running behind on the not-time-critical issues I assigned to myself.
Discussed in T-compiler meeting. This is a blocker for the existential type feature. But there is no schedule yet set for stabilizing that feature. Thus, downgrading fixing this to P-medium.
This no longer produces an ICE on the latest nightly.
Yes, it was fixed by


This takes a while to compile. I presume because needs to hit the loop checker in miri. Changing the foofoo&(loop{}, 1).1'staticlifetime. () Errors:
The following code times out with either borrow checker:
The reason that foo matters is because of
I don't think this is an NLL issue in particular?
Based on 's identification of a test that reproduces the issue on either borrow-checker, I am going to remove the A-NLL label.
That example is not problematic, because nothing is promoted at all. I now don't even think my example is problematic anymore, because it seems to be perfectly alright to promote anything if we diverge before we give the user access to the value. I guess this just needs a test now (just a ui test with a comment, not a run-pass test, as that would hang forever)
Can I work on this? I'm a newbie to rust.
Sure! You can take the example from the issue message and create a new file in and add the comment at the top. Then, when running it should succeed to run the tests.


No matter what kind of const eval features we add, we should never allow this. Even if we managed to allow this, I think the current impl would ICE. Even if it does not ICE, it could never actually modify the memory. We should ensure that the following code always errors.
Hi , I would like to work on this if that's ok. I'm a new Rustacean and I'm learning rustc development and testing. It's time to get my feet wet
Great! I think the following steps should suffice, but don't hesitate to ask if anything is unclear or doesn't work as expected the test in a new file in a annotation to the line that should report an error (replace "error message here" with the relevant error message) 3 until everything is green your test and the generated file and open a PR to the PR message so when it gets merged this issue gets closed automatically
Hi , When I was running the test in step 3, or compiled the new test with nightly rustc (rust-lang/rust I got errors like this. error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants --mod-static-with-const- | 24 | () = 5; | ^^^^^^^^^^^ error[E0658]: statements in statics are unstable (see issue ) --mod-static-with-const- | 24 | () = 5; | ^^^^^^^^^^^^^^^^ | = help: add #![feature(constlet)] to the crate attributes to enable error: aborting due to 2 previous errors I think E0015 is the expected error. But I'm not sure about E0658. It seems that the constlet feature is not stabilized yet. (But compiling doesn't return this error.) Could you please help with this problem? Thanks a lot.
These errors are fine. the idea of this issue is to just make sure the code always fails to compile. More errors are fine, too. the const let feature has a bug where even enabling it will still report it. that's not problematic for this issue. Can you add a comment to the test mentioning that this test should never ever succeed? If you want you can additionally try to minimize the test to something still emitting the feature gate error even though the feature gate is active (and maybe to something that should be perfectly fine at compile time). then open a new issue about that.
Thanks ! I will try to reproduce the unexpected error related to the feature gate. Meanwhile it seems that this task will be blocked by that issue since the ui test will fail if the error signature doesn't match with the expected one. Is that right?
you can just make them match ;) Add all the annotations you need to make the test pass. Whenever someone changes your test, because they fixed other bugs or implemented new features, they'll hopefully look at the comment about the fact that the test should never succeed to compile.


This also occurs with etc. Changing requires only the reverse dependencies of to be recompiled. is also recompiled. As you can see, this takes twice as much as compiling the reverse dependencies of alone, leading to compilation being 3x slower.


Discovered in it turns out that our vendored copies of these libraires cause problems when they override the system versions by accident. We should rename our copies with a Rust-specific name to avoid this name clash.


std::io::Seek I got confused by this line and over on so after a little discussion it seems like this might be better wording for those of us who are silly A seek beyond the end of a stream is allowed, but it is implementation-defined. The hyphen makes it clear “implementation defined” is a known concept (and matches it’s usage elsewhere) and the “it is” makes it a bit more clear that the full sentence is considered and intentional. While normally I find brevity improves clarity, in this case if you don’t realize “implementation defined” is a single concept, it sounds like a thought that trailed off after an edit
Thanks I know other projects I've worked with have Easy and Documentation as tags so I wasn't sure if you guys might do the same
Yep, they're just actual labels over on the right ;-) (I also tabbed away and forgot to put the easy label on immediately )
Don't worry about that! It's very easy for developers to misjudge whether such descriptions will make sense to the target users. Pointing these things out is a great way to contribute to documentation.


Compiling code like: results in: presumably because attempts to translate it into an x86-specific ABI, which the AArch64 backend rightly rejects. already ignores for non-x86 targets: I'm not completely sure what the right answer for Rust is. I think is the rough equivalent of the above clang bit and needs to take a few more cases into account for non-x86 Windows: does that sound right? If so, I'll code up a patch.
Sounds like a good place to me!


Because LLVM doesn't know what is, we currently , relying on the  function. So if the current CPU's family is Haswell, we convert to . As noticed and , some Intel Pentiums belong to the Haswell microarch, but they lack AVX. <hr/Here are the flags Clang generates for : Not only does it set the right for optimization purposes, it actually manually enables / disables all the features available / not available on the host. This ensures no matter what the microarch is, only available features will be used. <hr/We should probably use the . I think this issue will supersede both rust-lang/rust and rust-lang/rust. If we can fix this, we will never generate code with unavailable target features. Reproducing these errors is pretty hard, unless you have a machine with a Haswell Intel Pentium. I think it might be possible to reproduce this in QEMU with
Alternatively, we could also use the macros to do this. I'll work on this.
To add another example, doesn't detect the feature on broadwell (see ).
I submitted a PR for a


Rust version: How to reproduce: Error:
Minimized reproduction:
I'd like to work on this.


That is, appears to lose incremental artifacts. cc
Yes, I believe this is because rustc/cargo will otherwise error on "found a new std" or something like that? I don't quite see how incremental is different from the normal compilation here?
incremental would still work even if dependencies changed. I think the fundamental problem here is that deletes everything, whereas (which, IIRC, does not remove incremental artifacts by default) would be appropriate.
Hm, I thought was equivalent to essentially -- could you clarify that? Would it be better to use cargo clean in rustbuild?
Regardless of what does I don't think we should execute it here. Rustbuild is overly conservative in what it deletes, and it can get away probably with just deleting the folder instead of the entire folder. That would leave around the incremental cache. I believe, however, that is like
Maybe the benchmarks I remember having for incremental had the incremental dir elsewhere than . I sure was confused by it, since I'd expect to remove all artifacts. If it does do that, then I agree should just remove a subset of the contents of target dirs.
Looking at the code, these calls appear to be relevant: The problem is that the directory refers to is non-trivially structured. Instead of removing , we need to remove all the files (or at least the ones that are artifacts) and the directory in .
I keep hitting this, specifically it keeps rebuilding and , every time I change rustc, which cause them to take much longer than any of the rustc crates, and this issue has become my main bottleneck (now that I'm building on a machine).
Nominating for discussion (specifically, allocating resources towards this) at the next relevant team meeting (tagged both and as I'm not sure which has "jurisdiction" here).
It'd be helpful to know how much rustbuild can "trust" the compiler here. Can we keep incremental artifact directories around from previous versions of the compiler?
The compiler can only work with incremental artifacts that it created itself. For any other version of the compiler it has to assume that it's incompatible. It usually just ignores such incompatible artifacts, but in the bootstrapping scenario, it might not always be smart enough to do that.
I think the question here is will rustc's incremental artifacts correctly deal with crates changing (including adding and removing crates) in the sysroot. If so, we could keep the folder around. Cargo assumes the sysroot is unchanging, which is why we remove the directory in the first place.
Incremental doesn't care about vs , so I'd expect it to be pretty resilient here.
triage: P-medium. (this inefficiency in incremental comp. would be nice to resolve, but is not P-high IMO.)


On rustc 1.31.0-nightly ( 2018-10-07) and x8664-unknown-linux-gnu, we see the following surprising behavior: In release mode it seems the write has not happened in the place that it should. Mentioning threadlocal tracking issue: .
Ah, apparently this is missing a . With the behavior is correct. We need to make sure mutating a thread_local static that does not have does not compile.
cc Did fix this by any chance?
It looks like this is fixed on nightly; I'm guessing is the reason. We probably should add some regression tests for the cases listed here.


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


Regression from 1.26.0 to 1.27.0 and later. See for example See also and


Hi, I noticed a weird internal error using . The smallest example I could make to reproduce the bug is an basic library project () whose contains: , , and all work fine; and as mentioned in the code, the place where is declared seems to matter. Here is the output and trace of : [log was from an out of date nightly rust, see my comment below for the log for the latest nightly as of this edit] Have a nice day.
My bad, I appear to have accidentally used a version of rust that wasn't up to date. The bug still occurs in the latest nightly, here's the backtrace: Sorry again about that.
It looks like is only checking for explicit negative impls at the very beginning, and not throughout the process. I should have a fix for this later today.
Looks like this error has been there the whole time that synthetic impls have been there - that sample fails all the way back to 1.26.0.


We're incorrectly suggesting wrapping with when it won't help: It should be suggesting using using instead.
Duplicate of . Let me commit to submitting a fix for this on (or, less likely, before) Sunday the twenty-eighth (hopefully preserving the -wrapping suggestion in the cases where it is correct, but if we have to scrap the whole suggestion, we will; false-positives are pretty bad)


Hi, I'm not sure if this has been reported or is known at all. If it has feel free to close it out. This example: causes an ICE on rustc 1.31.0-nightly ( 2018-10-25) This is the error I'm getting, backtrace included:
Okay, the good news here is that I only see this ICE with ; it does not arise with the NLL migration mode being deployed as part of the 2018 edition. See e.g. this .
The code in question is rejected by AST-borrowck. It looks like it is being rejected by NLL as well, and the problem is that we hit an error when trying to generated our diagnostic. Therefore, I'm going to tag this as NLL-sound (since this seems like a case where we want to reject the code in question) and NLL-diagnostics (since the ICE itself is stemming from diagnostics code). And I think I'm going to make it P-high, because 1. ICE's are super annoying and 2. I bet its not hard to fix. But I'm not going to tag it with the Release milestone, because its not something we need to worry about backporting to the beta channel (because it does not arise with NLL migration mode).
actually I'll remove NLL-sound; this isn't a case where NLL is incorrectly accepting the code. Its just incorrectly behaving while generating the diagnostics.


review comments:
I've looked into this some - NLL misses three errors, all of the form u.yu.x`. In each of the three cases, there is a mutable borrow of some field of the union and then a shared borrow of some other field immediately following. The issue seems to be that the mutable borrow is killed straight away as it isn't used later - therefore not causing a conflict with the shared borrow. I'm inclined to think that this is fine - and that NLL is correct in having less errors here. However, we might want to update the test to use the first mutable borrow for each case in order to make the error happen and demonstrate the diagnostic - if this is the case, I've that we can open a PR for that will update the test. cc
I'm inclined to agree that this is an instance where the test was not robust and that we need to add uses of those first mutable borrows.
I've submitted a PR () that makes the test more robust.


I have two crates: Notice that the implementation of contains an . Something is not happy about that. This currently affects Serde trait impls that use a private helper type with a Serde derive, which is a common pattern. The following script reproduces the issue as of rustc 1.31.0-beta.4 ( 2018-11-01) as well as rustc 1.32.0-nightly ( 2018-11-07).
Mentioning who seems to know about extern_prelude.
The issue is caused by entering infinite recursion when trying to print the impl path. If returns and finishes , then this issue should be fixed as well.
(Also, the issue reproduces on 2015 edition as well.)
I'm hitting this on stable 1.32.0 with a , and I confirmed that replacing it with a manual impl works. Is there any other workaround?
Just ran into this on with the serde helper pattern.
Copying <kbdI-nominated</kbdfrom .
pre-triage: P-high. Leaving nominated for discussion at compiler triage meeting tomorrow.
From what I can tell, this was fixed sometime between nightly-2020-01-04 and nightly-2020-01-05. Here's what landed during that time:
I just discovered a detail about this bug that I did not previously appreciate: It needed the invocation (or some similar call to e.g. ) to replicate. The bug as described here ended up being fixed by PR . I suspect that's due to that rollup PR's inclusion of PR , but I have not yet verified this. The question I have remaining: Is the bug here really fixed, or is it merely masked by the changes from PR ? E.g. PR makes heavy revisions to the expansion of ; can one manually write code that emulates the previous expansion, and then replicate the original bug atop that? Anyway, even if the bug here is truly fixed, we should add the code from the description here as a regression test.
It's not fixed, the repro at the top still overflows rustc's stack as of 1.42.0-nightly ( 2020-01-09). We would need to minimize again to get a different minimal repro post-.
Okay I've got a new reproduction now, thanks for the pointer
removing nomination tag since I do not think this needs explicit discussion. However, it should get assignment. I'm not yet sure if I will take it on myself or try to get someone else to investigate it.
For posterity, here's the current backtrace (since the module no longer exists):
The issue is here Removing the check makes the repro case compile successfully, but it degrades some existing test output: an example of the changes: I'll see what can be done.
Just checking, did you see this? I don't remember all the details but I found that comment after looking at the context around the code you linked, which seemed vaguely familiar.
I'd seen that comment, but didn't grok the full meaning of it until I looked at this in more detail. Is there any reason not to change the to be ? is precisely as a way to avoid the problem at hand of unconditional recursion for other cases.
I found this separately in Workaround: add an (or whichever crate) at the root of your crate.
triage: nominating for discussion as part of attempt to burn down set of unassigned P-high issues at an otherwise light triage meeting.
discussed at . Assigning to
just ran into this bug in their GSoC project when adding a trybuild test (). EDIT: Rest of the comment was probably nonsense.
Just to confirm, still there in 1.46.0 (same repro with serde as posted above).
Didn't see this when it was posted, my bad, but I wanted to reply because it's not that simple because that recursion tracking is limited to , but currently, gets in between that, so that you have many independent sets, none of them containing the of the item.
I ran into this as well with while trying to delete based on the status here.


I may have found a bug in the compiler. The entirety of the code to reproduce this bug is this: The program should build successfully, assuming the rustc type checker does not detect any errors at the level of the Rust type system. The rustc type checker seems happy with the program. However, presumably after the LLVM IR generation phase, and during some IR verification phase, I get this type error:
Reduced:
I thought we already fixed that by adding casts. One possible fix that might be less harmful would be to give all types that are subtyping-equivalent the same LLVM type. They should be having the same layout anyway, and their fields should be subtyping-equivalent (because that's what subtyping-equivalence means). The other option would be to insert casts when subtyping is taking place.
This looks like a new instance of . cc
was just an instance of the general problem, we just started generating named types for trait objects then, which made the problem show up in more cases. I agree with first proposal, i.e. destroy the distinction ahead of time. We're only wasting time by inserting casts and LLVM wastes time ignoring those casts (insert rant about how counterproductive LLVM's types are).
Reduced to its essence:
An example that my previous approach will not make compile (but currently gives an ICE outputtypeparametermismatch):
Nah you can do it without an ICE, but you're still within deep ICE territory
This is making me suspect, that when we get higher-ranked type bounds, finding a "canonical form for subtyping" will be impossible (note: don't be so sure. You can't? (shouldn't?) have higher-ranged type bounds in trait objects, so life might be better). Might as well insert casts. Note that my old approach has problems with anonymization in invariant types:
marking this as p-medium as per the
labels +T-types This seems like a problem around higher ranked normalization etc, so we are tagging as T-types. We think it may have been fixed as a side-effect of some LLVM change or other (cc for the details).
Seems to be fixed since 1.23.
Triage: The issue hasn't been fixed actually, at least on CI (CI stderr from ):
That's interesting. It doesn't fail in a playground. Is this a debug assert now or something?
The build says so maybe this is fixed with nighty that uses llvm but llvm 13 still causes problems?
Likely, we could use if so. Is there a CI builder that uses a newer LLVM on bors?
Yeah, this is fixed by LLVM using its opaque pointers, so that's why it's possibly broken on LLVM 13?
Re-submitted a PR with :


The following example ICEs yields (Same is true on stable.)
That's because the ObjectCandidate code is not normalizing the upcast trait refs. Should we wait for Chalk for the fix?
Hitting this error, any updates?
Triage: no longer ICEs.
It's still an ICE, note that we should build/run the snippet to check it ().
Triage: It's no longer ICE with the latest nightly, I think it's fixed by .


reduced from num_cpus: built with yields cc `
What’s the target? Ah, never mind, I missed that its .
More minimal: Issue does not occur on stable (or 1.30.0 nightly), but occurs on rustc beta.
Marking T-libs as that is likely to be an issue within implementation of , but I didn’t investigate further.
Excerpt: Clearly both of those adjacent i32 aren't going to be 8-byte aligned ^^ It seems that we're storing to an key with wrong alignment for some reason.
Don't need to look particularly far, this code generates It looks like some code is assuming that both elements in a scalar pair have the same alignment as the whole pair.
Probably the easiest way to get to the root cause is to bisect.
This code is very likely the culprit: It takes the 0 and 1 GEPs, but uses the same alignment, without offset adjustment.
Ouch, that's bad. To obtain the alignment for both fields, we need to do: Note that we can't use because the components do not match fields (the latter come from the user type definitions, whereas the former are extracted as an optimization).


An showed that removing the dependency from LLVM speed up its test suite by a huge amount. For us libstd doesn't depend on directly but it does depend on which depends on (according to the blog post). Specificaly it looks like , the same function as LLVM, is used by us! It'd be great to investigate removing the shell32 dependency from libstd (may be a few other functions here and there). We should run some tests on Windows to see if this improves rustc cycle times!
Based on my limited investigation, it's likely that replacing with a pure Rust equivalent should be good enough to get rid of the gdi32 dependency in things that only use libstd. So really someone just needs to write that pure Rust implementation which should be easy to do.
It would be nice to get rid of this in the compiler too. We spawn a lot of compiler instances during bootstrapping.
So now that the change has been implemented, have we actually investigated how much of an impact the change made?
Perf, an lolbench are both linux only. So nether help with this question. So don't waste your time like I did.
Here are just number for on 8 cores / 16 threads on Windows 10 v1809: Without the dependency: 333.012 325.587 320.650 With : 310.852 319.165 323.645
For what it's worth, though there's no good way to differentiate PR-to-PR due to very high variance, it does look like there was a recent regression in PR build times: <img width="1409" alt="image" src="https://user-"
I see that the CPU usage averages about 40% when running , so maybe we'd see some real improvements if we got rid of in the compiler too. Something is certainly holding things back.
Yeah, I saw that the compiler doesn't load . So there's probably some other reason why doesn't load all the cores.


The following commands no longer seem to work: With incoming, I just get check-stage2-doc-tutorial'. Stop.` and so on.
Note: the pull request I just filed fixes the targets, but the manual target is , not as you've written in the bug here. I think if the latter used to work, it's stopped working as-intended. The document name is after all.
I got the names from
Sorry, that was fallout from reorganization of
adjusted wiki page


The following buggy code: produces the error: This is usefully documented in TRPL (ch08-02-strings), but that is not easily discoverable from the error. Meanwhile, the error itself is a natural one that programmers from many languages (C, C++, etc) might run into. Speaking as someone who spent some time assuming that the issue was related to slices/references/usize (i.e. various new, Rust-specific concepts), not strings and UTF-8 encoding, I wonder whether a special case might be produced, replacing error E0277, when the types involved are specifically strings/strs and integers. :
We should add a pointing to in the following code of E0277 errors. The example has a similar case to this one, but the additional code should be something along the lines of This will cause an extra to be displayed for this case. Beyond changing the code, you will also need to add a new test case with the repro case above and (running and possibly updating the test comments for any remaining failing tests).
I would like to work on this.
do not hesitate to reach out either here or on if you need help!
Possible proposed output from :


When you download the 0.6 tarball and execute ./configure && make, a download occurs. and a wget info dump appears. It would be really awesome if this piece was integrated with the tarball. Not all environments are friendly to downloading arbitrary code off the net. E.g., I might be in a SCIF[1] and experimenting with Rust on a machine disconnected from the public net. Or I might be on a laptop working in a no-wifi area. :-/ (I know this is probably a real low priority issue, but it IS a (usually minor) hassle) [1]
Please note that you can avoid that if you already have a (compatible) locally installed rust compiler. Check the --local-rust and --local-rust-root parameters for ./configure. Also, I'm against bundling binaries in source tarballs. They are target-dependent and bundling all of them will make the released archive quite large. Downloading an external bootstrapper is a minor issue for downstream packagers too, though. See
far-future
Yeah, you can also just populate the directory in your builddir with an appropriate snapshot tarball. There's not much else we can do here. Putting binaries in a source tarball feels even worse, to me. Closing as I don't expect we're going to much change the requirements here and have several workable workarounds.


As of rustc 1.33.0-nightly ( 2018-12-22) the following macro invocation fails with an ICE. Mentioning and because this may have to do with slicing introduced in . Same repro in script form:
is working on a solution in


This code should be correct, because according to document, all address in are not global reachable. But it panic on assertion failed in latest nightly (2019-01-11) (see )
Relevant thread:
Sorry, fixed


Minimised, reproducible example: See Backtrace
Hello I'm getting the same ICE, but without any unstable features. I don't have a minimized example, though, but it may be another data point when searching for the problem. It's this commit: The commit happens with The code is not correct, it wouldn't compile even if the compiler didn't panic. It doesn't happen on stable, but I guess it's because it bails out sooner on closures taking references:
This still produces an error on the latest nightly (not sure if it's supposed to compile or not), but no longer ICEs.


When building a statically-linked Rust binary crate for the target, linking a crate fails with the following error: Expected result: the crate successfully compiles. Actual result: the crate fails to compile, with an error during the linking stage. Platform: Ubuntu 18.04, x8664. Output of : MUSL standard C library version: 1.1.20. C compiler: MIPS GCC version 7.3, provided by Ubuntu 18.04 (). I tried searching the open and closed issues for this project, and couldn't find any others exhibiting this same error. Forgive me if this is the wrong place to file this bug, but I'm not entirely sure how to debug this problem, so I'm starting here with Rust. The file in makes a call to on big-endian hosts (). This function gets translated into the symbol for the MIPS target, and should be present in the compiler's built-in library, but it appears it's absent here. Now, I can see that uses GCC 5.3 from the OpenWRT toolchain. I'm not entirely sure why this should give any different results from using the GCC 7.3 package provided by Ubuntu 18.04 (, which provides GCC 5.5, and the results are the same (fails to link due to undefined reference to ). Here is the full error message from trying to build the crate: An easy way to reproduce this is to create a with the following contents, and then build it with :
The necessary functions should be to the .
This does look like an interesting idea, but when trying to compile with that crate, I get lots of errors of this sort: You should be able to recreate this by adding the following line to the I mentioned in the original issue, just before the line at the end: I'm currently working on a project that I'd like to keep on the stable channel. Will this crate not work at all on the stable channel?
modify labels: +O-musl
possibly related to
Any updates with this issue? Have the same problem
Adding "-C", "link-args=-lgcc" to re-add libgcc removed by -nostdlib to rustargs fixes the problem, at least for the simple hello world. Or you could implement __bswapsi2 yourself. I'm guessing that openwrt toolchain targets mips32 as opposed of mips32r2, so it requires "libcall" for bswap. Hope it helps.
It works, thanks!


Encountered this when working on test cases for an RFC: cc This seems related to other issues.
I'm confused. Either this was fixed since yesterday's nightly (it still ICEs on nightly but works locally on master), or something really odd is going on
Is that the upstream master? Otherwise maybe someone merged a PR or something..
This still ICEs on nightly.
This now compiles successfully on the latest nightly.


When using this branch of bitflags: through a patch in a local directory rls crashes with the following errors:
i had enabled dev overrides for dependencies in using: removing that out the output from rls is now the normal debug flags but still the same errors:
This is now causing widespread ICEs in the RLS. Nominating to get this fixed (maybe has an idea?). See for a simpler reproducer.
I encountered this issue trying out which causes rustc to crash on when invoked by RLS. I can confirm it's the exact same backtrace as
I ran into this trying out on Windows 10. RLS inside vscode ends up panicking with this backtrace: (note for repro: I had changed the default feature in tui-rs to be "crossterm" because the default feature "termion" doesn't compile on windows - but after the termion compile errors, rustc was giving me a similar panic anyway)
JFYI I could work around this problem by adding to my
I tried that with the tui-rs (it had ) but same panic. [Edit] you're right, I had missed the inside the version.
Thanks !
Running into the same issue when trying to build Clap
Same issue in vscode on linuxmint and rust 1.34.1 when trying to build glib (dependency of gtk).
There is no need to list every crate which depends on , it only clutters the thread and makes less visible.
Here's a small repro, extracted from what is doing: I'm struggling to get a repro without the compile error, though.
Thank you for such a small repro! I’ll take a closer look tomorrow and see what may be causing that. On Tue, 7 May 2019 at 22:32, Sean Gillespie <:
Looks like isn't written back for a resolution error? That still repros without , right?
Correct, it does. Further minimized repro:
Interesting. I managed to reduce it to: with: Any other combination is okay, it has to be under under and it has to be combined with a field access (bare unknown identifier doesn't ICE). I'm only guessing but it seems that it tries to emplace def 'path' under a which seems to skip a def path segment?
I think this is confirmed by A, what I believe is, more accurate guess is that we somehow don't correctly nest appropriate typeck tables when visiting .
Oh, you need to have one table per body: look in HIR for fields and map all of those cases back to the AST. This makes a lot more sense now: so is not wrong, but is looking in the wrong place.
What about this: Seems like we need to before walking the expression of the associated const?
Hm, probably! I imagined the problem is we don't nest it before visiting trait items (hence missing segment) but you may be right! Let's see :sweat_smile:
With the fix applied this still ICEs on (this time for type) which means we should nest tables for as well


With specialization, it is possible to define a default associated type that does not fulfill its trait bounds. Here is a minimal example, that surely should not compile, but does with rustc 1.35.0-nightly: Unsurprisingly, adding the main function causes an ICE. Error message and backtrace (compiled at the playground):
Triage: the latest nightly rejects the code, marking as E-needs-test.


Expected the following code to compile But getting Repro:
Also happens on beta, not on stable
Stable says:
For reference, the function signature as defined is exactly the same.
The actual ICE occurs first in nightly-2019-03-03 (...). But interesting enough, stable (as jonas pointed out) procuces an error, saying, that the third argument must be a constant. Since nightly-2019-02-16 (...) this does not emit an error anymore, but also does not ICE.
I guess for the "does not emit an error anymore" can say something about it. should be responsible for it.
triage: P-high
Note that because of the on the definition, you can't wrap it (without matching on and having 256 separate calls). I don't think this is intentional, but I'm not sure why it would happen, maybe arguments are treated incorrectly in the qualifier. cc
So I agree that this code can't compile, that's the expected behavior; if you want to wrap it, you have to use a macro - Rust functions aren't able to abstract over this type of hardware operations yet. The ICE is a regression over the error message that was being produced before. We should definitely add an ui test for that.
triage, assigning to self to fix the stable-to-beta regression.
The behavior here varies with edition as well as channel. edition 2018 ------------------ ------------------------ stable expected error beta unexpected compile-pass nightly-2019-04-05 ICE I think the most immediate thing to address is the unexpected compile-pass that has leaked into beta.
The easiest thing might be to revert
I have an actual fix in (also easier to backport than a revert)
Okay then I'm reassigning to


Discovered a compiler panic, thought it might relate to , but was told to post a new issue. In minimizing, it seems the generic types are required to trigger the panic, I was unable to reproduce when inlining t7p or t8n. This code panics on 1.33 - 1.35, but does not panic on 1.32 (): On 1.32: On 1.35 nightly: --Bryan
triage: P-high. Removing nominated tag since there's little to discuss beyond its P-highness. (The fact its unassigned will be discussed regardless of nomination state.)
Bisection points to i.e. as the culprit. The backtrace in that commit looks very similar to the one reported here, and the parent commit () gives the same compiler error.
I spent some time looking at this a few weeks ago but did not manage to find anything conclusive. At this point I'm going to be taking a break for a few months, so I am unassigning myself from this issue.
triage: assigning self.
triage: downgrading to P-medium; this does not warrant revisiting every week.
I was able to minify it a bit further:
Triage: It's no longer ICE with the latest nightly.


() Output: Version: 1.34.0 1.35.0 2019-04-15 nightly () Expected: Original report:
26.0 is the first version that accepts this. 1.25.0 rejects it with:
(not really a regression since more code now compiles)
Adding T-compiler since is a built-in.
Opened —it should fix the issue.
triage: P-medium. I'm going to assume we don't need any future-compat machinery for a bug of this nature, unless the crater run on PR indicates that there are occurrences of this mis-use of in the wild.


With the following code: comes the following error: However, this function compiles correctly without the keyword.
cc
You can trigger this without async/await using : cc
Some more reduction in genericity and clearing up a few things: The problem is that is not know in impl trait items. It's also not related to the return position, but refers to any impl trait in the function. Outside of impl trait can be resolved without a problem, so it must be something related to the way impl trait reuses the generics of its parent.
It seems to be a missing normalization, most likely.
I have a local fix for reduction above, but is making this rather difficult as it makes output not work properly.
This also happens for definitions: My fix only seems to turn this into a cycle error for some reason. EDIT: Nevermind I just broke existential types in general lol
Marking as blocking, although I think there's minimal future compat risk. If push came to shove I personally would be ok with removing this from the blocking list. But then it looks like already fixed it =)
I think the problem is on this line of code: in particular, we "instantiate" the predicates -- meaning, substitute in the values for their type parameters -- but we never normalize them. We should be able to invoke the methods. Note that in this code we do have an available, as well, in . I think we should be able to invoke: this returns an  value, which contains obligations that must be pushed into .
Hmm, that code is only invoked if is true, which I think wouldn't be the case here since there are no region bounds at all (right?). I also noticed that does not exist in this context ( is an ), and there's no nearby either. However, another place where is called without normalizing the result is here, further down in the same file: there does exist (as does ). Quick testing shows that normalizing there fixes this issue as well, and as a bonus also fixes the issue with without ICEs!
good catch -- actually I think the lines you found are the ones I meant to direct you to in the first place. I see you have some other problems on the PR, looking now.


I was using nightly rust extensively for its async/await and specialization feature. After a recent update (nightly-2019-05-02), a new ICE introduced with following logs: After a quick search it seems like is the only in direct cause (stack frame 10). ~I cannot share the code or produce a minimal case because the code base is rather big.~
I've the minimal case for reproducing. Hope that would help!
Thanks! Looks like even this line is enough to trigger the ICE:
: rustc complains you should have variable mut although it is already mut.
That's and should be fixed in the next nightly
cc it looks like the desugaring may have broken in argument-position?
Oops, sorry. I'll take a look.
Denominating since already has a fix
Thanks guys! This is a super fast fix!


Following code sample causes a compiler panic. should be .
Also happens on nightly. Likely due to const generics changes (cc
Minimal reproduction:
Another case:


shows that the impl of is not idempotent. That is, if fails, the is left in an "un-droppable" state, and trying to re-drop the vector invokes undefined behavior - that is, the vector must be leaked. It might be possible to make it idempotent without adding significant overhead [0], but I don't know whether we should do this. I think we should be clearer about whether the impl of a type is idempotent or not, since making the wrong assumption can lead to UB, so I believe we should document this somewhere. We could document this for the type, but maybe this can also be something that can be documented at the top of the // crates for all types (e.g. impls of standard types are not idempotent). [0] Maybe setting the vector field to zero before dropping the slice elements and having the impl of set the capacity to zero before exiting is enough to avoid trying to re-drop the elements or trying to deallocate the memory (which is always freed on the first drop attempt).
cc
"It's not idempotent" should be the safe default assumption, and I know of no case so far where we've documented that a drop glue is idempotent. We might want to mention the general principle in suitable places (e.g., nomicon, UCG) but I don't think we should repeat "as usual, double-dropping this type causes UB" again on all specific types. We should only document the exceptions, if any. (I am also quite unsure whether going through the effort of guaranteeing that certain types' drop glue is idempotent is a good use of time, as it seems extremely niche and I don't know any use cases for that. But that just means I personally won't invest time in that discussion.)
I think this is not an issue wit . Rather, any unsafe code needs to be careful about panic safety, especially if it is also generic. FWIW I’ve always assumed that double drop could be as much a memory safety issue as use-after-free. (“One and a half” drop even more so.) I don’t think idempotency should be expected for any type, but that sounds like a decision for more than
Fully agreed. The best you can hope for, IMO, is that a type will make an effort to drop as much as possible even when there's a panic during dropping. actually does that by using the slice drop glue, which, if dropping one element panics, will keep dropping the other elements. This seems more useful than allowing idempotent dropping (it minimizes leakage even without any being involved), and it makes idempotent dropping unnecessary (if you catch a panic, the involved types already did everything they can to drop as much as possible, so there's no point in calling drop again). I think it makes more sense to improve panic-resiliance of our drop impls than to make them idempotent. For example, AFAIK drops two 's; if dropping the first panics, the second one will be leaked. This could be improved. One interesting question I see here is the interaction with . Does deallocate the backing store if dropping one of the elements panicked? If yes, is that a violation of the drop guarantee (assuming we extended with pinning projections -- )?
Today double-drops are not a form of undefined behavior. They could, however, lead to undefined behavior depending on the types involved and how is implemented for those types. As part of the UCGs one could try to make double-drops UB per se. That would mean that unsafe code needs to make sure that double-drops don't happen, period. That might be a breaking change. If we don't do that, then we have some types for which double-drops are ok, and some types for which they are not, and the only way to tell is either by reading the documentation, or inspecting the type's source code. I'd rather not recommend people to rely on what the source code does. It suffices that one crate starts relying on some impl being "accidentally idempotent" in libstd today, for us to not be able to evolve that impl in the future without breaking code. A "Unless stated otherwise, impls of standard library types are not guaranteed to be idempotent, and if they are, we reserve the right to change that without maintaining backwards compatibility" note somewhere might be enough to prevent that. I expect that to happen in an idempotent impl for as well. Right now, the issue is that all elements that can be dropped are dropped, the backing allocation of the Vec is deallocated, but the len of the Vec is not set to zero, so a double drop will try to double drop the elements again (and then the drop impl of RawVec will be invoked, whose capacity has not been set to zero, which will try to double-free memory). Yes. When drop panics, the destructors of the fields are invoked. For Vec this means that the contained RawVec is dropped, which deallocates the backing storage of the Vec without setting the capacity of the Vec to zero. AFAICT, no. If you have a the only thing that will be deallocated without running destructors when that is dropped is the storage of the . Since the destructor of the does not run, the destructor of the does not run, and the backing allocation of the gets leaked, which is fine (some other thread could still write to it).
https://rust- (both the proposal that is now implemented an the description of the status quo before that) is relevant to the efforts that the language makes to not let double- happen in safe Rust. This guarantee has existed for years, since before 1.0, so writers of unsafe code rely on it. Although calling twice is not inherently UB in the Rust language, many unsafe libraries are written with the assumption that it never happens. Therefore, writers of generic unsafe code should assume that double drop of a value of a type parameter can cause UB. Calling twice with the Unix system allocator causes a double , which is UB. But is only an example.
Drop is not the only operation that has such issues; pretty much any function you call can be UB or not under certain circumstances depending on implementation details. One example is e.g. relying on not to reallocate -- if we did a before, is that guaranteed? What if we did and then ? And so on. If we really consider such details to be stable just because they are observable by "this program was not UB but now it is", we'd have to bake an abstract model of all of these data structures into our operational semantics, just to make some more code UB. I think that is a bad approach. UB is for enabling compiler optimizations. It is not for catching clients that exploit unstable details of the current implementation of some library. Conflating these two problems makes the definition of UB much, much more complicated, I think that's a mistake. Just because some interaction with is not UB currently, doesn't mean we are not allowed to ever change it to be UB. There is no implicit stabilization of the full set of UB-free interactions. I agree catching such "overfit" clients is an important problem, but let's keep that library-level discussion separate from the language-level discussion of what is and is not UB. I don't understand why you'd even want to call again, if we already agree that the first should do the maximal amount of dropping that it can. You are basically saying "make 's drop idempotent by making the second a NOP". I don't see the point. Seems like you want to write generic code that drops stuff again if the first drop panicked. But what would be a situation where that is ever a good idea? From all I can see, the only place where this can help is if the second drops stuff that the first "missed" because of the panic. I am saying, if that is the problem, then fix to not "miss" stuff. This misses the point, because . The interesting case is a . Then we could pin the , and from our get a , and insert that into the list. Now we are in a situation where if the 's backing store gets deallocated without dropping the , we have a safety violation. But it seems to me if can guarantee that it itself does not panic, then we are okay: if an earlier element in the list panics while dropping (maybe it's a heterogeneous list through an or trait objects), we know we still get dropped properly.
How can you drop the while s into the vector are still live ? The documentation of guarantees these details, e.g., see , so AFAICT Rust unsafe code can rely on these details, and breaking that code would be an API breaking change.
I was talking about the implicit drop that happens when the vector goes out of scope. I am aware. When libraries decide to document such details, clients may of course rely on them. has no such section even though many similar questions apply; thus, clients may not rely on the same properties for even if they happen to be true currently. This matches the situation for idempotent drop: clients may rely on this if and only if the library decides to document this as a guarantee. I don't think we should change our language spec to detect clients relying on implementation details, and similarly, I don't think we should change our language spec to detect clients that rely on some being idempotent even though that is not documented (e.g., double-drop of an empty that had called on it).
The problem is that safe Rust can be called from Rust, and it isn't clear to me from that RFC whether writers of code can rely on other code not performing a double-drop. It isn't clear either whether code can assume that double-dropping something is ok.
Are you saying that this is analogous to whether users should be able to rely on double-drops invoking / not invoking UB? These data-structure properties feel quite obvious to me, but I have no idea how users can today learn that, at least when using the libstd types, they should always assume that is not idempotent unless a type guarantees otherwise. AFAICT they can just try it for some type, and if it works, deduce that it is ok. Then they publish their crate, and some time later we break their code. Saying that "we did not guarantee that it worked anywhere" does not change the fact that the code now is broken, and we are not warning them about this either. So even if we might be right in that technically we are allowed to break that code, it might turn out that in practice, now we cannot, and that user has somehow managed to, by accident, specify that double-drops for some type must be ok. We'd have a stronger case if we explicitly call this out in the docs, warn when users do this (or panic or similar), etc.
Both seem equally obvious to me. We also don't document that you cannot to a vector after dropping it. leaves the data structure is a "deinitialized" state in which no further operation can be performed on it. I don't understand why you or anyone else might think that dropping would be special in the sense of being the only operation that you may call on such a "deinitialized" data structure. I mean, nobody thinks that you can an already free'd piece of the heap either, right? Surely we don't have to exhaustively list everything we do not guarantee. That could get exhausting indeed... I'm all for being more explicit, and in that sense I am okay with noting this explicitly somewhere. But in no way does that mean that other undocumented assumptions can randomly be conjured. (This is how the discussion at hand feels to me: coming up with a random assumption and then arguing that just because nothing says that you can not assume this, hence you can. I understand you do not consider it random, but I see nothing distinguishing this from any other not-documented-not-to-hold assumption that people might come up with.)
further operation can be performed on it. AFAICT a second attempt to drop a value only makes sense if the first one failed (which is what the issue cited in the top comment does). You seem to be arguing that a drop that fails (panics) actually deinitializes the value and therefore trying to re-drop isn’t a logical operation to perform. If this is the case, to me this imply that a drop that fails actually succeeds, such that drops are infallible, which makes me wonder why do we allow drop to panic at all?
I mostly agree with especially wrt. to turning "unstated non-guarantees" through random assumptions into guarantees. However, I think if there are reasonable assumptions that could be made that we don't want to guarantee, it's a practical idea to disabuse users of those assumptions.
Note however that themselves demonstrated that currently double-drops (of Vecs) don't work -- elements get double-dropped on the second drop. That means if a hypothetical users actually tries to determine this behavior experimentally, they'd quickly find double frees and similar issues if they are at all diligent.
that holds as long as users try it with types for which this is the case. maybe you can explain to me how this assumption feels random to you (and maybe the others). Rust allows fallible drop, that is, drop can fail. I don't understand how from this it follows that, because drop failed, one cannot attempt to drop the value again. The only idea I have about how this could be the case is if drop is infallible, that is, even if drop fails, the value is dropped, but then I don't understand why we allow drops to fail in the first place. AFAICT, drop failed, therefore the value was not dropped, therefore I can try to drop it again, and that is not a double-drop because the value wasn't dropped in the first place. It is just a second attempt to drop a value, and this issue is about whether attempting to drop should be idempotent until drop succeeds (once the value is dropped, you don't longer own it, so attempting to drop further is a use-after-move kind of UB AFAICT).
My impression is that it's been considered bad form in general to panic in a implementation, if only because it causes an abort if the drop occurred during unwinding. It's allowed just because the alternative (always aborting when a impl panics) is worse.
...however, this could certainly be documented better. Currently the has an oddly worded note: I think it's trying to explain that double panic = abort, but as worded it doesn't really make sense. It should probably explain that more clearly, and also explicitly state that panicking in is discouraged.
It should also cover the case in which the double panic does not happen, and suggest what users should assume if the details of a particular drop implementation are not guaranteed. For example, that a dropped value for which drop fails must, in general, be leaked, because it is, in general, left in an unspecified partially-dropped state which is neither "initialized" nor "deinitialized" and which does not, in general, support an attempt to re-drop the value or any other operation. How bad would it be to make drop impls ?
Well, at least I am arguing that that might be the case. You have no way to tell. Would you expect it to be legal to to a vector after panicked? I guess not. Same for calling again. "panic" doesn't mean "I failed in a clean way and nothing happened", it means "something went wrong half-way through this operation and any part of it might or might not have happened".
Why not? If the value was not dropped, then I'd expect that to work just like pushing into an empty vector would.
For , on , the memory is deallocated, but the length and capacity of the vector are not set to . Are you saying that it is ok to leave safe abstractions over unsafe code in such an invalid state when a happens?
"panic during drop" is very different from "not dropped". This is true for any operation. I don't understand why you would assume that an operation that panicked had no effect and thus can be considered as having not happened. You keep just changing my words "drop panicked" into "not dropped". Please don't. :) I think it is okay to leave safe abstrcations in an invalid state when completes (whether that is return or unwind), because we can rely on this being the last operation. This is actually an advantage of Rust over C++, we don't need run-time tracking for this as we have proper static move tracking. would be the only operation where the "return" and "unwind" ways of completing would have widely different guarantees. I see no grounds for assuming it is special.
Where are you getting the impression that I assume that? How could you make have no effect? AFAICT you would need to revert the of the already dropped elements of the vector which is not possible. How can we rely on this? The example I show using corrupts memory at run-time, and is neither rejected statically, nor at run-time (e.g. via a proper run-time error).
You keep saying "not dropped" for "drop panicked", making it sound as if a drop-that-panicked was the same thing as if drop had never been called. I am sorry if I misunderstood you here, but I also don't know any other way to interpret your words. The Rust compiler ensures that is called exactly once. It inserts boolean variables to track this at run-time if necessary. Calling manually from safe code is impossible (even though its signature looks like it should be possible). Sure, unsafe code can circumvent this. Needless to say, unsafe code can circumvent any compiler-enforced restriction. But "drop is called exactly once" has been deeply entrenched in the guarantees and considerations around dropping in Rust as far back as I can remember. There is plenty of unsafe code in libstd that relies on this. This is as close to a guarantee as we get without formal proofs. The docs for say "using the pointed-to value after calling dropinplace can cause undefined behavior". It doesn't have an exception for when this operation panicked.
I am repeating myself here, but just to be clear: I am all for improving the docs. But I find it implausible to assume that doing double-drops could ever be legal (in generic code). There is plenty of evidence for code relying on no double drops happening, there is plenty of mechanism to make sure this doesn't happen in safe code, says so in the docs. I don't even know of a in libstd that would be safe to call twice (probably there are some). As a random example, is also not idempotent and might release a lock not even held by the current thread if it gets called a second time. The run-time tracking of the "move" state that the compiler does would literally be useless if drop was idempotent! Heck, before we had proper move tracking we even had a compiler-implemented mechanism to make drop idempotent (overwriting memory with some bit pattern, I forgot the details) and we got rid of it because of its unnecessary run-time cost. It feels to me like you are altering the deal here, and the deal has been set and clear for many years. We should discuss how to improve the docs because clearly it is still possible to assume that drop might be idempotent , but there is no point discussing the deal itself. Unfortunately, I do not understand at all where you got the idea from that drop might be idempotent, so I don't know where the docs could be improved to fix this. This issue has nothing to do with , it is more general. Where would you expect such things to be said? In ? We basically already say that there but maybe the case where drop panics could be called out more explicitly. Or maybe the Nomicon should have a chapter on dropping?
By "not dropped" I precisely mean "a value was not dropped". A drop-that-panics is a drop that fails, which is not the same as if drop was never called (how could it panic if it was never called?). I assumed a couple of things. First, that a drop that fails does not successfully drop a value, and since the value has not been dropped, code is allowed to try to drop it again. Again, this does not mean that I thought that a failed call to would have no effect here. It can have an effect, but that effect is not "the value is dropped" if the call fails - the effect is just "trying to drop the value failed", which is different from "drop was never called". Nothing nowhere taught me otherwise. For me, it just feel obvious that a value that has not been dropped (which is what AFAICT happens if calling for it fails), can be dropped just like any other value (unless these values are special somehow). Second, I assumed that correct safe abstractions over unsafe code made sure this works. My own abstractions do this, e.g., is left in a valid but unspecified state if fails (len = capacity = 0, ptr = null, just like ). This means that, after for fails, you can call or the value without invoking undefined behavior. Last weekend, I one of the test to last week, and this test ran slower. The reason was that does not put itself into a valid state after fails, and this results in UB in the example shown, while was putting itself into a valid state in a sub-optimal way (enough to be noticeable, and easy to fix). I then asked on Discord why was that, and whether the Drop impl for Vec has a bug, or whether Drop impls never have to account for that, and the discussion was that for is not idempotent, but whether this is by design or a bug was not clear, so I filled this bug.
It seems, in other words, that you assumed the drop glue is exception safe in a fairly strong way (even when it fails, it upholds the safety invariants necessary for dropping). Of course, as you might guess from my phrasing, that seems like a pretty big and unwarranted assumption to me. We don't generally expect any Rust code to be very exception safe (that's why we have marker traits like ). Some basic exception safety is required from unsafe code to ensure that safe code mustn't be able to cause UB just by catching a panic, but no more. Yet to run the drop glue again after the drop glue fails, you have to dip into unsafe code, so that principle doesn't apply.
The whole safe API is exception safe in such a strong way (e.g. ). AFAICT, the only part of the API for which this does not hold is the of for , so I suppose the assumption might have come from there.
The entire safe API, yes, by necessity (and only as exception safe as required to maintain memory safety -- e.g., it will happily leak memory). Though there don't seem to be any unsafe APIs (or methods at least) that have to worry about panics, so I guess it's true that distinction might not be apparent just from looking at Vec.
From the point-of-view of safe code, it does not matter whether is exception safe, because it can only be called once. From the POV of unsafe code, I knew that double-drops cannot happen, but what I did not know is that what also cannot happen is getting called twice. I thought, of course that can happen, if code calls , and that panics, and then is called again, that will call twice, but is not a double-drop, because the first time the value failed to drop. When mentions that the issue is not double-drops, but calling more than once, that's news to me.
I would like to close this issue. We have open to document the exact guarantees around drop and panicking, and it seems like that would be the place for this; I agree with others on this thread that I don't really see how one could assume that initiating drop twice in any way (whether it be due to unwinding or otherwise) is safe. Specifically, any method which conceptually has a signature of or so, if it panics, shouldn't be called again assuming that you still have a T; that seems like it should be fairly easy to understand, unless I'm missing something, as the T is almost guaranteed to have dropped already (so it would be odd to assume that you can drop it again, as that calls something on that T -- you've lost ownership already). This sentence is confusing to me -- double-drops cannot happen sounds equivalent to Drop::drop getting called twice; Drop::drop is the drop operation? Specifically, I think the confusion lies here: " I thought, of course that can happen, if unsafe code calls dropinplace, and that panics, and then Drop::drop is called again, that will call Drop::drop twice, but is not a double-drop, because the first time the value failed to drop" -- this is a double drop. When dropinplace panics, it cannot assumed to have done nothing, so calling drop again means that you're violating the safety contract of dropinplace. This is why or equivalents are commonly needed when calling dropinplace, as you need to be sure that the value you're dropping in place is not dropped again (during unwinding or otherwise), otherwise your unsafe code is incorrect. Presuming there's not further discussion here I will aim to close this issue in a week or so.
In the context of this discussion, the question that needs to be properly answered somewhere in the reference is: If a call to fails, was the value dropped? If the answer is "no", then calling again isn't a "double-drop" because the value has not been dropped. Looking at the comments here there is a certain amount of consensus that a call that fails "succeeds" in dropping the value, which is why even if fails, calling it again on a value drops the value twice and that's a double drop, which is UB. That's what should be documented somewhere in the reference. Which part of the reference issue summarizes / super-seeds this discussion ? If there isn't any, could you post a summary of this discussion there before closing this, so that documenting this still gets tracked somewhere?


When I used the character in comment, combined with some (invalid) code preceding it, the compiler panicked. I tried this code: I expected to see this happen: rustc compiles this code. Instead, this happened: rustc panicked with the following output : Backtrace:
Regressed in 1.34.0. Used to be:
cc
Miminized: Probably some span handcrafting?
Probably some span handcrafting? +1
I was idly curious, so I took a brief look at this. The diagnostic that triggers this was introduced in , but I don't think it is responsible for the error (it's just stepping through characters looking for a closing brace). There is some strange math in  (introduced in ). It oscillates between zero-length and 1+ length spans as it is stepping over characters. When it hits a multi-byte character, it returns an invalid span. Example: Starting with a span of (0,1), using would result in (1,1), then (1,2), then (2,2), then (2,4). That last one slices into the middle of the multi-byte character (because of , where width is 3), causing a panic. I'm not familiar enough with this stuff to say how it should behave. It seems like is being used for two different purposes (getting the next zero-length span, and getting the "next" character), and it's not clear to me what the behavior should be since it is used in a variety of places. I don't think it can be changed to always return zero-length spans, and it can't be changed to always return non-zero length spans. Perhaps there should be two different functions?
triage: P-medium, removing nomination; the ICE to me appears to include enough information for a user to identify the offending character and work-around the problem (namely by getting rid of the character). I do agree with that there should probably be two distinct functions corresponding to the two distinct purposes that they identified for the current callers of .
More test cases have been brought up in
I guess this is the same bug, but the examples I've seen here concern non-ASCII characters in comments. I'm getting a similar rustc panic from an erroneous code without comments: Compilation attempt:
Please file a new issue and reference this one.
I think it's fixed, try .
confirmed fixed by .


Creating a recursive type with infinite size by removing a leads to an internal compiler error. Might be the same issue as . To reproduce this bug, run on this code: Replace by and run again: I expected to see this happen: Instead, this happened: :
triage: P-high. Removing nomination.
assigning to with expectation that they will delegate.
nominating to try to find someone to investigate this.
well spotted ;) Because this issue has the tag and the other doesn't I will post the incremental test here:
triage: Reassigning to self and in hopes that one of us will find time to investigate, since it seems to be an issue with the dep-graph/incr-comp infrastructure.
triage: Downgrading to P-medium. I still want to resolve this, but it simply does not warrant revisiting every week during T-compiler triage.
I encountered the same bug. I starting to create a new issue, but it's exactly the same than this one. In case it's needed, I uploaded the code on on the branch (there is two commits, the first is fine, the second generate the ICE) in case you want to validate your patch when you will eventually have time to fix it.
I am running into this issue as well. Since the corresponding pr has been merged 24 days ago and the latest version was tagged 14 days ago, I am not sure, if this error should have been fixed with . (I did not find the commit on the master but I am also unsure if it was squashed with other commits.) Therefore, I thought I would at least post my error as well, just in case this is supposed to work. In my case I have an enum which holds a struct which in turn references that enum. I know that this can't work and I know how the correct way of handling this scenario is, I just wanted to let you know that this crashes the compiler. If you need a more detailed code sample, let me know and I will try to reproduce the error outside of my project.


The code: It produced error: Although RFC not yet implemented, this code must work already. Or I'm wrong and this syntax does not supported by const-generics?
Not sure where you see the ICE, removing that.
This is glitch after the previous 2 issues.. It is not ICE.
To Minimal code: produce error: The variant also give this error.
Now it is ICE:
It's back to the original error.
Now it produce this errors:
The behaviour is now as expected. We just need a test now.
Const Generic RFC leads the code as possible: Is there another issue that is tracking it?
Yes, there are some subtle issues about making sure that constants in types are well-formed. The tracking issue for this is


There are still of IRC in the repo. Removing them is not a priority but it will avoid confusion for newcomers.
Should these places be replaced with references to the rust discord server, or just be removed outright?
Probably replaced. Gonna update title.
Opened to address this.
This is horrible. Replacing IRC with Discord.. :/
If you haven't read about it yet, is the post from April.
Yeah I read already. I'd remove the mention of any particular discussion channel, instead of putting Discord in. I can't wait for Matrix to become more mature so the Rust project can use it. Falling back to Discord is quite bad for a FOSS project.
IMO we should just mirror subreddit solution and point to Discord.


Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool miri no longer builds. A follow-up PR to the repository is needed to fix the fallout. cc do you think you would have time to do the follow-up work? If so, that would be great! cc the PR reviewer, and -- nominating for prioritization.
Miri is fixed upstream, but will be broken again by so I'd like to land that before updating.


Probably one should never write this, and I wonder if it will be disallowed in the future. Happens on stable, beta and nightly, in all const-forms existing (includes const generics) <details<summaryBacktrace:</summary</details
Note: You could also write it the following way, in order to not need the attribute, as the previous code complains about recursion without that attribute.
Regression introduced in
cc due to Edit: I think I have a fix for this.


This code (): results in an ICE:
Isn't that a close cousin of
Not really, this is an associated function rather than an inner function.
I'm investigating this. Still repros on . With : <details<summaryBacktrace </summary</details
After investigating, the current ICE is caused by the () inside of not being able to locate the generic parameter it is trying to substitute for. The code at fault is: Which should try and find based on the (), but the current code only handles the situation like .
No longer ICEs, I believe down to Looking at the backtrace on nightly-2019-12-05 this seems related to and also
This no longer ICEs OR errors, at least for me. What backtrace do you mean? AFAICT this can be closed.
Whoops, wrote the wrong date down. I meant the nightly when it did ICE, it was 2019-12-01 or thereabouts. Yeah it can be closed once there's a regression test


With we are now suggesting people to use when they have a raw pointer and need a reference. With gets some expanded documentation on UB avoidance. It might be a good idea to mention that also in the actual suggestion, so people don't have to open the docs to be aware of this. Cc
Can I take this on, since no one seems to have done it yet?
Sure, it's yours!


I compiled the following code expecting some sort of error message. Instead, the compiler panicked unexpectedly. () errors: errors: :
Triage: Likely dupe of cc Preliminarily assigning P-high before compiler team meeting.


One of the many new (or newly enabled by default) warnings in Servo in today’s Nightly: The suggestion is wrong, which means also fails and therefore does not apply fixes for (the many) other warnings where the suggestion is correct.
Triage: Preliminarily assigning P-high before Felix reviews this.
Also cc since iirc you did some macro related work here.
Possible solution: when a warning’s span is exactly a macro invocation, don’t emit a “suggested fix” that is likely wrong. (But still emit a warning.)
We have that check for most suggestions, but it might be missing for . Was this in latest nightly? I know a couple of these have been fixed in the past few weeks.
This is in rustc 1.37.0-nightly ( 2019-06-18). works around this and allows ’ing the rest of the warnings (namely old syntax for inclusive ranges) or warnings in other crates.
Oh. I just noticed the suggestion. I’d missed it in that blob of text.
Apologies for the time this has taken - I've struggled to find time to dig in to this. So far, I've managed to make a smaller example (it still depends on , and ) that reproduces the issue, you can find it in (run in the directory).
Thanks to some help from I've now got a minimal test case w/out any dependencies that outputs the same tokens that the reduced example from servo did (you can see it in ). When inspecting the span that the lint is emitted for, it isn't marked as coming from a macro expansion, and it appears that it was created that way during the macro expansion. I'd appreciate any opinions on what the correct fix is here - is it a bug in / that they output what appears to be incorrect spans? Should rustc be able to handle this case? If so, where should I be looking to mark the span or what check should I be performing to identify it as a result of macro expansion?
cc
I believe this is a compiler bug, not something that needs a fix in syn or quote. is a call_site span. It is the span of tokens in macro output that are not attributable to any particular input token. Usually that will be most of the tokens in any macro output; diagnostics need to take this into account.


Consider the following three examples: A and C are accepted and B has a compilation error. However, the message reported in B looks more like a lint than a compilation error. A consequence of this error is that adding a non-public function to a module (e.g. the in B) may break code that imports from that module. This causes surprises when refactoring. Shouldn't "A non-empty glob must import something with the glob's visibility" be a lint? The original discussion is here:
The error was introduced in as a part of import modularization, and discussed in one of the related issues, but I can't find where exactly. The error was introduced by analogy with errors for single imports (and just to be conservative): The error is not technically necessary, and we should be able to report it as a lint for glob imports while keeping it an error for single imports.
Would this be a "good first issue" or is it complex to fix?
No, not complex. Find where "non-empty glob must import something" is reported. Replace with .
I want to do this issue but the problem I have is with a test (ui/imports/reexports) that checks for this error, I don't know the compiler structure so I don't know when compiling this file the lint will not be reported because of the other errors or not. Else I changed the to