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

"failed to normalize" ICE in NLL borrow checker #61311

Closed
jonas-schievink opened this issue May 29, 2019 · 5 comments · Fixed by #61488
Closed

"failed to normalize" ICE in NLL borrow checker #61311

jonas-schievink opened this issue May 29, 2019 · 5 comments · Fixed by #61488
Assignees
Labels
A-borrow-checker Area: The borrow checker A-NLL Area: Non-lexical lifetimes (NLL) 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

@jonas-schievink
Copy link
Contributor

Happens on stable 1.34.2, 1.35.0 and current nightly (2019-05-28). Playground.

pub trait IntoFuture {
    type Item;
    type Error;
    type Future: Future<Item=Self::Item, Error=Self::Error>;
}

impl<T, E> IntoFuture for Result<T, E> {
    type Item = T;
    type Error = E;
    type Future = Fut<T, E>;
}

pub trait Future {
    type Item;
    type Error;
}

struct Fut<T, E>(T, E);
impl<T, E> Future for Fut<T, E> {
    type Item = T;
    type Error = E;
}

type BoxedError = Box<dyn std::error::Error + Send + Sync>;

trait FromRequest {
    type Context;
    fn from_request(context: Self::Context);
}

trait Guard {
    type Result;
}

struct Authenticated<R> {
    inner: R,
}

impl<R> FromRequest for Authenticated<R>
where
    <User as Guard>::Result:
        IntoFuture<Item = User, Error = BoxedError>,
    <<User as Guard>::Result as IntoFuture>::Future:
        Send,
{
    type Context = ();
    fn from_request(_: Self::Context) {}
}

struct User;
impl Guard for User {
    type Result = Result<Self, BoxedError>;
}

Results in:

error: internal compiler error: src/librustc_mir/borrow_check/nll/type_check/free_region_relations.rs:260: failed to normalize <Authenticated<R> as FromRequest>::Context

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:637:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/backtrace-0.3.25/src/backtrace/libunwind.rs:97
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/backtrace-0.3.25/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:47
   3: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:36
   4: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:197
   5: std::panicking::default_hook
             at src/libstd/panicking.rs:211
   6: rustc::util::common::panic_hook
   7: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   8: std::panicking::begin_panic
   9: rustc_errors::Handler::bug
  10: rustc::util::bug::opt_span_bug_fmt::{{closure}}
  11: rustc::ty::context::tls::with_opt::{{closure}}
  12: rustc::ty::context::tls::with_context_opt
  13: rustc::ty::context::tls::with_opt
  14: rustc::util::bug::opt_span_bug_fmt
  15: rustc::util::bug::bug_fmt
  16: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once
  17: <core::iter::adapters::flatten::FlatMap<I,U,F> as core::iter::traits::iterator::Iterator>::next
  18: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::from_iter
  19: rustc_mir::borrow_check::nll::type_check::free_region_relations::create
  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 for rustc::ty::query::queries::mir_borrowck>::compute
  27: rustc::dep_graph::graph::DepGraph::with_task_impl
  28: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  29: rustc::ty::<impl rustc::ty::context::TyCtxt>::par_body_owners
  30: rustc::util::common::time
  31: rustc_interface::passes::analysis
  32: rustc::ty::query::__query_compute::analysis
  33: rustc::dep_graph::graph::DepGraph::with_task_impl
  34: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  35: rustc::ty::context::tls::enter_global
  36: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  37: rustc_interface::passes::create_global_ctxt::{{closure}}
  38: rustc_interface::interface::run_compiler_in_existing_thread_pool
  39: std::thread::local::LocalKey<T>::with
  40: scoped_tls::ScopedKey<T>::set
  41: syntax::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
query stack during panic:
#0 [mir_borrowck] processing `<Authenticated<R> as FromRequest>::from_request`
#1 [analysis] running analysis passes on this crate
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.37.0-nightly (721268583 2019-05-28) running on x86_64-unknown-linux-gnu

note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type lib

note: some of the compiler flags provided by cargo are hidden
@jonas-schievink jonas-schievink added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-nominated A-borrow-checker Area: The borrow checker T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-NLL Area: Non-lexical lifetimes (NLL) C-bug Category: This is a bug. labels May 29, 2019
@Centril
Copy link
Contributor

Centril commented May 29, 2019

Reduced:

pub struct Unit;
trait Obj {}

trait Bound {}
impl Bound for Unit {}

pub trait HasProj {
    type Proj;
}

impl<T> HasProj for T {
    type Proj = Unit;
}

