about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-06-21 17:10:09 +0000
committerbors <bors@rust-lang.org>2020-06-21 17:10:09 +0000
commita8cf3991177f30694200002cd9479ffbbe6d9a1a (patch)
treef6b483650a05ed5c3f25b19e82cab033b522f0e4
parent349f6bfb11d73ebb6a272f9a3d00883484f8218c (diff)
parentd63195b0bc581837f77a22f46f2aa2303b911e56 (diff)
downloadrust-a8cf3991177f30694200002cd9479ffbbe6d9a1a.tar.gz
rust-a8cf3991177f30694200002cd9479ffbbe6d9a1a.zip
Auto merge of #72936 - jackh726:chalk-more, r=nikomatsakis
Upgrade Chalk

Things done in this PR:
- Upgrade Chalk to `0.11.0`
- Added compare-mode=chalk
- Bump rustc-hash in `librustc_data_structures` to `1.1.0` to match Chalk
- Removed `RustDefId` since the builtin type support is there
- Add a few more `FIXME(chalk)`s for problem spots I hit when running all tests with chalk
- Added some more implementation code for some newer builtin Chalk types (e.g. `FnDef`, `Array`)
- Lower `RegionOutlives` and `ObjectSafe` predicates
- Lower `Dyn` without the region
- Handle `Int`/`Float` `CanonicalVarKind`s
- Uncomment some Chalk tests that actually work now
- Remove the revisions in `src/test/ui/coherence/coherence-subtyping.rs` since they aren't doing anything different

r? @nikomatsakis
-rw-r--r--Cargo.lock82
-rw-r--r--src/librustc_data_structures/Cargo.toml2
-rw-r--r--src/librustc_middle/Cargo.toml2
-rw-r--r--src/librustc_middle/traits/chalk.rs94
-rw-r--r--src/librustc_middle/traits/mod.rs3
-rw-r--r--src/librustc_trait_selection/traits/chalk_fulfill.rs6
-rw-r--r--src/librustc_traits/Cargo.toml5
-rw-r--r--src/librustc_traits/chalk/db.rs407
-rw-r--r--src/librustc_traits/chalk/lowering.rs276
-rw-r--r--src/librustc_traits/chalk/mod.rs57
-rw-r--r--src/test/ui/chalkify/impl_wf.rs7
-rw-r--r--src/test/ui/chalkify/impl_wf.stderr16
-rw-r--r--src/test/ui/chalkify/inherent_impl.rs15
-rw-r--r--src/test/ui/chalkify/type_inference.rs8
-rw-r--r--src/test/ui/chalkify/type_inference.stderr12
-rw-r--r--src/test/ui/chalkify/type_wf.rs11
-rw-r--r--src/test/ui/chalkify/type_wf.stderr12
-rw-r--r--src/test/ui/coherence/coherence-subtyping.re.stderr16
-rw-r--r--src/test/ui/coherence/coherence-subtyping.rs7
-rw-r--r--src/test/ui/coherence/coherence-subtyping.stderr (renamed from src/test/ui/coherence/coherence-subtyping.old.stderr)2
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs1
-rw-r--r--src/tools/compiletest/src/runtest.rs3
-rw-r--r--src/tools/tidy/src/deps.rs2
24 files changed, 550 insertions, 499 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5bb6cda64cb..0c1c533f395 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -434,9 +434,9 @@ dependencies = [
 
 [[package]]
 name = "chalk-derive"
-version = "0.10.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d4620afad4d4d9e63f915cfa10c930b7a3c9c3ca5cd88dd771ff8e5bf04ea10"
+checksum = "5b9bd01eab87277d973183a1d2e56bace1c11f8242c52c20636fb7dddf343ac9"
 dependencies = [
  "proc-macro2 1.0.3",
  "quote 1.0.2",
@@ -446,58 +446,35 @@ dependencies = [
 
 [[package]]
 name = "chalk-engine"
-version = "0.10.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ca6e5cef10197789da0b4ec310eda58da4c55530613b2323432642a97372735"
+checksum = "6c7a637c3d17ed555aef16e16952a5d1e127bd55178cc30be22afeb92da90c7d"
 dependencies = [
- "chalk-macros",
+ "chalk-derive",
+ "chalk-ir",
  "rustc-hash",
 ]
 
 [[package]]
 name = "chalk-ir"
-version = "0.10.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d45df5fb6328527f976e8a32c9e1c9970084d937ebe93d0d34f5bbf4231cb956"
+checksum = "595e5735ded16c3f3dc348f7b15bbb2521a0080b1863cac38ad5271589944670"
 dependencies = [
  "chalk-derive",
- "chalk-engine",
- "chalk-macros",
-]
-
-[[package]]
-name = "chalk-macros"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e4782d108e420a1fcf94d8a919cf248db33c5071678e87d9c2d4f20ed1feb32"
-dependencies = [
  "lazy_static",
 ]
 
 [[package]]
-name = "chalk-rust-ir"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0ec96dbe0ab5fdbadfca4179ec2e1d35f0439c3b53a74988b1aec239c63eb08"
-dependencies = [
- "chalk-derive",
- "chalk-engine",
- "chalk-ir",
- "chalk-macros",
-]
-
-[[package]]
 name = "chalk-solve"
-version = "0.10.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfb99fa9530f0e101475fb60adc931f51bdea05b4642a48928b814d7f0141a6b"
+checksum = "5d9d938139db425867a30cc0cfec0269406d8238d0571d829041eaa7a8455d11"
 dependencies = [
  "chalk-derive",
  "chalk-engine",
  "chalk-ir",
- "chalk-macros",
- "chalk-rust-ir",
- "ena 0.13.1",
+ "ena",
  "itertools 0.9.0",
  "petgraph",
  "rustc-hash",
@@ -1063,15 +1040,6 @@ dependencies = [
 
 [[package]]
 name = "ena"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36"
-dependencies = [
- "log",
-]
-
-[[package]]
-name = "ena"
 version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
@@ -1181,9 +1149,9 @@ dependencies = [
 
 [[package]]
 name = "fixedbitset"
-version = "0.1.9"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
+checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
 
 [[package]]
 name = "flate2"
@@ -2371,12 +2339,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "ordermap"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
-
-[[package]]
 name = "ordslice"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2546,12 +2508,12 @@ dependencies = [
 
 [[package]]
 name = "petgraph"
-version = "0.4.13"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
+checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
 dependencies = [
  "fixedbitset",
- "ordermap",
+ "indexmap",
 ]
 
 [[package]]
@@ -3292,7 +3254,7 @@ dependencies = [
  "bitflags",
  "cfg-if",
  "crossbeam-utils 0.7.2",
- "ena 0.14.0",
+ "ena",
  "indexmap",
  "jobserver",
  "lazy_static",
@@ -3501,12 +3463,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-hash"
-version = "1.0.1"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
-dependencies = [
- "byteorder",
-]
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 
 [[package]]
 name = "rustc-main"
@@ -3757,7 +3716,7 @@ dependencies = [
  "bitflags",
  "cfg-if",
  "crossbeam-utils 0.7.2",
- "ena 0.14.0",
+ "ena",
  "indexmap",
  "jobserver",
  "lazy_static",
@@ -4376,7 +4335,6 @@ name = "rustc_traits"
 version = "0.0.0"
 dependencies = [
  "chalk-ir",
- "chalk-rust-ir",
  "chalk-solve",
  "log",
  "rustc_ast",
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index bf2ab0787cb..1c2fb90b2d8 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -23,7 +23,7 @@ crossbeam-utils = { version = "0.7", features = ["nightly"] }
 stable_deref_trait = "1.0.0"
 rayon = { version = "0.3.0", package = "rustc-rayon" }
 rayon-core = { version = "0.3.0", package = "rustc-rayon-core" }
-rustc-hash = "1.0.1"
+rustc-hash = "1.1.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc_index = { path = "../librustc_index", package = "rustc_index" }
 bitflags = "1.2.1"
diff --git a/src/librustc_middle/Cargo.toml b/src/librustc_middle/Cargo.toml
index 0c22672d5fb..21d0b102a4a 100644
--- a/src/librustc_middle/Cargo.toml
+++ b/src/librustc_middle/Cargo.toml
@@ -30,7 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
 byteorder = { version = "1.3" }
-chalk-ir = "0.10.0"
+chalk-ir = "0.11.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 measureme = "0.7.1"
 rustc_session = { path = "../librustc_session" }
diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs
index b963af96f50..a49a0045812 100644
--- a/src/librustc_middle/traits/chalk.rs
+++ b/src/librustc_middle/traits/chalk.rs
@@ -5,11 +5,9 @@
 //! its name suggest, is to provide an abstraction boundary for creating
 //! interned Chalk types.
 
-use chalk_ir::{GoalData, Parameter};
-
-use rustc_middle::mir::Mutability;
+use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
 
 use rustc_hir::def_id::DefId;
 
@@ -19,27 +17,6 @@ use std::cmp::Ordering;
 use std::fmt;
 use std::hash::{Hash, Hasher};
 
-/// Since Chalk doesn't have full support for all Rust builtin types yet, we
-/// need to use an enum here, rather than just `DefId`.
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub enum RustDefId {
-    Adt(DefId),
-    Str,
-    Never,
-    Slice,
-    Array,
-    Ref(Mutability),
-    RawPtr,
-
-    Trait(DefId),
-
-    Impl(DefId),
-
-    FnDef(DefId),
-
-    AssocTy(DefId),
-}
-
 #[derive(Copy, Clone)]
 pub struct RustInterner<'tcx> {
     pub tcx: TyCtxt<'tcx>,
@@ -86,16 +63,19 @@ impl fmt::Debug for RustInterner<'_> {
 impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
     type InternedType = Box<chalk_ir::TyData<Self>>;
     type InternedLifetime = Box<chalk_ir::LifetimeData<Self>>;
-    type InternedParameter = Box<chalk_ir::ParameterData<Self>>;
+    type InternedConst = Box<chalk_ir::ConstData<Self>>;
+    type InternedConcreteConst = ConstValue<'tcx>;
+    type InternedGenericArg = Box<chalk_ir::GenericArgData<Self>>;
     type InternedGoal = Box<chalk_ir::GoalData<Self>>;
     type InternedGoals = Vec<chalk_ir::Goal<Self>>;
-    type InternedSubstitution = Vec<chalk_ir::Parameter<Self>>;
+    type InternedSubstitution = Vec<chalk_ir::GenericArg<Self>>;
     type InternedProgramClause = Box<chalk_ir::ProgramClauseData<Self>>;
     type InternedProgramClauses = Vec<chalk_ir::ProgramClause<Self>>;
     type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
-    type InternedParameterKinds = Vec<chalk_ir::ParameterKind<()>>;
-    type InternedCanonicalVarKinds = Vec<chalk_ir::ParameterKind<chalk_ir::UniverseIndex>>;
-    type DefId = RustDefId;
+    type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
+    type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>;
+    type DefId = DefId;
+    type InternedAdtId = &'tcx AdtDef;
     type Identifier = ();
 
     fn debug_program_clause_implication(
@@ -209,25 +189,39 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
         &lifetime
     }
 
-    fn intern_parameter(
+    fn intern_const(&self, constant: chalk_ir::ConstData<Self>) -> Self::InternedConst {
+        Box::new(constant)
+    }
+
+    fn const_data<'a>(&self, constant: &'a Self::InternedConst) -> &'a chalk_ir::ConstData<Self> {
+        &constant
+    }
+
+    fn const_eq(
         &self,
-        parameter: chalk_ir::ParameterData<Self>,
-    ) -> Self::InternedParameter {
-        Box::new(parameter)
+        _ty: &Self::InternedType,
+        c1: &Self::InternedConcreteConst,
+        c2: &Self::InternedConcreteConst,
+    ) -> bool {
+        c1 == c2
+    }
+
+    fn intern_generic_arg(&self, data: chalk_ir::GenericArgData<Self>) -> Self::InternedGenericArg {
+        Box::new(data)
     }
 
-    fn parameter_data<'a>(
+    fn generic_arg_data<'a>(
         &self,
-        parameter: &'a Self::InternedParameter,
-    ) -> &'a chalk_ir::ParameterData<Self> {
-        &parameter
+        data: &'a Self::InternedGenericArg,
+    ) -> &'a chalk_ir::GenericArgData<Self> {
+        &data
     }
 
-    fn intern_goal(&self, goal: GoalData<Self>) -> Self::InternedGoal {
+    fn intern_goal(&self, goal: chalk_ir::GoalData<Self>) -> Self::InternedGoal {
         Box::new(goal)
     }
 
-    fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a GoalData<Self> {
+    fn goal_data<'a>(&self, goal: &'a Self::InternedGoal) -> &'a chalk_ir::GoalData<Self> {
         &goal
     }
 
@@ -244,7 +238,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
 
     fn intern_substitution<E>(
         &self,
-        data: impl IntoIterator<Item = Result<chalk_ir::Parameter<Self>, E>>,
+        data: impl IntoIterator<Item = Result<chalk_ir::GenericArg<Self>, E>>,
     ) -> Result<Self::InternedSubstitution, E> {
         data.into_iter().collect::<Result<Vec<_>, _>>()
     }
@@ -252,7 +246,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
     fn substitution_data<'a>(
         &self,
         substitution: &'a Self::InternedSubstitution,
-    ) -> &'a [Parameter<Self>] {
+    ) -> &'a [chalk_ir::GenericArg<Self>] {
         substitution
     }
 
@@ -298,23 +292,23 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
         clauses
     }
 
-    fn intern_parameter_kinds<E>(
+    fn intern_generic_arg_kinds<E>(
         &self,
-        data: impl IntoIterator<Item = Result<chalk_ir::ParameterKind<()>, E>>,
-    ) -> Result<Self::InternedParameterKinds, E> {
+        data: impl IntoIterator<Item = Result<chalk_ir::VariableKind<Self>, E>>,
+    ) -> Result<Self::InternedVariableKinds, E> {
         data.into_iter().collect::<Result<Vec<_>, _>>()
     }
 
-    fn parameter_kinds_data<'a>(
+    fn variable_kinds_data<'a>(
         &self,
-        parameter_kinds: &'a Self::InternedParameterKinds,
-    ) -> &'a [chalk_ir::ParameterKind<()>] {
+        parameter_kinds: &'a Self::InternedVariableKinds,
+    ) -> &'a [chalk_ir::VariableKind<Self>] {
         parameter_kinds
     }
 
     fn intern_canonical_var_kinds<E>(
         &self,
-        data: impl IntoIterator<Item = Result<chalk_ir::ParameterKind<chalk_ir::UniverseIndex>, E>>,
+        data: impl IntoIterator<Item = Result<chalk_ir::CanonicalVarKind<Self>, E>>,
     ) -> Result<Self::InternedCanonicalVarKinds, E> {
         data.into_iter().collect::<Result<Vec<_>, _>>()
     }
