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

ICE: stack overflow using imported type in Fn/FnMut across three crates #61711

Closed
carado opened this issue Jun 10, 2019 · 7 comments · Fixed by #62503
Closed

ICE: stack overflow using imported type in Fn/FnMut across three crates #61711

carado opened this issue Jun 10, 2019 · 7 comments · Fixed by #62503
Assignees
Labels
A-resolve Area: Name/path resolution done by `rustc_resolve` specifically C-bug Category: This is a bug. 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

@carado
Copy link

carado commented Jun 10, 2019

I have three crates: a (library), b (library), and c (binary).

a has no dependencies, and its src/lib.rs is just:

pub struct Struct;

b has the following dependency and src/lib.rs:

[dependencies]
a = { path = "../a", version = "*" }
pub use a;
pub use crate as alias;

c has the following dependency and src/main.rs:

[dependencies]
b = { path = "../b", version = "*" }
use b::alias;

// the error happens with Fn and FnMut but not FnOnce
// (the error also happens if the `F` parameter is an `impl Trait`)
// (the error also happens if crate c depends on crate a and uses `a::Struct` directly)
fn f<F: Fn(b::a::Struct)>(_: F) {}

fn main() {}

The following error happens running cargo check or cargo build in crate c:

carado@ram:~/tmp/rust8/c $ rustc --version
rustc 1.37.0-nightly (400b409ef 2019-06-09)
carado@ram:~/tmp/rust8/c $ RUST_BACKTRACE=full cargo check
    Checking a v0.1.0 (/home/carado/tmp/rust8/a)
    Checking b v0.1.0 (/home/carado/tmp/rust8/b)
    Checking c v0.1.0 (/home/carado/tmp/rust8/c)
warning: unused import: `b::alias`
 --> src/main.rs:1:5
  |
1 | use b::alias;
  |     ^^^^^^^^
  |
  = note: #[warn(unused_imports)] on by default


thread 'rustc' has overflowed its stack
fatal runtime error: stack overflow
error: Could not compile `c`.

Caused by:
  process didn't exit successfully: `rustc --edition=2018 --crate-name c src/main.rs --color always --crate-type bin --emit=dep-info,metadata -C debuginfo=2 -C metadata=d99834104ec97a8f -C extra-filename=-d99834104ec97a8f --out-dir /home/carado/tmp/rust8/c/target/debug/deps -C incremental=/home/carado/tmp/rust8/c/target/debug/incremental -L dependency=/home/carado/tmp/rust8/c/target/debug/deps --extern a=/home/carado/tmp/rust8/c/target/debug/deps/liba-abc860a16fd4c695.rmeta --extern b=/home/carado/tmp/rust8/c/target/debug/deps/libb-b7de48bb96cbc467.rmeta` (signal: 6, SIGABRT: process abort signal)

Try as I may, I can't manage to make the error happen without putting in every one of those lines and dependencies.

EDIT: the bug only requires crate as alias, not crate::{self as alias}

@jonas-schievink jonas-schievink added A-resolve Area: Name/path resolution done by `rustc_resolve` specifically C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 10, 2019
@pnkfelix
Copy link
Member

pre-triage: P-high, removing nomination tag. assigning to self for initial investigation.

@pnkfelix pnkfelix added P-high High priority and removed I-nominated labels Jun 27, 2019
@pnkfelix pnkfelix self-assigned this Jun 27, 2019
@pnkfelix
Copy link
Member

pnkfelix commented Jul 8, 2019

(seems to me like the use b::alias; line is not necessary to reproduce the bug?)

((but the pub use crate as alias nonetheless does remain necessary for reproduction....))

@pnkfelix
Copy link
Member

pnkfelix commented Jul 8, 2019

Here is a shell script to compile the files using rustc itself (so we get cargo out of the way) and run the compile of c.rs under gdb:

#!/bin/bash

set -e

mkdir -p build

FLAGS="--edition=2018 --out-dir build  --emit=dep-info,link -L dependency=./build --extern a=./build/liba.rlib  --extern b=./buil\
d/libb.rlib "

# RUSTC=rustc
RUSTC=./rust-61711/objdir-dbgopt/build/x86_64-unknown-linux-gnu/stage1/bin/rustc

echo "Building a.rs"
$RUSTC --crate-name a a.rs --crate-type lib $FLAGS

echo "Building b.rs"
$RUSTC --crate-name b b.rs --crate-type lib $FLAGS

echo "Building c.rs"
gdb --args $RUSTC --crate-name c c.rs --crate-type bin $FLAGS

@pnkfelix
Copy link
Member

pnkfelix commented Jul 8, 2019

and the backtrace from gdb gives us a pretty good hint as to where we might be infinite-looping:

(gdb) bt
#0  0x00007ffff6ba3e7c in rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query (self=..., span=...,
    key=...) at src/librustc/ty/query/plumbing.rs:350
#1  0x00007ffff68185bb in rustc::ty::query::TyCtxtAt::extern_crate (self=..., key=...)
    at src/librustc/ty/query/plumbing.rs:1074
#2  rustc::ty::query::<impl rustc::ty::context::TyCtxt>::extern_crate (self=..., key=...)
    at src/librustc/ty/query/plumbing.rs:1066
#3  rustc::ty::print::pretty::PrettyPrinter::try_print_visible_def_path (self=..., def_id=...)
    at src/librustc/ty/print/pretty.rs:257
#4  0x00007ffff68187d4 in rustc::ty::print::pretty::PrettyPrinter::try_print_visible_def_path (self=..., def_id=...)
    at src/librustc/ty/print/pretty.rs:309
#5  0x00007ffff68187d4 in rustc::ty::print::pretty::PrettyPrinter::try_print_visible_def_path (self=..., def_id=...)
    at src/librustc/ty/print/pretty.rs:309
#6  0x00007ffff68187d4 in rustc::ty::print::pretty::PrettyPrinter::try_print_visible_def_path (self=..., def_id=...)
    at src/librustc/ty/print/pretty.rs:309
#7  0x00007ffff68187d4 in rustc::ty::print::pretty::PrettyPrinter::try_print_visible_def_path (self=..., def_id=...)
    at src/librustc/ty/print/pretty.rs:309
#8  0x00007ffff68187d4 in rustc::ty::print::pretty::PrettyPrinter::try_print_visible_def_path (self=..., def_id=...)
    at src/librustc/ty/print/pretty.rs:309

(and so on, for at least 15,000 stack frames...)

@pnkfelix
Copy link
Member

pnkfelix commented Jul 8, 2019

(prior to rust 1.35.0, it seems like we might have infinite looped here with no stack overflow. Not 100% sure of that yet; and this test case currently relies on 2018 edition, so its not easy to go back to earlier than 1.31.0)

@pnkfelix
Copy link
Member

pnkfelix commented Jul 8, 2019

Also, you can inline the contents of crate a into crate b and preserve the erroneous behavior:

// b.rs
#![crate_type="lib"]
pub struct Struct;
pub use crate as alias;
// c.rs
fn f<F: Fn(b::Struct)>(_: F) { }
fn main() { }

@pnkfelix
Copy link
Member

pnkfelix commented Jul 8, 2019

Okay I think I have a solution for this. Hope to post PR today or tomorrow.

bors added a commit that referenced this issue Jul 11, 2019
…ath, r=eddyb

Dont recur infinitely from print_def_path

Fix #61711
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-resolve Area: Name/path resolution done by `rustc_resolve` specifically C-bug Category: This is a bug. 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.

3 participants