trait HasProjFn {
    type Proj;
    fn the_fn(_: Self::Proj);
}

impl HasProjFn for Unit
where
    Box<dyn Obj>: HasProj,
    <Box<dyn Obj> as HasProj>::Proj: Bound,
{
    type Proj = Unit;
    fn the_fn(_: Self::Proj) {}
}

@Centril Centril added the regression-from-stable-to-stable Performance or correctness regression from one stable version to another. label May 29, 2019
@Centril
Copy link
Contributor

Centril commented May 29, 2019

Compiles fine on 1.34.0; haven't tested 1.34.1.

@jonas-schievink
Copy link
Contributor Author

@Centril both my repro and your reduced one do ICE on rustc 1.34.0 (91856ed52 2019-04-10) (and rustc 1.34.1 (fc50f328b 2019-04-24)) for me, can you verify that again?

@jonas-schievink
Copy link
Contributor Author

Happens all the way back to 1.30.0 (with RUSTC_BOOTSTRAP=1) for me, as long as --edition=2018 is passed to rustc.

@Centril
Copy link
Contributor

Centril commented May 29, 2019

@jonas-schievink Ah of course! --edition=2018 is needed for NLL on older versions... :) I forgot that godbolt doesn't have that by default.

@Centril Centril removed the regression-from-stable-to-stable Performance or correctness regression from one stable version to another. label May 29, 2019
@matthewjasper matthewjasper self-assigned this May 29, 2019
Centril added a commit to Centril/rust that referenced this issue Jun 4, 2019
…r=pnkfelix

Fix NLL typeck ICEs

* Don't ICE when a type containing a region is constrained by nothing
* Don't ICE trying to normalize a type in a `ParamEnv` containing global bounds.

To explain what was happening in the `issue-61311-normalize.rs` case:

* When borrow checking the `the_fn` in the last `impl` we would try to normalize `Self::Proj` (`<Unit as HasProjFn>::Proj`).
* We would find the `impl` that we're checking and and check its `where` clause.
* This would need us to check `<Box<dyn Obj + 'static> as HasProj>::Proj: Bound`
* We find two possible implementations, the blanket impl and the bound in our `ParamEnv`.
* The bound in our `ParamEnv` was canonicalized, so we don't see it as a global bound. As such we prefer it to the `impl`.
* This means that we cannot normalize `<Box<dyn Obj + 'static> as HasProj>::Proj` to `Unit`.
* The `<Box<dyn Obj + 'static> as HasProj>::Proj: Bound` bound, which looks like it should be in our `ParamEnv` has been normalized to `Unit: Bound`.
* We fail to prove `<Box<dyn Obj + 'static> as HasProj>::Proj: Bound`.
* We ICE, since we believe typeck have errored.

Closes rust-lang#61311
Closes rust-lang#61315
Closes rust-lang#61320

r? @pnkfelix
cc @nikomatsakis
pietroalbini added a commit to pietroalbini/rust that referenced this issue Jun 4, 2019
…r=pnkfelix

Fix NLL typeck ICEs

* Don't ICE when a type containing a region is constrained by nothing
* Don't ICE trying to normalize a type in a `ParamEnv` containing global bounds.

To explain what was happening in the `issue-61311-normalize.rs` case:

* When borrow checking the `the_fn` in the last `impl` we would try to normalize `Self::Proj` (`<Unit as HasProjFn>::Proj`).
* We would find the `impl` that we're checking and and check its `where` clause.
* This would need us to check `<Box<dyn Obj + 'static> as HasProj>::Proj: Bound`
* We find two possible implementations, the blanket impl and the bound in our `ParamEnv`.
* The bound in our `ParamEnv` was canonicalized, so we don't see it as a global bound. As such we prefer it to the `impl`.
* This means that we cannot normalize `<Box<dyn Obj + 'static> as HasProj>::Proj` to `Unit`.
* The `<Box<dyn Obj + 'static> as HasProj>::Proj: Bound` bound, which looks like it should be in our `ParamEnv` has been normalized to `Unit: Bound`.
* We fail to prove `<Box<dyn Obj + 'static> as HasProj>::Proj: Bound`.
* We ICE, since we believe typeck have errored.

Closes rust-lang#61311
Closes rust-lang#61315
Closes rust-lang#61320

r? @pnkfelix
cc @nikomatsakis
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker A-NLL Area: Non-lexical lifetimes (NLL) 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

Successfully merging a pull request may close this issue.

3 participants