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

Using impl Trait with closure local functions across crates results in ICE #43135

Closed
Nemo157 opened this issue Jul 9, 2017 · 7 comments
Closed
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. 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. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@Nemo157
Copy link
Member

Nemo157 commented Jul 9, 2017

Having an impl Trait type, containing a closure, where the closure has a locally defined function inside it, being passed across crate boundaries, results in an ICE.

The following function, defined in one crate, then used in another:

pub fn foo2() -> impl Future<Item=String, Error=()> {
    future::ok(()).and_then(|()| {
        fn msg() -> String { format!("Hello, {}!", "world") }
        future::ok(msg())
    })
}

gives the error:

error: internal compiler error: src/librustc_trans/collector.rs:662: Cannot create local trans-item for DefId { krate: CrateNum(12), node: DefIndex(9) => bar/ab23142::foo2[0]::{{closure}}[0]::msg[0] }

note: rustc 1.20.0-nightly (9b85e1cfa 2017-07-07) running on x86_64-apple-darwin

Presumably related to #40839/#35870, I found this while trying to come up with a decent workaround for #40839 specifically.

I have pushed a full testcase to https://github.com/Nemo157/impl-trait-across-crates, try building the foo2 crate.

@Nemo157
Copy link
Member Author

Nemo157 commented Jul 9, 2017

Actually, it looks like defining the function inside the closure is not needed, even just a private helper function in the crate that is only called from the closure will trigger this, e.g.

fn msg() -> String { format!("Hello, {}!", "world") }

pub fn foo2() -> impl Future<Item=String, Error=()> {
    future::ok(()).and_then(|()| future::ok(msg()) )
}

@Mark-Simulacrum Mark-Simulacrum added A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ C-bug Category: This is a bug. labels Jul 19, 2017
@ishitatsuyuki
Copy link
Contributor

Stack trace:

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:490:8
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
  (panic handler, omitted)
  10: rustc_trans::collector::should_trans_locally
  11: rustc_trans::collector::visit_instance_use
  12: <rustc_trans::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_terminator_kind
  13: rustc::mir::visit::Visitor::visit_mir
  14: rustc_trans::collector::collect_items_rec
  (... recursion, omitted ...)
  42: rustc_trans::collector::collect_items_rec
  43: rustc_trans::base::collect_and_partition_translation_items::{{closure}}
  44: rustc_trans::base::trans_crate
  45: rustc_driver::driver::phase_4_translate_to_llvm
  46: rustc_driver::driver::compile_input::{{closure}}
  47: rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}
  48: rustc_driver::driver::phase_3_run_analysis_passes
  49: rustc_driver::driver::compile_input
  50: rustc_driver::run_compiler

@mhristache
Copy link

I am also hitting this ICE. Is there a workaround?

@ishitatsuyuki
Copy link
Contributor

@maximih Yes. Marking #[inline] as you encounter the error.

@mhristache
Copy link

mhristache commented Aug 13, 2017

Thanks. Using #[inline] seem to fix some occurances but not all. I still get the error for this method:

    #[inline]
    fn login<'a>(&'a self) -> impl Future<Item = String, Error = Error> + 'a {
        let req = self.prepare_login_request();
        result(req)
            .and_then(move |resp| check_http_status_parse_body(resp, hyper::Ok))
            .and_then(move |api_resp| {

                // check if the authentication was successful
                if &api_resp.status.reqStatus[..] == "SUCCESS" {

                    if api_resp.status.credentials.is_some() {

                        // save a copy of the token to be returned later
                        let to_return = api_resp.status.credentials.as_ref().unwrap().clone();

                        // add the data to cache
                        debug!("Login successful! Caching the response");
                        let to_store = Arc::new(api_resp);

                        // add the data to the cache
                        self.cache.insert_new(self.auth_url.clone(), to_store);

                        // return the token
                        ok(to_return)

                    } else {
                        err(Error::Auth)
                    }
                } else {
                    err(Error::Auth)
                }
            })
    }

The error I get:

error: internal compiler error: /checkout/src/librustc_trans/collector.rs:735: Cannot create local trans-item for DefId { krate: CrateNum(12), node: DefIndex(744) => ecmclient/ef9542a::{{impl}}[1]::login[0]::{{closure}}[1]::_LOC[0] }

bors added a commit that referenced this issue Aug 14, 2017
…=eddyb

Mark closures return via impl-trait as reachable.

This should fix some of the open `impl trait` issues, like #40839, #43135, and #35870.

r? @eddyb
@plietar
Copy link
Contributor

plietar commented Aug 30, 2017

I can't reproduce the original ICE, which was presumably fixed by #43857. This issue can probably be closed.

I'm however running into this ICE with generators, and have opened #44181 for that.

@ishitatsuyuki
Copy link
Contributor

Triage: close? @Mark-Simulacrum

@Mark-Simulacrum Mark-Simulacrum added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Nov 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. 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. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

5 participants