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

Rustc 1.33 stable panicked on a closure inside a closure #58840

Closed
julien1619 opened this issue Mar 1, 2019 · 29 comments · Fixed by #60765
Closed

Rustc 1.33 stable panicked on a closure inside a closure #58840

julien1619 opened this issue Mar 1, 2019 · 29 comments · Fixed by #60765
Assignees
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@julien1619
Copy link

Rustc 1.33 panicked while compiling a code that was working well on 1.32.

I tried this code:

extern crate chrono;
extern crate dotenv;
extern crate futures;
extern crate hyper;
#[macro_use]
extern crate juniper;
extern crate juniper_hyper;
#[macro_use]
extern crate log;
extern crate pretty_env_logger;
extern crate uuid;

mod context;
mod schema;

use context::Context;
use dotenv::dotenv;
use futures::future;
use hyper::rt::Future;
use hyper::service::service_fn;
use hyper::{Body, Method, Response, Server, StatusCode};
use schema::{Mutation, Query, Schema};
use std::sync::Arc;

fn main() {
    // Load configuration
    dotenv().ok();

    // Prepare logger
    pretty_env_logger::init();

    info!("Starting Cardioid API");

    // Prepare HOST configuration
    let host = std::env::var("HOST").expect("Missing HOST definition in env variables");
    let address = host.parse().expect("Invalid HOST configuration");

    // Prepare context and schema
    let context = Arc::new(Context {});
    let root_node = Arc::new(Schema::new(Query {}, Mutation {}));

    // Define network service
    let new_service = move || {
        let root_node = root_node.clone();
        let ctx = context.clone();
        service_fn(move |req| -> Box<Future<Item = _, Error = _> + Send> {
            let root_node = root_node.clone();
            let ctx = ctx.clone();
            match (req.method(), req.uri().path()) {
                // GraphiQL
                (&Method::GET, "/") => Box::new(juniper_hyper::graphiql("/graphql")),

                // GraphQL
                (&Method::GET, "/graphql") => Box::new(juniper_hyper::graphql(root_node, ctx, req)),
                (&Method::POST, "/graphql") => {
                    Box::new(juniper_hyper::graphql(root_node, ctx, req))
                }

                // Default response
                _ => {
                    let mut response = Response::new(Body::empty());
                    *response.status_mut() = StatusCode::NOT_FOUND;
                    Box::new(future::ok(response))
                }
            }
        })
    };

    // Create server with service
    let server = Server::bind(&address)
        .serve(new_service)
        .map_err(|e| error!("Server error: {}", e));

    info!("Listening on http://{}", address);

    // Run server
    hyper::rt::run(server);
}

This happened: error: internal compiler error: src/librustc_mir/borrow_check/nll/universal_regions.rs:744: cannot convert `ReScope(Node(238))` to a region vid

Meta

rustc --version --verbose:

rustc 1.33.0 (2aa4c46cf 2019-02-28)
binary: rustc
commit-hash: 2aa4c46cfdd726e97360c2734835aa3515e8c858
commit-date: 2019-02-28
host: x86_64-apple-darwin
release: 1.33.0
LLVM version: 8.0

Backtrace:

