Rust: [ICE] [conservative_impl_trait] escaping regions in predicate

Created on 10 Apr 2017  路  9Comments  路  Source: rust-lang/rust

#![feature(conservative_impl_trait)]

fn split_whitespace(text: &str) -> impl Iterator<Item=&str> {
    fn is_not_empty(s: &&str) -> bool {
        !s.is_empty()
    }
    let is_not_empty: fn(&&str) -> bool = is_not_empty; // coerce to fn pointer

    fn is_whitespace(c: char) -> bool {
        c.is_whitespace()
    }
    let is_whitespace: fn(char) -> bool = is_whitespace; // coerce to fn pointer

    text.split(is_whitespace).filter(is_not_empty)
}
error: internal compiler error: /checkout/src/librustc_typeck/check/mod.rs:1787: escaping regions in predicate Obligation(predicate=Binder(ProjectionPredicate(ProjectionTy { trait_ref: <_ as std::iter::Iterator>, item_name: Item(88) }, &str)),depth=0)
 --> kek.rs:3:36
  |
3 | fn split_whitespace(text: &str) -> impl Iterator<Item=&str> {
  |                                    ^^^^^^^^^^^^^^^^^^^^^^^^

Using explicit lifetimes does not trigger this ICE.

A-impl-trait C-bug I-ICE T-compiler

Most helpful comment

This is fixed on the current nightly.

All 9 comments

I've run into the same error. here's my data:
This is a short example producing the error:
https://play.rust-lang.org/?gist=35775bb4f3cc3a143e0c46a433580b94&version=nightly&backtrace=1

The backtrace it produces is

   0: rustc::session::opt_span_bug_fmt::{{closure}}
   1: rustc::session::span_bug_fmt
   2: rustc_typeck::check::FnCtxt::register_predicate
   3: <rustc::ty::fold::BottomUpFolder<'a, 'gcx, 'tcx, F> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
   4: rustc_typeck::check::check_fn
   5: rustc_typeck::check::typeck_tables
   6: rustc::ty::maps::<impl rustc::ty::maps::queries::typeck_tables<'tcx>>::try_get
   7: rustc::ty::maps::<impl rustc::ty::maps::queries::typeck_tables<'tcx>>::get
   8: rustc::ty::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::item_tables
   9: rustc_typeck::check::typeck_item_bodies
  10: rustc::ty::maps::<impl rustc::ty::maps::queries::typeck_item_bodies<'tcx>>::try_get
  11: rustc::ty::maps::<impl rustc::ty::maps::queries::typeck_item_bodies<'tcx>>::get
  12: rustc_typeck::check_crate
  13: rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}
  14: rustc::ty::context::TyCtxt::create_and_enter
  15: rustc_driver::driver::phase_3_run_analysis_passes
  16: rustc_driver::driver::compile_input
  17: rustc_driver::run_compiler
  18: std::panicking::try::do_call
  19: __rust_maybe_catch_panic
             at /checkout/src/libpanic_unwind/lib.rs:98
  20: <F as alloc::boxed::FnBox<A>>::call_box
  21: std::sys::imp::thread::Thread::new::thread_start
             at /checkout/src/liballoc/boxed.rs:650
             at /checkout/src/libstd/sys_common/thread.rs:21
             at /checkout/src/libstd/sys/unix/thread.rs:84
  22: start_thread
  23: clone

My rustc --version --verbose is

rustc 1.17.0-nightly (fd182c401 2017-03-13)
binary: rustc
commit-hash: fd182c4010b5aee72d070b15e90c98cb0fdc3776
commit-date: 2017-03-13
host: x86_64-unknown-linux-gnu
release: 1.17.0-nightly
LLVM version: 3.9

I just ran into this issue. It seems to occur when you take in a reference as function argument which does not have to be related to whatever you return.

The code below gives us the same ICE:

static SLICE: [usize; 1] = [0; 1];

fn ice(_: &str) -> impl Iterator<Item=&usize> {
    SLICE.iter()
}

While the following code does not. It gives the expected error message that a lifetime parameter is expected.

static SLICE: [usize; 1] = [0; 1];

fn clear_error_message() -> impl Iterator<Item=&usize> {
    SLICE.iter()
}

I ran into this bug last night. My case is similar to others.

@Zalastra's first example can be fixed using separate lifetime parameters for the argument and the return value:

static SLICE: [usize; 1] = [0; 1];

fn ice<'b, 'a: 'b>(_: &'a str) -> impl Iterator<Item=&'a usize> + 'b {
    SLICE.iter()
}

Getting this myself in multiple situations when returning references as items.

I also ran into this with the function signature fn iter(&self) -> impl Iterator<Item=&T>, but had it compile by using @mikeyhew's suggestion.

I ran into this with the lazy_static crate; minimal repro is here

My cube of ICE:

fn x(_: &i8) -> impl Iterator<Item = &u8> {
    panic!()
}

rustc 1.19.0-nightly (4bf5c99af 2017-06-10)

Got same internal compiler error on this:

#![feature(conservative_impl_trait)]

struct S {
    v: Vec<u32>,
}

impl S {
    //fn all<'a>(&'a self) -> impl Iterator<Item=&'a u32> {
    fn all(&self) -> impl Iterator<Item=&u32> {
        self.v.iter()
    }
}

fn main() {
    let s = S { v: Vec::new() };
    s.all().count();
}

Specifying lifetimes (as in comment) fixes the problem.
rustc 1.22.0-nightly (4502e2aa9 2017-10-03) running on x86_64-pc-windows-msvc

This is fixed on the current nightly.

Was this page helpful?
0 / 5 - 0 ratings