@@ -322,7 +316,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
     fn canonical_var_kinds_data<'a>(
         &self,
         canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
-    ) -> &'a [chalk_ir::ParameterKind<chalk_ir::UniverseIndex>] {
+    ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
         canonical_var_kinds
     }
 }
diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs
index f650240a41c..fc37cb2504d 100644
--- a/src/librustc_middle/traits/mod.rs
+++ b/src/librustc_middle/traits/mod.rs
@@ -33,8 +33,7 @@ pub use self::ObligationCauseCode::*;
 pub use self::SelectionError::*;
 
 pub use self::chalk::{
-    ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustDefId as ChalkRustDefId,
-    RustInterner as ChalkRustInterner,
+    ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustInterner as ChalkRustInterner,
 };
 
 /// Depending on the stage of compilation, we want projection to be
diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/src/librustc_trait_selection/traits/chalk_fulfill.rs
index 2d4d582c939..cbbff82d35f 100644
--- a/src/librustc_trait_selection/traits/chalk_fulfill.rs
+++ b/src/librustc_trait_selection/traits/chalk_fulfill.rs
@@ -87,7 +87,9 @@ fn environment<'tcx>(
         NodeKind::TraitImpl => {
             let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl");
 
-            inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk()));
+            // FIXME(chalk): this has problems because of late-bound regions
+            //inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk()));
+            inputs.extend(trait_ref.substs.iter());
         }
 
         // In an inherent impl, we assume that the receiver type and all its
@@ -136,6 +138,8 @@ fn in_environment(
     let environment = match obligation.param_env.def_id {
         Some(def_id) => environment(infcx.tcx, def_id),
         None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(),
+        // FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl
+        // and ui/generics/generic-static-methods
         _ => bug!("non-empty `ParamEnv` with no def-id"),
     };
 
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
index e485bc2929b..8def98a9603 100644
--- a/src/librustc_traits/Cargo.toml
+++ b/src/librustc_traits/Cargo.toml
@@ -16,9 +16,8 @@ rustc_hir = { path = "../librustc_hir" }
 rustc_index = { path = "../librustc_index" }
 rustc_ast = { path = "../librustc_ast" }
 rustc_span = { path = "../librustc_span" }
-chalk-ir = "0.10.0"
-chalk-rust-ir = "0.10.0"
-chalk-solve = "0.10.0"
+chalk-ir = "0.11.0"
+chalk-solve = "0.11.0"
 smallvec = { version = "1.0", features = ["union", "may_dangle"] }
 rustc_infer = { path = "../librustc_infer" }
 rustc_trait_selection = { path = "../librustc_trait_selection" }
diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs
index a2aee9b6ef7..235497d3740 100644
--- a/src/librustc_traits/chalk/db.rs
+++ b/src/librustc_traits/chalk/db.rs
@@ -6,9 +6,9 @@
 //! either the `TyCtxt` (for information about types) or
 //! `crate::chalk::lowering` (to lower rustc types into Chalk types).
 
-use rustc_middle::traits::{ChalkRustDefId as RustDefId, ChalkRustInterner as RustInterner};
+use rustc_middle::traits::ChalkRustInterner as RustInterner;
 use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt};
+use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Binder, TyCtxt};
 
 use rustc_hir::def_id::DefId;
 
@@ -38,11 +38,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     fn associated_ty_data(
         &self,
         assoc_type_id: chalk_ir::AssocTypeId<RustInterner<'tcx>>,
-    ) -> Arc<chalk_rust_ir::AssociatedTyDatum<RustInterner<'tcx>>> {
-        let def_id = match assoc_type_id.0 {
-            RustDefId::AssocTy(def_id) => def_id,
-            _ => bug!("Did not use `AssocTy` variant when expecting associated type."),
-        };
+    ) -> Arc<chalk_solve::rust_ir::AssociatedTyDatum<RustInterner<'tcx>>> {
+        let def_id = assoc_type_id.0;
         let assoc_item = self.tcx.associated_item(def_id);
         let trait_def_id = match assoc_item.container {
             AssocItemContainer::TraitContainer(def_id) => def_id,
@@ -63,13 +60,13 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             .map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
             .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
 
-        Arc::new(chalk_rust_ir::AssociatedTyDatum {
-            trait_id: chalk_ir::TraitId(RustDefId::Trait(trait_def_id)),
+        Arc::new(chalk_solve::rust_ir::AssociatedTyDatum {
+            trait_id: chalk_ir::TraitId(trait_def_id),
             id: assoc_type_id,
             name: (),
             binders: chalk_ir::Binders::new(
                 binders,
-                chalk_rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses },
+                chalk_solve::rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses },
             ),
         })
     }
