Skip to content

Commit be64bf3

Browse files
committedOct 10, 2018
Rollup merge of #54909 - scalexm:finish-rules, r=nikomatsakis
Fixes #47311. r? @nrc
2 parents ff3e4d9 + 282559c commit be64bf3

File tree

12 files changed

+198
-93
lines changed

12 files changed

+198
-93
lines changed
 

‎src/Cargo.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
270270

271271
[[package]]
272272
name = "chalk-engine"
273-
version = "0.7.0"
273+
version = "0.8.0"
274274
source = "registry+https://github.com/rust-lang/crates.io-index"
275275
dependencies = [
276276
"chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1898,7 +1898,7 @@ dependencies = [
18981898
"backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
18991899
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
19001900
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
1901-
"chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
1901+
"chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
19021902
"flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
19031903
"fmt_macros 0.0.0",
19041904
"graphviz 0.0.0",
@@ -2434,7 +2434,7 @@ name = "rustc_traits"
24342434
version = "0.0.0"
24352435
dependencies = [
24362436
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
2437-
"chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
2437+
"chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
24382438
"graphviz 0.0.0",
24392439
"log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
24402440
"rustc 0.0.0",
@@ -3195,7 +3195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
31953195
"checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1"
31963196
"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
31973197
"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
3198-
"checksum chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25ce2f28f55ed544a2a3756b7acf41dd7d6f27acffb2086439950925506af7d0"
3198+
"checksum chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6749eb72e7d4355d944a99f15fbaea701b978c18c5e184a025fcde942b0c9779"
31993199
"checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e"
32003200
"checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37"
32013201
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"

‎src/librustc/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ syntax_pos = { path = "../libsyntax_pos" }
3131
backtrace = "0.3.3"
3232
parking_lot = "0.6"
3333
byteorder = { version = "1.1", features = ["i128"]}
34-
chalk-engine = { version = "0.7.0", default-features=false }
34+
chalk-engine = { version = "0.8.0", default-features=false }
3535
rustc_fs_util = { path = "../librustc_fs_util" }
3636
smallvec = { version = "0.6.5", features = ["union"] }
3737

‎src/librustc/ich/impls_ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1370,7 +1370,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
13701370
fn hash_stable<W: StableHasherResult>(&self,
13711371
hcx: &mut StableHashingContext<'a>,
13721372
hasher: &mut StableHasher<W>) {
1373-
use traits::Goal::*;
1373+
use traits::GoalKind::*;
13741374

13751375
mem::discriminant(self).hash_stable(hcx, hasher);
13761376
match self {

‎src/librustc/traits/mod.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -318,31 +318,33 @@ pub enum QuantifierKind {
318318
}
319319

320320
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
321-
pub enum Goal<'tcx> {
322-
Implies(Clauses<'tcx>, &'tcx Goal<'tcx>),
323-
And(&'tcx Goal<'tcx>, &'tcx Goal<'tcx>),
324-
Not(&'tcx Goal<'tcx>),
321+
pub enum GoalKind<'tcx> {
322+
Implies(Clauses<'tcx>, Goal<'tcx>),
323+
And(Goal<'tcx>, Goal<'tcx>),
324+
Not(Goal<'tcx>),
325325
DomainGoal(DomainGoal<'tcx>),
326-
Quantified(QuantifierKind, ty::Binder<&'tcx Goal<'tcx>>),
326+
Quantified(QuantifierKind, ty::Binder<Goal<'tcx>>),
327327
CannotProve,
328328
}
329329

330+
pub type Goal<'tcx> = &'tcx GoalKind<'tcx>;
331+
330332
pub type Goals<'tcx> = &'tcx List<Goal<'tcx>>;
331333

332334
impl<'tcx> DomainGoal<'tcx> {
333-
pub fn into_goal(self) -> Goal<'tcx> {
334-
Goal::DomainGoal(self)
335+
pub fn into_goal(self) -> GoalKind<'tcx> {
336+
GoalKind::DomainGoal(self)
335337
}
336338
}
337339

338-
impl<'tcx> Goal<'tcx> {
340+
impl<'tcx> GoalKind<'tcx> {
339341
pub fn from_poly_domain_goal<'a>(
340342
domain_goal: PolyDomainGoal<'tcx>,
341343
tcx: TyCtxt<'a, 'tcx, 'tcx>,
342-
) -> Goal<'tcx> {
344+
) -> GoalKind<'tcx> {
343345
match domain_goal.no_late_bound_regions() {
344346
Some(p) => p.into_goal(),
345-
None => Goal::Quantified(
347+
None => GoalKind::Quantified(
346348
QuantifierKind::Universal,
347349
domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal()))
348350
),

‎src/librustc/traits/structural_impls.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ impl fmt::Display for traits::QuantifierKind {
469469

470470
impl<'tcx> fmt::Display for traits::Goal<'tcx> {
471471
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
472-
use traits::Goal::*;
472+
use traits::GoalKind::*;
473473

474474
match self {
475475
Implies(hypotheses, goal) => {
@@ -598,25 +598,25 @@ CloneTypeFoldableAndLiftImpls! {
598598
}
599599

600600
EnumTypeFoldableImpl! {
601-
impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
602-
(traits::Goal::Implies)(hypotheses, goal),
603-
(traits::Goal::And)(goal1, goal2),
604-
(traits::Goal::Not)(goal),
605-
(traits::Goal::DomainGoal)(domain_goal),
606-
(traits::Goal::Quantified)(qkind, goal),
607-
(traits::Goal::CannotProve),
601+
impl<'tcx> TypeFoldable<'tcx> for traits::GoalKind<'tcx> {
602+
(traits::GoalKind::Implies)(hypotheses, goal),
603+
(traits::GoalKind::And)(goal1, goal2),
604+
(traits::GoalKind::Not)(goal),
605+
(traits::GoalKind::DomainGoal)(domain_goal),
606+
(traits::GoalKind::Quantified)(qkind, goal),
607+
(traits::GoalKind::CannotProve),
608608
}
609609
}
610610

611611
EnumLiftImpl! {
612-
impl<'a, 'tcx> Lift<'tcx> for traits::Goal<'a> {
613-
type Lifted = traits::Goal<'tcx>;
614-
(traits::Goal::Implies)(hypotheses, goal),
615-
(traits::Goal::And)(goal1, goal2),
616-
(traits::Goal::Not)(goal),
617-
(traits::Goal::DomainGoal)(domain_goal),
618-
(traits::Goal::Quantified)(kind, goal),
619-
(traits::Goal::CannotProve),
612+
impl<'a, 'tcx> Lift<'tcx> for traits::GoalKind<'a> {
613+
type Lifted = traits::GoalKind<'tcx>;
614+
(traits::GoalKind::Implies)(hypotheses, goal),
615+
(traits::GoalKind::And)(goal1, goal2),
616+
(traits::GoalKind::Not)(goal),
617+
(traits::GoalKind::DomainGoal)(domain_goal),
618+
(traits::GoalKind::Quantified)(kind, goal),
619+
(traits::GoalKind::CannotProve),
620620
}
621621
}
622622

@@ -633,7 +633,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<traits::Goal<'tcx>> {
633633
}
634634
}
635635

636-
impl<'tcx> TypeFoldable<'tcx> for &'tcx traits::Goal<'tcx> {
636+
impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
637637
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
638638
let v = (**self).fold_with(folder);
639639
folder.tcx().mk_goal(v)

‎src/librustc/ty/context.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use mir::interpret::Allocation;
3636
use ty::subst::{CanonicalSubsts, Kind, Substs, Subst};
3737
use ty::ReprOptions;
3838
use traits;
39-
use traits::{Clause, Clauses, Goal, Goals};
39+
use traits::{Clause, Clauses, GoalKind, Goal, Goals};
4040
use ty::{self, Ty, TypeAndMut};
4141
use ty::{TyS, TyKind, List};
4242
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const};
@@ -143,7 +143,8 @@ pub struct CtxtInterners<'tcx> {
143143
predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
144144
const_: InternedSet<'tcx, Const<'tcx>>,
145145
clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
146-
goals: InternedSet<'tcx, List<Goal<'tcx>>>,
146+
goal: InternedSet<'tcx, GoalKind<'tcx>>,
147+
goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
147148
}
148149

149150
impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
@@ -159,7 +160,8 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
159160
predicates: Default::default(),
160161
const_: Default::default(),
161162
clauses: Default::default(),
162-
goals: Default::default(),
163+
goal: Default::default(),
164+
goal_list: Default::default(),
163165
}
164166
}
165167

@@ -1731,9 +1733,9 @@ impl<'a, 'tcx> Lift<'tcx> for Region<'a> {
17311733
}
17321734
}
17331735

1734-
impl<'a, 'tcx> Lift<'tcx> for &'a Goal<'a> {
1735-
type Lifted = &'tcx Goal<'tcx>;
1736-
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Goal<'tcx>> {
1736+
impl<'a, 'tcx> Lift<'tcx> for Goal<'a> {
1737+
type Lifted = Goal<'tcx>;
1738+
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Goal<'tcx>> {
17371739
if tcx.interners.arena.in_arena(*self as *const _) {
17381740
return Some(unsafe { mem::transmute(*self) });
17391741
}
@@ -2304,6 +2306,12 @@ impl<'tcx> Borrow<RegionKind> for Interned<'tcx, RegionKind> {
23042306
}
23052307
}
23062308

2309+
impl<'tcx: 'lcx, 'lcx> Borrow<GoalKind<'lcx>> for Interned<'tcx, GoalKind<'tcx>> {
2310+
fn borrow<'a>(&'a self) -> &'a GoalKind<'lcx> {
2311+
&self.0
2312+
}
2313+
}
2314+
23072315
impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]>
23082316
for Interned<'tcx, List<ExistentialPredicate<'tcx>>> {
23092317
fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] {
@@ -2419,7 +2427,8 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
24192427

24202428
direct_interners!('tcx,
24212429
region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
2422-
const_: mk_const(|c: &Const<'_>| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>
2430+
const_: mk_const(|c: &Const<'_>| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>,
2431+
goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>
24232432
);
24242433

24252434
macro_rules! slice_interners {
@@ -2438,7 +2447,7 @@ slice_interners!(
24382447
type_list: _intern_type_list(Ty),
24392448
substs: _intern_substs(Kind),
24402449
clauses: _intern_clauses(Clause),
2441-
goals: _intern_goals(Goal)
2450+
goal_list: _intern_goals(Goal)
24422451
);
24432452

24442453
// This isn't a perfect fit: CanonicalVarInfo slices are always
@@ -2818,10 +2827,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
28182827
iter.intern_with(|xs| self.intern_goals(xs))
28192828
}
28202829

2821-
pub fn mk_goal(self, goal: Goal<'tcx>) -> &'tcx Goal<'_> {
2822-
&self.intern_goals(&[goal])[0]
2823-
}
2824-
28252830
pub fn lint_hir<S: Into<MultiSpan>>(self,
28262831
lint: &'static Lint,
28272832
hir_id: HirId,

‎src/librustc/ty/flags.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ impl FlagComputation {
148148
self.add_projection_ty(data);
149149
}
150150

151-
&ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"),
151+
&ty::UnnormalizedProjection(ref data) => {
152+
self.add_flags(TypeFlags::HAS_PROJECTION);
153+
self.add_projection_ty(data);
154+
},
152155

153156
&ty::Opaque(_, substs) => {
154157
self.add_flags(TypeFlags::HAS_PROJECTION);

‎src/librustc_traits/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ rustc = { path = "../librustc" }
1616
rustc_data_structures = { path = "../librustc_data_structures" }
1717
syntax = { path = "../libsyntax" }
1818
syntax_pos = { path = "../libsyntax_pos" }
19-
chalk-engine = { version = "0.7.0", default-features=false }
19+
chalk-engine = { version = "0.8.0", default-features=false }
2020
smallvec = { version = "0.6.5", features = ["union"] }

‎src/librustc_traits/chalk_context.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc::traits::{
1919
ExClauseFold,
2020
ExClauseLift,
2121
Goal,
22+
GoalKind,
2223
ProgramClause,
2324
QuantifierKind
2425
};
@@ -92,7 +93,7 @@ impl context::Context for ChalkArenas<'tcx> {
9293

9394
type DomainGoal = DomainGoal<'tcx>;
9495

95-
type BindersGoal = ty::Binder<&'tcx Goal<'tcx>>;
96+
type BindersGoal = ty::Binder<Goal<'tcx>>;
9697

9798
type Parameter = Kind<'tcx>;
9899

@@ -102,14 +103,6 @@ impl context::Context for ChalkArenas<'tcx> {
102103

103104
type UnificationResult = InferOk<'tcx, ()>;
104105

105-
fn into_goal(domain_goal: DomainGoal<'tcx>) -> Goal<'tcx> {
106-
Goal::DomainGoal(domain_goal)
107-
}
108-
109-
fn cannot_prove() -> Goal<'tcx> {
110-
Goal::CannotProve
111-
}
112-
113106
fn goal_in_environment(
114107
env: &ty::ParamEnv<'tcx>,
115108
goal: Goal<'tcx>,
@@ -251,15 +244,23 @@ impl context::ContextOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
251244
impl context::InferenceTable<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
252245
for ChalkInferenceContext<'cx, 'gcx, 'tcx>
253246
{
247+
fn into_goal(&self, domain_goal: DomainGoal<'tcx>) -> Goal<'tcx> {
248+
self.infcx.tcx.mk_goal(GoalKind::DomainGoal(domain_goal))
249+
}
250+
251+
fn cannot_prove(&self) -> Goal<'tcx> {
252+
self.infcx.tcx.mk_goal(GoalKind::CannotProve)
253+
}
254+
254255
fn into_hh_goal(&mut self, goal: Goal<'tcx>) -> ChalkHhGoal<'tcx> {
255-
match goal {
256-
Goal::Implies(..) => panic!("FIXME rust-lang-nursery/chalk#94"),
257-
Goal::And(left, right) => HhGoal::And(*left, *right),
258-
Goal::Not(subgoal) => HhGoal::Not(*subgoal),
259-
Goal::DomainGoal(d) => HhGoal::DomainGoal(d),
260-
Goal::Quantified(QuantifierKind::Universal, binder) => HhGoal::ForAll(binder),
261-
Goal::Quantified(QuantifierKind::Existential, binder) => HhGoal::Exists(binder),
262-
Goal::CannotProve => HhGoal::CannotProve,
256+
match *goal {
257+
GoalKind::Implies(..) => panic!("FIXME rust-lang-nursery/chalk#94"),
258+
GoalKind::And(left, right) => HhGoal::And(left, right),
259+
GoalKind::Not(subgoal) => HhGoal::Not(subgoal),
260+
GoalKind::DomainGoal(d) => HhGoal::DomainGoal(d),
261+
GoalKind::Quantified(QuantifierKind::Universal, binder) => HhGoal::ForAll(binder),
262+
GoalKind::Quantified(QuantifierKind::Existential, binder) => HhGoal::Exists(binder),
263+
GoalKind::CannotProve => HhGoal::CannotProve,
263264
}
264265
}
265266

@@ -363,21 +364,21 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
363364

364365
fn instantiate_binders_universally(
365366
&mut self,
366-
_arg: &ty::Binder<&'tcx Goal<'tcx>>,
367+
_arg: &ty::Binder<Goal<'tcx>>,
367368
) -> Goal<'tcx> {
368369
panic!("FIXME -- universal instantiation needs sgrif's branch")
369370
}
370371

371372
fn instantiate_binders_existentially(
372373
&mut self,
373-
arg: &ty::Binder<&'tcx Goal<'tcx>>,
374+
arg: &ty::Binder<Goal<'tcx>>,
374375
) -> Goal<'tcx> {
375376
let (value, _map) = self.infcx.replace_late_bound_regions_with_fresh_var(
376377
DUMMY_SP,
377378
LateBoundRegionConversionTime::HigherRankedType,
378379
arg,
379380
);
380-
*value
381+
value
381382
}
382383

383384
fn debug_ex_clause(&mut self, value: &'v ChalkExClause<'tcx>) -> Box<dyn Debug + 'v> {

‎src/librustc_traits/lowering.rs

Lines changed: 99 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
1313
use rustc::hir::map::definitions::DefPathData;
1414
use rustc::hir::{self, ImplPolarity};
1515
use rustc::traits::{
16-
Clause, Clauses, DomainGoal, FromEnv, Goal, PolyDomainGoal, ProgramClause, WellFormed,
16+
Clause,
17+
Clauses,
18+
DomainGoal,
19+
FromEnv,
20+
GoalKind,
21+
PolyDomainGoal,
22+
ProgramClause,
23+
WellFormed,
1724
WhereClause,
1825
};
1926
use rustc::ty::query::Providers;
@@ -249,7 +256,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
249256
let impl_trait: DomainGoal = trait_pred.lower();
250257

251258
// `FromEnv(Self: Trait<P1..Pn>)`
252-
let from_env_goal = impl_trait.into_from_env_goal().into_goal();
259+
let from_env_goal = tcx.mk_goal(impl_trait.into_from_env_goal().into_goal());
253260
let hypotheses = tcx.intern_goals(&[from_env_goal]);
254261

255262
// `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
@@ -308,7 +315,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
308315
let wf_clause = ProgramClause {
309316
goal: DomainGoal::WellFormed(WellFormed::Trait(trait_pred)),
310317
hypotheses: tcx.mk_goals(
311-
wf_conditions.map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
318+
wf_conditions.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
312319
),
313320
};
314321
let wf_clause = iter::once(Clause::ForAll(ty::Binder::dummy(wf_clause)));
@@ -352,10 +359,10 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
352359
hypotheses: tcx.mk_goals(
353360
where_clauses
354361
.into_iter()
355-
.map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
362+
.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
356363
),
357364
};
358-
tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))])
365+
tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause))))
359366
}
360367

361368
pub fn program_clauses_for_type_def<'a, 'tcx>(
@@ -388,7 +395,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
388395
where_clauses
389396
.iter()
390397
.cloned()
391-
.map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
398+
.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
392399
),
393400
};
394401

@@ -404,7 +411,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
404411
// ```
405412

406413
// `FromEnv(Ty<...>)`
407-
let from_env_goal = DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal();
414+
let from_env_goal = tcx.mk_goal(DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal());
408415
let hypotheses = tcx.intern_goals(&[from_env_goal]);
409416

410417
// For each where clause `WC`:
@@ -423,10 +430,86 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
423430
}
424431

425432
pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
426-
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
427-
_item_id: DefId,
433+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
434+
item_id: DefId,
428435
) -> Clauses<'tcx> {
429-
unimplemented!()
436+
// Rule ProjectionEq-Skolemize
437+
//
438+
// ```
439+
// trait Trait<P1..Pn> {
440+
// type AssocType<Pn+1..Pm>;
441+
// }
442+
// ```
443+
//
444+
// `ProjectionEq` can succeed by skolemizing, see "associated type"
445+
// chapter for more:
446+
// ```
447+
// forall<Self, P1..Pn, Pn+1..Pm> {
448+
// ProjectionEq(
449+
// <Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> =
450+
// (Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>
451+
// )
452+
// }
453+
// ```
454+
455+
let item = tcx.associated_item(item_id);
456+
debug_assert_eq!(item.kind, ty::AssociatedKind::Type);
457+
let trait_id = match item.container {
458+
ty::AssociatedItemContainer::TraitContainer(trait_id) => trait_id,
459+
_ => bug!("not an trait container"),
460+
};
461+
let trait_ref = ty::TraitRef::identity(tcx, trait_id);
462+
463+
let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.ident);
464+
let placeholder_ty = tcx.mk_ty(ty::UnnormalizedProjection(projection_ty));
465+
let projection_eq = WhereClause::ProjectionEq(ty::ProjectionPredicate {
466+
projection_ty,
467+
ty: placeholder_ty,
468+
});
469+
470+
let projection_eq_clause = ProgramClause {
471+
goal: DomainGoal::Holds(projection_eq),
472+
hypotheses: &ty::List::empty(),
473+
};
474+
475+
// Rule WellFormed-AssocTy
476+
// ```
477+
// forall<Self, P1..Pn, Pn+1..Pm> {
478+
// WellFormed((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
479+
// :- Implemented(Self: Trait<P1..Pn>)
480+
// }
481+
// ```
482+
483+
let trait_predicate = ty::TraitPredicate { trait_ref };
484+
let hypothesis = tcx.mk_goal(
485+
DomainGoal::Holds(WhereClause::Implemented(trait_predicate)).into_goal()
486+
);
487+
let wf_clause = ProgramClause {
488+
goal: DomainGoal::WellFormed(WellFormed::Ty(placeholder_ty)),
489+
hypotheses: tcx.mk_goals(iter::once(hypothesis)),
490+
};
491+
492+
// Rule Implied-Trait-From-AssocTy
493+
// ```
494+
// forall<Self, P1..Pn, Pn+1..Pm> {
495+
// FromEnv(Self: Trait<P1..Pn>)
496+
// :- FromEnv((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
497+
// }
498+
// ```
499+
500+
let hypothesis = tcx.mk_goal(
501+
DomainGoal::FromEnv(FromEnv::Ty(placeholder_ty)).into_goal()
502+
);
503+
let from_env_clause = ProgramClause {
504+
goal: DomainGoal::FromEnv(FromEnv::Trait(trait_predicate)),
505+
hypotheses: tcx.mk_goals(iter::once(hypothesis)),
506+
};
507+
508+
let clauses = iter::once(projection_eq_clause)
509+
.chain(iter::once(wf_clause))
510+
.chain(iter::once(from_env_clause));
511+
let clauses = clauses.map(|clause| Clause::ForAll(ty::Binder::dummy(clause)));
512+
tcx.mk_clauses(clauses)
430513
}
431514

432515
pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
@@ -435,10 +518,11 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
435518
) -> Clauses<'tcx> {
436519
// Rule Normalize-From-Impl (see rustc guide)
437520
//
438-
// ```impl<P0..Pn> Trait<A1..An> for A0
439-
// {
521+
// ```
522+
// impl<P0..Pn> Trait<A1..An> for A0 {
440523
// type AssocType<Pn+1..Pm> = T;
441-
// }```
524+
// }
525+
// ```
442526
//
443527
// FIXME: For the moment, we don't account for where clauses written on the associated
444528
// ty definition (i.e. in the trait def, as in `type AssocType<T> where T: Sized`).
@@ -482,10 +566,10 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
482566
hypotheses: tcx.mk_goals(
483567
hypotheses
484568
.into_iter()
485-
.map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
569+
.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
486570
),
487571
};
488-
tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))])
572+
tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause))))
489573
}
490574

491575
pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {

‎src/test/ui/chalkify/lower_trait.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010

1111
#![feature(rustc_attrs)]
1212

13+
trait Bar { }
14+
1315
#[rustc_dump_program_clauses] //~ ERROR program clause dump
14-
trait Foo<S, T, U> {
15-
fn s(_: S) -> S;
16-
fn t(_: T) -> T;
17-
fn u(_: U) -> U;
16+
trait Foo<S, T: ?Sized> {
17+
#[rustc_dump_program_clauses] //~ ERROR program clause dump
18+
type Assoc: Bar + ?Sized;
1819
}
1920

2021
fn main() {
Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
error: program clause dump
2-
--> $DIR/lower_trait.rs:13:1
2+
--> $DIR/lower_trait.rs:15:1
33
|
44
LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: FromEnv(S: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
8-
= note: FromEnv(T: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
9-
= note: FromEnv(U: std::marker::Sized) :- FromEnv(Self: Foo<S, T, U>).
10-
= note: Implemented(Self: Foo<S, T, U>) :- FromEnv(Self: Foo<S, T, U>).
11-
= note: WellFormed(Self: Foo<S, T, U>) :- Implemented(Self: Foo<S, T, U>), WellFormed(S: std::marker::Sized), WellFormed(T: std::marker::Sized), WellFormed(U: std::marker::Sized).
7+
= note: FromEnv(<Self as Foo<S, T>>::Assoc: Bar) :- FromEnv(Self: Foo<S, T>).
8+
= note: FromEnv(S: std::marker::Sized) :- FromEnv(Self: Foo<S, T>).
9+
= note: Implemented(Self: Foo<S, T>) :- FromEnv(Self: Foo<S, T>).
10+
= note: WellFormed(Self: Foo<S, T>) :- Implemented(Self: Foo<S, T>), WellFormed(S: std::marker::Sized), WellFormed(<Self as Foo<S, T>>::Assoc: Bar).
1211

13-
error: aborting due to previous error
12+
error: program clause dump
13+
--> $DIR/lower_trait.rs:17:5
14+
|
15+
LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
|
18+
= note: FromEnv(Self: Foo<S, T>) :- FromEnv(Unnormalized(<Self as Foo<S, T>>::Assoc)).
19+
= note: ProjectionEq(<Self as Foo<S, T>>::Assoc == Unnormalized(<Self as Foo<S, T>>::Assoc)).
20+
= note: WellFormed(Unnormalized(<Self as Foo<S, T>>::Assoc)) :- Implemented(Self: Foo<S, T>).
21+
22+
error: aborting due to 2 previous errors
1423

0 commit comments

Comments
 (0)
Please sign in to comment.