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

ICE !ty.needs_infer() && !ty.has_placeholders() from boxing closure of type dyn for<'a> _ #57843

Closed
nick-fischer opened this issue Jan 22, 2019 · 7 comments
Assignees
Labels
A-typesystem Area: The type system I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nick-fischer
Copy link

nick-fischer commented Jan 22, 2019

While experimenting with clonable closures (and encountering like a thousand one type is more general than the other errors), I eventually discovered a scenario which crashes rustc.

I tried this code (play:

trait ClonableFn<T> {
	fn clone(&self) -> Box<dyn Fn(T)>;
}

impl<T, F: 'static> ClonableFn<T> for F
where F: Fn(T) + Clone {
	fn clone(&self) -> Box<dyn Fn(T)> {
		Box::new(self.clone())
	}
}

struct Foo(Box<dyn for<'a> ClonableFn<&'a bool>>);

fn main() {
	Foo(Box::new(|_| ()));
}

I expected to see this happen: Actually, I am not sure ... Anyways, I guess I expected to see rustc surviving the input ...

Meta

rustc --version --verbose:
rustc 1.33.0-nightly (c0bbc39 2019-01-03)
binary: rustc
commit-hash: c0bbc39
commit-date: 2019-01-03
host: x86_64-unknown-linux-gnu
release: 1.33.0-nightly
LLVM version: 8.0

Backtrace:

thread 'rustc' panicked at 'assertion failed: !ty.needs_infer() && !ty.has_placeholders()', src/librustc_typeck/check/writeback.rs:109:9
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:215
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:482
   6: std::panicking::begin_panic
   7: rustc_typeck::check::writeback::WritebackCx::visit_node_id
   8: <rustc_typeck::check::writeback::WritebackCx<'cx, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_expr
   9: rustc::hir::intravisit::walk_expr
  10: <rustc_typeck::check::writeback::WritebackCx<'cx, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_expr
  11: rustc::hir::intravisit::walk_block
  12: <rustc_typeck::check::writeback::WritebackCx<'cx, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_expr
  13: rustc_typeck::check::writeback::<impl rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx>>::resolve_type_vars_in_body
  14: rustc::ty::context::GlobalCtxt::enter_local
  15: rustc_typeck::check::typeck_tables_of
  16: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::typeck_tables_of<'tcx>>::compute
  17: rustc::dep_graph::graph::DepGraph::with_task_impl
  18: <rustc::ty::query::plumbing::JobOwner<'a, 'tcx, Q>>::start
  19: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  20: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
  21: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
  22: rustc::session::Session::track_errors
  23: rustc_typeck::check::typeck_item_bodies
  24: rustc::ty::query::__query_compute::typeck_item_bodies
  25: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::typeck_item_bodies<'tcx>>::compute
  26: rustc::dep_graph::graph::DepGraph::with_task_impl
  27: <rustc::ty::query::plumbing::JobOwner<'a, 'tcx, Q>>::start
  28: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  29: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
  30: rustc::util::common::time
  31: rustc_typeck::check_crate
  32: <std::thread::local::LocalKey<T>>::with
  33: rustc::ty::context::TyCtxt::create_and_enter
  34: rustc_driver::driver::compile_input
  35: rustc_driver::run_compiler_with_pool
  36: <scoped_tls::ScopedKey<T>>::set
  37: rustc_driver::run_compiler
  38: <scoped_tls::ScopedKey<T>>::set
  39: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  40: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:92
  41: <F as alloc::boxed::FnBox<A>>::call_box
  42: std::sys::unix::thread::Thread::new::thread_start
             at /rustc/c0bbc3927e28c22edefe6a1353b5ecc95ea9a104/src/liballoc/boxed.rs:734
             at src/libstd/sys_common/thread.rs:14
             at src/libstd/sys/unix/thread.rs:81
  43: start_thread
  44: clone
query stack during panic:
#0 [typeck_tables_of] processing `main`
#1 [typeck_item_bodies] type-checking all item bodies
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.33.0-nightly (c0bbc3927 2019-01-03) running on x86_64-unknown-linux-gnu

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 `hello`.

Caused by:
  process didn't exit successfully: `rustc --crate-name hello src/main.rs --color always --crate-type bin --emit=dep-info,metadata -C debuginfo=2 -C metadata=9735c65936601b39 -C extra-filename=-9735c65936601b39 --out-dir /home/nick/Documents/rust/hello/target/debug/deps -C incremental=/home/nick/Documents/rust/hello/target/debug/incremental -L dependency=/home/nick/Documents/rust/hello/target/debug/deps` (exit code: 101)
@sfackler sfackler added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Jan 22, 2019
@hellow554
Copy link
Contributor

Happens on 1.33.0-beta.3 (!) and 1.33.0-nightly (4c2be9c 2019-01-22), but not on stable.

The ICE does not occur, if you change the line to struct Foo(Box<dyn ClonableFn<bool>>);

Was introduced with nightly-2019-01-04, so somewhere between ec19464...c0bbc39

@hellow554
Copy link
Contributor

Based on the commits I guess @nikomatsakis should be able to say something about it

@Centril Centril added A-typesystem Area: The type system P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. regression-from-stable-to-beta Performance or correctness regression from stable to beta. labels Jan 24, 2019
@pnkfelix
Copy link
Member

triage. Confirm P-high. Assigning to self for initial investigation.

@pnkfelix pnkfelix self-assigned this Jan 24, 2019
@pnkfelix
Copy link
Member

I have confirmed that this was injected by #55517

cc @nikomatsakis @scalexm

@pnkfelix
Copy link
Member

pnkfelix commented Jan 28, 2019

(We've been asserting !ty.needs_infer() or some variant thereof in the writeback method for years. I'm yet not sure what changed in #55517 to disrupt that invariant; its possible that something is triggering the assertion that previously did not. Or we might be writing-back a type that in the past we did not write-back...)

Also, something potentially of note: #50197 changed the definition of needs_infer, but was careful to preserve the meaning of the aforementioned assertion by expanding it to !ty.needs_infer() && !ty.has_placeholders() (or, at that time, !ty.has_skol()). This seems like a good (conservative) decision, but it may have interacted in some manner with the changes in #55517.

  • In particular, the type in question that is triggering the assertion has has_placeholders(): true.

@pnkfelix
Copy link
Member

@nick-fischer I don't know if this is of interest to you, but I did find that if you use this slightly different variant with an explicit type on the closure parameter, the code compiles (play):

trait ClonableFn<T> {
	fn clone(&self) -> Box<dyn Fn(T)>;
}

impl<T, F: 'static> ClonableFn<T> for F
where F: Fn(T) + Clone {
	fn clone(&self) -> Box<dyn Fn(T)> {
		Box::new(self.clone())
	}
}

struct Foo(Box<dyn for<'a> ClonableFn<&'a bool>>);

fn main() {
	Foo(Box::new(|_: &bool| ()));
	//             ~~~~~~~ this is what changed
}

@nick-fischer
Copy link
Author

Interesting ... Thank you!

@pnkfelix pnkfelix changed the title Compiler crash ICE !ty.needs_infer() && !ty.has_placeholders() from box of closure with dyn for<'a> type. Jan 31, 2019
@pnkfelix pnkfelix changed the title ICE !ty.needs_infer() && !ty.has_placeholders() from box of closure with dyn for<'a> type. ICE !ty.needs_infer() && !ty.has_placeholders() from boxing closure of type dyn for<'a> _ Jan 31, 2019
bors added a commit that referenced this issue Feb 20, 2019
…elix

make generalization code create new variables in correct universe

In our type inference system, when we "generalize" a type T to become
a suitable value for a type variable V, we sometimes wind up creating
new inference variables. So, for example, if we are making V be some
subtype of `&'X u32`, then we might instantiate V with `&'Y u32`.
This generalized type is then related `&'Y u32 <: &'X u32`, resulting
in a region constriant `'Y: 'X`. Previously, however, we were making
these fresh variables like `'Y` in the "current universe", but they
should be created in the universe of V. Moreover, we sometimes cheat
in an invariant context and avoid creating fresh variables if we know
the result must be equal -- we can only do that when the universes
work out.

Fixes #57843

r? @pnkfelix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-typesystem Area: The type system I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. 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