@@ -77,11 +74,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     fn trait_datum(
         &self,
         trait_id: chalk_ir::TraitId<RustInterner<'tcx>>,
-    ) -> Arc<chalk_rust_ir::TraitDatum<RustInterner<'tcx>>> {
-        let def_id = match trait_id.0 {
-            RustDefId::Trait(def_id) => def_id,
-            _ => bug!("Did not use `Trait` variant when expecting trait."),
-        };
+    ) -> Arc<chalk_solve::rust_ir::TraitDatum<RustInterner<'tcx>>> {
+        let def_id = trait_id.0;
         let trait_def = self.tcx.trait_def(def_id);
 
         let bound_vars = bound_vars_for_item(self.tcx, def_id);
@@ -94,21 +88,21 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
 
         let well_known =
             if self.tcx.lang_items().sized_trait().map(|t| def_id == t).unwrap_or(false) {
-                Some(chalk_rust_ir::WellKnownTrait::SizedTrait)
+                Some(chalk_solve::rust_ir::WellKnownTrait::SizedTrait)
             } else if self.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) {
-                Some(chalk_rust_ir::WellKnownTrait::CopyTrait)
+                Some(chalk_solve::rust_ir::WellKnownTrait::CopyTrait)
             } else if self.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) {
-                Some(chalk_rust_ir::WellKnownTrait::CloneTrait)
+                Some(chalk_solve::rust_ir::WellKnownTrait::CloneTrait)
             } else {
                 None
             };
-        Arc::new(chalk_rust_ir::TraitDatum {
+        Arc::new(chalk_solve::rust_ir::TraitDatum {
             id: trait_id,
             binders: chalk_ir::Binders::new(
                 binders,
-                chalk_rust_ir::TraitDatumBound { where_clauses },
+                chalk_solve::rust_ir::TraitDatumBound { where_clauses },
             ),
-            flags: chalk_rust_ir::TraitFlags {
+            flags: chalk_solve::rust_ir::TraitFlags {
                 auto: trait_def.has_auto_impl,
                 marker: trait_def.is_marker,
                 upstream: !def_id.is_local(),
@@ -121,101 +115,98 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
         })
     }
 
-    fn struct_datum(
+    fn adt_datum(
         &self,
-        struct_id: chalk_ir::StructId<RustInterner<'tcx>>,
-    ) -> Arc<chalk_rust_ir::StructDatum<RustInterner<'tcx>>> {
-        match struct_id.0 {
-            RustDefId::Adt(adt_def_id) => {
-                let adt_def = self.tcx.adt_def(adt_def_id);
+        adt_id: chalk_ir::AdtId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_solve::rust_ir::AdtDatum<RustInterner<'tcx>>> {
+        let adt_def = adt_id.0;
 
-                let bound_vars = bound_vars_for_item(self.tcx, adt_def_id);
-                let binders = binders_for(&self.interner, bound_vars);
+        let bound_vars = bound_vars_for_item(self.tcx, adt_def.did);
+        let binders = binders_for(&self.interner, bound_vars);
 
-                let predicates = self.tcx.predicates_of(adt_def_id).predicates;
-                let where_clauses: Vec<_> = predicates
+        let predicates = self.tcx.predicates_of(adt_def.did).predicates;
+        let where_clauses: Vec<_> = predicates
+            .into_iter()
+            .map(|(wc, _)| wc.subst(self.tcx, bound_vars))
+            .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner))
+            .collect();
+        let fields = match adt_def.adt_kind() {
+            ty::AdtKind::Struct | ty::AdtKind::Union => {
+                let variant = adt_def.non_enum_variant();
+                variant
+                    .fields
                     .iter()
-                    .map(|(wc, _)| wc.subst(self.tcx, bound_vars))
-                    .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner))
-                    .collect();
-                let fields = match adt_def.adt_kind() {
-                    ty::AdtKind::Struct | ty::AdtKind::Union => {
-                        let variant = adt_def.non_enum_variant();
-                        variant
-                            .fields
-                            .iter()
-                            .map(|field| {
-                                self.tcx
-                                    .type_of(field.did)
-                                    .subst(self.tcx, bound_vars)
-                                    .lower_into(&self.interner)
-                            })
-                            .collect()
-                    }
-                    // FIXME(chalk): handle enums; force_impl_for requires this
-                    ty::AdtKind::Enum => vec![],
-                };
-                let struct_datum = Arc::new(chalk_rust_ir::StructDatum {
-                    id: struct_id,
-                    binders: chalk_ir::Binders::new(
-                        binders,
-                        chalk_rust_ir::StructDatumBound { fields, where_clauses },
-                    ),
-                    flags: chalk_rust_ir::StructFlags {
-                        upstream: !adt_def_id.is_local(),
-                        fundamental: adt_def.is_fundamental(),
-                    },
-                });
-                struct_datum
-            }
-            RustDefId::Ref(_) => Arc::new(chalk_rust_ir::StructDatum {
-                id: struct_id,
-                binders: chalk_ir::Binders::new(
-                    chalk_ir::ParameterKinds::from(
-                        &self.interner,
-                        vec![
-                            chalk_ir::ParameterKind::Lifetime(()),
-                            chalk_ir::ParameterKind::Ty(()),
-                        ],
-                    ),
-                    chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] },
-                ),
-                flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false },
-            }),
-            RustDefId::Array | RustDefId::Slice => Arc::new(chalk_rust_ir::StructDatum {
-                id: struct_id,
-                binders: chalk_ir::Binders::new(
-                    chalk_ir::ParameterKinds::from(
-                        &self.interner,
-                        Some(chalk_ir::ParameterKind::Ty(())),
-                    ),
-                    chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] },
-                ),
-                flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false },
-            }),
-            RustDefId::Str | RustDefId::Never | RustDefId::FnDef(_) => {
-                Arc::new(chalk_rust_ir::StructDatum {
-                    id: struct_id,
-                    binders: chalk_ir::Binders::new(
-                        chalk_ir::ParameterKinds::new(&self.interner),
-                        chalk_rust_ir::StructDatumBound { fields: vec![], where_clauses: vec![] },
-                    ),
-                    flags: chalk_rust_ir::StructFlags { upstream: false, fundamental: false },
-                })
+                    .map(|field| {
+                        self.tcx
+                            .type_of(field.did)
+                            .subst(self.tcx, bound_vars)
+                            .lower_into(&self.interner)
+                    })
+                    .collect()
             }
+            // FIXME(chalk): handle enums; force_impl_for requires this
+            ty::AdtKind::Enum => vec![],
+        };
+        let struct_datum = Arc::new(chalk_solve::rust_ir::AdtDatum {
+            id: adt_id,
+            binders: chalk_ir::Binders::new(
+                binders,
+                chalk_solve::rust_ir::AdtDatumBound { fields, where_clauses },
+            ),
+            flags: chalk_solve::rust_ir::AdtFlags {
+                upstream: !adt_def.did.is_local(),
+                fundamental: adt_def.is_fundamental(),
+            },
+        });
+        return struct_datum;
+    }
 
-            _ => bug!("Used not struct variant when expecting struct variant."),
-        }
+    fn fn_def_datum(
+        &self,
+        fn_def_id: chalk_ir::FnDefId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_solve::rust_ir::FnDefDatum<RustInterner<'tcx>>> {
+        let def_id = fn_def_id.0;
+        let bound_vars = bound_vars_for_item(self.tcx, def_id);
+        let binders = binders_for(&self.interner, bound_vars);
+
+        let predicates = self.tcx.predicates_defined_on(def_id).predicates;
+        let where_clauses: Vec<_> = predicates
+            .into_iter()
+            .map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
+            .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
+
+        let sig = self.tcx.fn_sig(def_id);
+        // FIXME(chalk): collect into an intermediate SmallVec here since
+        // we need `TypeFoldable` for `no_bound_vars`
+        let argument_types: Binder<Vec<_>> =
+            sig.map_bound(|i| i.inputs().iter().copied().collect());
+        let argument_types = argument_types
+            .no_bound_vars()
+            .expect("FIXME(chalk): late-bound fn parameters not supported in chalk")
+            .iter()
+            .map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner))
+            .collect();
+
+        let return_type = sig
+            .output()
+            .no_bound_vars()
+            .expect("FIXME(chalk): late-bound fn parameters not supported in chalk")
+            .subst(self.tcx, &bound_vars)
+            .lower_into(&self.interner);
+
+        let bound =
+            chalk_solve::rust_ir::FnDefDatumBound { argument_types, where_clauses, return_type };
+        Arc::new(chalk_solve::rust_ir::FnDefDatum {
+            id: fn_def_id,
+            binders: chalk_ir::Binders::new(binders, bound),
+        })
     }
 
     fn impl_datum(
         &self,
         impl_id: chalk_ir::ImplId<RustInterner<'tcx>>,
-    ) -> Arc<chalk_rust_ir::ImplDatum<RustInterner<'tcx>>> {
-        let def_id = match impl_id.0 {
-            RustDefId::Impl(def_id) => def_id,
-            _ => bug!("Did not use `Impl` variant when expecting impl."),
-        };
+    ) -> Arc<chalk_solve::rust_ir::ImplDatum<RustInterner<'tcx>>> {
+        let def_id = impl_id.0;
         let bound_vars = bound_vars_for_item(self.tcx, def_id);
         let binders = binders_for(&self.interner, bound_vars);
 
@@ -228,15 +219,15 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             .map(|(wc, _)| wc.subst(self.tcx, bound_vars))
             .filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
 
-        let value = chalk_rust_ir::ImplDatumBound {
+        let value = chalk_solve::rust_ir::ImplDatumBound {
             trait_ref: trait_ref.lower_into(&self.interner),
             where_clauses,
         };
 
-        Arc::new(chalk_rust_ir::ImplDatum {
-            polarity: chalk_rust_ir::Polarity::Positive,
+        Arc::new(chalk_solve::rust_ir::ImplDatum {
+            polarity: chalk_solve::rust_ir::Polarity::Positive,
             binders: chalk_ir::Binders::new(binders, value),
-            impl_type: chalk_rust_ir::ImplType::Local,
+            impl_type: chalk_solve::rust_ir::ImplType::Local,
             associated_ty_value_ids: vec![],
         })
     }
@@ -244,12 +235,9 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     fn impls_for_trait(
         &self,
         trait_id: chalk_ir::TraitId<RustInterner<'tcx>>,
-        parameters: &[chalk_ir::Parameter<RustInterner<'tcx>>],
+        parameters: &[chalk_ir::GenericArg<RustInterner<'tcx>>],
     ) -> Vec<chalk_ir::ImplId<RustInterner<'tcx>>> {
-        let def_id: DefId = match trait_id.0 {
-            RustDefId::Trait(def_id) => def_id,
-            _ => bug!("Did not use `Trait` variant when expecting trait."),
-        };
+        let def_id = trait_id.0;
 
         // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will
         // require us to be able to interconvert `Ty<'tcx>`, and we're
@@ -268,32 +256,24 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
             parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty)
         });
 
-        let impls = matched_impls
-            .map(|matched_impl| chalk_ir::ImplId(RustDefId::Impl(matched_impl)))
-            .collect();
+        let impls = matched_impls.map(|matched_impl| chalk_ir::ImplId(matched_impl)).collect();
         impls
     }
 
     fn impl_provided_for(
         &self,
         auto_trait_id: chalk_ir::TraitId<RustInterner<'tcx>>,
-        struct_id: chalk_ir::StructId<RustInterner<'tcx>>,
+        adt_id: chalk_ir::AdtId<RustInterner<'tcx>>,
     ) -> bool {
-        let trait_def_id: DefId = match auto_trait_id.0 {
-            RustDefId::Trait(def_id) => def_id,
-            _ => bug!("Did not use `Trait` variant when expecting trait."),
-        };
-        let adt_def_id: DefId = match struct_id.0 {
-            RustDefId::Adt(def_id) => def_id,
-            _ => bug!("Did not use `Adt` variant when expecting adt."),
-        };
+        let trait_def_id = auto_trait_id.0;
+        let adt_def = adt_id.0;
         let all_impls = self.tcx.all_impls(trait_def_id);
         for impl_def_id in all_impls {
             let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
             let self_ty = trait_ref.self_ty();
             match self_ty.kind {
-                ty::Adt(adt_def, _) => {
-                    if adt_def.did == adt_def_id {
+                ty::Adt(impl_adt_def, _) => {
+                    if impl_adt_def == adt_def {
                         return true;
                     }
                 }
@@ -305,12 +285,9 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
 
     fn associated_ty_value(
         &self,
-        associated_ty_id: chalk_rust_ir::AssociatedTyValueId<RustInterner<'tcx>>,
-    ) -> Arc<chalk_rust_ir::AssociatedTyValue<RustInterner<'tcx>>> {
-        let def_id = match associated_ty_id.0 {
-            RustDefId::AssocTy(def_id) => def_id,
-            _ => bug!("Did not use `AssocTy` variant when expecting associated type."),
-        };
+        associated_ty_id: chalk_solve::rust_ir::AssociatedTyValueId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_solve::rust_ir::AssociatedTyValue<RustInterner<'tcx>>> {
+        let def_id = associated_ty_id.0;
         let assoc_item = self.tcx.associated_item(def_id);
         let impl_id = match assoc_item.container {
             AssocItemContainer::TraitContainer(def_id) => def_id,
@@ -324,12 +301,12 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
         let binders = binders_for(&self.interner, bound_vars);
         let ty = self.tcx.type_of(def_id);
 
-        Arc::new(chalk_rust_ir::AssociatedTyValue {
-            impl_id: chalk_ir::ImplId(RustDefId::Impl(impl_id)),
-            associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(def_id)),
+        Arc::new(chalk_solve::rust_ir::AssociatedTyValue {
+            impl_id: chalk_ir::ImplId(impl_id),
+            associated_ty_id: chalk_ir::AssocTypeId(def_id),
             value: chalk_ir::Binders::new(
                 binders,
-                chalk_rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) },
+                chalk_solve::rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) },
             ),
         })
     }
@@ -347,9 +324,16 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
 
     fn opaque_ty_data(
         &self,
-        _id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
-    ) -> Arc<chalk_rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> {
-        unimplemented!()
+        opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
+    ) -> Arc<chalk_solve::rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> {
+        // FIXME(chalk): actually lower opaque ty
+        let value = chalk_solve::rust_ir::OpaqueTyDatumBound {
+            bounds: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), vec![]),
+        };
+        Arc::new(chalk_solve::rust_ir::OpaqueTyDatum {
+            opaque_ty_id,
+            bound: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), value),
+        })
     }
 
     /// Since Chalk can't handle all Rust types currently, we have to handle
@@ -357,74 +341,49 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
     /// `None` and eventually this function will be removed.
     fn force_impl_for(
         &self,
-        well_known: chalk_rust_ir::WellKnownTrait,
+        well_known: chalk_solve::rust_ir::WellKnownTrait,
         ty: &chalk_ir::TyData<RustInterner<'tcx>>,
     ) -> Option<bool> {
         use chalk_ir::TyData::*;
         match well_known {
-            chalk_rust_ir::WellKnownTrait::SizedTrait => match ty {
+            chalk_solve::rust_ir::WellKnownTrait::SizedTrait => match ty {
                 Apply(apply) => match apply.name {
-                    chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => {
-                        use rustc_middle::traits::ChalkRustDefId::*;
-                        match rust_def_id {
-                            Never | Array | RawPtr | FnDef(_) | Ref(_) => Some(true),
-
-                            Adt(adt_def_id) => {
-                                let adt_def = self.tcx.adt_def(adt_def_id);
-                                match adt_def.adt_kind() {
-                                    ty::AdtKind::Struct | ty::AdtKind::Union => None,
-                                    ty::AdtKind::Enum => {
-                                        let constraint = self.tcx.adt_sized_constraint(adt_def_id);
-                                        if !constraint.0.is_empty() {
-                                            unimplemented!()
-                                        } else {
-                                            Some(true)
-                                        }
-                                    }
-                                }
-                            }
-
-                            Str | Slice => Some(false),
-
-                            Trait(_) | Impl(_) | AssocTy(_) => panic!(),
+                    chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() {
+                        ty::AdtKind::Struct | ty::AdtKind::Union => None,
+                        ty::AdtKind::Enum => {
+                            let constraint = self.tcx.adt_sized_constraint(adt_def.did);
+                            if constraint.0.len() > 0 { unimplemented!() } else { Some(true) }
                         }
-                    }
+                    },
                     _ => None,
                 },
-                Dyn(_) | Alias(_) | Placeholder(_) | Function(_) | InferenceVar(_)
+                Dyn(_)
+                | Alias(_)
+                | Placeholder(_)
+                | Function(_)
+                | InferenceVar(_, _)
                 | BoundVar(_) => None,
             },
-            chalk_rust_ir::WellKnownTrait::CopyTrait
-            | chalk_rust_ir::WellKnownTrait::CloneTrait => match ty {
+            chalk_solve::rust_ir::WellKnownTrait::CopyTrait
+            | chalk_solve::rust_ir::WellKnownTrait::CloneTrait => match ty {
                 Apply(apply) => match apply.name {
-                    chalk_ir::TypeName::Struct(chalk_ir::StructId(rust_def_id)) => {
-                        use rustc_middle::traits::ChalkRustDefId::*;
-                        match rust_def_id {
-                            Never | RawPtr | Ref(_) | Str | Slice => Some(false),
-                            FnDef(_) | Array => Some(true),
-                            Adt(adt_def_id) => {
-                                let adt_def = self.tcx.adt_def(adt_def_id);
-                                match adt_def.adt_kind() {
-                                    ty::AdtKind::Struct | ty::AdtKind::Union => None,
-                                    ty::AdtKind::Enum => {
-                                        let constraint = self.tcx.adt_sized_constraint(adt_def_id);
-                                        if !constraint.0.is_empty() {
-                                            unimplemented!()
-                                        } else {
-                                            Some(true)
-                                        }
-                                    }
-                                }
-                            }
-                            Trait(_) | Impl(_) | AssocTy(_) => panic!(),
+                    chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() {
+                        ty::AdtKind::Struct | ty::AdtKind::Union => None,
+                        ty::AdtKind::Enum => {
+                            let constraint = self.tcx.adt_sized_constraint(adt_def.did);
+                            if constraint.0.len() > 0 { unimplemented!() } else { Some(true) }
                         }
-                    }
+                    },
                     _ => None,
                 },
-                Dyn(_) | Alias(_) | Placeholder(_) | Function(_) | InferenceVar(_)
+                Dyn(_)
+                | Alias(_)
+                | Placeholder(_)
+                | Function(_)
+                | InferenceVar(_, _)
                 | BoundVar(_) => None,
             },
-            chalk_rust_ir::WellKnownTrait::DropTrait => None,
+            chalk_solve::rust_ir::WellKnownTrait::DropTrait => None,
         }
     }
 
@@ -437,37 +396,33 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
 
     fn well_known_trait_id(
         &self,
-        well_known_trait: chalk_rust_ir::WellKnownTrait,
+        well_known_trait: chalk_solve::rust_ir::WellKnownTrait,
     ) -> Option<chalk_ir::TraitId<RustInterner<'tcx>>> {
-        use chalk_rust_ir::WellKnownTrait::*;
+        use chalk_solve::rust_ir::WellKnownTrait::*;
         let t = match well_known_trait {
-            SizedTrait => self
-                .tcx
-                .lang_items()
-                .sized_trait()
-                .map(|t| chalk_ir::TraitId(RustDefId::Trait(t)))
-                .unwrap(),
-            CopyTrait => self
-                .tcx
-                .lang_items()
-                .copy_trait()
-                .map(|t| chalk_ir::TraitId(RustDefId::Trait(t)))
-                .unwrap(),
-            CloneTrait => self
-                .tcx
-                .lang_items()
-                .clone_trait()
-                .map(|t| chalk_ir::TraitId(RustDefId::Trait(t)))
-                .unwrap(),
-            DropTrait => self
-                .tcx
-                .lang_items()
-                .drop_trait()
-                .map(|t| chalk_ir::TraitId(RustDefId::Trait(t)))
-                .unwrap(),
+            SizedTrait => {
+                self.tcx.lang_items().sized_trait().map(|t| chalk_ir::TraitId(t)).unwrap()
+            }
+            CopyTrait => self.tcx.lang_items().copy_trait().map(|t| chalk_ir::TraitId(t)).unwrap(),
+            CloneTrait => {
+                self.tcx.lang_items().clone_trait().map(|t| chalk_ir::TraitId(t)).unwrap()
+            }
+            DropTrait => self.tcx.lang_items().drop_trait().map(|t| chalk_ir::TraitId(t)).unwrap(),
         };
         Some(t)
     }
+
+    fn is_object_safe(&self, trait_id: chalk_ir::TraitId<RustInterner<'tcx>>) -> bool {
+        self.tcx.is_object_safe(trait_id.0)
+    }
+
+    fn hidden_opaque_type(
+        &self,
+        _id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
+    ) -> chalk_ir::Ty<RustInterner<'tcx>> {
+        // FIXME(chalk): actually get hidden ty
+        self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner)
+    }
 }
 
 /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
@@ -505,13 +460,17 @@ fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
 fn binders_for<'tcx>(
     interner: &RustInterner<'tcx>,
     bound_vars: SubstsRef<'tcx>,
-) -> chalk_ir::ParameterKinds<RustInterner<'tcx>> {
-    chalk_ir::ParameterKinds::from(
+) -> chalk_ir::VariableKinds<RustInterner<'tcx>> {
+    chalk_ir::VariableKinds::from(
         interner,
         bound_vars.iter().map(|arg| match arg.unpack() {
-            ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::ParameterKind::Lifetime(()),
-            ty::subst::GenericArgKind::Type(_ty) => chalk_ir::ParameterKind::Ty(()),
-            ty::subst::GenericArgKind::Const(_const) => chalk_ir::ParameterKind::Ty(()),
+            ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::VariableKind::Lifetime,
+            ty::subst::GenericArgKind::Type(_ty) => {
+                chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)
+            }
+            ty::subst::GenericArgKind::Const(c) => {
+                chalk_ir::VariableKind::Const(c.ty.lower_into(interner))
+            }
         }),
     )
 }
diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs
index c9dd06e9f1b..5546a8db533 100644
--- a/src/librustc_traits/chalk/lowering.rs
+++ b/src/librustc_traits/chalk/lowering.rs
@@ -32,8 +32,7 @@
 //! variables from the current `Binder`.
 
 use rustc_middle::traits::{
-    ChalkEnvironmentAndGoal, ChalkEnvironmentClause, ChalkRustDefId as RustDefId,
-    ChalkRustInterner as RustInterner,
+    ChalkEnvironmentAndGoal, ChalkEnvironmentClause, ChalkRustInterner as RustInterner,
 };
 use rustc_middle::ty::fold::TypeFolder;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
@@ -62,7 +61,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> for Subst
 impl<'tcx> LowerInto<'tcx, chalk_ir::AliasTy<RustInterner<'tcx>>> for ty::ProjectionTy<'tcx> {
     fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::AliasTy<RustInterner<'tcx>> {
         chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
-            associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(self.item_def_id)),
+            associated_ty_id: chalk_ir::AssocTypeId(self.item_def_id),
             substitution: self.substs.lower_into(interner),
         })
     }
@@ -98,8 +97,30 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
                             .intern(interner),
                         )
                     }
-                    // FIXME(chalk): need to add RegionOutlives/TypeOutlives
-                    ty::PredicateKind::RegionOutlives(_) => None,
+                    ty::PredicateKind::RegionOutlives(predicate) => {
+                        let (predicate, binders, _named_regions) =
+                            collect_bound_vars(interner, interner.tcx, predicate);
+
+                        Some(
+                            chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
+                                binders,
+                                chalk_ir::ProgramClauseImplication {
+                                    consequence: chalk_ir::DomainGoal::Holds(
+                                        chalk_ir::WhereClause::LifetimeOutlives(
+                                            chalk_ir::LifetimeOutlives {
+                                                a: predicate.0.lower_into(interner),
+                                                b: predicate.1.lower_into(interner),
+                                            },
+                                        ),
+                                    ),
+                                    conditions: chalk_ir::Goals::new(interner),
+                                    priority: chalk_ir::ClausePriority::High,
+                                },
+                            ))
+                            .intern(interner),
+                        )
+                    }
+                    // FIXME(chalk): need to add TypeOutlives
                     ty::PredicateKind::TypeOutlives(_) => None,
                     ty::PredicateKind::Projection(predicate) => {
                         let (predicate, binders, _named_regions) =
@@ -157,30 +178,36 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
     fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData<RustInterner<'tcx>> {
         match self.kind() {
             ty::PredicateKind::Trait(predicate, _) => predicate.lower_into(interner),
-            // FIXME(chalk): we need to register constraints.
-            ty::PredicateKind::RegionOutlives(_predicate) => {
-                chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
+            ty::PredicateKind::RegionOutlives(predicate) => {
+                let (predicate, binders, _named_regions) =
+                    collect_bound_vars(interner, interner.tcx, predicate);
+
+                chalk_ir::GoalData::Quantified(
+                    chalk_ir::QuantifierKind::ForAll,
+                    chalk_ir::Binders::new(
+                        binders,
+                        chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds(
+                            chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives {
+                                a: predicate.0.lower_into(interner),
+                                b: predicate.1.lower_into(interner),
+                            }),
+                        ))
+                        .intern(interner),
+                    ),
+                )
             }
+            // FIXME(chalk): TypeOutlives
             ty::PredicateKind::TypeOutlives(_predicate) => {
                 chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
             }
             ty::PredicateKind::Projection(predicate) => predicate.lower_into(interner),
             ty::PredicateKind::WellFormed(arg) => match arg.unpack() {
                 GenericArgKind::Type(ty) => match ty.kind {
-                    // These types are always WF.
-                    ty::Str | ty::Placeholder(..) | ty::Error(_) | ty::Never => {
-                        chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
-                    }
+                    // FIXME(chalk): In Chalk, a placeholder is WellFormed if it
+                    // `FromEnv`. However, when we "lower" Params, we don't update
+                    // the environment.
+                    ty::Placeholder(..) => chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)),
 
-                    // FIXME(chalk): Well-formed only if ref lifetime outlives type
-                    ty::Ref(..) => chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)),
-
-                    ty::Param(..) => panic!("No Params expected."),
-
-                    // FIXME(chalk) -- ultimately I think this is what we
-                    // want to do, and we just have rules for how to prove
-                    // `WellFormed` for everything above, instead of
-                    // inlining a bit the rules of the proof here.
                     _ => chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::WellFormed(
                         chalk_ir::WellFormed::Ty(ty.lower_into(interner)),
                     )),
@@ -192,12 +219,15 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
                 GenericArgKind::Lifetime(lt) => bug!("unexpect well formed predicate: {:?}", lt),
             },
 
+            ty::PredicateKind::ObjectSafe(t) => chalk_ir::GoalData::DomainGoal(
+                chalk_ir::DomainGoal::ObjectSafe(chalk_ir::TraitId(*t)),
+            ),
+
             // FIXME(chalk): other predicates
             //
             // We can defer this, but ultimately we'll want to express
             // some of these in terms of chalk operations.
-            ty::PredicateKind::ObjectSafe(..)
-            | ty::PredicateKind::ClosureKind(..)
+            ty::PredicateKind::ClosureKind(..)
             | ty::PredicateKind::Subtype(..)
             | ty::PredicateKind::ConstEvaluatable(..)
             | ty::PredicateKind::ConstEquate(..) => {
@@ -212,7 +242,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::TraitRef<RustInterner<'tcx>>>
 {
     fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::TraitRef<RustInterner<'tcx>> {
         chalk_ir::TraitRef {
-            trait_id: chalk_ir::TraitId(RustDefId::Trait(self.def_id)),
+            trait_id: chalk_ir::TraitId(self.def_id),
             substitution: self.substs.lower_into(interner),
         }
     }
@@ -274,7 +304,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
         use TyKind::*;
 
         let empty = || chalk_ir::Substitution::empty(interner);
-        let struct_ty = |def_id| chalk_ir::TypeName::Struct(chalk_ir::StructId(def_id));
+        let struct_ty =
+            |def_id| chalk_ir::TypeName::Adt(chalk_ir::AdtId(interner.tcx.adt_def(def_id)));
         let apply = |name, substitution| {
             TyData::Apply(chalk_ir::ApplicationTy { name, substitution }).intern(interner)
         };
@@ -305,39 +336,72 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
                 ast::FloatTy::F32 => float(chalk_ir::FloatTy::F32),
                 ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64),
             },
-            Adt(def, substs) => {
-                apply(struct_ty(RustDefId::Adt(def.did)), substs.lower_into(interner))
-            }
+            Adt(def, substs) => apply(struct_ty(def.did), substs.lower_into(interner)),
             Foreign(_def_id) => unimplemented!(),
