Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yet another associated type ICE (probably more missing normalize calls) #65934

Closed
pnkfelix opened this issue Oct 29, 2019 · 25 comments · Fixed by #77741
Closed

yet another associated type ICE (probably more missing normalize calls) #65934

pnkfelix opened this issue Oct 29, 2019 · 25 comments · Fixed by #77741
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html A-trait-system Area: Trait system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@pnkfelix
Copy link
Member

(spawned off of #63154)

This variant of the code from #63154 still causes an ICE on nightly rustc (play):

trait Trait {
    type Assoc;
}

impl Trait for () {
    type Assoc = ();
}

trait Dummy<T> {}

impl<T> Dummy<T> for () {}

fn make<T: Trait>() -> impl Dummy<T::Assoc> {}

fn extract<T>(_: impl Dummy<T>) -> Option<T> {
    None
}

pub fn ice() {
    extract(make::<()>());
}

yields:

error: internal compiler error: broken MIR in DefId(0:26 ~ issue_63154_b[8787]::ice[0]) (NoSolution): could not prove Binder(TraitPredicate(<impl Dummy<<() as Trait>::Assoc> as Dummy<()>>))

thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:391:17
@pnkfelix pnkfelix added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Oct 29, 2019
@Centril Centril added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-nominated A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html labels Oct 30, 2019
@pnkfelix
Copy link
Member Author

triage: P-high, removing nomination label

@pnkfelix pnkfelix added P-high High priority and removed I-nominated labels Oct 31, 2019
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Nov 1, 2019
@Andlon
Copy link

Andlon commented Nov 22, 2019

I'm running into an issue which might be related to this, but I can't really tell if it is the same issue or not. Perhaps someone would be willing to help me determine if it is?

I'm experiencing ICEs across stable, beta and nightly. cargo check appears to work fine. I've turned off incremental compilation (e.g. export CARGO_INCREMENTAL=0), and the issue persists. I've attached the result of cargo clean && cargo build, with RUST_BACKTRACE=1.

buildlog.txt

The issue is also not entirely reproducible: on some computers, the issue is not triggered for the same code base, however when continuing to develop it will inevitably appear. Similarly, at present, I've just confirmed that compiling in release mode seems to have worked, whereas debug mode did not. I don't see any obvious patterns in what determines which configurations trigger the bug.

I don't see right now how I can reduce my code down to a minimal example, but since I'm working against an academic deadline and my code does not reliably compile right now, I'm in a bit of a pickle, and would really appreciate any pointers that could help me either properly report the bug or to resolve the issue.

@WildCryptoFox
Copy link
Contributor

@Andlon Can you provide the code?

@Andlon
Copy link

Andlon commented Nov 23, 2019

@WildCryptoFox: Not publicly, at this point, unfortunately, as it contains algorithms that we need to keep a little under wraps for some time (at least until it's been accepted for publication). But it's intended to be open sourced later on, so I think it won't be a problem to provide the code to select individuals, if that could work for you?

@WildCryptoFox
Copy link
Contributor

WildCryptoFox commented Nov 23, 2019

@Andlon I've pinged @eddyb who does enjoy reducing code.

Do you have a function in the form of fn make<T: Trait>() -> impl Dummy<T::Assoc>?

If so, my workaround may help you. Try transforming it as fn make<T: Trait<Assoc=Y>, Y>() -> impl Dummy<Y>.

@Andlon
Copy link

Andlon commented Nov 23, 2019

@WildCryptoFox: I don't think I have a function like that in the code that the compiler actually complains about, but there's a whole lot of generic and associated types used in various ways in general.

Actually, I looked at the code again and tried to reduce it a little, and it seems as if the problem is independent of the function signature, but instead has something to do with the interaction between nalgebra types Vector1, Vector2 and conversion to Point2, so it might be entirely unrelated to this issue after all. I'll try to see if I can reduce it further and come back to you (hopefully today, if not then tomorrow).

@WildCryptoFox
Copy link
Contributor

@Andlon It might hit the same problem via a different route. Good luck with reducing. I've pinged you in a private gist. I could take a look at the code; though I'm a bit busy right now so no guarantee for when.

@pnkfelix
Copy link
Member Author

By the way I wrote a recent blog post on generic techniques for reducing compiler bugs in Rust. It might give you ideas.

http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/

@Andlon
Copy link

Andlon commented Nov 23, 2019

@WildCryptoFox: thanks, appreciate it!

@pnkfelix: I skimmed your blog post, and there's some really good advice in there. I'll try to follow your approach and see where it takes me.

I observed something strange, btw. I have a workspace consisting of multiple crates, the relevant two are apps (which contains the main binary) and a library fenris. The following gives me an ICE:

cargo clean && cargo build -p apps -p fenris

The following two commands, run independently, do not give me an ICE:

cargo clean && cargo build -p apps
cargo clean && cargo build -p fenris

Not sure what to make of that. I'll report back once I (hopefully) manage to reduce stuff down to something more minimal, as per @pnkfelix's suggestions.

@Andlon
Copy link

Andlon commented Nov 23, 2019

As I started out trying to reduce the code, I realized the following:

The ICE occurs for nightly-2019-11-15 1bd30ce2a. It does however not seem to appear for nightly-2019-11-16 5c5b8afd8. I'm not entirely positive that the bug is gone, however, or if it's just not being triggered somehow. I can still try to make a somewhat reduced case for 2019-11-15 though. How can I figure out if there were any relevant changes in 11-16 compared to 11-15?

@lqd
Copy link
Member

lqd commented Nov 23, 2019

You may be able to use cargo-bisect-rustc to bisect to a commit, as documented in the tutorial, which also shows how to get the bors commits in that date range.

@Andlon
Copy link

Andlon commented Nov 24, 2019

@lqd: thanks for the tip, that sounds like an excellent idea!

So far I've spent hours gradually reducing the test case in the spirit of @pnkfelix's suggestions. That is, I copied the whole git repository, and removed piece by piece while making commits after verifying that the code still exhibits the ICEs when running cargo clean && cargo build with a specific rustc nightly version. It has taken some time since I keep having to completely rebuild nalgebra. However, after removing some unneeded dependencies, the ICE stopped appearing. I rolled back some commits, and the ICE also did not show up again. In fact, I went all the way back to my initial commit after cloning the repository, and indeed, the ICEs still did not appear. I then tried to remove my ~/.cargo/registry and ~/.cargo/git folders, and I still do not get the ICE. The ICEs are gone even on stable now.

I have no idea what's going on, and how to go further in debugging this. I would really appreciate some advice for how to proceed.

In my mind (knowing nothing about compiler/cargo internals), it seems as if the ICEs are perhaps only triggered under certain conditions related to the state of (cached) dependencies?

@WildCryptoFox
Copy link
Contributor

@Andlon Removing the registry or Cargo.lock may have caused versions of dependencies to have changed. The bisecting may need to involve dependencies... Glad to hear you're out of the ICEy waters.. though it would help if we knew what happened. 😕

@Andlon
Copy link

Andlon commented Nov 24, 2019

@WildCryptoFox: At least Cargo.lock was checked in during the whole time.

Unfortunately, I don't think I'm out of the waters yet - in fact, I expect it to come back, as I had the same issue a few days ago. Then I upgraded from 1.38 to 1.39, and I thought at first that this fixed my problems, but they reappeared later in the day. So unfortunately I expect it to come back again.

@Andlon
Copy link

Andlon commented Nov 25, 2019

So, here are some good news: I've successfully managed to create a testcase of less than 200 lines (plus a dependency on nalgebra), and it seems to be fully reproducible on the latest nightly and beta. At least I've tried it on two different Linux computers (one running Ubuntu 18.04 and the other Debian 10). Strangely, it seems to suddenly not produce an ICE on stable at the moment, but I must assume this is just a coincidence: the conditions that trigger the ICE seem to be extremely brittle to begin with.

To illustrate the latter, removing unused dependencies might cause it to go away. At one point, I could not remove a dependency, but by adding the dependencies of this dependency and removing them one-by-one, I could somehow manage to completely remove the original dependency while still being able to reproduce the ICE. I would perhaps guess that doing it this way ends up giving a slightly different Cargo.lock compared to just removing it outright?

After my previous comment, I double checked, and I was accidentally ignoring Cargo.lock. After going back to a Cargo.lock that exhibited the ICE and working my way from there, I was able to continue the reduction process.

Even though the code is in a single code file lib.rs, simply copy-pasting it into play.rust-lang.org does not reproduce the ICE. It seems that the way the dependencies are set up plays an important role: in particular, I had to leave a dependency on serde in Cargo.toml, even though serde is not used directly by the code. I've made a git repository here: https://github.com/Andlon/ice_testcase . I will leave it up for the foreseeable future, but please let me know if I should move the code to somewhere better suited. Note that there is a rust_toolchain file in the repository.

I think at this point, I am not able to get much further in reducing the test case, and so I would be happy if someone with more experience and knowledge about the compiler could pick up the trail. Please let me know if I can be of any assistance, however!

For completeness, here's the output of rustc --version --verbose on my Ubuntu machine:

rustc 1.41.0-nightly (0c987c5c0 2019-11-23)
binary: rustc
commit-hash: 0c987c5c02498b4e77f5dfae1f6914ffb9268575
commit-date: 2019-11-23
host: x86_64-unknown-linux-gnu
release: 1.41.0-nightly
LLVM version: 9.0

@WildCryptoFox
Copy link
Contributor

WildCryptoFox commented Nov 26, 2019

@Andlon Testing with both 2019-11-24 and 2019-11-25; only the build on the 24th triggers the ICE, indicating it was fixed in the build on the 25th.

Try updating your rust-toolchain to nightly-2019-11-25.

Edit: I tested with nightly-2019-11-26 too and that does ICE!

rustup update may have avoided the newest version due to missing optional components (clippy?) for that version at the time.

I can confirm the ICE of this issue remains in play.

I think you should open a new issue.

@WildCryptoFox
Copy link
Contributor

WildCryptoFox commented Nov 26, 2019

@Andlon Curiously when adding default-features = false to nalgebra the ICE goes away, and stays away if you enable its std feature. This is odd because nalgebra's default only implies std and none of its code is conditional to the feature = "default".

To add to the ICE reducing tips: remove everything the dead_code lint signals (including your things renamed with the underscore prefix), set your ICE-trigger as public (and make everything else you can private), use default-features = false on dependencies to reduce features and use #[no_std] to reduce std to core.

@WildCryptoFox
Copy link
Contributor

WildCryptoFox commented Nov 26, 2019

@Andlon
Copy link

Andlon commented Nov 26, 2019

@WildCryptoFox: that's great, thanks! As you suggested, I've opened a new issue here: #66768.

@WildCryptoFox
Copy link
Contributor

WildCryptoFox commented Nov 26, 2019

@pnkfelix I just noticed the test you included is the partially reduced variant, not the most reduced variant. Per @eddyb 's post in the previous issue. This smaller variant actually triggers two MIR errors - one more than the variant above.

trait Trait {
    type Assoc;
}

impl Trait for () {
    type Assoc = ();
}

fn unit() -> impl Into<<() as Trait>::Assoc> {}

pub fn ice() {
    Into::into(unit());
}

@pnkfelix pnkfelix added the A-trait-system Area: Trait system label Nov 28, 2019
@Aaron1011
Copy link
Member

It looks like this is cauesd by the un-normalized projection <() as Trait>::Assoc appearing in the result of tcx.predicate_of for the opaque return type of unit. This causes SelectionContext.match_projection_obligation_against_definition_bounds to fail to find a candidate from the opaque type's predicates, resulting in the ICE.

I've not entirely certain where the normalization should be taking place. Should tcx.predicates_of perform the normalization, or should SelectionContext be doing it?

@JohnTitor JohnTitor added the C-bug Category: This is a bug. label Jan 12, 2020
@eddyb
Copy link
Member

eddyb commented Jan 16, 2020

Should tcx.predicates_of perform the normalization

AFAIK no, predicates_of should be "as written", and the caller should do any necessary normalization. (pretty sure lazy normalization of associated type projections would fix this)

@WildCryptoFox
Copy link
Contributor

@WildCryptoFox
Copy link
Contributor

Update: This still triggers an ICE on the latest nightly.

(Still triggers ICE on latest nightly)

@JohnTitor
Copy link
Member

Triage: This is no longer ICE with the latest nightly, marking as E-needs-test.

@JohnTitor JohnTitor added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Oct 7, 2020
@bors bors closed this as completed in 5565241 Oct 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html A-trait-system Area: Trait system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants