Handle sub-typing in chalk-engine

This commit is contained in:
scalexm 2018-11-28 22:11:00 +01:00
parent ba6314a0d6
commit da9467d147
9 changed files with 41 additions and 11 deletions

View File

@ -273,7 +273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chalk-engine"
version = "0.8.0"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2067,7 +2067,7 @@ dependencies = [
"backtrace 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fmt_macros 0.0.0",
"graphviz 0.0.0",
@ -2640,7 +2640,7 @@ name = "rustc_traits"
version = "0.0.0"
dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"graphviz 0.0.0",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
@ -3403,7 +3403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cargo_metadata 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8dfe3adeb30f7938e6c1dd5327f29235d8ada3e898aeb08c343005ec2915a2"
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6749eb72e7d4355d944a99f15fbaea701b978c18c5e184a025fcde942b0c9779"
"checksum chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17ec698a6f053a23bfbe646d9f2fde4b02abc19125595270a99e6f44ae0bdd1a"
"checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"

View File

@ -30,7 +30,7 @@ syntax_pos = { path = "../libsyntax_pos" }
backtrace = "0.3.3"
parking_lot = "0.6"
byteorder = { version = "1.1", features = ["i128"]}
chalk-engine = { version = "0.8.0", default-features=false }
chalk-engine = { version = "0.9.0", default-features=false }
rustc_fs_util = { path = "../librustc_fs_util" }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }

View File

@ -1195,6 +1195,10 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
quantifier.hash_stable(hcx, hasher);
goal.hash_stable(hcx, hasher);
},
Subtype(a, b) => {
a.hash_stable(hcx, hasher);
b.hash_stable(hcx, hasher);
}
CannotProve => { },
}
}

View File

@ -324,6 +324,7 @@ pub enum GoalKind<'tcx> {
Not(Goal<'tcx>),
DomainGoal(DomainGoal<'tcx>),
Quantified(QuantifierKind, ty::Binder<Goal<'tcx>>),
Subtype(Ty<'tcx>, Ty<'tcx>),
CannotProve,
}

View File

@ -395,6 +395,7 @@ impl<'tcx> fmt::Display for traits::Goal<'tcx> {
Ok(())
}
Subtype(a, b) => write!(fmt, "{} <: {}", a, b),
CannotProve => write!(fmt, "CannotProve"),
}
}
@ -668,6 +669,7 @@ EnumLiftImpl! {
(traits::GoalKind::Not)(goal),
(traits::GoalKind::DomainGoal)(domain_goal),
(traits::GoalKind::Quantified)(kind, goal),
(traits::GoalKind::Subtype)(a, b),
(traits::GoalKind::CannotProve),
}
}
@ -864,6 +866,7 @@ EnumTypeFoldableImpl! {
(traits::GoalKind::Not)(goal),
(traits::GoalKind::DomainGoal)(domain_goal),
(traits::GoalKind::Quantified)(qkind, goal),
(traits::GoalKind::Subtype)(a, b),
(traits::GoalKind::CannotProve),
}
}

View File

@ -17,5 +17,5 @@ rustc_data_structures = { path = "../librustc_data_structures" }
rustc_target = { path = "../librustc_target" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
chalk-engine = { version = "0.8.0", default-features=false }
chalk-engine = { version = "0.9.0", default-features=false }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }

View File

@ -116,6 +116,8 @@ impl context::Context for ChalkArenas<'tcx> {
type UnificationResult = UnificationResult<'tcx>;
type Variance = ty::Variance;
fn goal_in_environment(
env: &Environment<'tcx>,
goal: Goal<'tcx>,
@ -332,6 +334,11 @@ impl context::InferenceTable<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
GoalKind::DomainGoal(d) => HhGoal::DomainGoal(d),
GoalKind::Quantified(QuantifierKind::Universal, binder) => HhGoal::ForAll(binder),
GoalKind::Quantified(QuantifierKind::Existential, binder) => HhGoal::Exists(binder),
GoalKind::Subtype(a, b) => HhGoal::Unify(
ty::Variance::Covariant,
a.into(),
b.into()
),
GoalKind::CannotProve => HhGoal::CannotProve,
}
}
@ -444,11 +451,13 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
fn unify_parameters(
&mut self,
environment: &Environment<'tcx>,
variance: ty::Variance,
a: &Kind<'tcx>,
b: &Kind<'tcx>,
) -> Fallible<UnificationResult<'tcx>> {
self.infcx.commit_if_ok(|_| {
unify(self.infcx, *environment, a, b).map_err(|_| chalk_engine::fallible::NoSolution)
unify(self.infcx, *environment, variance, a, b)
.map_err(|_| chalk_engine::fallible::NoSolution)
})
}
@ -673,6 +682,13 @@ crate fn evaluate_goal<'a, 'tcx>(
GoalKind::DomainGoal(DomainGoal::WellFormed(WellFormed::Ty(ty)))
),
ty::Predicate::Subtype(predicate) => tcx.mk_goal(
GoalKind::Quantified(
QuantifierKind::Universal,
predicate.map_bound(|pred| tcx.mk_goal(GoalKind::Subtype(pred.a, pred.b)))
)
),
other => tcx.mk_goal(
GoalKind::from_poly_domain_goal(other.lower(), tcx)
),

View File

@ -51,8 +51,13 @@ impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
).0,
};
let result = unify(self.infcx, *environment, goal, &consequence)
.map_err(|_| NoSolution)?;
let result = unify(
self.infcx,
*environment,
ty::Variance::Invariant,
goal,
&consequence
).map_err(|_| NoSolution)?;
let mut ex_clause = ExClause {
subst: subst.clone(),
@ -139,7 +144,7 @@ impl AnswerSubstitutor<'cx, 'gcx, 'tcx> {
);
super::into_ex_clause(
unify(self.infcx, self.environment, answer_param, pending)?,
unify(self.infcx, self.environment, ty::Variance::Invariant, answer_param, pending)?,
&mut self.ex_clause
);

View File

@ -13,6 +13,7 @@ crate struct UnificationResult<'tcx> {
crate fn unify<'me, 'gcx, 'tcx, T: Relate<'tcx>>(
infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
environment: Environment<'tcx>,
variance: ty::Variance,
a: &T,
b: &T
) -> RelateResult<'tcx, UnificationResult<'tcx>> {
@ -30,7 +31,7 @@ crate fn unify<'me, 'gcx, 'tcx, T: Relate<'tcx>>(
TypeRelating::new(
infcx,
&mut delegate,
ty::Variance::Invariant
variance
).relate(a, b)?;
debug!("unify: goals = {:?}, constraints = {:?}", delegate.goals, delegate.constraints);