Code: <details<summaryBacktrace</summary</details
modify labels: I-ICE C-Bug T-compiler A-mir Regression from 1.34 to 1.35
Additionally, this one ICEs with different error message: () <details<summaryBacktrace</summary</details
This code should not get all the way to codegen without an error
Another, different ICE? <details<summaryBacktrace</summary</summary
Regression somewhere between ...
looks suspicious, cc In particular, maybe is falsly returning here since the expected type is due to the other match arms?


The program below creates a promoted in a constant via but immediately casts this to a raw pointer. Now having weird values behind raw pointers is fine, but we have an intermediate reference to an invalid value. I don't understand how this compiles considering that the promoted is essentially Apparently we don't validate promoteds. I think we are allowed to fix this and validate promoteds, even though it will be a breaking change, because the user had to create an intermediate reference that pointed to an invalid bool. cc ()
So with the new promotion-as-consts scheme, what does that code "desugar" to?
before promotion as consts: after promotion as consts
Thanks. I agree in both of these cases we should do validation and consider this an error.
Hm, actually, thinking about it again... if we didn't do promotion in that , we'd not show any error. So I am not entirely sure if we really should show an error just because promotion happened? That would mean promoting more things can make compilation fail, which promotion explicitly does not want to happen. Also, right now validity check rejects some things that are not necessarily UB, such as integers in a reference (there's an open issue for this somewhere).
We'll do this in a PR that does nothing else but this change. already made the choice to not validate explicit in , so a PR fixing this issue will just remove the bail out and the comment
I have no idea what you just said but whatever.^^ That link just goes to the top of the diff, not any specific part of it.
Promotion in runtime code may not fail compilation. Promotion in constants should fail compilation imo because it's explicit promotion because you are in a const context
My argument was that it's seems to become kind of arbitrary when we do validation (even inside CTFE context) and when not -- suddenly that depends on details like what exactly promotion is doing. Not sure if that's good. It's certainly entirely random from a user's perspective: some CTFE code that causes UB through invalid values will work fine, other code will cause validation errrors.
Hmm... that's true. ok, so the current strategy of not validating promoteds makes sense and we can revisit the question later (or make validating promoteds just a lint)
I think this is actually closely related to I am not sure if it is worth keeping both of them open. Basically this issue is "we should validate promoteds maybe", and the other issue is "we cannot validate promoteds as we promote some things that are not valid".
Okay it's different kinds of validation -- one is the interior mutability part, done during interning, and the other is type-based validation of the final value.
We no longer promote union field accesses... but we still promote arbitrary calls in / initializers so the issue can be reproduced that way. Also I feel like my argument above only really works for implicit promoteds; explicit promoteds likely should be validated -- but I am not sure if there is an easy way we can make that distinction? It might just not be worth it.
The way it's currently set up we'd need to add that information to . Considering that we want to rework our error/lint stuff around const eval anyway, we should probably do that first, so the callers to the const eval queries can decide such things. Though now that I think of it, validation is orthogonal to reporting errors on it, so idk.
With , it seems like we are moving towards making promotion infallible. I think that means we should also validate promoteds (all of them). So I take back what I said earlier, where I argued against validating promoteds.


root: updns-0.0.6: v.
triage: P-high. Nominating for discussion.
self-assigned for investigation in short term (as in, next two or three days). However I suspect someone from will be a better choice to investigate this.
We should try to bisect this
used . Determined: searched nightlies: from nightly-2019-11-26 to nightly-2020-01-03 regressed nightly: nightly-2019-12-01 searched commits: from to  regressed commit:
is a rollup commit of the following PR's: I'm guessing this is due to PR
I'm still working on reducing this down to something that I could put into the playpen. However, one interesting thing I've found locally during my reduction: This version of the will signal an analogous compilation error: but if I lift the first argument out to a separate -binding (i.e. change it to use above, or the sub-expression out to a separate -binding (i.e. change the argument expression to use above), then the error goes away. I'll admit that I don't know all the details of how the fn-transformation works to support , but I strongly suspect that if this kind of local code change can make an error go away, then that represents a weakness somewhere (either in the fn-transformation, or in the borrowck).
Okay in the details block is a standalone version suitable for the : <details</detailsand the error it generates:
So this does seem like somewhat clear (expected?) fallout from PR : a use of a in a generator witness will be recorded as a unsafe pointer , and then is never , but the method requires that the task you give it is . I believe we can readily update the crate in question to avoid using the in the expression under the RHS of . But I do wonder whether we can/should improve the diagnostics here to try to guide the user towards such a solution ...?
I might have worded this too strongly, and/or over-reduced my example. In particular, its easy to move around the access to . But the borrow of may be trickier to deal with.
I'll have a look at addressing this with another approach I considered for . If that doesn't work out then I'll have a look at the error message.
The patch linked is enough to fix the crate in question, but I'm all for finding an in-compiler solution if we can do it soundly.
OK. I'm going to write some things up because I've changed my mind a bunch of times about how/if this can be fixed in MIR building and I don't want to keep forgetting things. Generators store values that if their value needs to be preserved across a yield. These values need to be visible for auto-traits, for example a generator may be resumed on a different thread after it yields, and so cannot be if any of theses values isn't . There are two passes that determine which values can be included in the generator: A pass that runs as part of typeck that walks the HIR to find the types of expressions and then checks for yields in the values scope (as determined by the RegionScopeTree). The types recorded here are stored in the GeneratorWitnesss type contained in the generator, which is then used for auto trait checking. This notably uses the types of expressions that HIR sees. The MIR transform that lowers the generator to a state machine. This determines the values that the generator actually stores. As a check for the compiler, we assert that any types that we capture here are included in the witness type (we don't know all auto traits, so can't check only for them). After statics no longer have a special representation in MIR. They are instead lowered to a dereference of a pointer to the given static: is lowered as if it were: Which becomes: The example above is somewhat deceptive in that the temporary that holds the pointer is used immediately after it's assigned. In this case it cannot end up in the generator since it's not live across any user code. However this isn't true in all cases, index and match expressions allow running user code while the pointer is live: In these cases MIR has to put the temporary pointer into the generator state and promptly ICEs. The obvious solution now is make type checking record the new pointer types in the generator witness in these cases. Unfortunately HIR is not a great tool for specifying "these cases". The methods that the region scope tree provides in HIR are either usually far too large (the "temporary scope") or occasionally too small (the "enclosing scope"). went for the sound but rather approximate approach, leaving us here. One idea might be to try changing MIR building so that the temporary is never live across user code. For example, one might change the lowering as follows However working out how to do this for in a reasonable to implement way is harder. MIR actually already contains an escape hatch for values that are in the MIR but aren't in the HIR in the form of a flag (called ) on the variable. We currently use it for drop flags and boxes created by expressions. It's unclear what exactly the difference is between is. I guess one could argue that auto traits are for layout introspection and this would be further breaking that. I think that's everything for now.
Visiting from triage. were you planning to work on this further?
It's definitely tempting to take advantage of the constraints around statics to just declare these equivalent, and use the flag to get out of this. While I don't see any soundness issues around that, I also don't quite trust myself to get this right :) Can you expand on this? I'm not sure I follow.
Another solution that comes to mind relies on the fact that these pointers never need to be stored in a generator. They are consts, and the temporaries containing them shouldn't ever be mutated. We could add semantics for "const temporaries" to MIR, and never store them inside generators. The semantics would (hopefully) be simple: defined once and assigned a value that doesn't depend on any other temporaries; never mutated or borrowed mutably. We can move the statements defining them to the top of the function inside the generator transform. But that would be adding more semantics and special casing to MIR to fix a change which removed extra semantics and special casing, so I'm not sure if that's what we want :)
The argument is that the given the following auto trait we guarantee that if then there are no raw pointers directly stored in an instance of . If we make that guarantee then using internal in generators would not be OK. I would argue that we're not making such (or really any) guarantees with user defined auto traits.
Yeah, I don't think auto traits should expose layout implementation details of generators. And this really does seem like a pure implementation detail -- it doesn't have any bearing on what kinds of (unsafe) operations are allowed on a generator, like a self-reference would. cc
So, I've been putting off commenting here to let these ideas sit, but let me leave a comment. I think I've reached a conclusion. TL;DR. I think we should mark these types as internal, but I think there are some better options for fixing this in the medium term, and this interaction should be taken into account as part of the "MIR 2.0" effort to rework places. Auto traits weren't really intended as a tool for probing layout, but rather semantic considerations. This is why traits like can be implemented by users. So I don't really think that auto traits give any sort of guarantee about their layout. Rather, this question is about is simply "what are the constituent types exposed by a generator", and this should correspond to the types that user code can directly access. The raw pointers here are not directly accessible. The values that are accessible are the "live values" that the user's code may later use -- and of course the code currently makes the constituent types be a superset of those, based on the AST structure. Of course, the real root cause of this error is a simplifying change to the definition of in MIR. It used to be that a Place had this grammar: but now we changed to just , which is why we are required to introduce the new temporary (and that holds the address of the ). As we've been talking about this change, I've been saying that we should be considering the older definition of as the one that is used by various analyses (and in particular by borrow check). This particular transformation of removing statics doesn't affect borrow check, but we failed to take into account the fact that the set of live variables can effect the definition of what is live in a generator. In particular, compiling for some expression requires a temporary unless corresponds to a place -- those places used to include statics like , but they no longer do. But I think that for analysis purposes, it should appear as if they do. We could fix this in two ways. We could write some code motion / duplication that takes temporaries like that are live across a yield and creates a fresh variable after the yield. The idea would be to make them never* live across a yield. We can do this because that operation is a compile-time constant, really, and thus the value doesn't need to be live across a yield. This might be worth doing as a size optimization regardless. Secondly, some of the proposals we've been kicking around for going further with simplifying include the idea of a distinct sort of temporaries that explicitly represent a "partially constructed that hasn't been used by the user". The idea was to allow borrowck (and other analyses) to trivially reconstruct the . We might want to add this interaction with auto-traits into the consideration for that design, and maybe it takes us some place (e.g., these special temporaries are not considered live for the purposes of auto traits). Having written out both of those options, though, I sort of lean towards the first, at least for this specific issue.
I think these references and raw pointers created by MIR construction should be marked as . They are not visible at the language level. They can be viewed as just prefetching the address of a static, so the compiler could pick any type it likes for it (, , , some compiler internal type) so it must not affect auto trait inference. Drop flags are ignored for similar reasons. You cannot use an auto trait like this to detect them: So I think that should be reverted and the temporary static references should be marked as .
Note: opened instituting this change and I r+'d it, since fixing the regression seems pretty important and time is of the essence; there is general consensus here on the thread; this is only restoring older behavior. In particular, there were some suggestions that this might be a lang team issue; I think there is some 'intersection' and I don't want the perception that I'm trying to shortcircuit discussion. That said, I also think this is primarily a compiler team matter, since it's a deviation from the old behavior, and further this deviation was caused by altering the MIR away from the "natural, Rust-based" definition and towards a lower-level definition.


results in: Removing the constgenerics feature flag gets the expected error message: (IIUC that itself is a bug related to ) Using directly outside of a const-context works, which I guess is something const_generics enables that isn't otherwise allowed. Finally, the error message is the same whether or not the code is in a provided method or a impl block; I actually ran into the bug in the later.
I believe this should be fixed by
Now, it shows different ICE(s) ():
Now ICE no longer occurs. I think it's fixed by .


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


When learning async/await feature I was struggling with running multiple tasks simultaneously. Loop causes compiler to crash Github Action crash output: I expected to see this happen: Error message if something goes wrong. Instead, this happened: Compiler crashed Crash happens on macOS rustc 1.40 / Linux rustc 1.40 / Linux rustc 1.39 ( github actions ) :
If you could provide an example that ICEs in e.g. the playground that would be helpful towards fixing the issue. :)
Provided example is pretty small, but it is dependent on tokio and actix-web. I do not know how to create such an example in playground, I do know know how I can replace async tokio::sync::mpsc with standard library which does not have async alternative as far as i know. I have tried to simplify code but then crash disappear. Just putting everything into one file and crash is gone, code wont compile and reasonable errors show up.
Visiting from triage.. we decided that as the first step we should reduce this reproducer to a more self-contained one.
Can repro. Will try and min.
Reduced version so far is here:
This no longer ICEs on the latest nightly.
Let's see if we can shrink further so that we can add a test. ping cleanup
Hey Cleanup Crew ICE-breakers! This bug has been identified as a good "Cleanup ICE-breaking candidate". In case it's useful, here are some [instructions] for tackling these sorts of bugs. Maybe take a look? Thanks! <3 [instructions]: https://rustc-dev- cc
I’ve reduced it quite a bit. Down to dependencies on only. Appears to need 2 crates.


