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

Panic compiling futures code with impl trait in nightly #40247

Closed
OneSadCookie opened this issue Mar 3, 2017 · 7 comments
Closed

Panic compiling futures code with impl trait in nightly #40247

OneSadCookie opened this issue Mar 3, 2017 · 7 comments
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@OneSadCookie
Copy link

I have some futures code that causes a compiler panic:
https://github.com/OneSadCookie/padgrid
(disclaimer: I have no idea if my code makes sense!)

Snippet of the offending code:

fn cell_desc_to_cell(
    cell_desc: String,
    handle: tokio_core::reactor::Handle,
) -> impl Future<Item=GridCell, Error=PadGridError> {
    let fallback_cell = match cell_desc.len() {
        0 => { GridCell::Empty }
        1 => { GridCell::Annotation(cell_desc.chars().nth(0).unwrap()) },
        _ => { GridCell::Annotation('?') }
    };
    future::result(cell_desc.parse::<usize>()).and_then(move |id| {
        monster_icon(id, handle).map(move |image| {
            GridCell::Icon(image)
        }).or_else(move |_| {
            Ok(GridCell::Annotation('?'))
        })
    }).or_else(move |_| -> Result<GridCell, PadGridError> {
        Ok(fallback_cell)
    })
}

fn row_desc_to_cells(
    row_desc: Vec<String>,
    handle: tokio_core::reactor::Handle
) -> impl Future<Item=Vec<GridCell>, Error=PadGridError> {
    let handles = std::iter::repeat(handle);
    let cell_futures = row_desc.into_iter().zip(handles).map(move |(cell_desc, handle)| {
        cell_desc_to_cell(cell_desc, handle)
    });
    future::join_all(cell_futures)
}

fn grid_desc_to_cells(
    grid_desc: Vec<Vec<String>>,
    handle: tokio_core::reactor::Handle
) -> impl Future<Item=Vec<Vec<GridCell>>, Error=PadGridError> {
    let handles = std::iter::repeat(handle);
    let row_futures = grid_desc.into_iter().zip(handles).map(move |(row_desc, handle)| {
        row_desc_to_cells(row_desc, handle)
    });
    future::join_all(row_futures)
}

(full source in the repo above)

The panic log:

error: internal compiler error: src/librustc_trans/common.rs:473: Encountered er
ror `Unimplemented` selecting `Binder(<std::vec::Vec<futures::future::join_all::
ElemState<futures::OrElse<futures::AndThen<futures::FutureResult<usize, std::num
::ParseIntError>, futures::OrElse<futures::Map<futures::AndThen<futures::OrElse<
futures::FutureResult<std::fs::File, PadGridError>, futures::OrElse<futures::And
Then<futures::AndThen<futures::AndThen<futures::future::FromErr<hyper::client::F
utureResponse, PadGridError>, std::result::Result<hyper::client::Response, PadGr
idError>, [closure@src/main.rs:79:41: 85:6 url_string:std::string::String]>, fut
ures::AndThen<futures::AndThen<futures::future::FromErr<futures::FutureResult<st
d::fs::File, std::io::Error>, PadGridError>, futures::future::FromErr<futures::s
tream::Fold<hyper::Body, [closure@src/main.rs:62:32: 67:10], std::result::Result
<std::fs::File, std::io::Error>, std::fs::File>, PadGridError>, [closure@src/mai
n.rs:61:86: 68:6 res:hyper::client::Response]>, std::result::Result<(), PadGridE
rror>, [closure@src/main.rs:68:17: 68:28]>, [closure@src/main.rs:85:17: 87:6 id:
usize]>, futures::FutureResult<std::fs::File, PadGridError>, [closure@src/main.r
s:87:17: 90:6 id:usize]>, std::result::Result<std::fs::File, PadGridError>, [clo
sure@src/main.rs:90:16: 94:6 id:usize]>, [closure@src/main.rs:101:33: 103:6 id:u
size, handle:tokio_core::reactor::Handle]>, std::result::Result<image::DynamicIm
age, PadGridError>, [closure@src/main.rs:110:44: 112:6]>, [closure@src/main.rs:1
50:38: 152:10]>, std::result::Result<GridCell, std::num::ParseIntError>, [closur
e@src/main.rs:152:20: 154:10]>, [closure@src/main.rs:149:57: 155:6 handle:tokio_
core::reactor::Handle]>, std::result::Result<GridCell, PadGridError>, [closure@s
rc/main.rs:155:16: 157:6 fallback_cell:GridCell]>>> as std::iter::IntoIterator>)
` during trans

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:376
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: rustc::session::opt_span_bug_fmt::{{closure}}
   1: rustc::session::span_bug_fmt
   2: rustc_trans::common::fulfill_obligation::{{closure}}::{{closure}}
   3: rustc_trans::common::fulfill_obligation
   4: rustc_trans::collector::do_static_dispatch
   5: <rustc_trans::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_operand
   6: <rustc_trans::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_terminator_kind
   7: rustc::mir::visit::Visitor::visit_mir
   8: rustc_trans::collector::collect_neighbours
   9: rustc_trans::collector::collect_items_rec
  10: rustc_trans::collector::collect_items_rec
  11: rustc_trans::collector::collect_items_rec
  12: rustc_trans::collector::collect_items_rec
  13: rustc_trans::collector::collect_items_rec
  14: rustc_trans::collector::collect_items_rec
  15: rustc_trans::collector::collect_items_rec
  16: rustc_trans::collector::collect_items_rec
  17: rustc_trans::collector::collect_items_rec
  18: rustc_trans::collector::collect_items_rec
  19: rustc_trans::collector::collect_items_rec
  20: rustc_trans::collector::collect_items_rec
  21: rustc_trans::collector::collect_items_rec
  22: rustc_trans::collector::collect_items_rec
  23: rustc_trans::base::collect_and_partition_translation_items::{{closure}}
  24: rustc_trans::base::collect_and_partition_translation_items
  25: rustc_trans::base::trans_crate
  26: rustc_driver::driver::phase_4_translate_to_llvm
  27: rustc_driver::driver::compile_input::{{closure}}
  28: rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}
  29: rustc_driver::driver::phase_3_run_analysis_passes
  30: rustc_driver::driver::compile_input
  31: rustc_driver::run_compiler
  32: std::panicking::try::do_call
  33: __rust_maybe_catch_panic
  34: <F as alloc::boxed::FnBox<A>>::call_box
  35: std::sys::imp::thread::Thread::new::thread_start
  36: _pthread_body
  37: _pthread_start