error: internal compiler error: src/librustc_mir/borrow_check/nll/universal_regions.rs:744: cannot convert `ReScope(Node(238))` to a region vid

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:588:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::_print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
   6: std::panicking::begin_panic
   7: rustc_errors::Handler::bug
   8: rustc::util::bug::opt_span_bug_fmt::{{closure}}
   9: rustc::ty::context::tls::with_opt::{{closure}}
  10: rustc::ty::context::tls::with_context_opt
  11: rustc::ty::context::tls::with_opt
  12: rustc::util::bug::opt_span_bug_fmt
  13: rustc::util::bug::bug_fmt
  14: rustc_mir::borrow_check::nll::universal_regions::UniversalRegionIndices::to_region_vid::{{closure}}
  15: rustc_mir::borrow_check::nll::universal_regions::UniversalRegionIndices::to_region_vid
  16: rustc_mir::borrow_check::nll::type_check::constraint_conversion::ConstraintConversion::convert_all
  17: rustc_mir::borrow_check::nll::type_check::TypeChecker::prove_predicate
  18: rustc_mir::borrow_check::nll::type_check::TypeChecker::check_stmt
  19: rustc_mir::borrow_check::nll::type_check::TypeChecker::typeck_mir
  20: rustc_mir::borrow_check::nll::type_check::type_check
  21: rustc_mir::borrow_check::nll::compute_regions
  22: rustc_mir::borrow_check::do_mir_borrowck
  23: rustc::ty::context::GlobalCtxt::enter_local
  24: rustc_mir::borrow_check::mir_borrowck
  25: rustc::ty::query::__query_compute::mir_borrowck
  26: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::mir_borrowck<'tcx>>::compute
  27: rustc::dep_graph::graph::DepGraph::with_task_impl
  28: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
  29: rustc_mir::borrow_check::nll::type_check::TypeChecker::check_stmt
  30: rustc_mir::borrow_check::nll::type_check::TypeChecker::typeck_mir
  31: rustc_mir::borrow_check::nll::type_check::type_check
  32: rustc_mir::borrow_check::nll::compute_regions
  33: rustc_mir::borrow_check::do_mir_borrowck
  34: rustc::ty::context::GlobalCtxt::enter_local
  35: rustc_mir::borrow_check::mir_borrowck
  36: rustc::ty::query::__query_compute::mir_borrowck
  37: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::mir_borrowck<'tcx>>::compute
  38: rustc::dep_graph::graph::DepGraph::with_task_impl
  39: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
  40: rustc_mir::borrow_check::nll::type_check::TypeChecker::check_stmt
  41: rustc_mir::borrow_check::nll::type_check::TypeChecker::typeck_mir
  42: rustc_mir::borrow_check::nll::type_check::type_check
  43: rustc_mir::borrow_check::nll::compute_regions
  44: rustc_mir::borrow_check::do_mir_borrowck
  45: rustc::ty::context::GlobalCtxt::enter_local
  46: rustc_mir::borrow_check::mir_borrowck
  47: rustc::ty::query::__query_compute::mir_borrowck
  48: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::mir_borrowck<'tcx>>::compute
  49: rustc::dep_graph::graph::DepGraph::with_task_impl
  50: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
  51: rustc::ty::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::par_body_owners
  52: rustc::util::common::time
  53: <std::thread::local::LocalKey<T>>::with
  54: rustc::ty::context::TyCtxt::create_and_enter
  55: rustc_driver::driver::compile_input
  56: rustc_driver::run_compiler_with_pool
  57: <scoped_tls::ScopedKey<T>>::set
  58: rustc_driver::run_compiler
  59: <scoped_tls::ScopedKey<T>>::set
query stack during panic:
#0 [mir_borrowck] processing `main::{{closure}}::{{closure}}`
#1 [mir_borrowck] processing `main::{{closure}}`
#2 [mir_borrowck] processing `main`
end of query stack
error: aborting due to previous error


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: rustc 1.33.0 (2aa4c46cf 2019-02-28) running on x86_64-apple-darwin

note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin

note: some of the compiler flags provided by cargo are hidden

error: Could not compile `api`.
@julien1619
Copy link
Author

After some testing, this is the lines Box::new(juniper_hyper::graphql(root_node, ctx, req)) that cause the compiler to crash.

@jonas-schievink jonas-schievink added 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. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. C-bug Category: This is a bug. labels Mar 1, 2019
@jethrogb
Copy link
Contributor

jethrogb commented Mar 1, 2019

@julien1619 can you post a reduced test case or the full source including Cargo.toml and the module files?

@jatsrt
Copy link

jatsrt commented Mar 3, 2019

Simple project that causes this:
https://github.com/zenlist/clincl

@pietroalbini
Copy link
Member

Bisected, the cause of the regression is #55517. cc @nikomatsakis @scalexm

@julien1619
Copy link
Author

@jethrogb : @jatsrt just did a test case (thanks!).

@pnkfelix
Copy link
Member

pnkfelix commented Mar 7, 2019

triage: P-high.

@pnkfelix pnkfelix added the P-high High priority label Mar 7, 2019
@pnkfelix
Copy link
Member

pnkfelix commented Mar 7, 2019

assigning to self based on stack trace and related work on region-vid conversion issues, and removing nomination tag.

@pnkfelix pnkfelix self-assigned this Mar 7, 2019
@jsgf
Copy link
Contributor

jsgf commented Mar 11, 2019

Is this likely to be in a 1.33.1 release?

@pietroalbini
Copy link
Member

If we do a release and the fix is not risky to land in a point release probably yes, but there aren't other point release worthy issues to fix so I'm not sure if we'll end up doing one.

@jsgf
Copy link
Contributor

jsgf commented Mar 20, 2019

This is currently blocking us from updating to 1.33.

@fanzeyi
Copy link

fanzeyi commented Mar 20, 2019

Judging from our code and the code above, it might be related to Arc.

@pnkfelix
Copy link
Member

Simple project that causes this:
https://github.com/zenlist/clincl

This project has been deleted. Can someone either repost it, or share a copy with me?

@bturner-bw
Copy link

bturner-bw commented Mar 27, 2019

Simple project that causes this:
https://github.com/zenlist/clincl

This project has been deleted. Can someone either repost it, or share a copy with me?

The comment below is now posted separately as #59494.


Not sure if it triggers the same bug, but I found this issue (in details below) while searching for a solution.

This code panics on 1.33 - 1.35, but does not panic on 1.32:

fn t7p<A,B,C>( f:impl Fn(B) -> C, g:impl Fn(A) -> B ) -> impl Fn(A) -> C
{
  move |a:A| -> C { f(g(a)) }
}

fn t8n<A,B,C>( f:impl Fn(A) -> B, g:impl Fn(A) -> C ) -> impl Fn(A) -> (B,C)
  where
    A: Copy
{
  move |a:A| -> (B,C) {
    let b = a;
    let fa = f(a);
    let ga = g(b);
    (fa, ga)
  }
}

fn main() {

  let f = |(_,_)| {  };
  let g = |(a,_)| { a };
  let t7 = |env| { |a| { |b| {  t7p(f, g)(((env,a),b))  }}};
  let t8 = t8n(t7, t7p(f, g));
}

On 1.32:

error[E0277]: expected a `std::ops::Fn<(_,)>` closure, found `impl std::ops::Fn<(((_, _), _),)>`
  --> src/main.rs:32:12
   |
32 |   let t8 = pair_panic(t7, o_panic(f, g));
   |            ^^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl std::ops::Fn<(((_, _), _),)>`
   |
   = help: the trait `std::ops::Fn<(_,)>` is not implemented for `impl std::ops::Fn<(((_, _), _),)>`
note: required by `pair_panic`
  --> src/main.rs:9:1
   |
9  | / fn pair_panic<A,B,C>( f:impl Fn(A) -> B, g:impl Fn(A) -> C ) -> impl Fn(A) -> (B,C)
10 | |   where
11 | |     A: Copy
12 | | {
...  |
18 | |   }
19 | | }
   | |_^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: Could not compile `panic`.

To learn more, run the command again with --verbose.

On 1.35 nightly (today):

thread 'rustc' panicked at 'assertion failed: result', src/librustc/traits/select.rs:2779:13
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::_print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
   6: std::panicking::begin_panic
   7: rustc::infer::InferCtxt::in_snapshot
   8: rustc::traits::select::SelectionContext::confirm_candidate
   9: rustc::traits::select::SelectionContext::select
  10: rustc_data_structures::obligation_forest::ObligationForest<O>::process_obligations
  11: <rustc::traits::fulfill::FulfillmentContext as rustc::traits::engine::TraitEngine>::select_where_possible
  12: rustc_typeck::check::FnCtxt::select_obligations_where_possible
  13: rustc_typeck::check::FnCtxt::check_argument_types
  14: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::confirm_builtin_call
  15: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::check_call
  16: rustc_typeck::check::FnCtxt::check_expr_kind
  17: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  18: rustc_typeck::check::FnCtxt::check_decl_initializer
  19: rustc_typeck::check::FnCtxt::check_decl_local
  20: rustc_typeck::check::FnCtxt::check_stmt
  21: rustc_typeck::check::FnCtxt::check_block_with_expected
  22: rustc_typeck::check::FnCtxt::check_expr_kind
  23: rustc_typeck::check::FnCtxt::check_expr_with_expectation_and_needs
  24: rustc_typeck::check::FnCtxt::check_return_expr
  25: rustc_typeck::check::check_fn
  26: rustc::ty::context::GlobalCtxt::enter_local
  27: rustc_typeck::check::typeck_tables_of
  28: rustc::ty::query::__query_compute::typeck_tables_of
  29: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::typeck_tables_of>::compute
  30: rustc::dep_graph::graph::DepGraph::with_task_impl
  31: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  32: rustc::ty::<impl rustc::ty::context::TyCtxt>::par_body_owners
  33: rustc_typeck::check::typeck_item_bodies
  34: rustc::ty::query::__query_compute::typeck_item_bodies
  35: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::typeck_item_bodies>::compute
  36: rustc::dep_graph::graph::DepGraph::with_task_impl
  37: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  38: rustc::util::common::time
  39: rustc_typeck::check_crate
  40: rustc_interface::passes::analysis
  41: rustc::ty::query::__query_compute::analysis
  42: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::analysis>::compute
  43: rustc::dep_graph::graph::DepGraph::with_task_impl
  44: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  45: rustc::ty::context::tls::enter_global
  46: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  47: rustc_interface::passes::create_global_ctxt::{{closure}}
  48: rustc_interface::passes::BoxedGlobalCtxt::enter
  49: rustc_interface::interface::run_compiler_in_existing_thread_pool
  50: std::thread::local::LocalKey<T>::with
  51: scoped_tls::ScopedKey<T>::set
  52: syntax::with_globals
query stack during panic:
#0 [typeck_tables_of] processing `main`
#1 [typeck_item_bodies] type-checking all item bodies
#2 [analysis] running analysis passes on this crate
end of query stack

error: internal compiler error: unexpected panic
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: rustc 1.35.0-nightly (fbd34efb3 2019-03-26) running on x86_64-apple-darwin
note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin
note: some of the compiler flags provided by cargo are hidden
error: Could not compile `rust`.
To learn more, run the command again with --verbose.

--Bryan

@pnkfelix
Copy link
Member

@bryturner based on the stack trace, I do not think that is the exact same bug. Thanks for investigating; Lets make sure to file a separate issue for it!

@pnkfelix
Copy link
Member

@bryturner also, your code seems to be missing the definition for t7p? (I recommend posting reproduction in the playpen play.rust-lang.org and seeing if they reproduce there, for ease of sharing and also catching little cut-and-paste omissions along the way.)

@pnkfelix
Copy link
Member

Simple project that causes this:
https://github.com/zenlist/clincl

This project has been deleted. Can someone either repost it, or share a copy with me?

I probably should have pinged @jatsrt when I wrote that question. Let's seeing if pinging here helps.

@pnkfelix
Copy link
Member

pnkfelix commented Apr 4, 2019

Since the sample project that causes this was taken down, I guessed I will take an example from either #59606 or #59344 and use that as the basis for investigation going forward. #59344 in particular seems to have the best bet of having enough information (namely a Cargo.toml dependencies section) to allow easy reproduction.

@julien1619
Copy link
Author

@pnkfelix I've just checked on Rust 1.34.1 and I confirm the bug is still present. @darnuria and @GuillaumeGomez told me yesterday at the Paris meetup to bump this issue. I'll try to create a minimal testcase later today.

@GuillaumeGomez
Copy link
Member

cc @rust-lang/compiler

@nikomatsakis
Copy link
Contributor

Compiler triage: It seems like are still missing a case for reproduction?

@jethrogb
Copy link
Contributor

jethrogb commented May 9, 2019

@pietroalbini do you still have a local checkout of @jatsrt's repro?

@lqd
Copy link
Member

lqd commented May 9, 2019

@julien1619 by the way, were you able to create the minimal testcase you mentioned ?

@pietroalbini
Copy link
Member

@jethrogb nope :(

@lqd
Copy link
Member

lqd commented May 10, 2019

I created a simple (but not minimal) project based on the initial comment, and checked it indeed ICEs on nightly with the expected "cannot convert ReScope(Node(...)) to a region vid" error.

I haven't tried minimizing or bisecting, however (but since very similar errors had been fixed by #60449, I thought this issue here would have been fixed at the same time — so maybe it won't be bisected to the Universes PR after all).


edit: I also ran a quick bisect on it, and it started ICEing (with a different error location) in nightly-2019-01-04 which is IIRC the one where Universes landed).

A minimization would be very helpful indeed.

@jethrogb
Copy link
Contributor

jethrogb commented May 10, 2019

@lqd if I change main to no longer ICE (or if I inline mod deps), I get this error. Do you think you can have a repro that doesn't error when the ICE is gone?

error[E0507]: cannot move out of captured variable in an `FnMut` closure
  --> src/deps.rs:51:29
   |
42 |           root_node: Arc<RootNode<'a, QueryT, MutationT, S>>,
   |           --------- captured outer variable
...
51 |               future::poll_fn(move || {
   |  _____________________________^
52 | |                 let _res = request.execute(&root_node);
53 | |                 Ok(Async::Ready(()))
54 | |             })
   | |_____________^ cannot move out of captured variable in an `FnMut` closure

error: aborting due to previous error

@jethrogb
Copy link
Contributor

jethrogb commented May 10, 2019

a repro that doesn't error when the ICE is gone

Got it:

diff --git a/src/deps.rs b/src/deps.rs
index d5ad25a..a10b259 100644
--- a/src/deps.rs
+++ b/src/deps.rs
@@ -48,6 +48,7 @@ where
     {
         let requests: Vec<JuniperGraphQLRequest<S>> = vec![];
         future::join_all(requests.into_iter().map(move |request| {
+            let root_node = root_node.clone();
             future::poll_fn(move || {
                 let _res = request.execute(&root_node);
                 Ok(Async::Ready(()))

@jethrogb
Copy link
Contributor

Reduced:

trait Future {
    type Item;
}

struct PollFn<F> {
    _i: F,
}
fn poll_fn<T, F>(_: F) -> PollFn<F>
where
    F: FnMut() -> T,
{
    unimplemented!()
}
impl<T, F> Future for PollFn<F>
where
    F: FnMut() -> T,
{
    type Item = T;
}

struct JoinAll<I>
where
    I: IntoIterator,
    I::Item: Future,
{
    _f: I::Item,
}
fn join_all<I>(_: I) -> JoinAll<I>
where
    I: IntoIterator,
    I::Item: Future,
{
    unimplemented!()
}
impl<I> Future for JoinAll<I>
where
    I: IntoIterator,
    I::Item: Future,
{
    type Item = I;
}

fn f<'a, T: 'a>(r: &'a T) -> impl Future + 'a {
    let requests = Vec::<()>::new();
    join_all(requests.into_iter().map(move |_| {
        poll_fn(move || {
            r;
        })
    }))
}

fn main() {
    || -> Box<Send> { Box::new(f(&())) };
}

Since this involves IntoIterator, it makes me think of another recent ICE involving universes, but I can't find the exact issue right now.

@jethrogb
Copy link
Contributor

jethrogb commented May 11, 2019

Maybe #58375?

bors added a commit that referenced this issue May 13, 2019
@lqd
Copy link
Member

lqd commented May 14, 2019

I manually checked the latest nightly on the bigger repro project, and we have the expected error[E0507]: cannot move out of captured variable in an FnMut closure error instead of the ICE 👍 . The minimized code above (thanks again @jethrogb) doesn't ICE either.

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) ❄️ P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. 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.