Repository: rust-analyzer/rust-analyzer
Pull request #4982 (2020-06-22 12:17:09)

Bump chalk
This passes the tests, but fails in a weird way on `analysis-stats`:

```
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /home/me/.cargo/registry/src/github.com-1ecc6299db9ec823/chalk-solve-0.14.0/src/clauses/builtin_traits/fn_family.rs:96:20
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1076
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1537
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:477
  11: rust_begin_unwind
             at src/libstd/panicking.rs:385
  12: core::panicking::panic_fmt
             at src/libcore/panicking.rs:86
  13: core::panicking::panic
             at src/libcore/panicking.rs:51
  14: chalk_solve::clauses::builtin_traits::fn_family::add_fn_trait_program_clauses
  15: chalk_solve::clauses::builder::ClauseBuilder<I>::push_binders
  16: chalk_solve::clauses::program_clauses_that_could_match
  17: chalk_solve::clauses::program_clauses_for_goal
  18: chalk_solve::recursive::Solver<I>::solve_new_subgoal
  19: <chalk_solve::recursive::Solver<I> as chalk_solve::recursive::solve::SolveDatabase<I>>::solve_goal
  20: chalk_solve::recursive::Solver<I>::solve_root_goal
  21: chalk_solve::solve::Solver<I>::solve_limited
  22: ra_hir_ty::traits::trait_solve_query
  23: salsa::runtime::Runtime<DB>::execute_query_implementation
  24: salsa::derived::slot::Slot<DB,Q,MP>::read_upgrade
  25: salsa::derived::slot::Slot<DB,Q,MP>::read
  26: <salsa::derived::DerivedStorage<DB,Q,MP> as salsa::plumbing::QueryStorageOps<DB,Q>>::try_fetch
  27: salsa::QueryTable<DB,Q>::get
  28: <T as ra_hir_ty::db::HirDatabase>::trait_solve
  29: ra_hir_ty::infer::InferenceContext::resolve_ty_as_possible
  30: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  31: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_coerce
  32: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::check_call_arguments
  33: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_method_call
  34: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  35: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr
  36: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_method_call
  37: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  38: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_coerce
  39: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  40: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  41: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_coerce
  42: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  43: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_coerce
  44: ra_hir_ty::infer::infer_query
  45: salsa::runtime::Runtime<DB>::execute_query_implementation
  46: salsa::derived::slot::Slot<DB,Q,MP>::read_upgrade
  47: salsa::derived::slot::Slot<DB,Q,MP>::read
  48: <salsa::derived::DerivedStorage<DB,Q,MP> as salsa::plumbing::QueryStorageOps<DB,Q>>::try_fetch
  49: ra_hir_ty::db::infer_wait
  50: rust_analyzer::cli::analysis_stats::analysis_stats
  51: rust_analyzer::main
  52: std::rt::lang_start::{{closure}}
  53: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:52
  54: std::panicking::try::do_call
             at src/libstd/panicking.rs:297
  55: std::panicking::try
             at src/libstd/panicking.rs:274
  56: std::panic::catch_unwind
             at src/libstd/panic.rs:394
  57: std::rt::lang_start_internal
             at src/libstd/rt.rs:51
  58: main
  59: __libc_start_main
  60: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

It's as if we're returning `None` for a well-known trait that `chalk` asks about. That seems to happen for `Deref`, `CoerceUnsized` and `Try`.

r? @flodiebold

flodiebold: > It's as if we're returning None for a well-known trait that chalk asks about. That seems to happen for Deref, CoerceUnsized and Try.

What do you mean? Do these even exist as well-known traits in Chalk?
lnicola: > What do you mean? Do these even exist as well-known traits in Chalk?

Ah, never mind those. I think the problem is that [here](https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_hir_ty/src/traits/chalk.rs#L132) `lang_items.target("fn_mut")` returns `None`.
lnicola: It looks like `lang_item` is empty. Maybe we pass the wrong crate to `self.db.crate_lang_items(self.krate)`?
flodiebold: Ah, that should be `self.db.lang_item(self.krate, lang_attr)` :weary: `crate_lang_items` is not transitive. I think I made that exact mistake once already :facepalm: 
flodiebold: Maybe we should rename `crate_lang_items` to something like `lang_items_defined_in_crate`.
lnicola: Done, but after a rebase it crashes with

```
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `^1`,
 right: `^0`', /home/me/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/macros.rs:16:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1076
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1537
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:218
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:477
  11: rust_begin_unwind
             at src/libstd/panicking.rs:385
  12: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:339
  13: <&chalk_ir::SubstFolder<I> as chalk_ir::fold::Folder<I>>::fold_free_var_ty
  14: <chalk_ir::Ty<I> as chalk_ir::fold::SuperFold<I,TI>>::super_fold_with
  15: chalk_ir::_DERIVE_chalk_ir_fold_Fold_I_TI_FOR_DomainGoal::<impl chalk_ir::fold::Fold<I,_TI> for chalk_ir::DomainGoal<I>>::fold_with
  16: chalk_ir::_DERIVE_chalk_ir_fold_Fold_I_TI_FOR_ProgramClauseImplication::<impl chalk_ir::fold::Fold<I,_TI> for chalk_ir::ProgramClauseImplication<I>>::fold_with
  17: chalk_solve::infer::instantiate::<impl chalk_solve::infer::InferenceTable<I>>::instantiate_binders_existentially
  18: chalk_solve::recursive::fulfill::Fulfill<I,Solver,Infer>::new_with_clause
  19: chalk_solve::recursive::Solver<I>::solve_new_subgoal
  20: <chalk_solve::recursive::Solver<I> as chalk_solve::recursive::solve::SolveDatabase<I>>::solve_goal
  21: chalk_solve::recursive::fulfill::Fulfill<I,Solver,Infer>::prove
  22: chalk_solve::recursive::fulfill::Fulfill<I,Solver,Infer>::solve
  23: chalk_solve::recursive::Solver<I>::solve_new_subgoal
  24: <chalk_solve::recursive::Solver<I> as chalk_solve::recursive::solve::SolveDatabase<I>>::solve_goal
  25: chalk_solve::recursive::Solver<I>::solve_root_goal
  26: chalk_solve::solve::Solver<I>::solve_limited
  27: ra_hir_ty::traits::trait_solve_query
  28: salsa::runtime::Runtime<DB>::execute_query_implementation
  29: salsa::derived::slot::Slot<DB,Q,MP>::read_upgrade
  30: salsa::derived::slot::Slot<DB,Q,MP>::read
  31: <salsa::derived::DerivedStorage<DB,Q,MP> as salsa::plumbing::QueryStorageOps<DB,Q>>::try_fetch
  32: salsa::QueryTable<DB,Q>::get
  33: <T as ra_hir_ty::db::HirDatabase>::trait_solve
  34: ra_hir_ty::infer::InferenceContext::resolve_ty_as_possible