This code crashes in LLVM during codegen on stable, beta, and nightly: This originally happened in real-world code (a code base derived from ). <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
We generally don't guarantee behavior with no_mangle, I think. I guess a segfault in llvm is unexpected though :)
I think the is a red herring, since the name of that function doesn't actually matter (ie. it can be or something completely harmless). I think it's just needed to make sure the function is codegen-ed.
I keep seeing this in my output when I play around with this on the playpen: that does not use , adding credence to 's point that it is probably a red herring.
triage: P-high. Leaving nominated in hopes that someone at triage meeting has a bright idea has to what's going on here (and what we might do about it).
Hm, bad_alloc implies OOM to me, but maybe that's not always the case.
Compiling with LLVM debug symbols + assertions, I get the same assertion failure for both: Tracing the callstack with gdb, the assertion is triggered on the call in this function: As the error suggests, this means that the downcast from to failed for . Printing out what type is (with some casting because gdb doesn't know what the return types are): That's strange -- it's reported as a function pointer, which is the same as what's reported for actual s, but we're still failing the downcast. Usually, dumping an should give you the contents of the function. For example: gives us But dumping gives this: So it appears to be pointing to a instruction? I'm not 100% sure -- I've ever seen a instruction being prefixed with a type, but I've taken it to be indicating the type of , the operand. I'll do a bit more digging. claim
After manually removing the LLVM build to force a complete rebuild with debug symbols, I was able to get a proper dump which makes far more sense: Note that this is not a bitcast instruction but a constant expr bitcast -- ie, one generated at compile time. As it turns out, in the event that a function exists with athe same name but a different type in a module, will return a compile time bitcast to that function: which is the overload called here So, later, when we attempt to use any functions that do a downcast to , we trigger the assertion failure because the downcast from constant expr bitcast to is not valid. We run into this in both your cases because when codegen attempts to insert a declaration for with signature , the program's already exists in the module with the signature , so the bitcast is returned instead of an . This issue can be reproduced without causing a crash by forcing a name collision with a function that's not (as we don't end up trying to cast the bitcast to a Function in this scenario): Compiling with we get this bitcode here: which I think exposes the problem more clearly: In an extern block which declares a function with the same name as some existing function within the module, we'll end up generating a call to the function in the module (potentially with an unsafe bitcast), instead of shadowing the module's function and generating a call to the external function (which, to me, appeared to be the intent of the example). You can see that this example shows that the in the original example isn't quite so much a red herring as it might seem -- in my example particularly, it's needed to ensure the name collision which demonstrates this behaviour. The examples without work because we induce a name collision on the unmangled function instead (not the user-defined one; the one which calls ). At this point, I'm not sure how to proceed. Should we error out here because of the name collision to avoid generating crazy function pointer bitcasts? Or should we do some kind of trickery to rename the shadowing symbol so that it correctly calls the extern function? Or is it as says -- is the current codegen into bitcast fine because we don't make any behaviour guarantees for symbols?


Got this error message when trying to compile a crate using rustc 1.42.0-nightly ( 2020-01-07). The text reads substract instead of subtract.
if you want to contribute a fix, you would just need to modify these three lines:
thanks for your response, I submitted a PR to fix this.


Attempting to compile this code: Playground link: Causes this ICE in nightly 2019-12-29 ,and stable with a slightly different stack trace.
reduced to 2 lines: also, when the is removed from the line, OR both 's are removed, it compiles fine.
yeah, I prepared the fix but has already submitted another fix so assignment is unnecessary?


I'm not sure when exactly it happens, but it reproduces roughly like this: Rebase my working branch on upstream/master. Run , the build starts from or later and succeeds. Run again, should be a trivial build, but the build starts from or again and succeeds. Run again, trivial build happens. The target is x86_64-pc-windows-gnu. The issue exists for several weeks, so it's a regression. cc
Reproduction script: You might have to run it multiple times to cause the spurious rebuild in the last command.
For some reason is getting recompiled:
cc
I think was hitting this at some point as well, though we weren't able to determine quite why.
I haven't encountered these rebuilds before, but recently (since December?) they happen quite often, like every second or third build, and that's pretty inconvenient given the long builds. Perhaps something changed in itself?
I don't think we've changed backtrace itself recently. It would perhaps be handy to check if this still happens before (which changed how/when we clear out std's target directory). However, I don't expect it would have, as that would cause all of std to be rebuilt, not just backtrace. Maybe backtrace is unique in being a dependency of both std and the compiler (for example?). I'm not sure what could be causing this odd behavior :/
I'm pretty sure the rebuilds appeared before (and I hoped that PR would fix them, but it didn't).
I suspect to be the cause, at least based on timing.
I've been hitting similar (this?) issue with x86_64-pc-windows-gnu when doing builds. Somehow it disappeared whenever I ran before so I kept doing that as the workaround.
Hm, so in theory at least wouldn't have affected backtrace specifically, I think, though there may have been knock on effects. One thing that might be helpful is getting a log with on the spurious rebuild (to know why Cargo thinks it needs to rebuild it).
Update: this reproduces on too (which runs much quicker and involves less moving parts), just got a rebuild after a clean build this way. I'll try .
Reproduced on () with :
I was able to reproduce this once, but I'm having trouble reproducing it again. When I did reproduce it, I noticed that the included . That is not normal, and I think points to a race condition with the libcore rlib getting emitted at just the wrong time. I suspect it is due to pipelining and maybe . I'm still trying to figure that out.
binary-dep-depinfo should not include backtrace into libcore, I think, since we don't pass to libcore (nor is there an implicit "sysroot" dep from libcore; core depends on nothing). I don't know why we're including dep-lib-backtrace in the libcore dep file though, that does sound like a bug. I guess this is then likely an upstream bug in some sense? I think leaving it here for tracking at least for now makes sense though.
It's the other way around. 's dep-info file noted a dependency on , which is normal. Normally it should only list the file, but when I saw it, it also included the file. That normally shouldn't happen because the libcore codegen step takes such a long time (normally finishes after backtrace is finished). I'm not too familiar with the compiler, so it's a little slow for me to figure out. I seem to recall being told that writing the file is not done in an atomic fashion, is that correct? Perhaps writing it can take a long time, and backtrace started after the was created and finished running before the was done? I also seem to recall that there are protections in rustc to deal with partially written rlib files, but I'm not sure how that is accomplished (are there checksums?).
We currently emit a dependency on both the rmeta and rlib files (presuming they were found during building, I guess?) with . That might be in error! I did so as the most pessimistic option when initially adding that feature, but perhaps I was too eager in pulling in dependencies. If I'm understanding correctly, that may mean that if libcore's codegen completes before backtrace is built, we'll pull in the libcore rlib as a dependency of backtrace, and then when backtrace is checked for freshness in the future, we'll notice that it's actually been built before the rlib (which we finished writing after libbacktrace started). Is there ever a case where there's a dependency on rlibs directly? Maybe we should only emit rmeta/dylib filepaths in binary-dep-depinfo?
For reference, here's what I have in that file (with NUL bytes removed):
Hm, so it looks like in practice we that we find -- so in some sense, we don't actually depend on all three, but rather rlib/rmeta/dylib, in that order, when we're loading up dependency information. I guess there's not really any tracking for which one we've used metadata from, but in practice, we should probably only emit one of these (probably rmeta/rlib/dylib, in that order) that we have set as the CrateSource.
Hm, so it looks like in practice we read metadata from the first of the three that we find -- so in some sense, we don't actually depend on all three, but rather rlib/rmeta/dylib, in that order, when we're loading up dependency information. This is actually something that I wanted to try to change () and read from the rmeta first.
Even if is used for reading metadata, can still be used for reading object code, in that case both should indeed be in dependencies? Perhaps cargo just timestamps the link time dependencies at the wrong time? (Earlier than necessary, together with .)
I was able to record exactly what happens. The timeline is: T1. emitted T2. backtrace build starts T3. emitted T4. backtrace loads T5. backtrace writes dep-info with and T6. backtrace finishes T7. Cargo reverses backtrace dep-info timestamp to T2 () (this is intended to deal with files that are modified in the middle of the build) The result is that 's timestamp is T3 and backtrace dep-info timestamp is T2, and since T3 T2, the next time Cargo runs it thinks backtrace needs to be rebuilt. I'm not sure how to fix this. One solution would be to change the priority to load rmeta over rlib, and have only emit one file. Or Cargo could hash the files :wink:. Maybe has ideas?
I like the idea of inverting rustc's preference, using only the rmeta rather than both the rmeta and rlib if they're available. Other than that though I don't know of a great way to solve this :( I may be missing something though, is this rustc-specific? This seems like a bug that everyone should be hitting naively which makes it quite serious?
It is only with . Also, the timing has to be just right for the rlib to be created in a very small window (the time between T2 and T4 is extremely small).
Ah I see, makes sense! Here's another possible question and/or solution. When Cargo builds libbacktrace it's presumably only passing , so I think it's rustc's automatic logic to pick up . Is that correct? If so it may be more correct to, if is passed, disable all other auto-loading?
Backtrace only sees via . is loaded as a dependency of that. (Via I think?)
I think this is our best bet -- furthermore, I wonder if there's some wins to be had in terms of compile times. It seems like we are currently loading libcore's rmeta/rlib for all crates out there, which presumably is not great (more IO, etc.). I can pursue a PR to that effect soon.
aha ok that makes sense as well. Then yeah I think your suggestion is indeed the only thing I can think of as well!
Hm, actually, in going to do this, it sounds like we can't quite just emit one of them, per "Even if rmeta is used for reading metadata, rlib can still be used for reading object code, in that case both should indeed be in dependencies?" -- right?
When building an rlib we never use contents of upstream rlibs. When building dynamically linked artifacts, though (or executables) we do use upstream object code. (this is basically pipelining)
Aha, okay, so it sounds like a partial fix would be to: If we're producing rmeta/rlib: emit just rmeta dependency if we're producing dylib/cydlib/binary: emit just rlib dependency Does that sound right? Basically, we emit "worst case" for either situation which I think might mean that for dylibs this bug persists -- since they'll start compilation before the rlib is finished -- but I don't know how much we can do about it under the current model.
That should be right yeah, and I think the dylib bug won't be an issue because Cargo won't start libstd until all subsequent rlib compilations are finished (e.g. it doesn't pipeline it)
Great! Okay, then I'll try to get that impl up. (I presume the "dylib bug won't be an issue" also applies to dylibs in the wild, right?)
That's the theory at least!


Currently requires the failure ordering to "be equivalent to or weaker than a success ordering". On the other hand C11/C++11 requires only that "failure shall be no stronger than the success", which arguably means that one can write e.g. in C/C++ but not in Rust. Arguably, because neither C11 standard nor C++11 standard defines what it means for an ordering to be stronger from another. When the issue was raised in [LWG2445], the proposed and accepted resolution was to lift those restrictions altogether, leaving only requirement that "the failure argument shall not be nor ". It would be beneficial to remove success/failure ordering restrictions for reasons described in C++ proposal [P0418r2]. [LWG2445]: [P0418r2]: EDIT: Restrictions were lifted in clang & LLVM:
Blocked on The cmpxchg release acquire is accepted by LLVM but miscompiled on AArch64.
I'm about to send a PR that implements this.
I do have implementation ready as well, but that's fine, I can review instead :-).
I split it in a PR that renames the intrinsics first, and a separate PR for exposing the new ordering combinations afterwards.
Looks like llvm 12 doesn't support this: Can we make things conditionally fall back to a stronger ordering depending on the llvm version? I don't think we do anything like that in the library right now, but maybe the compiler already does things differently for different llvm versions?
Ah yes, some code checks . I suppose Builder::atomic_cmpxchg could check the same, and upgrade the ordering if necessary in that case.
Did exactly that in
To do: [x] Add codegen test. [x] Publicly expose the new orderings. [x] Update memory order lint to accept the new orderings.


Here's the crashing code I came down to: An empty contains a single line: "pub mod " a file with the following code: This happened as I permuted type and size in my array definition. My intention was not to declare a zero sized array but to declare an array filled with zeros. Anyway, the compiler crashed. I noticed that if I remove the from the line in , it compiles fine. Backtrace:
cc
cc did the value visitor changes get merged?
is still waiting for review if that's the one you mean.
The ICE seems to be , though. So likely just needs a test (or checking that we already have an appropriate test)?
Maybe we should also find the PR that fixed this and beta nominate?
points to as being responsible for fixing this.
That PR is too big to backport. I suggest to just remove the assertion on beta as the ICE is properly fixed on master
Still need to backport
The fix is already on beta so backport is unneeded?
Yeah, playground confirms that this ICEs on stable but works fine on beta and nightly.


I'm seeing an internal compiler error on the following input (found by ): The error happens on , , and .
I'm looking into this! But mostly as a learning exercise. Spent ~4 hours exploring typeck & error handling today to see why this exact combination of things triggers an error. My friend and I will probably have a solution at some point, but it might be a few weeks from now. If anyone has a good & quick solution, or if it is deemed high-priority, then feel free to ignore me.
~According to , this regressed between 2019-07-30 and 2019-07-31. Unfortunately, seems to be incapable of narrowing it down to a commit because that was more than 167 days ago.~ EDIT: gave me a misleading result. This error is at least as old as .
This error started happening in cc
The ICE goes away if I apply this patch: (Though I'd guess that making this change would cause us to regress on the problems that fixed.)
This change fixes the ICE and avoids regressing on : I'm unsure whether this respects the intended meaning of , though.
on a very cursory look that patch looks reasonable.
has some additional relevant context.
Unfortunately, the patch that I proposed above fails on this modification of :
triage: P-high. Removing nomination. Added regression stable-to-stable tag.
I think I found a way to resolve this without regressing on . The point of this PR is to not emit an error if it might be invalid to the user. But there are errors in context still. The patch I propose is this: This does pass every UI test. I'll open a PR so this can be discussed more easely.


Hello, this is your friendly neighborhood mergebot. After merging PR rust-lang/rust, I observed that the tool clippy-driver 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! And nominating for compiler team prioritization.


<!-- 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. --The setup under which this occurs is somewhat complicated, but I'll try to reduce it as much as I can and update this issue with details. But basically it's using the latest nightly rustc and running on the latest code (, rev ). <!-- 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. --: (See full output in the backtrace details below) <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details
Also to note: so far this has happened 2/2 times today. It didn't happen yesterday (which presumably was running using a slightly-older rustc and checking slightly-older glean code).
Re-running the command: in the proper directory on the machine in question reproduces the error. The file it's complaining about () exists and doesn't appear corrupted.
Running the command over and over changes which crate it errors out on. In the initial run it was erroring out on but on subsequent runs it changes to , , etc.
If I remove the bit then it works fine. So seems related to the save-analysis code. /cc
I'm able to reproduce this in a local environment as well. Minimal steps so far (on a Ubuntu 18.04 VM) I ran with and the specific invocation that's reliably reproducing the failure is: (Obviously your paths may vary) Also note that this does NOT happen with (which installs a rustc built on 2020-03-09) so it's a regression between rustc version and rustc version .
Rust regression range:
If you're unable to repro or need more detail feel free to let me know. Otherwise for now I'm leaving this with you (i.e. rust developers) to dig into.
I have the very same crush with rustc 1.43.0-nightly ( 2020-03-11) on both of Mac and WSL2/Ubuntu, every time Rust language Server starts up in VSCode. No problem in rustc 1.43.0-nightly ( 2020-03-01). ### Error message:
I used to narrow the range to ...
Therefore regression from , cc
cc
I'd say this is a pre-existing save-analysis bug that was exposed by . should handle source files missing, which might require to return .
Same here:
Actually, this doesn't have to fail at all either, it's just hardcoded to non-external files: Before checking for the source, it would need to do this: And then something like this to handle both local and external sources: EDIT: nevermind about that last part, it's already.
So what are next steps here? I don't know what rustc's policy is with respect to regressions, is the regressing patch author responsible for fixing the regression?
Downgrading to fixes the issues in the vscode plugin for now.
Sorry, I'll go implement now. EDIT: up at .
I'm not sure why the original reproduction seemed so daunting, it triggered the bug as expected. I was also able to reproduce it on the problem crate itself: and it succeeds with this (which is my local build including ): also gets past the ICEs, but I can't easily do a full build because build scripts failed.
Thank you for the fix! At the moment using rustup to pull a nightly still gives me an older nightly (due to newer ones missing various components) but once I can get a nightly with the fix I'll report back whether or not it solved my original issue.
Confirmed the fix by forcing a nightly update. Thanks!
I am running into this / similar issue when is used as dependency: versions Here is the simple reproducible test case
Never mind I see now that version I have is . If I I do force update it works.


: <details<summary<strongBacktrace</strong</summary<p</p</details
It doesn't require feature flag.
I am currently working on this
my first idea was to fix this ICE locally by offsetting in line 1318 for each wrongly placed const param. This only moves the error further back. I currently think that it would be best to actually fix the param order if order fails. Is this a good approach? And how should this be done, as is used in , which only receives an immutable reference to .
I think the right fix for this would be to make sure we can handle generic parameters in any order — there's no technical reason the parameters should be in a fixed order; it's just historical. This would involve doing what you started with, and fixing each problem in turn. However, I don't know how many things still rely on this order, so it could be an involved task. For a shorter-term fix, we could just make sure that generics are sorted if they're in the wrong order. We could probably do this in and sort the before creating the . This might be more pragmatic, though we should leave a to address later if we do this. Thanks for looking into this


Doctest test names have changed due to . Doc comments that pass through a macro defined in another crate now seem to report a different span. /// assert!(true); /// running with previously looked like this: Now the test names look like this: Frankly, neither are particularly great. It would be nice if the test name used the span from where the macro was invoked, not where it was defined.
I think this also affects normal backtraces :( Just got this rather unuseful backtrace while bootstrapping: full:
cc
What you're describing is entirely in the opposite direction, is the old (and arguably bad) kind of that's impossible to get anymore. I've hidden your comment to focus on the reported issue.
That makes sense, we have a way to get the outermost invocation, that is used by / and : We'd just need to use this in .
cc
cc
Removed label, left nomination for to decide about this issue.
Well, using what suggested seems like the best thing to do.


gives: My guess is that this has the same underlying cause as , but this one doesn't involve associated consts or arrays at all, so it might be different still.
This appears to be due to a bad interaction between and associated type projections involving lifetimes. When we normalize the function signature during type-checking, we project to . We then convert back to the 'generic' region for , which is . However, this is a distinct early bound region, different from the in (changing the regions to not all be called in the example makes this clearer). This causes issues during , since we've essentially pulled a region out of thin air. This issue doesn't seem to come up for type parameters ( with lifetimes replaced with types). I'm not sure if this is because our handling of type parameters is correct for this kind of projection, or if we need a more complicated example to break things.
The ICE no longer happens with the latest nightly (note that the playground's nightly isn't the latest). That was removed by . Marked as E-needs-test.


<!-- 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. --I was writing some generic code over vectors using the under-construction feature of const generics, and had a circular chain of super-traits that required me to cast the Self type to the trait as can be seen in the supertrait requirement. I believe that is causing the MIR error. I think this may be related to but it is subtly different so I'm putting the issue up regardless. <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: I updated my rust version on nightly right before I ran this so hopefully it is up to date: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
minimized: claim
Looks like maybe constants in trait paths don't get their type correctly? cc
Initially I thought this was about bounds but no, this also fails: ()
I believe this code is responsible: And the problem is that this doesn't handle associated types which need the same treatment:
Alternatively, instead of using to get the , maybe we could use the olution from the segment we found the const parameter in? I believe nowadays we have per-segment resolutions, which would avoid breaking GATs in the future. Actually, I expect is also broken, let's try it... Yupp: () EDIT: took a second look and that is in a , which has to be resolved by the body of , which means it's as bad as the method call form (which I just ). Maybe we should disallow passing explicit generic args to methods for now? Since I have no idea how one would figure out the expected type.
If you look at this later btw, my comment above () still isn't addressed, but I haven't made an issue yet about it.


In a recent PR I made a change to unify the wording of multiple privacy errors, but : used to be This one change needs to be reversed while keeping the rest.
Hi! Could I give this issue a shot?
I am sorry I forgot to claim the issue
No worries :-)


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! And nominating for compiler team prioritization.
Removing nomination, as part of pre-triage we are looking anyways into tool breakage.


const-prop checks statics for whether they contain relocations, and if they do, it refuses to read from them. It is not clear why that happens. Cc
I just realized the condition is , so maybe the allocation in question was not even mutable but had relocations in it. I am testing that now. I do not understand the argument given in the code for why relocations are a problem: If the memory behind that pointer is mutable, we will notice that when that allocation is being accessed. Why do we have to bail out so early? Is it because the hook used to only be called for statics, not all global allocations?
Also the mystery about why validation is even happening is answered here: I think I understand why, conservatively, this does validation... can this ever fail? Validation is quite picky about the kinds of errors in expects can happen, and with const-prop having a machine that bails out early on many operations, that could be a problem. The reason validation is so picky is to make sure we get good errors, which const-prop does not care about (the errors are not shown to the user), but it re-uses the same machinery.
Okay so the actual problem turned out to be relocations. There is no bug here, we can reject all reads from mutable globals (phew). What remains open is why we check for the presence of relocations at all. you that I mentioned above, would be great if you could explain it a bit more. :)
: But I'm not quite sure why...
Basically I want to avoid the following (assume it compiles with more boilerplate) from optimizing to Since we can't ever know what users are up to with their code, the presence of relocations was the easiest way to avoid any kind of troubles there. Furthermore, assuming we just forbid raw pointers from being derefed in const prop, we'd still have problems with the following getting const propped:: I want to prevent const prop from creating any kind of mutable global memory that we may end up pointing to. While we can probably devise a smart scheme, right now it seems better to just forbid any relocations.
that sounds to me like an indirect way to do the check that we can now do much more reliably and directly: This is done for all accesses to globals (things stored in ). So if a constant global points to a mutable one, the check will fire when the mutable global actually gets accessed.
that's true. Makes more sense to handle the first case like that.
But how does that help with the second example I gave?
The second example does not involve any global though? So nothing we do in that hook will have any effect? I am confused.^^
The problem is that it would magically create a global if we used const prop here. Basically the same problems apply that we have with promotion (except that it's not a problem if we regress optimizations as they aren't "stable")
But again, what does the hook have to do with that? It won't prevent creation of that global, just access to it. I also cannot imagine how const-prop could do anything in your example... doesn't have a known value. And in a case like it would be entirely okay to replace by . Of course with it would not be okay, but then that is exactly the same as using mutable references -- and it has nothing to do with globals. So I fail to see the relevance of any of this for the discussion at hand.
I'm not worried about . I'm worried about const propping into , so is eliminated entirely. optimized to I'm not sure how we're supposed to prevent this without banning relocations in propagated constants.
I don't see why we would even try to do that, that seems like a really odd transformation? And certainly, if any code is responsible for getting things like that right, it's the code that constructs new constants, not the code that reads from existing constants? You still didn't explain how the prevents anything like that. It prevents reading from constants that have relocation, but you keep talking about constructing new constants that have relocations. My confusion remains: what does anything you say have to do with what the issue is about, namely ?
Ah, that's where the confusion comes from. Let's start with a code example again: If we const prop the at some point (or construct your own lockfree datastructure that doesn't use any intrinsics), we have now changed behaviour because we never read the runtime value of (0) but instead the initializer value (42).
(Sorry for the double-post, GH keeps submitting comments for me way before I am done. Probably some silly trigger-happy shortcut.) Indeed, that would be a problem. And that problem is caught by which would reject any read from a mutable global allocation such as . Which additional problem necessitates the additional check that follows next?
Oh. I see now. Yea, we don't need the second check, any later const prop will do the mutability check and bail out, no matter the number and kind of indirections. We can remove the check
That's what I thought, thanks. :)


Should the following code be accepted? if so, we probably also want to accept the following: cc
So,how would the following be handled? That is (passing an identifier as a const argument).
should be equal to imo. rn literals which are in both the type and the value namespace are always used as type params though (see ). So this would fail to compile even if we get to work.


I tried this code: I expected the code to fail to compile with a cycle error. Instead, it compiled and ran,printing the value of . I was able to verify that this bug happens for the 1.42.0 stable, 1.43-beta.5, and 1.44.0-nightly(2020-04-11 ) versions. Trying this code in it errors up to 1.36.0,and doesn't error anymore from 1.37.0 onwards.
cc
narrowed to the following: Auto merge of - petrochenkov:builtout, r=eddyb Auto merge of - luca-barbieri:optimize-refcell-borrow, r=RalfJung Auto merge of - Centril:rollup-, r=Centril Auto merge of - petrochenkov:rpass, r=Centril Possibly ?
Weaponized soundness hole (using as a foundation): ==
cc
oopsie yeah... is probably where this started. But that is crucial to fix The problem is that "reading from a ZST" isn't actually doing anything. Here's the MIR for : So there actually is a that loads from this static (I didn't expect that). But in Miri, a ZST load just checks that the address is in-bounds; no actual access to the underlying memory happens so there is no cycle error.
Assigning as and removing .


The JSON for is broken because the for attributes serializes to nothing. An empty library produces the following: The important bit which is clearly not valid JSON. It looks like the  serialization was removed in . I'm not sure what a solution is here. I'm guessing AST serialization is used elsewhere, where this field isn't needed. I'm not too familiar with , so I'm not sure if it has something equivalent to . cc <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Looks like the encoding/decoding change from needs to be reverted. Reverting should be ok because and don't do anything anyway (at least when inlined) during metadata encoding and decoding. The change is trivial, so marking this as E-easy, but if it's not done until the weekend I'll submit the PR myself.
claim


When calling in a fn that expects we currently emit: We should check whether and suggest the removal of the call. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
feel free to reach out either on this ticket or on a PR, but be warned that this has the potential to be quite involved. It is a great introduction to how some parts of fit together though.
I've been looking into this for a while now, and my idea was to: Check if there a .into() call, check if the type of self was T and finally check if the argument of the function was Into<T. However I cannot figure how to get the type of Self. As far as my understanding goes, rustc hasn't yet inferred the type.
You can query the in-progress type table with the for the expression. You're gonna have an with a . From the first argument in that variant you can take the first element and get the expression for in . Then you can use the for that expression to do I do not know if we will have populated 's type by then, but if we have, then that will give you the type of . Then, if you're in an you can use to see if the inferred type for can be coerced to in the original example. I know this is a bit vague, but for this is inherently exploratory work :)
Hi, are you still working on this issue
No, feel free to claim it if you want
release-assignment


This is a variant of that was not fixed by still fails with
Given that libcore and liballoc enable this feature, I am rather concerned they could inadvertently use it in a way that is still unsound. Also, unless we can fix this, the feature should probably be to to warn people against using it.
rustc bootstraps successfully with applied, so at least right now that does not seem to be the case (modulo the part of libstd that rustc never monomorphizes). Of course, that could change any time, there is no check for this.
Yes, thanks for opening this. To be specific, the issue here is centered on this line: and the fact that we have , and LLVM alloca's don't respect the alignment requirements, right? I think there may be a separate issue on that. (Link?) But: one thing we had discussed was separating out the "sound" part and the "unsound" part into distinct feature gates, so that we can enable only the former in libstd. Perhaps that's a good focus for this issue?
cc who had discussed the separate feature gate, and who might be interested in doing the follow-up work to create that gate.
Yes. Oh, I didn't know that. Let's see if someone finds it.^^ Unlike the other unsound features, this is one where we don't even have a plan for how to soundly implement it. Not sure how much I like keeping that around.
Yes, I see that argument. I'm reminded of , which limits the max alignment to 4K because of limits in dynamic linkers, though there's no real connection. It's just that part of the challenge here is that the alignment of a is totally unknown -- it's not like we can conservatively align to 64 bytes or something.
If lands we could conservatively align to 4k here. :rofl: (no I am not serious)
Assigning as , removing and nominating for discussion on our next weekly meeting.
Can't we do something dynamic where we allocate and align it ourselves? Also, this has been discussed before, hasn't it?
With being stable, this can be observed in stable compiler: EDIT: its fixed in nightly, never mind.
I don't know -- in we mostly talked about how to mitigate the effect on stable Rust. D'oh, I somehow forgot that one can manually implement "aligned" allocation on top of an unaligned allocator. Of course that would work. That's probably better than killing this part of codegen entirely.^^
, leaving the nomination up for now as requested by He wants to open some fresh issues about this.
Now that I've created more specific issues to track the important sub-tasks identified here, I think we can remove this from the nominated tickets.
Given that this feature has been removed from core/alloc and is unstable, I'm going to downgrade this to P-medium. This should obviously block stabilization of , but doesn't need special attention outside of that.


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


I've been playing around with today, and it comes in super handy in blocks. However, it seems to run into issues when combined with the feature. I tried this code: I expected to see this happen: the code should compile just fine. Instead, this happened: This is a continuation of the discussion . As , this code (following the from the label-break-value RFC) compiles: : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --This issue has been assigned to via . <!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --
So the error is generated here if I had to guess, I would assume that this function ought to be modified to check whether the and, if so, not to emit the error. (See  rust docs for a bit more info.)
Tagged as E-mentor since there are some instructions above.
claim


The following code: gives the following output: The "unused lifetimes" warning is redundant - not using a lifetime parameter is a hard error, so the warning gives no additional information.
Note that this lint still makes sense for functions: But then running clippy on the following looks dumb (the lints are redundant): I don't really know the compiler internals, but should this lint just skip structs ? (is that even possible ?)
label +E-needs-test This was fixed in but no test was for nonduplication.


I just tried the latest nightly (rustc 1.45.0-nightly ( 2020-06-01)) and noticed it can't compile one of the crates I work on. The crate does have an enum with a a huge number of variants (almost 6000), for which I use serde to derive Serialize and Deserialize. When building, even with just 'cargo check', the build fails with It works on stable 1.43.1. I tried running rustc under gdb. It didn't crash exactly the same way, I got SIGSEGV instead. Looking at the callstack in gdb, it is suspiciously deep ( functions deep). The top most functions are: If I reduce the number of enum variants to 5000, or stop using serde to derive Serialize/Deserialize, it starts working again. Since it works using stable, but not using nightly, I thought it might be some kind of regression. I totally realize this may not be a bug and that what I'm doing (Serde + giant enum) is just not a good idea. Accept my apologies if this kind of thing shouldn't be reported here!
cc -- I believe should have fixed this but I guess we're missing at least this case?
As an experiment I tried doubling the number of enum variants and compiling using stable. That still worked. So it seems the code wasn't just on the brink to stop working using the stable compiler.
Here is a github repo with a minimized test case for this issue:
It introduced a mechanism for dealing with this kind of issue, but I don’t doubt that we might have missed instances where the compiler is doing something recursive. MIR construction for matches appears to be one of these cases.
Yeah, that's what I expected, I just recalled seeing some commentary suggesting that we'd perhaps covered all cases. Definitely not unexpected that we didn't, though, nor did I intend to imply we should have :)
The beta seems to not have the problem. The problem does not occur with "rustc 1.44.0-beta.4 ( 2020-05-23)".
I saw the 'E-needs-mcve'-tag. Did you see my repro-case? (but maybe you're talking about something more self-contained, not referencing 'serde'?)
I saw the repo, but it still needs some work to be reduced to a viable regression test case that could be included into the repo along with fix. This is what I’m working on now as I already have the fix itself.
Assigning .
If anyone else gets here having the same problem, manually implementing Serialize and Deserialize rather than relying on serde-derive, is one way around the problem. I adapted the examples at for my enum and this made the compile time insignificant. It also improved performance using the old rust considerably.
Mhh, I remember having seen some other issues related to derive macros recently... cc who might know.


<!-- 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</detailsThis is a recent regression, since we run this command every day in automation.
Almost certainly a regression from /cc
looks like a duplicate of


I'm currently doing some benchmarks and I've seen that is taking a really long time to calculate on wasm. Turns out that none of the helper functions it uses are inlined at all, so it does a ton of unnecessary calls and misses a lot of potential optimizations: The same is probably true for the Float trait.
It seems like initially had a lot more inline annotations but removed them later on. That may have regressed the performance on wasm, but I'm not entirely sure. This makes me wonder if compiler-builtins is even compiled with LTO at all as it supposedly is meant to be?!
Looks like this is indeed a regression that started with Rust 1.44, which switched from compiler-builtins 0.1.25 to 0.1.27, which is where this PR is part of. These are the instructions in 1.43: cc
There's been a few various changes around codegen units handling and compiler-builtins recently, and it looks like this is caused by compiling this crate with . The compiler but with only one CGU.
Ok I've transferred this to the rust-lang/rust repository since this isn't a bug with compiler-builtins itself I believe but rather how we build compiler-builtins. I believe this is an accidental regression from because only part of the compiler knows that compiler-builtins is built with more than one CGU, the rest of the compiler thinks it's one CGU (respecting CLI flags). I'll be opening a PR shortly to fix this.
Assigning as and removing .


Code like Generates the error Which is wrong. is not a type, it's a module.


Some Miri tests, e.g. , now ICE with This is a regression introduced by The likely cause is Cc
I removed "regression from stable" as Miri does not exist on stable.
Sorry, got it.


When encountering a , there must be a corresponding in the MIR body. If there isn't, later passes can panic due to indexing out of bounds of the array. The validation pass could detect this problem earlier. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Instructions: Extend the validation pass in by implementing for the MIR visitor: The trait is documented . The method should check that the local exists in , and fail with a descriptive error message if not (by calling , not by panicking directly).
claim
FYI, the validation pass currently fails on even libcore until is merged, so you need to either wait for that, or cherry-pick some commits from there to get it to work. You can test your changes by running (the validator only runs on very little code by default, turns it on for everything).
I wanted to double check, running should fail when I run it, right? It actually passed for me after I merged in your branch from I wonder if I should try clean and build stage 1 again. :
It should pass with applied, but fail on current master.
So your PR fixes this issue () as well?
Ah, no, this issue is just about adding additional validation. It shouldn't actually detect any locals that don't exist. So the command should work both before and after implementing this. If it fails after implementing this, something else is going on that we should look into.
are you still working on this?
No, sorry. Didn’t have time for it. Go ahead.
release-assignment
Would like to work on this, but it seems there is another check, not on the declaration like this one, but on the memory liveness. This should cover the case that the local is not declared (I think), or would it not?


Recently enabled benchmarks () frequently fail on arm-android builder on GitHub Actions: The issue looks similar to previously reported .
I'm sorry, I noticed this during my local testing, but figured it was due to my hardware which had a very high parallel count, and it seemed to go away when I lowered the parallel test threads. I also had great difficulty running these tests at -j32 on android as well: They either seemed to hang, or took a very long time to finish. Would people prefer to just disable the bench tests on android, or should we do more investigation?
Again? cc
Looks like didn't fix the "died due to signal 11" errors either :(
hm, yeah if these keep coming back I guess that's reason enough for me to allocate time for it again.
will open a PR disabling collectionsbench on Android for the time being.


The following code: gives the following error: However, is a , so this code can be made to compile by creating a new item: We should suggest this to user when a function is being called in the array initializer. <strikeAssuming that is accepted, we could eventually suggest an inline block.</strikeOn Nightly, we could suggest an inline block. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I think this would make a good first issue for someone looking to get started contributing. I'd be happy to mentor anyone who wants to work on this.
claim
Is this still an issue that I can work on?
Yes, assuming that is no longer working on this.
Should I claim it?
It looks like DavidHusicka hasn't had any activity this month, so I think it would be fine for you to take the issue. Feel free to reach out to me if you have any questions about how to get started implementing this.
claim


So I had a trait system in my (nightly) code for a while now that utilized specialization, but it no longer seems to be working after a recent update: Now, I haven't been following the development of the specialization feature too closely, so it is possible that this is somehow actually intended and I am missing something. However, given that this previously compiled and ran just fine a couple weeks ago and given that the specialization incomplete warning was only recently, I am inclined to think that it is probably a regression of some sort. compiler version:
Another MVCE (): Regressed in , looks like
cc as far as I can tell this wasn't an intended outcome of the change?
It wasn't really, it was just slightly more complex to have this still work after that PR.
Would you mind describing at a high level what needs to be done?
It looks like the problem stems from the bound predicate not being fully normalized when checking the defaulted associated type. From my reproducer above: which should instead be . I'm not certain yet how this ought to be implemented. Perhaps a pass after normalization that looks for occurrences of the defaulted type ( in this case) and replaces it with the defaulted type. Seems simple enough, in theory :) But maybe there are cases I'm not thinking of.


Hey, This code attempts to increment a integer behind a tokio RwLock by 1, This causes a compiler error. Minimized example that reproduces the ICE: But, making this very small modification makes the code not break the compiler my contains as a dependency. This code does not compile, and generates the following error (full backtrace in bottom of the issue) rustc --version --verbose also breaks the same way on (the traces attached are from nightly ^) rustup run stable rustc --version -v
Confirmed this also breaks the same way on
MCVE: Fun fact: changing to doesn't ICE. Also I can't inline an instance into the function. It has to be created outside?!. Weird stuff somtimes. Also it would be nice to get rid of the deref, but I couldn't figure out how. So it's on this currently. Also worth mentioning: this needs . isn't sufficient. modify labels: -E-needs-mcve +E-needs-bisection
The bisection doesn't emit anything useful. This panics like forever. I went back to 2019-01-01 (with the old API and stuff) and it still ICEs there, so I guess it was like this forever. Feel free to add the tag again, but I'll remove it. modify labels: -E-needs-bisection
modify labels: -E-needs-bisection


This is just my personal taste. I'm never a fan of making comments italic. It is hard to read for me. Rather, I really enjoy what Dark and Light theme is doing: Mark doc comments with different color than normal comments. cc
Can you add a screenshot of what this looks like in both Ayu and Dark themes?
Here in Ayu and Dark theme respectively: ! !
I was searching about the italic comment topic and found that people prefer both. But I think the good choice is to default to non-italic and add a rustdoc config to change to italic.
We will definitely not add a rustdoc config for that (way too specific). :)
Thanks for your critique of the theme, it's been very helpful :) I would like to keep the comment style italic because: It provides a rustdoc theme with italic comments for those who like it (if one dislikes this there are two other themes that don't make this choice) The Ayu theme everywhere else has italic comments, example: ! I don't want to break with the standard Ayu look in this regard unless a significant number of people find the italics to be a problem. As far as the color being different between doc comments and normal comments, I am personally against this. I've never seen an editor highlight doc comments differently from normal comments, nor do I see a reason to do so. The only thing that sets doc comments apart from normal comments is that they are present in the generated rustdoc HTML, and to me this is not a reason to introduce an entirely new color into the mix just for the sake of styling them differently (why would you care about this when reading the comment? What benefit does the color being different from a normal comment provide, and does that benefit outweigh the visual clutter introduced by using another color? I'm interested to hear your thoughts about this). Here I would say similar to the above: the Ayu theme provides a choice to view comments with a unified color. If one dislikes this, there are two other themes available with that feature .
I'd like to comment in favour of removing the italic. In here it's important to remember that themes are only supposed to change colors, not presentation. Adding italic on comments is breaking the coherency with the other themes and I think it should be removed, even though the original theme has it (are you sure it's the theme and not the IDE btw?).
That's a fair point, I can agree with that. Yes it is the theme
I will note that my vim configuration at least does this and I personally quite like it -- I differentiate between regular comments and doc comments when reading. Regular comments are intended for the programmer and doc comments for the end-user of the API; those are at least for me two different mindsets. !
Thanks for letting me know about its origins. I've never used Ayu theme in editor other than in mdbook and rustdoc. It is great. This issue () is not related to rustdoc but it points out a group of people finding a way to disable italic on comments and language keywords on VS Code. I wish Rust-Enhancement package (Sublime Text) render they differently. already did it. Mark already posted a reason for the difference:
Interesting! Thanks for chiming in. Your point about who each type of comment is written for makes sense I'll look into a color that would make sense to use for doc comments in the theme here.
I'll throw another vote in favor of not using italics. They are, in general, a poor experience with monospaced fonts.
If people are interested, we could use a different color for the doc comments. It sounds like a good add.
I played around with some options and I believe meshes reasonably well as a doc comment color. Before: ! After: ! Another potential option that draws less attention away from the code itself is : ! Thoughts on this?
I find the last proposal better, but maybe we should put it into another issue to not lose track of the original issue? ;)
Opened a new issue :)


() Errors: Removing the makes this generate appropriate error messages. Seems like combining and is rather uncommon, at least there are no other issues with both labels yet. modify labels: I-ICE, T-compiler, requires-nightly, F-associatedtypedefaults, F-genericassociatedtypes, A-traits, A-associated-items, C-bug
Okay, this bug allows you to do basically everything. For example () () arbitrary transmutes (as long as LLVM doesn’t complain like it did above) ()
Error: Parsing relabel command in failed: ...'fy labels:' '"I-unsound'... Please let know if you're having trouble with this bot.
Error: Label can only be set by Rust team members Please let know if you're having trouble with this bot.
Error: Parsing relabel command in failed: ...'fy labels:' '"I-unsound'... Please let know if you're having trouble with this bot.
Error: Label can only be set by Rust team members Please let know if you're having trouble with this bot.
Here's another one ICE's with:
Triage: This is no longer ICE with the latest nightly, marking as E-needs-test.
Looks like this was the fix:


<!-- 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. --(I know this is probably incorrect code, but this is what triggered the internal compiler error). <!-- 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
Assigning as and removing .
44 doesn't have the ICE.
shows that this can result in no user-facing error message. I suggest increasing priority to .


Crash occurs in both 1.46.0 beta and in current nightly. : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
I made the false assumption that this was rustc crashing, but it's actually the binary that crashes upon running it.
Cc We probably just want to ban track caller on main (and maybe any lang item function?)
claim
Same with : results in edit: I think is a more general problem so I won't change that here
Assigning as and removing .


Been working in JavaScript a lot lately and find myself accidentally typing this a lot. It would be nice to automatically detect this and offer a proper fix. Lots of languages use this syntax in addition to JavaScript so it seems like a reasonable error to make. Playground example below. () Errors:
I think the current error message is clear enough. Also I don't think providing auto-fix suggestion is easy, because the error happened when parsing AST.
Nice. But I still think the current error message is fine as is.
don't disagree, but handling it was relatively easy because there's no case where would be valid.


As reported on Zulip: https://rust- This works for simple enums with one or more variants, but for zero it fails, possibly due to interaction with . This kind of code can come up in macro code. cc
I think for zero-variant enums it fails mostly as an oversight. This doesn't even have to generate any MIR as it is unreachable code anyway. Nominating for lang team discussion.
From the head comment at , I infer that this is indeed only designed to work with C-style enums. My proposal would be to add another cast category saying that empty enums can cast to anything, desugaring to .
No, enum casts have nothing to do with C-style enums. This works:
Oh, the comment says "C-like". That's not the same as . "C-like" just means that all enum variants have no data. This is satisfied by -- there are no enum variants, and thus all of them have no data.
Here's the offending check: It seems that the "payload-free" check is not just "all variants have no data" but also "it is not empty". I would hesitate to change this definition because it's likely to affect C-like enum handling elsewhere, but maybe can get another class specifically for uninhabited enums.
I'd argue a no-variant enum is payload-free. But all uses of that function should be carefully checked. Adding a new case to seems like a hack to me.
These were historically known as "C-like" enums, and is not C-like. From GCC: Can you maybe elaborate more on this?
Sure, C might not permit them, but I don't see how that's a reason to disallow casts in Rust.
I mean, what value does have that will make sense?
It's not actually reachable, so it could just typecheck without actually ever needing to produce a value.
It can compile the same way as , which is to say, produce no code and mark the remainder of the function as unreachable. Compiling to would also work for all numeric types that this could target, although then appears unused which might cause other unintended behaviors in the compiler.
Currently, the compiler marks code . What do you mean ? Unreachable is unsafe, does it mean that is unsafe ?
This uses no unsafe code: Here the code after the match statement (if there was any) would be unreachable, and this requires no unsafe code. Basically is an impossible value, therefore the function cannot be called in the first place and no code need be generated. EDIT: Your linked example is pattern matching on an with no branches. Here is an empty enum, , so an empty match of an empty enum is exhaustive without any unsafe.
Thanks, I got that part now. But the question raised by : What is the concrete example of macros that have use cases for ? Also, is a never type, if allowed, would we want to make any operations on unreachable?
The actual macro where this came up was a safe wrapper that declares an int-like enum and an array indexed by the enum. Roughly, it creates a type and , and then the implementation for uses where . When has zero elements, this causes the macro to produce malformed code. It is possible to work around this issue by explicitly checking for this case, but I don't really see a reason for it not to work in the first place. Any operation on Void is unreachable. That means that the compiler can do whatever it wants to for codegen here because it doesn't matter, the function is not callable. But from a typing point of view, I think that should have type , not .
It's no surprise that macros run into this -- this happens any time that we have special exceptions. "s without fields can be cast to integers, except if the enum has 0 variants" is such a special exception, and from a language design perspective it has no reason to exist. Not sure what the next step here is -- probably an RFC? This is a language extension after all.
Discussed in the meeting today: We agreed that this seems like a harmless extension (specifically: permitting zero variant enums to be to a usize). We don't feel an RFC is required and we would recommend somebody creating a PR that fixes this and nominates the PR for lang-team consideration, we can do an FCP directly on the PR.
I have opened to fix this issue.


<!-- 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
Given that it doesn't reproduce on godbolt I guess this is apple specific?.
I can reproduce it in playground: godbolt builds Rust code as by default.
Assigning as and removing .
There is no need for containing . Renaming to anything and make it is suffice. The error traces back to 1.0 Rust release:
here is the unwrap to blame.
Triage: This is no longer ICE with the latest nightly, marking as E-needs-test.


! Note that "Ayu" is already highlighted, it happens to mdbook too. CC
The contrast is too small indeed. Want to send a fix?
I will pass on this, I sent too many pull requests today, I can do this maybe another day (a few days) or if anyone is interested can take up this task before I do.
I'll certainly send a PR tomorrow then.


This code (): prints out This is pretty unhelpful for beginners - normally this happens when they try to use in a closure, which tells them they need async: But when they do they get an error about async being unstable, which they have no idea how to solve. The fix is to remove the pipe symbols: However, this requires knowledge that async blocks desugar internally into closures, which is not at all clear from the syntax. It would be better for the compiler to suggest it:
Hey, I saw this and it looked like it might be easy so I took a shot with I haven't fixed the tests yet because I wasn't sure if this approach is reasonable or not. You end up with Re-ordering the note and help, or adding a nested span on to put the help would be considerably more involved.
Given the current is equivalent to , it may be preferable to suggest instead of .
the point of this is that the user didn't mean though. If you add then you can no longer await it: For context, the original code was something like , where the user tried to use outside of an async function.
Thanks for clarifying. What suggestion is preferable seems to depend on the expected return type. Perhaps it is preferable to have both notes?


<!-- 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. --: I see similar behavior in stable : The example always succeeds to compile the first time, but uses a large amount of time and memory. : Upon incremental re-compilation, I almost always see one of the following errors. I saw other open issues with a similar error message as the 1.46.0 output below, but in this one the error is affected by the value the array was filled with. : Running sometimes yields a different yet similar error: On 1.46.0: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongBacktrace</strong</summary<pOn 1.46.0: </p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
do you know if this is still a problem for you? claim
On 1.66.0, I still get an error upon incremental recompilation with the same code: <details<summary<strongBacktrace</strong</summary</details
Oh wow I didn't know anyone actually hit this so long ago! I turned this into a much nicer panic a few months ago:


I believe the error message for E0308 is incorrect. Here it is, with my emphasis on the part that seems incorrect: Isn't this error because the compiler was able to infer the type, but it was not what was expected? For example, in the example provided in the error explanation, the value assigned to is most definitely , and is expected, so the types don't match. modify labels: A-diagnostics D-incorrect D-confusing C-bug
Also the explanation says: between two types: the type the author explicitly assigned, and the type the compiler inferred. Isn't the most common case passing the wrong type to a function? Usually people do not provide a type annotation to a unless it is necessary to help the compiler figure out what concrete type a generic is. Perhaps the explanation could be clarified and expanded upon for that.
You beat me to it :)
Mentoring instructions: Change to have an up-to-date diagnostic and appropriate long description.
On it.
Proposed text:
Overall text looks good. Can you open a PR and -mention me on it?


The feature gate for the issue is . Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label. <!-- Include each step required to complete the feature. Typically this is a PR implementing a feature, followed by a PR that stabilises the feature. However for larger features an implementation could be broken up into multiple PRs. --- [x] Implementation () [ ] Adjust documentation ([see instructions on rustc-dev-guide][doc-guide]) [ ] Stabilization PR ([see instructions on rustc-dev-guide][stabilization-guide]) [stabilization-guide]: https://rustc-dev- [doc-guide]: https://rustc-dev-
Ad discussed starting in I’m not convinced this feature carries its weight to be included in the standard library, given that also exists.
may be more useful.
How so? Trying to go beyond "I want to borrow because I want to borrow"
In a similar vein, I was curious if the opposite existed, converting from to : I do not have a specific usecase in mind. My thoughts were likewise around avoiding the copy (small as it may be).
Something kind of like that exists:  It returns because the byte slice might not be aligned properly for an , so it returns the unaligned parts separately. It's also unsafe because it can transmute to any type. A safe version for integers could be possible, but that won't solve the alignment problem.
A good point! The original case had a , which I neglected to show here. You get that "for free" if you store a and have something like the suggested .
Sorry for replying really late here (I accidentally unsubscribed from the issue.) but how should I proceed from here? Remove the function from std as per Simon's suggestion Add another function Though, the one does sound interesting to me although it is unrelated my original use case.
This feature would be useful to make this be a safe conversion. Currently this requires unsafe code. We use this type of abstraction in ; it would also be handy in some serialization-type libraries.
One other suggestion. It would be useful if this method returned a type like (pseudo-code for a newtype that guarantees that the byte array is 4-byte aligned). This would allow for safe two-way <-conversion. In other words, returning is nice in that it remembers the length, but it throws away the alignment. It would be nice if we could also retain the alignment information.
Which "this" are you referring to? Why does not work for you?
I meant that allows the conversion from to to be safe. Right now it requires .
Also: in conjunction with , this feature would also enable safe conversion from to .
Regarding : I believe that would be out of scope for this feature? At least, I am not aware of any machinery in that allows one to say "the returned value is N-byte aligned", so doing that would require a new feature that mimics the crate in .
I think I'm with on this one. Given that this can't (portably) have and , I'm not sure it's worth having as a distinct thing, assuming that the Safe Transmute project lands -- as one of its top two use cases is offering native-endian views into everything where it's safe to do so, including and and such.
Agreed. I think it would be great to wait and see what the Safe Transmute project gives us here.
The use case is valid but a more general mechanism is direly needed here (something like this came up in Portable SIMD discussions).
Opened which removes this feature.


xref: In the of , one of the tests crashed with on s390x, while it passed on every other architecture. The reporter in Red Hat bugzilla found that it happens equally with system LLVM 11 or 10. The crate's also has , but they didn't see any improvement after turning that off. The distro builds run tests in release mode (to avoid recompiling from the main build) with flags in : The tests pass if we don't set , which suggests to me that some relevant (mis)optimization is only triggered with the full unit. The tests are also fine with Fedora's rust-1.45.2, only crashing on rust-1.46.0. I also reproduced the crash on rustup's stable 1.46.0, and I used to narrow down to passing, while crashes. That's ..., which is just (cc I don't know if would affect that, or if it's just triggering something new in LLVM. Here's the reporter's backtrace:
cc , another miscompilation on a tier 2 architecture that appeared after a similar optimization. If the root cause is the same, we should have a better chance of diagnosing it now, since it occurs in a crate's test case instead of while compiling Firefox. cc as well.
Assigning as discussed as part of the and removing .
Is supposed to avoid 's changes? That was mentioned in zulip , but I still get the crash with that option on nightly-2020-07-06.
No. That person was mistaken. Drop elaboration runs unconditionally as part of "".
Updating for cross-reference: I tried in , but it didn't help.
As a sanity check, was there any difference in the generated MIR for ? I tested the flag locally and it worked, but we should make sure. If there's no trivial error with the flag, I'm not sure what's going on. I guess we could with the more precise version of but the less precise version of (that was the status quo before ). I would be surprised if we had a miscompilation when using the precise version of both () or the imprecise version of both ( with or a release prior to ) but not with one precise and one imprecise (a release between and ).
Here are the test's after : They were compiled on Fedora Rawhide (34), in case anyone wants to find libraries to actually run the test executables.
Here's for reference: From : The error we get during the test case is , , "No such file or directory", which prints fine. With , the assembly after printing is: I believe that 2 is comparing the tag, where only needs dropping. When I step through, that branch is taken to skip ahead. Otherwise, you can see that it would load (offset 8 from before) for the into , then proceed to dereference that pointer. With , the assembly after printing is: Looks similar with 2, but I don't really speak SystemZ to guess what and are doing. But in the debugger I see that this branch is not taken, and then it loads a garbage pointer into (always seems to be ). The load of is where we .
Found the instruction reference... is Load Logical Immediate (low high) is Add (64), Condition code set So it seems to be clobbering the condition. I'm guessing the revised enum drops just exposed an existing codegen bug.
Nice! Since I didn't want you to have all the fun, here is the LLVM IR for the relevant section. The first basic block is the comparison with the enum discriminant of and the second is the first piece of drop glue. The structure looks to be the exact same, but there are additional annotations in the one with the miscompilation. I think these are correct in a vacuum, but I don't have enough LLVM knowledge to say for sure. I certainly don't have enough to hypothesize why they caused the instruction scheduler to forget all about the need to preserve flags/condition codes. 2020-07-05: 2020-07-06:
gets special treatment -- -- did something about your patch affect that visibility? I'm guessing, maybe before it was dropped indirectly through ( pending ), but with the more precise drops it may be dropped by value? ( does get .) Or if it used a raw before (like ), that doesn't get any annotations. Of course the trait uses , but I don't know what it looks like when an implicit MIR is elaborated.
In the MIR for the "precise" version, we move the error variant into a local, then drop the local. In the MIR for the imprecise version, we check the drop flag for the variant, then drop that projection. As you alluded to, perhaps there's some difference in how we were emitting LLVM IR for drops of locals vs drops of projections? I'm not an expert on codegen. However, given that this miscompilation is present on the latest master even without "precise" drop elaboration, we must have eliminated this difference at some point. Indeed, the declarations persist even with precise drop elaboration disabled on a recent : <details<summary<b -Zprecise-enum-drop-elaboration=no</b</summary</detailsOne thing occurs to me now that didn't last night: These lines seem to be checking the vtable for the boxed trait object in : However, trait object vtables can definitely alias globally. I don't see how this kind of error would cause the miscompilation we're seeing, but as I said I don't have much LLVM expertise. Regardless, it seems like something we should fix?
The actual vtable should be shared read-only, which is fine for LLVM .
Let's see what LLVM devs say:
It looks like an LLVM patch was accepted:
I'll backport that patch after the LLVM 11.0.0 final rebase lands -- . (I thought about doing that together, but figured it would be better to separate concerns.)


ing a value of an empty enum is valid, however ing a reference to a value of an empty enum produces . I tried this code (): I expected to see this happen: The code should compile with no issue, and the function should never actually execute because has no variants and thus cannot be instantiated. Instead, this happened: The bug exists on 1.47.0 and 1.49.0-nightly (2020-10-18 ) running on the playground. I first found this bug on 1.46.0. : <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
This is currently working as intended, but maybe we should say so in the diagnostic
Why is this the intended behavior? I find it notably surprising because I can usually replace with , and the commiler takes care to insert (de)references magically. This would be an exception.
I don't recall, but you might be able to find some of the old discussions
I was just reading some discussion on the exhaustive_patterns issue: IIUC, the reason that (where is an uninhabited type) is considered inhabited is because unsafe code can construct an -reference to an uninhabited type (e.g. with or ). I don't know enough to be sure though.
Though unsafe code can also construct an uninhabited without using references; e.g.: () Output: Errors: So maybe what I said in is not correct?
I think the difference is that creating a value of type like you did is Undefined Behavior, but creating a isn't. Try running your code using the MIRI tool (available on the playground under Tools), it usually tells you when you do UB
Indeed, transmuting to didn't make Miri report UB (though attempting to print the value did) but transmuting to did.
Nice. Indeed dereferencing a reference to unintialized memory is also UB. Instructions to fix this: add a test case named after this issue in the folder find where the error message is emitted (somewhere in ) check when the type is and the subtype is uninhabited (which you can test using ) in the above case, add a note to the error message, saying something like "references are always considered inhabited". I'm not sure if we want to mention why. maybe add some related positive and negative tests to make sure we only emit the new note when relevant maybe test and handle cases like as well? modify labels: +E-easy +E-mentor
On the contrary, constructing a which does not reference a valid is instant UB . A value of type is just as invalid as a value of type .
Oh shoot, I understood the opposite. Then I've misunderstood what says in their blog post: Maybe that post is old and things have changed since? Or maybe unintialized memory does not count as an invalid value?
The rules for validity of reference are not finally decided yet, but still being discussed at rust-lang/unsafe-code-guidelines. To not preempt the conclusion of this discussion, the docs declare as much UB as is possible -- we can always relax UB later, but introducing more UB is a breaking change.
Ok, I understand that if we want to have the option to relax this later, then we can't have the compiler rely on it. So we must treat as inhabited. Otherwise we would accept the following but it would become unsound if we relax the UB: So should stay as it currently is and my are still the way to go.
claim
Thanks for taking this on ! Feel free to ask me questions here or on .
Thanks for the warm welcome :) I do have questions, but I already made a preliminary commit to check if I'm going in the right direction: (edited because I missed a file) Is that ok, or is it better if I ask questions before committing, or just make a PR and adapt it?
That commit looks like what we want yes :) Go ahead and make a PR, it's easier to comment on specific bits of the code
For those who (like me) find this after googling "references are always considered inhabited" (the compiler's help message), the current discussion on this topic is happening in
I've a comment here: Which suggests that we consider making it UB to construct such a reference, so that this macro code doesn't confusingly start breaking for empty enums: