Change:
Hi, I just got a crash on Travis, on stable (1.35.0), when enabling edition="2018" Commands ran by Travis: which causes this output: But I can't reproduce this on my computer. Link to the Travis log: https://travis-
Cannot reproduce with local 1.35.0. Build passes with the exact same compiler, git commit and command line. Maybe something travis specific? Can you try to upgrade to the latest 1.36.0 and see if it still happens?
It works on 1.36.0-beta.7 on travis: https://travis-
does this happen even after clearing the Travis cache?
That fixed it. Should I close the issue?
No, that means it's an incremental compilation bug. Finding a way to reproduce this would be good.
I just got the same error on my project, and I am able to reproduce it first building on a first commit and then immediately building again on the next commit. Edit: see my message below
Okay I got it: a new library crate (this way unused stuff doesn't get optimized out): a public trait with a function named : the trait to a structure (keeping the same name), and the function to a field (with the same name too). I don't think the type matters but I haven't tried with different types: again; here the error shows up for me.
Can confirm the mcve above!
<strikeRegression in nightly-2019-05-06 (looking for the exact commit)</strikeregression in CC modify labels: -E-needs-bisection
You have to be kidding me. Just from causing a regression, we can tell that: 's method 's field used to have different s but don't after that PR. Now they're both . But there should exist examples of collisions before , I don't think I introduced the only ones that cause this bug. EDIT: I can't get those to trigger an ICE, traits might be special :(.
cc Any idea how matching s can cause an ICE? AFAIK you would still have the different HIR, which would result in the old query results being discarded.
Compiler team triage: Marking as P-high as this is some sort of regression. No assignee yet.
Hi, I'm affected by this too, I saw from comment it's related to incremental build. What command should I use to workaround this?
Use when you encounter it. It should not happen unless you change something between builds. Or you could disable incremental compilation
DefPaths a probably expected to be unique in many places.
Not sure that makes sense to me, they're based on names, and names can get reused - sounds maybe like a small red-green oversight? Or maybe just older quirks of the first incremental attempts, that stuck around?
reused as in "the same name can refer to different things in subsequent compilation sessions" or reused as in "there can be two things with the same name in the same scope"? The former should be handled just fine incremental compilation. That latter should lead to differing disambiguation indices in the given components.
The former, it's what's causing this ICE. changes from a method to a field and that breaks incremental.
Yes, that's a bug then. Just wanted to clarify.
Hey so and I were talking and he's going to take a crack at this -- and neither of you have any in-progress fixes, right?
No, I don't think anyone has gotten farther than the original testcases. I tried to construct other examples that result in the same def paths (some of them have been like that forever), but they're not drastic enough to cause the bug to show up.
I haven't really been looking into this.
looks like it probably is a duplicate of this.
I encountered this but too today. rustc 1.38.0 ( 2019-09-23) Did exactly the same. Had a trait and made it a struct later on. Different name and field though, which remained the same. Only occurs if cargo is in the game. not if compiled with rustc ..rs
You can reproduce with if you pass (Cargo passes I think).
reassigning to self
Reproduced locally. Looking into it. Potentially interesting observation: the bug only arises when replacing a trait with a struct. (Going in the other direction does not ICE.)
(I haven't looked at this since I last checked in, but I want to look more into it, because its one of the few cases of an incremental compilation ICE where we actually have enough information to reproduce the bug locally...)
The problem seems to be that called from is untracked and reveals the without adding a dependency. When is changed from a method to a field, this will change without causing to be re-executed. just a workaround for this, but doesn't really fix the issue.
I see 3 ways we can fix this: use a query for to track the dependency encode the into so receives this information as an argument instead of discovering it through make sure there's a 1:1 correspondence from to HIR owners ('s with as the local item)
Nitpick: is meant to mean "item-local (node) ID", maybe something like would be better at describing this but unsure. and HIR owners matching is something I want in the medium-term but I'm unsure how long it would take to get there.
do you think it was a mistake to add the "workaround" in PR ? My observations was that these bugs were so hard to track down in practice, they simply weren't getting fixed, at least not in any reasonable time frame. Bug reporters almost never provided enough context for us to reproduce them, which meant they were not actionable on our end. Now, if the ICE here were preventing an even worse outcome, such as incorrect codegen, then I would want to keep the ICE in place. But my understanding, at least for PR , that the alternative to ICE'ing in that case was to just do some potentially unnecessary re-compilation work. Which is unfortunate and wasteful, but not the same sort of criticial misstep that could really have bad conseqences downstream, in my opinion. if we had some infrastructure in place to more readily reproduce such bugs when they arise, then I would be more readily convinced that we could remove a workarounds like PR . An example of such an infrastructure I have mused about: Snapshot the source for a crate on each successful compile (i.e. each compile where we emit build products that we will reuse as part of a subsequent incremental build). Then, when a compile fails due to an ICE originating from the incremental dep-graph infrastructure, request that user include the original source as well as the their changed version.
Neither you nor found the root cause, so I don't think the workaround PR was a mistake, but I do think it should be reverted once the root cause is fixed (it seems quite specific anyway). I think auditing information reachable from is more effective than the incremental bug reports we get. We should also audit manual implementations (we sort collections for some reason, which is incorrect and slow, and there's probably other bugs lurking). After showed incremental regressions I looked over the HIR map and found . The type might hold some other bugs too. Having query system from the start (before parsing) would help prevent bugs by ensuring things go through queries instead of through .
I'd like to understand this in more detail. I think is not a workaround, it just removes false positives from the assertion. do you know where in the error occurs? Is there an untracked decision made based on the ? E.g. is used to determine if this is an item or just a field? That would indeed be problematic. However, that also sounds like a different issue. The assertion triggered here checks if the DepNode for all current HIR items exist as expected. The problem you are describing is that we miss a change in a downstream query. I'd like to know how the two relate? Did you run into this assertion while working on Only sets and maps should be sorted in order for generating a stable hash value. Otherwise they'd still be "sorted" just by whatever logic and random runtime values determine their position in the collection.
calls which uses the to select which dep node to read. If the HIR id refers to a HIR owner, like the trait method , we read from , if it doesn't refer to a HIR owner, like the struct field , then we read from the parent HIR owner, which will be . In , will have a dependency on . In , will have a dependency on . If our incremental state correspond to and we try to build . We'll try to mark as green. We assume that the first dependency of must always be executed in since has no information available to it to conditionally execute the first dependency. Hence we know that has a dependency on so executing is safe. However that is incorrect, since we know that in should have a dependency on not . The compiler will (incorrectly) still go ahead and try to force which leads to this ICE (or another ICE in ).
Hm, I think I see what's going on now. From that description it looks to me like does the correct thing here: In we register a dependency on . In , where is not a standalone item anymore, we don't allocate a for (because has been removed as far as dep-tracking is concerned), and then during try-mark-green we reach one of the branches that appropriately deals with removed inputs by treating them as changed. So far this is the behavior I would expect. However, at that point things can still go wrong: came back as , i.e. is considered and the caller of , i.e. concludes that in order to find out if it has changed. As a consequence is called, which in turn will call but, alas, is a field now, so calling for it will ICE. Is that correct? I.e. is the ICE happening when trying to force (as opposed to when trying to force )?
No. Forcing/executing works fine in both and . This ICE happens in . When we call in the compiler is already in an invalid state. We're trying to mark a dep node which is not used or needed in as green. That must never happen. If instead used an query. It would have an additional dependency before the / dependency. In that case in when marking , we'd see that is red and exit early before we even get a chance to look at the non-existing .
I wouldn't call that an invalid state. The previous dep-graph is expected to contain nodes that don't exist in the current context anymore; it's how we deal with removed items. Failing to mark such removed dependencies as green is a way of handling this appropriately -- except that that strategy fails when query key reconstruction accidentally succeeds because of overlaps, as demonstrated in this bug. I can see how an query would solve this particular problem. But the underlying problem would persist. Including the component-kind in the might be a more fundamental fix. I'm not sure how viable it is. Switching to a setup where inputs cannot be removed (e.g. because there is always exactly one input like ) would also solve the problem.
and : am I correct in my understanding that with the "workaround", for lack of a better term, that landed in PR , we should no longer see any ICE's here, and the remaining work item(s) here are about fixing more fundamental issues in the compiler internals that might allow us to remove that workaround? If this is the case, then I would probably prefer that we open a fresh issue for that follow-up work, and (re)close this issue as fixed, if for no other reason than to keep the comment thread clean.
I'm not entirely sure. I think the changes in make sense, but I also see how they might just "shift" the problem in some cases (as described ). Also and I might have been talking about two separate problems, both of which can exist at the same time. I think this particular issue should be closed as it talks about a "dep-node pre-allocation" failure (a false positive which is fixed by ). I'd like to understand more about the problem is seeing in A separate issue with a reproduction case is a better venue for that. I would have expected that makes most DepNode pre-allocation go away, but due to illness I haven't actually had the chance to review that PR in any detail.
In my efforts to add things to the , I couldn't get the MVCE to ICE on the latest nightly.
Just wanted to confirm it again by renaming of trait to struct with rustc 1.41.0 ( 2020-01-27)
Triage: Since this has been fixed and is covered by a regression test, is it still relevant to keep open?
Going to close as fixed with test.

Discussion:
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; use rustc_errors::Diagnostic; <ins> use rustc_hir::def_id::DefId; </ins> use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::collections::hash_map::Entry;

} else { match dep_dep_node.kind { DepKind::Hir | DepKind::HirBody | DepKind::CrateMetadata => { <del> if dep_dep_node.extract_def_id(tcx).is_none() { </del> <ins> if let Some(def_id) = dep_dep_node.extract_def_id(tcx) { if def_id_corresponds_to_hir_dep_node(tcx, def_id) { // The `DefPath` has corresponding node, // and that node should have been marked // either red or green in `data.colors`. bug!( "DepNode {:?} should have been  pre-marked as red or green but wasn't.", dep_dep_node ); } else { // This `DefPath` does not have a // corresponding `DepNode` (e.g. a // struct field), and the ` DefPath` // collided with the `DefPath` of a // proper item that existed in the // previous compilation session. // // Since the given `DefPath` does not // denote the item that previously // existed, we just fail to mark green. return None; } } else { </ins> // If the node does not exist anymore, we // just fail to mark green. return None; <del> } else { // If the node does exist, it should have // been pre-allocated. bug!( "DepNode {:?} should have been  pre-allocated but wasn't.", dep_dep_node ) </del> } } _ => {

} } <ins> fn def_id_corresponds_to_hir_dep_node(tcx: TyCtxt<'_>, def_id: DefId) -> bool { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); def_id.index == hir_id.owner } </ins> /// A "work product" is an intermediate result that we save into the /// incremental directory for later re-use. The primary example are /// the object files that we save for each partition at code

<ins> // revisions: rpass1 rpass2 #[cfg(rpass1)] pub trait Something { fn foo(); } #[cfg(rpass2)] pub struct Something { pub foo: u8, } fn main() {} </ins>