```
flodiebold: Hmm I think that's a bug in Chalk. Looking into it.
flodiebold: I think that Chalk PR should fix it.
lnicola: It does!

I updated the PR with a `git` dependency, but we can wait until the Sunday release instead.
matklad: > but we can wait until the Sunday release instead.

Hm, long-term, this is not the pattern I'd love to see.... I'd say its pretty crucial to be able to apply improvements immediately, without waiting (as blocking easily accumulates). But that interacts with vendoring....
lnicola: ```
Expressions of unknown type: 2070 (1%)
Expressions of partially unknown type: 2243 (1%)
Type mismatches: 780

Expressions of unknown type: 1581 (0%)
Expressions of partially unknown type: 1098 (0%)
Type mismatches: 593
```

> But that interacts with vendoring....

`rustc` already uses `chalk`, so I guess it would be nice to use the same version.. OTOH we (might want to) upgrade more often.
cynecx: Unfortunately, this doesn't fix https://github.com/rust-analyzer/rust-analyzer/issues/2880.
lnicola: This doesn't implement closures.
flodiebold: It shouldn't need to, since we still have our own implementation of the built-in impl for that -- but isn't #2880 about function pointers? :thinking: 
cynecx: Sorry, I just had the impression we’ve had support for that (per https://github.com/rust-analyzer/rust-analyzer/pull/4493).

Patch:
diff --git a/Cargo.lock b/Cargo.lock
index b2b6242126..f22366a362 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -24,6 +24,15 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "ansi_term"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
+dependencies = [
+ "winapi 0.3.8",
+]
+
 [[package]]
 name = "anyhow"
 version = "1.0.31"
@@ -94,6 +103,12 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "byteorder"
+version = "1.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+
 [[package]]
 name = "cargo_metadata"
 version = "0.10.0"
@@ -120,9 +135,8 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 
 [[package]]
 name = "chalk-derive"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b9bd01eab87277d973183a1d2e56bace1c11f8242c52c20636fb7dddf343ac9"
+version = "0.15.0-dev.0"
+source = "git+https://github.com/rust-lang/chalk#57037a53f7decc965d25972606c3ea930e9cb39f"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -132,20 +146,19 @@ dependencies = [
 
 [[package]]
 name = "chalk-engine"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c7a637c3d17ed555aef16e16952a5d1e127bd55178cc30be22afeb92da90c7d"
+version = "0.15.0-dev.0"
+source = "git+https://github.com/rust-lang/chalk#57037a53f7decc965d25972606c3ea930e9cb39f"
 dependencies = [
  "chalk-derive",
  "chalk-ir",
  "rustc-hash",
+ "tracing",
 ]
 
 [[package]]
 name = "chalk-ir"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "595e5735ded16c3f3dc348f7b15bbb2521a0080b1863cac38ad5271589944670"
+version = "0.15.0-dev.0"
+source = "git+https://github.com/rust-lang/chalk#57037a53f7decc965d25972606c3ea930e9cb39f"
 dependencies = [
  "chalk-derive",
  "lazy_static",
@@ -153,9 +166,8 @@ dependencies = [
 
 [[package]]
 name = "chalk-solve"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d9d938139db425867a30cc0cfec0269406d8238d0571d829041eaa7a8455d11"
+version = "0.15.0-dev.0"
+source = "git+https://github.com/rust-lang/chalk#57037a53f7decc965d25972606c3ea930e9cb39f"
 dependencies = [
  "chalk-derive",
  "chalk-engine",
@@ -164,6 +176,19 @@ dependencies = [
  "itertools",
  "petgraph",
  "rustc-hash",
+ "tracing",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "chrono"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
+dependencies = [
+ "num-integer",
+ "num-traits",
+ "time",
 ]
 
 [[package]]
@@ -676,6 +701,15 @@ dependencies = [
  "url",
 ]
 
+[[package]]
+name = "matchers"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
+dependencies = [
+ "regex-automata",
+]
+
 [[package]]
 name = "matches"
 version = "0.1.8"
@@ -796,6 +830,25 @@ dependencies = [
  "winapi 0.3.8",
 ]
 
+[[package]]
+name = "num-integer"
+version = "0.1.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
+dependencies = [
+ "autocfg",
+]
+
 [[package]]
 name = "num_cpus"
 version = "1.13.0"
@@ -1333,6 +1386,16 @@ dependencies = [
  "thread_local",
 ]
 
+[[package]]
+name = "regex-automata"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
+dependencies = [
+ "byteorder",
+ "regex-syntax",
+]
+
 [[package]]
 name = "regex-syntax"
 version = "0.6.18"
@@ -1523,18 +1586,18 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 
 [[package]]
 name = "serde"
-version = "1.0.113"
+version = "1.0.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6135c78461981c79497158ef777264c51d9d0f4f3fc3a4d22b915900e42dac6a"
+checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.113"
+version = "1.0.114"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93c5eaa17d0954cb481cdcfffe9d84fcfa7a1a9f2349271e678677be4c26ae31"
+checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1575,6 +1638,15 @@ dependencies = [
  "yaml-rust",
 ]
 
+[[package]]
+name = "sharded-slab"
+version = "0.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e"
+dependencies = [
+ "lazy_static",
+]
+
 [[package]]
 name = "slab"
 version = "0.4.2"
@@ -1608,9 +1680,9 @@ checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
 
 [[package]]
 name = "syn"
-version = "1.0.32"
+version = "1.0.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a994520748611c17d163e81b6c4a4b13d11b7f63884362ab2efac3aa9cf16d00"
+checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1703,12 +1775,94 @@ dependencies = [
  "num_cpus",
 ]
 
+[[package]]
+name = "time"
+version = "0.1.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+dependencies = [
+ "libc",
+ "winapi 0.3.8",
+]
+
 [[package]]
 name = "tinyvec"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed"
 
+[[package]]
+name = "tracing"
+version = "0.1.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a41f40ed0e162c911ac6fcb53ecdc8134c46905fdbbae8c50add462a538b495f"
+dependencies = [
+ "cfg-if",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99bbad0de3fd923c9c3232ead88510b783e5a4d16a6154adffa3d53308de984c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9"
+dependencies = [
+ "lazy_static",
+ "log",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-serde"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6ccba2f8f16e0ed268fc765d9b7ff22e965e7185d32f8f1ec8294fe17d86e79"
+dependencies = [
+ "serde",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04a11b459109e38ff6e1b580bafef4142a11d44889f5d07424cbce2fd2a2a119"
+dependencies = [
+ "ansi_term",
+ "chrono",
+ "lazy_static",
+ "matchers",
+ "regex",
+ "serde",
+ "serde_json",
+ "sharded-slab",
+ "smallvec",
+ "tracing-core",
+ "tracing-log",
+ "tracing-serde",
+]
+
 [[package]]
 name = "unicode-bidi"
 version = "0.3.4"
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 112fcd07e7..407322dc16 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -27,8 +27,8 @@ test_utils = { path = "../test_utils" }
 
 scoped-tls = "1"
 
-chalk-solve = "0.11"
-chalk-ir = "0.11"
+chalk-solve = { version = "0.15.0-dev.0", git = "https://github.com/rust-lang/chalk" }
+chalk-ir = { version = "0.15.0-dev.0", git = "https://github.com/rust-lang/chalk" }
 
 [dev-dependencies]
 insta = "0.16.0"
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 2f35d6d499..8ef4941c0a 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -48,6 +48,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
     fn adt_datum(&self, struct_id: AdtId) -> Arc<StructDatum> {
         self.db.struct_datum(self.krate, struct_id)
     }
+    fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr {
+        unreachable!()
+    }
     fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
         self.db.impl_datum(self.krate, impl_id)
     }
@@ -128,8 +131,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
         well_known_trait: rust_ir::WellKnownTrait,
     ) -> Option<chalk_ir::TraitId<Interner>> {
         let lang_attr = lang_attr_from_well_known_trait(well_known_trait);
-        let lang_items = self.db.crate_lang_items(self.krate);
-        let trait_ = match lang_items.target(lang_attr) {
+        let trait_ = match self.db.lang_item(self.krate, lang_attr.into()) {
             Some(LangItemTarget::TraitId(trait_)) => trait_,
             _ => return None,
         };
@@ -186,6 +188,39 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
         // FIXME: implement actual object safety
         true
     }
+
+    fn closure_kind(
+        &self,
+        _closure_id: chalk_ir::ClosureId<Interner>,
+        _substs: &chalk_ir::Substitution<Interner>,
+    ) -> rust_ir::ClosureKind {
+        // FIXME: implement closure support
+        unimplemented!()
+    }
+    fn closure_inputs_and_output(
+        &self,
+        _closure_id: chalk_ir::ClosureId<Interner>,
+        _substs: &chalk_ir::Substitution<Interner>,
+    ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
+        // FIXME: implement closure support
+        unimplemented!()
+    }
+    fn closure_upvars(
+        &self,
+        _closure_id: chalk_ir::ClosureId<Interner>,
+        _substs: &chalk_ir::Substitution<Interner>,
+    ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
+        // FIXME: implement closure support
+        unimplemented!()
+    }
+    fn closure_fn_substitution(
+        &self,
+        _closure_id: chalk_ir::ClosureId<Interner>,
+        _substs: &chalk_ir::Substitution<Interner>,
+    ) -> chalk_ir::Substitution<Interner> {
+        // FIXME: implement closure support
+        unimplemented!()
+    }
 }
 
 pub(crate) fn program_clauses_for_chalk_env_query(
@@ -250,7 +285,7 @@ pub(crate) fn trait_datum_query(
         upstream: trait_.lookup(db.upcast()).container.module(db.upcast()).krate != krate,
         non_enumerable: true,
         coinductive: false, // only relevant for Chalk testing
-        // FIXME set these flags correctly
+        // FIXME: set these flags correctly
         marker: false,
         fundamental: false,
     };
@@ -272,20 +307,28 @@ pub(crate) fn trait_datum_query(
 
 fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> {
     Some(match name {
-        "sized" => WellKnownTrait::SizedTrait,
-        "copy" => WellKnownTrait::CopyTrait,
-        "clone" => WellKnownTrait::CloneTrait,
-        "drop" => WellKnownTrait::DropTrait,
+        "sized" => WellKnownTrait::Sized,
+        "copy" => WellKnownTrait::Copy,
+        "clone" => WellKnownTrait::Clone,
+        "drop" => WellKnownTrait::Drop,
+        "fn_once" => WellKnownTrait::FnOnce,
+        "fn_mut" => WellKnownTrait::FnMut,
+        "fn" => WellKnownTrait::Fn,
+        "unsize" => WellKnownTrait::Unsize,
         _ => return None,
     })
 }
 
 fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
     match attr {
-        WellKnownTrait::SizedTrait => "sized",
-        WellKnownTrait::CopyTrait => "copy",
-        WellKnownTrait::CloneTrait => "clone",
-        WellKnownTrait::DropTrait => "drop",
+        WellKnownTrait::Sized => "sized",
+        WellKnownTrait::Copy => "copy",
+        WellKnownTrait::Clone => "clone",
+        WellKnownTrait::Drop => "drop",
+        WellKnownTrait::FnOnce => "fn_once",
+        WellKnownTrait::FnMut => "fn_mut",
+        WellKnownTrait::Fn => "fn",
+        WellKnownTrait::Unsize => "unsize",
     }
 }
 
@@ -309,8 +352,9 @@ pub(crate) fn struct_datum_query(
         .unwrap_or_else(Vec::new);
     let flags = rust_ir::AdtFlags {
         upstream,
-        // FIXME set fundamental flag correctly
+        // FIXME set fundamental and phantom_data flags correctly
         fundamental: false,
+        phantom_data: false,
     };
     let struct_datum_bound = rust_ir::AdtDatumBound {
         fields: Vec::new(), // FIXME add fields (only relevant for auto traits)
@@ -448,11 +492,23 @@ pub(crate) fn fn_def_datum_query(
     let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
     let bound = rust_ir::FnDefDatumBound {
         // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
-        argument_types: sig.value.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(),
-        return_type: sig.value.ret().clone().to_chalk(db),
+        inputs_and_output: make_binders(
+            rust_ir::FnDefInputsAndOutputDatum {
+                argument_types: sig
+                    .value
+                    .params()
+                    .iter()
+                    .map(|ty| ty.clone().to_chalk(db))
+                    .collect(),
+                return_type: sig.value.ret().clone().to_chalk(db),
+            }
+            .shifted_in(&Interner),
+            0,
+        ),
         where_clauses,
     };
-    let datum = FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders) };
+    let datum =
+        FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders), abi: () };
     Arc::new(datum)
 }
 
diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs
index 56aab640c8..15426b0224 100644
--- a/crates/ra_hir_ty/src/traits/chalk/interner.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs
@@ -42,6 +42,7 @@ impl chalk_ir::interner::Interner for Interner {
     type DefId = InternId;
     type InternedAdtId = crate::TypeCtorId;
     type Identifier = TypeAliasId;
+    type FnAbi = ();
 
     fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
         tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
index 18e5c9c16f..ac82ea8310 100644
--- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
@@ -65,7 +65,10 @@ impl ToChalk for Ty {
                     &Interner,
                     predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
                 );
-                let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) };
+                let bounded_ty = chalk_ir::DynTy {
+                    bounds: make_binders(where_clauses, 1),
+                    lifetime: LIFETIME_PLACEHOLDER.to_lifetime(&Interner),
+                };
                 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
             }
             Ty::Opaque(opaque_ty) => {
@@ -319,6 +322,10 @@ impl ToChalk for TypeCtor {
                 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
                 unreachable!()
             }
+            TypeName::Closure(_) => {
+                // FIXME: implement closure support
+                unreachable!()
+            }
         }
     }
 }


Test patch:
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs
index a2601c68a5..5a1c6ccc35 100644
--- a/crates/ra_hir_ty/src/tests/coercion.rs
+++ b/crates/ra_hir_ty/src/tests/coercion.rs
@@ -664,6 +664,8 @@ fn test() {
 fn coerce_unsize_trait_object() {
     assert_snapshot!(
         infer_with_mismatches(r#"
+#[lang = "sized"]
+pub trait Sized {}
 #[lang = "unsize"]
 pub trait Unsize<T> {}
 #[lang = "coerce_unsized"]
@@ -689,19 +691,19 @@ fn test() {
 }
 "#, true),
         @r###"
-    387..572 '{     ...bj2; }': ()
-    397..400 'obj': &dyn Baz<i8, i16>
-    422..424 '&S': &S<i8, i16>
-    423..424 'S': S<i8, i16>
-    434..437 'obj': &dyn Bar<usize, i8, i16>
-    459..462 'obj': &dyn Baz<i8, i16>
-    472..475 'obj': &dyn Foo<i8, usize>
-    494..497 'obj': &dyn Bar<usize, i8, i16>
-    507..511 'obj2': &dyn Baz<i8, i16>
-    533..535 '&S': &S<i8, i16>
-    534..535 'S': S<i8, i16>
-    545..546 '_': &dyn Foo<i8, usize>
-    565..569 'obj2': &dyn Baz<i8, i16>
+    424..609 '{     ...bj2; }': ()
+    434..437 'obj': &dyn Baz<i8, i16>
+    459..461 '&S': &S<i8, i16>
+    460..461 'S': S<i8, i16>
+    471..474 'obj': &dyn Bar<usize, i8, i16>
+    496..499 'obj': &dyn Baz<i8, i16>
+    509..512 'obj': &dyn Foo<i8, usize>
+    531..534 'obj': &dyn Bar<usize, i8, i16>
+    544..548 'obj2': &dyn Baz<i8, i16>
+    570..572 '&S': &S<i8, i16>
+    571..572 'S': S<i8, i16>
+    582..583 '_': &dyn Foo<i8, usize>
+    602..606 'obj2': &dyn Baz<i8, i16>
     "###
     );
 }
@@ -710,6 +712,8 @@ fn test() {
 fn coerce_unsize_super_trait_cycle() {
     assert_snapshot!(
         infer_with_mismatches(r#"
+#[lang = "sized"]
+pub trait Sized {}
 #[lang = "unsize"]
 pub trait Unsize<T> {}
 #[lang = "coerce_unsized"]
@@ -734,12 +738,12 @@ fn test() {
 }
 "#, true),
         @r###"
-    291..347 '{     ...obj; }': ()
-    301..304 'obj': &dyn D
-    315..317 '&S': &S
-    316..317 'S': S
-    327..330 'obj': &dyn A
-    341..344 'obj': &dyn D
+    328..384 '{     ...obj; }': ()
+    338..341 'obj': &dyn D
+    352..354 '&S': &S
+    353..354 'S': S
+    364..367 'obj': &dyn A
+    378..381 'obj': &dyn D
     "###
     );
 }
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 646e1715c1..71c0c2d27e 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -1753,11 +1753,11 @@ fn test() {
     384..500 '{     ...(f); }': ()
     394..397 'bar': Bar<fn(u8) -> u32>
     423..426 'bar': Bar<fn(u8) -> u32>
-    423..432 'bar.foo()': {unknown}
+    423..432 'bar.foo()': (u8, u32)
     443..446 'opt': Opt<u8>
     465..466 'f': fn(u8) -> u32
     487..490 'opt': Opt<u8>
-    487..497 'opt.map(f)': Opt<FnOnce::Output<fn(u8) -> u32, (u8,)>>
+    487..497 'opt.map(f)': Opt<u32>
     495..496 'f': fn(u8) -> u32
     "###
     );
@@ -1830,9 +1830,9 @@ fn test() {
     634..643 'Lazy::new': fn new<Foo, fn() -> Foo>(fn() -> Foo) -> Lazy<Foo, fn() -> Foo>
     634..660 'Lazy::...n_ptr)': Lazy<Foo, fn() -> Foo>
     644..659 'make_foo_fn_ptr': fn() -> Foo
-    670..672 'r2': {unknown}
+    670..672 'r2': usize
     675..680 'lazy2': Lazy<Foo, fn() -> Foo>
-    675..686 'lazy2.foo()': {unknown}
+    675..686 'lazy2.foo()': usize
     549..551 '{}': ()
     "###
     );