about summary refs log tree commit diff
path: root/src/librustc_traits
diff options
context:
space:
mode:
authorJack Huey <jack.huey@umassmed.edu>2020-05-27 01:05:09 -0400
committerJack Huey <jack.huey@umassmed.edu>2020-06-19 14:05:14 -0400
commita42e5a14c46dd57493fe38cc2fa51909edb70848 (patch)
tree1a97b5ab4f3b24e8ea3f06e5d203f49ea3ec28c3 /src/librustc_traits
parent7c09ad0627938949829de181ab23b976b9a1507f (diff)
downloadrust-a42e5a14c46dd57493fe38cc2fa51909edb70848.tar.gz
rust-a42e5a14c46dd57493fe38cc2fa51909edb70848.zip
Implement fn_def_datum
Diffstat (limited to 'src/librustc_traits')
-rw-r--r--src/librustc_traits/Cargo.toml4
-rw-r--r--src/librustc_traits/chalk/db.rs34
-rw-r--r--src/librustc_traits/chalk/lowering.rs21
3 files changed, 40 insertions, 19 deletions
diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml
index c85cd1765ab..cb056dba9ea 100644
--- a/src/librustc_traits/Cargo.toml
+++ b/src/librustc_traits/Cargo.toml
@@ -19,8 +19,8 @@ rustc_span = { path = "../librustc_span" }
 #chalk-ir = "0.10.0"
 #chalk-rust-ir = "0.10.0"
 #chalk-solve = "0.10.0"
-chalk-solve =   { git = "https://github.com/rust-lang/chalk.git", rev = "f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" }
-chalk-ir =      { git = "https://github.com/rust-lang/chalk.git", rev = "f4977ab4c781e4f3b7fdb9310edbdab6daf56e29" }
+chalk-solve =   { git = "https://github.com/jackh726/chalk.git", rev = "58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" }
+chalk-ir =      { git = "https://github.com/jackh726/chalk.git", rev = "58e5a31f48ddd4b940c682e7079d3e79e6ffaa1b" }
 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 367c5980279..95a6f45f92f 100644
--- a/src/librustc_traits/chalk/db.rs
+++ b/src/librustc_traits/chalk/db.rs
@@ -175,9 +175,39 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
 
     fn fn_def_datum(
         &self,
-        _fn_def_id: chalk_ir::FnDefId<RustInterner<'tcx>>,
+        fn_def_id: chalk_ir::FnDefId<RustInterner<'tcx>>,
     ) -> Arc<chalk_solve::rust_ir::FnDefDatum<RustInterner<'tcx>>> {
-        unimplemented!()
+        let def_id = match fn_def_id.0 {
+            RustDefId::FnDef(def_id) => def_id,
+            _ => bug!("Did not use `FnDef` variant when expecting FnDef."),
+        };
+        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): Why does this have a Binder
+        let argument_types = sig
+            .inputs()
+            .skip_binder()
+            .iter()
+            .map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner))
+            .collect();
+
+        let return_type =
+            sig.output().skip_binder().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(
diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs
index e4483843dd0..247dcb76c13 100644
--- a/src/librustc_traits/chalk/lowering.rs
+++ b/src/librustc_traits/chalk/lowering.rs
@@ -167,20 +167,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
             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): 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): 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) -- 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)),
                     )),
@@ -360,9 +351,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
                     ),
                 )
             }
-            FnDef(def_id, _) => apply(
+            FnDef(def_id, substs) => apply(
                 chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(RustDefId::FnDef(def_id))),
-                empty(),
+                substs.lower_into(interner),
             ),
             FnPtr(sig) => {
                 let (inputs_and_outputs, binders, _named_regions) =