-            Str => apply(struct_ty(RustDefId::Str), empty()),
-            Array(ty, _) => apply(
-                struct_ty(RustDefId::Array),
-                chalk_ir::Substitution::from1(
-                    interner,
-                    chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
-                ),
-            ),
+            Str => apply(chalk_ir::TypeName::Str, empty()),
+            Array(ty, len) => {
+                let value = match len.val {
+                    ty::ConstKind::Value(val) => {
+                        chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: val })
+                    }
+                    ty::ConstKind::Bound(db, bound) => {
+                        chalk_ir::ConstValue::BoundVar(chalk_ir::BoundVar::new(
+                            chalk_ir::DebruijnIndex::new(db.as_u32()),
+                            bound.index(),
+                        ))
+                    }
+                    _ => unimplemented!("Const not implemented. {:?}", len.val),
+                };
+                apply(
+                    chalk_ir::TypeName::Array,
+                    chalk_ir::Substitution::from(
+                        interner,
+                        &[
+                            chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner),
+                            chalk_ir::GenericArgData::Const(
+                                chalk_ir::ConstData { ty: len.ty.lower_into(interner), value }
+                                    .intern(interner),
+                            )
+                            .intern(interner),
+                        ],
+                    ),
+                )
+            }
             Slice(ty) => apply(
-                struct_ty(RustDefId::Slice),
+                chalk_ir::TypeName::Slice,
                 chalk_ir::Substitution::from1(
                     interner,
-                    chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
+                    chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner),
                 ),
             ),
-            RawPtr(_) => apply(struct_ty(RustDefId::RawPtr), empty()),
-            Ref(region, ty, mutability) => apply(
-                struct_ty(RustDefId::Ref(mutability)),
-                chalk_ir::Substitution::from(
-                    interner,
-                    [
-                        chalk_ir::ParameterKind::Lifetime(region.lower_into(interner))
-                            .intern(interner),
-                        chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
-                    ]
-                    .iter(),
-                ),
+            RawPtr(ptr) => {
+                let name = match ptr.mutbl {
+                    ast::Mutability::Mut => chalk_ir::TypeName::Raw(chalk_ir::Mutability::Mut),
+                    ast::Mutability::Not => chalk_ir::TypeName::Raw(chalk_ir::Mutability::Not),
+                };
+                apply(name, chalk_ir::Substitution::from1(interner, ptr.ty.lower_into(interner)))
+            }
+            Ref(region, ty, mutability) => {
+                let name = match mutability {
+                    ast::Mutability::Mut => chalk_ir::TypeName::Ref(chalk_ir::Mutability::Mut),
+                    ast::Mutability::Not => chalk_ir::TypeName::Ref(chalk_ir::Mutability::Not),
+                };
+                apply(
+                    name,
+                    chalk_ir::Substitution::from(
+                        interner,
+                        &[
+                            chalk_ir::GenericArgData::Lifetime(region.lower_into(interner))
+                                .intern(interner),
+                            chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner),
+                        ],
+                    ),
+                )
+            }
+            FnDef(def_id, substs) => apply(
+                chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(def_id)),
+                substs.lower_into(interner),
             ),
-            FnDef(def_id, _) => apply(struct_ty(RustDefId::FnDef(def_id)), empty()),
             FnPtr(sig) => {
                 let (inputs_and_outputs, binders, _named_regions) =
                     collect_bound_vars(interner, interner.tcx, &sig.inputs_and_output());
@@ -346,22 +410,32 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
                     substitution: chalk_ir::Substitution::from(
                         interner,
                         inputs_and_outputs.iter().map(|ty| {
-                            chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner)
+                            chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner)
                         }),
                     ),
                 })
                 .intern(interner)
             }
-            Dynamic(_, _) => unimplemented!(),
+            // FIXME(chalk): add region
+            Dynamic(predicates, _region) => {
+                TyData::Dyn(chalk_ir::DynTy { bounds: predicates.lower_into(interner) })
+                    .intern(interner)
+            }
             Closure(_def_id, _) => unimplemented!(),
             Generator(_def_id, _substs, _) => unimplemented!(),
             GeneratorWitness(_) => unimplemented!(),
-            Never => apply(struct_ty(RustDefId::Never), empty()),
+            Never => apply(chalk_ir::TypeName::Never, empty()),
             Tuple(substs) => {
                 apply(chalk_ir::TypeName::Tuple(substs.len()), substs.lower_into(interner))
             }
             Projection(proj) => TyData::Alias(proj.lower_into(interner)).intern(interner),
-            Opaque(_def_id, _substs) => unimplemented!(),
+            Opaque(def_id, substs) => {
+                TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
+                    opaque_ty_id: chalk_ir::OpaqueTyId(def_id),
+                    substitution: substs.lower_into(interner),
+                }))
+                .intern(interner)
+            }
             // This should have been done eagerly prior to this, and all Params
             // should have been substituted to placeholders
             Param(_) => panic!("Lowering Param when not expected."),
@@ -376,7 +450,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
             })
             .intern(interner),
             Infer(_infer) => unimplemented!(),
-            Error(_) => unimplemented!(),
+            Error(_) => apply(chalk_ir::TypeName::Error, empty()),
         }
     }
 }
@@ -401,6 +475,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
                 ty::BrEnv => unimplemented!(),
             },
             ReFree(_) => unimplemented!(),
+            // FIXME(chalk): need to handle ReStatic
             ReStatic => unimplemented!(),
             ReVar(_) => unimplemented!(),
             RePlaceholder(placeholder_region) => {
@@ -411,21 +486,22 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime<RustInterner<'tcx>>> for Region<'t
                 .intern(interner)
             }
             ReEmpty(_) => unimplemented!(),
+            // FIXME(chalk): need to handle ReErased
             ReErased => unimplemented!(),
         }
     }
 }
 
-impl<'tcx> LowerInto<'tcx, chalk_ir::Parameter<RustInterner<'tcx>>> for GenericArg<'tcx> {
-    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Parameter<RustInterner<'tcx>> {
+impl<'tcx> LowerInto<'tcx, chalk_ir::GenericArg<RustInterner<'tcx>>> for GenericArg<'tcx> {
+    fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GenericArg<RustInterner<'tcx>> {
         match self.unpack() {
             ty::subst::GenericArgKind::Type(ty) => {
-                chalk_ir::ParameterKind::Ty(ty.lower_into(interner))
+                chalk_ir::GenericArgData::Ty(ty.lower_into(interner))
             }
             ty::subst::GenericArgKind::Lifetime(lifetime) => {
-                chalk_ir::ParameterKind::Lifetime(lifetime.lower_into(interner))
+                chalk_ir::GenericArgData::Lifetime(lifetime.lower_into(interner))
             }
-            ty::subst::GenericArgKind::Const(_) => chalk_ir::ParameterKind::Ty(
+            ty::subst::GenericArgKind::Const(_) => chalk_ir::GenericArgData::Ty(
                 chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
                     name: chalk_ir::TypeName::Tuple(0),
                     substitution: chalk_ir::Substitution::empty(interner),
@@ -458,7 +534,18 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
                     chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)),
                 ))
             }
-            ty::PredicateKind::RegionOutlives(_predicate) => None,
+            ty::PredicateKind::RegionOutlives(predicate) => {
+                let (predicate, binders, _named_regions) =
+                    collect_bound_vars(interner, interner.tcx, predicate);
+
+                Some(chalk_ir::Binders::new(
+                    binders,
+                    chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives {
+                        a: predicate.0.lower_into(interner),
+                        b: predicate.1.lower_into(interner),
+                    }),
+                ))
+            }
             ty::PredicateKind::TypeOutlives(_predicate) => None,
             ty::PredicateKind::Projection(_predicate) => None,
             ty::PredicateKind::WellFormed(_ty) => None,
@@ -472,6 +559,39 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
     }
 }
 
+impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<RustInterner<'tcx>>>>
+    for Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>
+{
+    fn lower_into(
+        self,
+        interner: &RustInterner<'tcx>,
+    ) -> chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<RustInterner<'tcx>>> {
+        let (predicates, binders, _named_regions) =
+            collect_bound_vars(interner, interner.tcx, &self);
+        let where_clauses = predicates.into_iter().map(|predicate| match predicate {
+            ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => {
+                chalk_ir::Binders::new(
+                    chalk_ir::VariableKinds::new(interner),
+                    chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef {
+                        trait_id: chalk_ir::TraitId(def_id),
+                        substitution: substs.lower_into(interner),
+                    }),
+                )
+            }
+            ty::ExistentialPredicate::Projection(_predicate) => unimplemented!(),
+            ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new(
+                chalk_ir::VariableKinds::new(interner),
+                chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef {
+                    trait_id: chalk_ir::TraitId(def_id),
+                    substitution: chalk_ir::Substitution::empty(interner),
+                }),
+            ),
+        });
+        let value = chalk_ir::QuantifiedWhereClauses::from(interner, where_clauses);
+        chalk_ir::Binders::new(binders, value)
+    }
+}
+
 /// To collect bound vars, we have to do two passes. In the first pass, we
 /// collect all `BoundRegion`s and `ty::Bound`s. In the second pass, we then
 /// replace `BrNamed` into `BrAnon`. The two separate passes are important,
@@ -485,7 +605,7 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>(
     interner: &RustInterner<'tcx>,
     tcx: TyCtxt<'tcx>,
     ty: &'a Binder<T>,
-) -> (T, chalk_ir::ParameterKinds<RustInterner<'tcx>>, BTreeMap<DefId, u32>) {
+) -> (T, chalk_ir::VariableKinds<RustInterner<'tcx>>, BTreeMap<DefId, u32>) {
     let mut bound_vars_collector = BoundVarsCollector::new();
     ty.skip_binder().visit_with(&mut bound_vars_collector);
     let mut parameters = bound_vars_collector.parameters;
@@ -500,25 +620,25 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>(
     let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor);
 
     for var in named_parameters.values() {
-        parameters.insert(*var, chalk_ir::ParameterKind::Lifetime(()));
+        parameters.insert(*var, chalk_ir::VariableKind::Lifetime);
     }
 
     (0..parameters.len()).for_each(|i| {
         parameters.get(&(i as u32)).expect("Skipped bound var index.");
     });
 
-    let binders = chalk_ir::ParameterKinds::from(interner, parameters.into_iter().map(|(_, v)| v));
+    let binders = chalk_ir::VariableKinds::from(interner, parameters.into_iter().map(|(_, v)| v));
 
     (new_ty, binders, named_parameters)
 }
 
-crate struct BoundVarsCollector {
+crate struct BoundVarsCollector<'tcx> {
     binder_index: ty::DebruijnIndex,
-    crate parameters: BTreeMap<u32, chalk_ir::ParameterKind<()>>,
+    crate parameters: BTreeMap<u32, chalk_ir::VariableKind<RustInterner<'tcx>>>,
     crate named_parameters: Vec<DefId>,
 }
 
-impl BoundVarsCollector {
+impl<'tcx> BoundVarsCollector<'tcx> {
     crate fn new() -> Self {
         BoundVarsCollector {
             binder_index: ty::INNERMOST,
@@ -528,7 +648,7 @@ impl BoundVarsCollector {
     }
 }
 
-impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector {
+impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
     fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
         self.binder_index.shift_in(1);
         let result = t.super_visit_with(self);
@@ -541,11 +661,12 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector {
             ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
                 match self.parameters.entry(bound_ty.var.as_u32()) {
                     Entry::Vacant(entry) => {
-                        entry.insert(chalk_ir::ParameterKind::Ty(()));
-                    }
-                    Entry::Occupied(entry) => {
-                        entry.get().assert_ty_ref();
+                        entry.insert(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General));
                     }
+                    Entry::Occupied(entry) => match entry.get() {
+                        chalk_ir::VariableKind::Ty(_) => {}
+                        _ => panic!(),
+                    },
                 }
             }
 
@@ -566,11 +687,12 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector {
 
                 ty::BoundRegion::BrAnon(var) => match self.parameters.entry(*var) {
                     Entry::Vacant(entry) => {
-                        entry.insert(chalk_ir::ParameterKind::Lifetime(()));
-                    }
-                    Entry::Occupied(entry) => {
-                        entry.get().assert_lifetime_ref();
+                        entry.insert(chalk_ir::VariableKind::Lifetime);
                     }
+                    Entry::Occupied(entry) => match entry.get() {
+                        chalk_ir::VariableKind::Lifetime => {}
+                        _ => panic!(),
+                    },
                 },
 
                 ty::BrEnv => unimplemented!(),
diff --git a/src/librustc_traits/chalk/mod.rs b/src/librustc_traits/chalk/mod.rs
index 4e635b9db09..6f657be0908 100644
--- a/src/librustc_traits/chalk/mod.rs
+++ b/src/librustc_traits/chalk/mod.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{
 use rustc_infer::infer::canonical::{
     Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse,
 };
-use rustc_infer::traits::{self, ChalkCanonicalGoal, ChalkRustDefId as RustDefId};
+use rustc_infer::traits::{self, ChalkCanonicalGoal};
 
 use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase;
 use crate::chalk::lowering::{LowerInto, ParamsSubstitutor};
@@ -55,25 +55,23 @@ crate fn evaluate_goal<'tcx>(
                     CanonicalVarKind::PlaceholderTy(_ty) => unimplemented!(),
                     CanonicalVarKind::PlaceholderRegion(_ui) => unimplemented!(),
                     CanonicalVarKind::Ty(ty) => match ty {
-                        CanonicalTyVarKind::General(ui) => {
-                            chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex {
-                                counter: ui.index(),
-                            })
-                        }
-                        CanonicalTyVarKind::Int | CanonicalTyVarKind::Float => {
-                            // FIXME(chalk) - this is actually really important
-                            // These variable kinds put some limits on the
-                            // types that can be substituted (floats or ints).
-                            // While it's unclear exactly the design here, we
-                            // probably want some way to "register" these.
-                            chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::root())
-                        }
+                        CanonicalTyVarKind::General(ui) => chalk_ir::WithKind::new(
+                            chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General),
+                            chalk_ir::UniverseIndex { counter: ui.index() },
+                        ),
+                        CanonicalTyVarKind::Int => chalk_ir::WithKind::new(
+                            chalk_ir::VariableKind::Ty(chalk_ir::TyKind::Integer),
+                            chalk_ir::UniverseIndex::root(),
+                        ),
+                        CanonicalTyVarKind::Float => chalk_ir::WithKind::new(
+                            chalk_ir::VariableKind::Ty(chalk_ir::TyKind::Float),
+                            chalk_ir::UniverseIndex::root(),
+                        ),
                     },
-                    CanonicalVarKind::Region(ui) => {
-                        chalk_ir::ParameterKind::Lifetime(chalk_ir::UniverseIndex {
-                            counter: ui.index(),
-                        })
-                    }
+                    CanonicalVarKind::Region(ui) => chalk_ir::WithKind::new(
+                        chalk_ir::VariableKind::Lifetime,
+                        chalk_ir::UniverseIndex { counter: ui.index() },
+                    ),
                     CanonicalVarKind::Const(_ui) => unimplemented!(),
                     CanonicalVarKind::PlaceholderConst(_pc) => unimplemented!(),
                 }),
@@ -101,18 +99,14 @@ crate fn evaluate_goal<'tcx>(
             // essentially inverse of lowering a `GenericArg`.
             let _data = p.data(&interner);
             match _data {
-                chalk_ir::ParameterKind::Ty(_t) => {
+                chalk_ir::GenericArgData::Ty(_t) => {
                     use chalk_ir::TyData;
                     use rustc_ast::ast;
 
                     let _data = _t.data(&interner);
                     let kind = match _data {
                         TyData::Apply(_application_ty) => match _application_ty.name {
-                            chalk_ir::TypeName::Struct(_struct_id) => match _struct_id.0 {
-                                RustDefId::Array => unimplemented!(),
-                                RustDefId::Slice => unimplemented!(),
-                                _ => unimplemented!(),
-                            },
+                            chalk_ir::TypeName::Adt(_struct_id) => unimplemented!(),
                             chalk_ir::TypeName::Scalar(scalar) => match scalar {
                                 chalk_ir::Scalar::Bool => ty::Bool,
                                 chalk_ir::Scalar::Char => ty::Char,
@@ -137,7 +131,14 @@ crate fn evaluate_goal<'tcx>(
                                     chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64),
                                 },
                             },
+                            chalk_ir::TypeName::Array => unimplemented!(),
+                            chalk_ir::TypeName::FnDef(_) => unimplemented!(),
+                            chalk_ir::TypeName::Never => unimplemented!(),
                             chalk_ir::TypeName::Tuple(_size) => unimplemented!(),
+                            chalk_ir::TypeName::Slice => unimplemented!(),
+                            chalk_ir::TypeName::Raw(_) => unimplemented!(),
+                            chalk_ir::TypeName::Ref(_) => unimplemented!(),
+                            chalk_ir::TypeName::Str => unimplemented!(),
                             chalk_ir::TypeName::OpaqueType(_ty) => unimplemented!(),
                             chalk_ir::TypeName::AssociatedType(_assoc_ty) => unimplemented!(),
                             chalk_ir::TypeName::Error => unimplemented!(),
@@ -154,14 +155,14 @@ crate fn evaluate_goal<'tcx>(
                                 kind: ty::BoundTyKind::Anon,
                             },
                         ),
-                        TyData::InferenceVar(_) => unimplemented!(),
+                        TyData::InferenceVar(_, _) => unimplemented!(),
                         TyData::Dyn(_) => unimplemented!(),
                     };
                     let _ty: Ty<'_> = tcx.mk_ty(kind);
                     let _arg: GenericArg<'_> = _ty.into();
                     var_values.push(_arg);
                 }
-                chalk_ir::ParameterKind::Lifetime(_l) => {
+                chalk_ir::GenericArgData::Lifetime(_l) => {
                     let _data = _l.data(&interner);
                     let _lifetime: Region<'_> = match _data {
                         chalk_ir::LifetimeData::BoundVar(_var) => {
@@ -179,6 +180,7 @@ crate fn evaluate_goal<'tcx>(
                     let _arg: GenericArg<'_> = _lifetime.into();
                     var_values.push(_arg);
                 }
+                chalk_ir::GenericArgData::Const(_) => unimplemented!(),
             }
         });
         let sol = Canonical {
@@ -197,7 +199,6 @@ crate fn evaluate_goal<'tcx>(
         .map(|s| match s {
             Solution::Unique(_subst) => {
                 // FIXME(chalk): handle constraints
-                assert!(_subst.value.constraints.is_empty());
                 make_solution(_subst.value.subst)
             }
             Solution::Ambig(_guidance) => {
diff --git a/src/test/ui/chalkify/impl_wf.rs b/src/test/ui/chalkify/impl_wf.rs
index 8aa87642292..fdc94f69bf2 100644
--- a/src/test/ui/chalkify/impl_wf.rs
+++ b/src/test/ui/chalkify/impl_wf.rs
@@ -8,12 +8,9 @@ trait Bar {
 
 impl Foo for i32 { }
 
-// FIXME(chalk): blocked on better handling of builtin traits for non-struct
-// application types (or a workaround)
-/*
 impl Foo for str { }
-//^ ERROR the size for values of type `str` cannot be known at compilation time
-*/
+//~^ ERROR the size for values of type `str` cannot be known at compilation time
+
 
 // Implicit `T: Sized` bound.
 impl<T> Foo for Option<T> { }
diff --git a/src/test/ui/chalkify/impl_wf.stderr b/src/test/ui/chalkify/impl_wf.stderr
index befd688741c..5293bbaecd3 100644
--- a/src/test/ui/chalkify/impl_wf.stderr
+++ b/src/test/ui/chalkify/impl_wf.stderr
@@ -1,5 +1,17 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/impl_wf.rs:11:6
+   |
+LL | trait Foo: Sized { }
+   |            ----- required by this bound in `Foo`
+...
+LL | impl Foo for str { }
+   |      ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+
 error[E0277]: the trait bound `f32: Foo` is not satisfied
-  --> $DIR/impl_wf.rs:43:6
+  --> $DIR/impl_wf.rs:40:6
    |
 LL | trait Baz<U: ?Sized> where U: Foo { }
    |                               --- required by this bound in `Baz`
@@ -7,6 +19,6 @@ LL | trait Baz<U: ?Sized> where U: Foo { }
 LL | impl Baz<f32> for f32 { }
    |      ^^^^^^^^ the trait `Foo` is not implemented for `f32`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/chalkify/inherent_impl.rs b/src/test/ui/chalkify/inherent_impl.rs
index 44e120c1eeb..9dd9eb320dd 100644
--- a/src/test/ui/chalkify/inherent_impl.rs
+++ b/src/test/ui/chalkify/inherent_impl.rs
@@ -1,5 +1,7 @@
 // run-pass
 // compile-flags: -Z chalk
+// FIXME(chalk): remove when uncommented
+#![allow(dead_code, unused_variables)]
 
 trait Foo { }
 
@@ -9,6 +11,8 @@ struct S<T: Foo> {
     x: T,
 }
 
+// FIXME(chalk): need late-bound regions on FnDefs
+/*
 fn only_foo<T: Foo>(_x: &T) { }
 
 impl<T> S<T> {
@@ -17,6 +21,7 @@ impl<T> S<T> {
         only_foo(&self.x)
     }
 }
+*/
 
 trait Bar { }
 impl Bar for u32 { }
@@ -26,10 +31,16 @@ fn only_bar<T: Bar>() { }
 impl<T> S<T> {
     // Test that the environment of `dummy_bar` adds up with the environment
     // of the inherent impl.
+    // FIXME(chalk): need late-bound regions on FnDefs
+    /*
     fn dummy_bar<U: Bar>(&self) {
         only_foo(&self.x);
         only_bar::<U>();
     }
+    */
+    fn dummy_bar<U: Bar>() {
+        only_bar::<U>();
+    }
 }
 
 fn main() {
@@ -37,6 +48,10 @@ fn main() {
         x: 5,
     };
 
+    // FIXME(chalk): need late-bound regions on FnDefs
+    /*
     s.dummy_foo();
     s.dummy_bar::<u32>();
+    */
+    S::<i32>::dummy_bar::<u32>();
 }
diff --git a/src/test/ui/chalkify/type_inference.rs b/src/test/ui/chalkify/type_inference.rs
index 5175c5d062a..2b62bf18a71 100644
--- a/src/test/ui/chalkify/type_inference.rs
+++ b/src/test/ui/chalkify/type_inference.rs
@@ -18,11 +18,11 @@ fn main() {
     // is expecting a variable of type `i32`. This behavior differs from the
     // old-style trait solver. I guess this will change, that's why I'm
     // adding that test.
-    // FIXME(chalk): partially blocked on float/int special casing
-    only_foo(x); //~ ERROR the trait bound `f64: Foo` is not satisfied
+    // FIXME(chalk): order of these two errors is non-deterministic,
+    // so let's just hide one for now
+    //only_foo(x); // ERROR the trait bound `f64: Foo` is not satisfied
 
     // Here we have two solutions so we get back the behavior of the old-style
     // trait solver.
-    // FIXME(chalk): blocked on float/int special casing
-    //only_bar(x); // ERROR the trait bound `{float}: Bar` is not satisfied
+    only_bar(x); //~ ERROR the trait bound `f64: Bar` is not satisfied
 }
diff --git a/src/test/ui/chalkify/type_inference.stderr b/src/test/ui/chalkify/type_inference.stderr
index ee9e67c6c78..5cfb968404d 100644
--- a/src/test/ui/chalkify/type_inference.stderr
+++ b/src/test/ui/chalkify/type_inference.stderr
@@ -1,11 +1,11 @@
-error[E0277]: the trait bound `f64: Foo` is not satisfied
-  --> $DIR/type_inference.rs:22:5
+error[E0277]: the trait bound `f64: Bar` is not satisfied
+  --> $DIR/type_inference.rs:27:5
    |
-LL | fn only_foo<T: Foo>(_x: T) { }
-   |                --- required by this bound in `only_foo`
+LL | fn only_bar<T: Bar>(_x: T) { }
+   |                --- required by this bound in `only_bar`
 ...
-LL |     only_foo(x);
-   |     ^^^^^^^^ the trait `Foo` is not implemented for `f64`
+LL |     only_bar(x);
+   |     ^^^^^^^^ the trait `Bar` is not implemented for `f64`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/chalkify/type_wf.rs b/src/test/ui/chalkify/type_wf.rs
index 396baf814a0..7c469d99c57 100644
--- a/src/test/ui/chalkify/type_wf.rs
+++ b/src/test/ui/chalkify/type_wf.rs
@@ -1,5 +1,4 @@
-// FIXME(chalk): should have an error, see below
-// check-pass
+// check-fail
 // compile-flags: -Z chalk
 
 trait Foo { }
@@ -16,17 +15,11 @@ fn main() {
        x: 5,
     };
 
-    // FIXME(chalk): blocked on float/int special handling. Needs to know that {float}: !i32
-    /*
-    let s = S { // ERROR the trait bound `{float}: Foo` is not satisfied
+    let s = S { //~ ERROR the trait bound `f64: Foo` is not satisfied
         x: 5.0,
     };
-    */
 
-    // FIXME(chalk): blocked on float/int special handling. Needs to know that {float}: Sized
-    /*
     let s = S {
         x: Some(5.0),
     };
-    */
 }
diff --git a/src/test/ui/chalkify/type_wf.stderr b/src/test/ui/chalkify/type_wf.stderr
new file mode 100644
index 00000000000..ab585a6ed21
--- /dev/null
+++ b/src/test/ui/chalkify/type_wf.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `f64: Foo` is not satisfied
+  --> $DIR/type_wf.rs:18:13
+   |
+LL | struct S<T: Foo> {
+   | ---------------- required by `S`
+...
+LL |     let s = S {
+   |             ^ the trait `Foo` is not implemented for `f64`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/coherence/coherence-subtyping.re.stderr b/src/test/ui/coherence/coherence-subtyping.re.stderr
deleted file mode 100644
index b3c2f451634..00000000000
--- a/src/test/ui/coherence/coherence-subtyping.re.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`:
-  --> $DIR/coherence-subtyping.rs:16:1
-   |
-LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {}
-   | ---------------------------------------------------------- first implementation here
-LL | 
-LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`
-   |
-   = note: `#[warn(coherence_leak_check)]` on by default
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
-   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs
index f5c1d92411b..b3ed728a81c 100644
--- a/src/test/ui/coherence/coherence-subtyping.rs
+++ b/src/test/ui/coherence/coherence-subtyping.rs
@@ -4,7 +4,6 @@
 // Note: This scenario is currently accepted, but as part of the
 // universe transition (#56105) may eventually become an error.
 
-// revisions: old re
 // check-pass
 
 trait TheTrait {
@@ -14,10 +13,8 @@ trait TheTrait {
 impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {}
 
 impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 {
-    //[re]~^ WARNING conflicting implementation
-    //[re]~^^ WARNING this was previously accepted by the compiler but is being phased out
-    //[old]~^^^ WARNING conflicting implementation
-    //[old]~^^^^ WARNING this was previously accepted by the compiler but is being phased out
+    //~^ WARNING conflicting implementation
+    //~^^ WARNING this was previously accepted by the compiler but is being phased out
 }
 
 fn main() {}
diff --git a/src/test/ui/coherence/coherence-subtyping.old.stderr b/src/test/ui/coherence/coherence-subtyping.stderr
index b3c2f451634..7f751a24c75 100644
--- a/src/test/ui/coherence/coherence-subtyping.old.stderr
+++ b/src/test/ui/coherence/coherence-subtyping.stderr
@@ -1,5 +1,5 @@
 warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`:
-  --> $DIR/coherence-subtyping.rs:16:1
+  --> $DIR/coherence-subtyping.rs:15:1
    |
 LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {}
    | ---------------------------------------------------------- first implementation here
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 64c0298c1fa..703b87634ce 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -123,6 +123,7 @@ pub enum FailMode {
 pub enum CompareMode {
     Nll,
     Polonius,
+    Chalk,
 }
 
 impl CompareMode {
@@ -130,6 +131,7 @@ impl CompareMode {
         match *self {
             CompareMode::Nll => "nll",
             CompareMode::Polonius => "polonius",
+            CompareMode::Chalk => "chalk",
         }
     }
 
@@ -137,6 +139,7 @@ impl CompareMode {
         match s.as_str() {
             "nll" => CompareMode::Nll,
             "polonius" => CompareMode::Polonius,
+            "chalk" => CompareMode::Chalk,
             x => panic!("unknown --compare-mode option: {}", x),
         }
     }
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 9614707433e..7d2c83881d1 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -875,6 +875,7 @@ impl Config {
             match self.compare_mode {
                 Some(CompareMode::Nll) => name == "compare-mode-nll",
                 Some(CompareMode::Polonius) => name == "compare-mode-polonius",
+                Some(CompareMode::Chalk) => name == "compare-mode-chalk",
                 None => false,
             } ||
             (cfg!(debug_assertions) && name == "debug") ||
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 18f00db3d8e..95ea4fb0789 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1985,6 +1985,9 @@ impl<'test> TestCx<'test> {
             Some(CompareMode::Polonius) => {
                 rustc.args(&["-Zpolonius", "-Zborrowck=mir"]);
             }
+            Some(CompareMode::Chalk) => {
+                rustc.args(&["-Zchalk"]);
+            }
             None => {}
         }
 
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index c08f02b972e..093db2a49d0 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -80,9 +80,7 @@ const WHITELIST: &[&str] = &[
     "cc",
     "cfg-if",
     "chalk-derive",
-    "chalk-engine",
     "chalk-ir",
-    "chalk-macros",
     "cloudabi",
     "cmake",
     "compiler_builtins",