error: Could not compile `padgrid`.

compiler version:

rustc --version --verbose
rustc 1.17.0-nightly (c0b7112ba 2017-03-02)
binary: rustc
commit-hash: c0b7112ba246d96f253ba845d91f36c0b7398e42
commit-date: 2017-03-02
host: x86_64-apple-darwin
release: 1.17.0-nightly
LLVM version: 3.9
@OneSadCookie
Copy link
Author

So, I worked around this by changing the return types of both cell_desc_to_cell and row_desc_to_cells to Box<Future<Item=GridCell, Error=PadGridError>>.

Just changing cell_desc_to_cell wasn't sufficient; that gave a different error about exceeding a recursion limit, but calling cell_desc_to_cell as written in isolation worked fine.

I think this is therefore "just" that the types returned by these functions are "too complex". That seems like a fairly harsh limitation of impl Trait! Perhaps rather than impl Trait returning the exact type the function does, it should return a newtype that erases all the other (irrelevant!) implementation details?

@radix
Copy link
Contributor

radix commented Mar 22, 2017

I'm getting this with a simpler example:

  fn walk_paths(&self, parent: &FolderPath) -> impl Iterator<Item=&FolderPath> {
    self.nodes.keys().filter(|p| p.is_child_of(parent))
  }

where self.nodes is a HashMap<FolderPath, _>. If I change the return type to impl Iterator<Item=FolderPath> (no &) it doesn't crash any more, but I am getting some other compilation error. This code probably isn't correct, I just ran into the crash while trying to explore my way to the solution.

@radix
Copy link
Contributor

radix commented Mar 22, 2017

I noticed that before the panic, I do get a normal compilation error pointing to my impl trait usage:

Error: internal compiler error: src\librustc_typeck\check/mod.rs:1708: escaping regions in predicate Obligation(predicate=Binder(ProjectionPredicate(ProjectionTy { trait_ref: <_ as std::iter::Iterator>, item_name: Item(747) }, &foldertree::FolderPath)),depth=0)
  --> src\foldertree.rs:121:48
    |
121 |   fn walk_paths(&self, parent: &FolderPath) -> impl Iterator<Item=&FolderPath> {
    |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

@radix
Copy link
Contributor

radix commented Mar 22, 2017

And here's code that eventually ended up working, for comparison (returning an iterator of references, and adding the explicit lifetime)

  pub fn walk_paths<'a>(&'a self, parent: FolderPath) -> impl Iterator<Item=&FolderPath> + 'a {
    self.nodes.keys().filter(move |p| p.is_child_of(&parent))
  }

@sfackler sfackler added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Mar 22, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 22, 2017
@steveklabnik
Copy link
Member

This example relies on nightly features that were removed:

error[E0432]: unresolved import `std::net::lookup_host`
 --> C:\Users\Steve Klabnik\.cargo\registry\src\github.com-1ecc6299db9ec823\rocket-0.2.2\src\config\config.rs:2:24
  |
2 | use std::net::{IpAddr, lookup_host};
  |                        ^^^^^^^^^^^ no `lookup_host` in `net`

Are you still seeing this today? Any chance of an updated test case?

@OneSadCookie
Copy link
Author

(After a little work updating Rocket) this works on the latest nightly and can be closed, as far as I'm concerned.

@Centril
Copy link
Contributor

Centril commented Mar 10, 2020

Closing per ^---

@Centril Centril closed this as completed Mar 10, 2020
@Centril Centril added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Mar 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants