Skip to content

Commit 6656c0f

Browse files
committed
Add rules for type well-formedness
1 parent 0347b32 commit 6656c0f

File tree

2 files changed

+74
-4
lines changed

2 files changed

+74
-4
lines changed

src/librustc_traits/chalk_context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc::infer::canonical::{
1515
};
1616
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
1717
use rustc::traits::{
18-
WellFormed,
18+
WellFormed,
1919
FromEnv,
2020
DomainGoal,
2121
ExClauseFold,

src/librustc_traits/lowering.rs

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ crate fn program_clauses_for<'a, 'tcx>(
134134
DefPathData::Trait(_) => program_clauses_for_trait(tcx, def_id),
135135
DefPathData::Impl => program_clauses_for_impl(tcx, def_id),
136136
DefPathData::AssocTypeInImpl(..) => program_clauses_for_associated_type_value(tcx, def_id),
137+
DefPathData::AssocTypeInTrait(..) => program_clauses_for_associated_type_def(tcx, def_id),
138+
DefPathData::TypeNs(..) => program_clauses_for_type_def(tcx, def_id),
137139
_ => Slice::empty(),
138140
}
139141
}
@@ -224,10 +226,10 @@ fn program_clauses_for_trait<'a, 'tcx>(
224226
let impl_trait: DomainGoal = trait_pred.lower();
225227

226228
// `FromEnv(Self: Trait<P1..Pn>)`
227-
let from_env = impl_trait.into_from_env_goal().into_goal();
229+
let from_env_goal = impl_trait.into_from_env_goal().into_goal();
230+
let hypotheses = tcx.intern_goals(&[from_env_goal]);
228231

229232
// `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
230-
let hypotheses = tcx.intern_goals(&[from_env]);
231233
let implemented_from_env = ProgramClause {
232234
goal: impl_trait,
233235
hypotheses,
@@ -298,6 +300,72 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
298300
tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))])
299301
}
300302

303+
pub fn program_clauses_for_type_def<'a, 'tcx>(
304+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
305+
def_id: DefId,
306+
) -> Clauses<'tcx> {
307+
308+
// Rule WellFormed-Type
309+
//
310+
// `struct Ty<P1..Pn> where WC1, ..., WCm`
311+
//
312+
// ```
313+
// forall<P1..Pn> {
314+
// WellFormed(Ty<...>) :- WC1, ..., WCm`
315+
// }
316+
// ```
317+
318+
// `Ty<...>`
319+
let ty = tcx.type_of(def_id);
320+
321+
// `WC`
322+
let where_clauses = tcx.predicates_of(def_id).predicates.lower();
323+
324+
// `WellFormed(Ty<...>) :- WC1, ..., WCm`
325+
let well_formed = ProgramClause {
326+
goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
327+
hypotheses: tcx.mk_goals(
328+
where_clauses.iter().cloned().map(|wc| Goal::from_poly_domain_goal(wc, tcx))
329+
),
330+
};
331+
332+
let well_formed_clause = iter::once(Clause::ForAll(ty::Binder::dummy(well_formed)));
333+
334+
// Rule FromEnv-Type
335+
//
336+
// For each where clause `WC`:
337+
// ```
338+
// forall<P1..Pn> {
339+
// FromEnv(WC) :- FromEnv(Ty<...>)
340+
// }
341+
// ```
342+
343+
// `FromEnv(Ty<...>)`
344+
let from_env_goal = DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal();
345+
let hypotheses = tcx.intern_goals(&[from_env_goal]);
346+
347+
// For each where clause `WC`:
348+
let from_env_clauses = where_clauses
349+
.into_iter()
350+
351+
// `FromEnv(WC) :- FromEnv(Ty<...>)`
352+
.map(|wc| wc.map_bound(|goal| ProgramClause {
353+
goal: goal.into_from_env_goal(),
354+
hypotheses,
355+
}))
356+
357+
.map(Clause::ForAll);
358+
359+
tcx.mk_clauses(well_formed_clause.chain(from_env_clauses))
360+
}
361+
362+
pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
363+
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
364+
_item_id: DefId,
365+
) -> Clauses<'tcx> {
366+
unimplemented!()
367+
}
368+
301369
pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
302370
tcx: TyCtxt<'a, 'tcx, 'tcx>,
303371
item_id: DefId,
@@ -309,6 +377,8 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
309377
// type AssocType<Pn+1..Pm> = T;
310378
// }```
311379
//
380+
// FIXME: For the moment, we don't account for where clauses written on the associated
381+
// ty definition (i.e. in the trait def, as in `type AssocType<T> where T: Sized`).
312382
// ```
313383
// forall<P0..Pm> {
314384
// forall<Pn+1..Pm> {
@@ -324,7 +394,7 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
324394
ty::AssociatedItemContainer::ImplContainer(impl_id) => impl_id,
325395
_ => bug!("not an impl container"),
326396
};
327-
397+
328398
// `A0 as Trait<A1..An>`
329399
let trait_ref = tcx.impl_trait_ref(impl_id).unwrap();
330400

0 commit comments

Comments
 (0)