Skip to content

Commit e2f3577

Browse files
committed
wellformed wc
1 parent c865d39 commit e2f3577

File tree

1 file changed

+80
-22
lines changed

1 file changed

+80
-22
lines changed

src/librustc_traits/lowering.rs

Lines changed: 80 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ use rustc::hir::def_id::DefId;
1212
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
1313
use rustc::hir::map::definitions::DefPathData;
1414
use rustc::hir::{self, ImplPolarity};
15-
use rustc::traits::{Clause, Clauses, DomainGoal, Goal, PolyDomainGoal, ProgramClause,
16-
WhereClause, FromEnv, WellFormed};
15+
use rustc::traits::{
16+
Clause, Clauses, DomainGoal, FromEnv, Goal, PolyDomainGoal, ProgramClause, WellFormed,
17+
WhereClause,
18+
};
1719
use rustc::ty::query::Providers;
1820
use rustc::ty::{self, Slice, TyCtxt};
1921
use rustc_data_structures::fx::FxHashSet;
@@ -101,39 +103,52 @@ impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
101103
Predicate::RegionOutlives(predicate) => predicate.lower(),
102104
Predicate::TypeOutlives(predicate) => predicate.lower(),
103105
Predicate::Projection(predicate) => predicate.lower(),
104-
Predicate::WellFormed(ty) => ty::Binder::dummy(
105-
DomainGoal::WellFormed(WellFormed::Ty(*ty))
106-
),
107-
Predicate::ObjectSafe(..) |
108-
Predicate::ClosureKind(..) |
109-
Predicate::Subtype(..) |
110-
Predicate::ConstEvaluatable(..) => {
111-
unimplemented!()
106+
Predicate::WellFormed(ty) => {
107+
ty::Binder::dummy(DomainGoal::WellFormed(WellFormed::Ty(*ty)))
112108
}
109+
Predicate::ObjectSafe(..)
110+
| Predicate::ClosureKind(..)
111+
| Predicate::Subtype(..)
112+
| Predicate::ConstEvaluatable(..) => unimplemented!(),
113113
}
114114
}
115115
}
116116

117-
/// Transforms an existing goal into a FromEnv goal.
118-
///
119117
/// Used for lowered where clauses (see rustc guide).
120118
trait IntoFromEnvGoal {
119+
// Transforms an existing goal into a FromEnv goal.
121120
fn into_from_env_goal(self) -> Self;
122121
}
123122

124-
impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> {
123+
trait IntoWellFormedGoal {
124+
fn into_wellformed_goal(self) -> Self;
125+
}
126+
127+
impl<'tcx> IntoGoal for DomainGoal<'tcx> {
128+
// Transforms an existing goal into a WellFormed goal.
125129
fn into_from_env_goal(self) -> DomainGoal<'tcx> {
126130
use self::WhereClause::*;
127131

128132
match self {
129-
DomainGoal::Holds(Implemented(trait_ref)) => DomainGoal::FromEnv(
130-
FromEnv::Trait(trait_ref)
131-
),
133+
DomainGoal::Holds(Implemented(trait_ref)) => {
134+
DomainGoal::FromEnv(FromEnv::Trait(trait_ref))
135+
}
132136
other => other,
133137
}
134138
}
135139
}
136140

141+
impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> {
142+
fn into_wellformed_goal(self) -> DomainGoal<'tcx> {
143+
use self::DomainGoal::*;
144+
match self {
145+
Holds(wc_atom) => WellFormed(wc_atom),
146+
WellFormed(..) | FromEnv(..) | WellFormedTy(..) | FromEnvTy(..) | Normalize(..)
147+
| RegionOutlives(..) | TypeOutlives(..) => self,
148+
}
149+
}
150+
}
151+
137152
crate fn program_clauses_for<'a, 'tcx>(
138153
tcx: TyCtxt<'a, 'tcx, 'tcx>,
139154
def_id: DefId,
@@ -230,7 +245,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
230245
// `Implemented(Self: Trait<P1..Pn>)`
231246
let impl_trait: DomainGoal = trait_pred.lower();
232247

233-
// `FromEnv(Self: Trait<P1..Pn>)`
248+
// `FromEnv(Self: Trait<P1..Pn>)`
234249
let from_env_goal = impl_trait.into_from_env_goal().into_goal();
235250
let hypotheses = tcx.intern_goals(&[from_env_goal]);
236251

@@ -262,10 +277,50 @@ fn program_clauses_for_trait<'a, 'tcx>(
262277
goal: goal.into_from_env_goal(),
263278
hypotheses,
264279
}))
280+
.map(|wc| implied_bound_from_trait(tcx, trait_pred, wc));
281+
let wellformed_clauses = where_clauses[1..]
282+
.into_iter()
283+
.map(|wc| wellformed_from_bound(tcx, trait_pred, wc));
284+
tcx.mk_clauses(
285+
clauses
286+
.chain(implied_bound_clauses)
287+
.chain(wellformed_clauses),
288+
)
289+
}
265290

266-
.map(Clause::ForAll);
291+
fn wellformed_from_bound<'a, 'tcx>(
292+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
293+
trait_pred: ty::TraitPredicate<'tcx>,
294+
where_clause: &ty::Predicate<'tcx>,
295+
) -> Clause<'tcx> {
296+
// Rule WellFormed-TraitRef
297+
//
298+
// For each where clause WC:
299+
// forall<Self, P1..Pn> {
300+
// WellFormed(Self: Trait<P1..Pn>) :- Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)
301+
// }
267302

268-
tcx.mk_clauses(clauses.chain(implied_bound_clauses))
303+
// WellFormed(Self: Trait<P1..Pn>)
304+
let wellformed_trait = DomainGoal::WellFormed(WhereClauseAtom::Implemented(trait_pred));
305+
// Impemented(Self: Trait<P1..Pn>)
306+
let impl_trait = ty::Binder::dummy(DomainGoal::Holds(WhereClauseAtom::Implemented(trait_pred)));
307+
// WellFormed(WC)
308+
let wellformed_wc = where_clause
309+
.lower()
310+
.map_bound(|wc| wc.into_wellformed_goal());
311+
// Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)
312+
let mut where_clauses = vec![impl_trait];
313+
where_clauses.push(wellformed_wc);
314+
Clause::ForAll(where_clause.lower().map_bound(|_| {
315+
ProgramClause {
316+
goal: wellformed_trait,
317+
hypotheses: tcx.mk_goals(
318+
where_clauses
319+
.into_iter()
320+
.map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
321+
),
322+
}
323+
}))
269324
}
270325

271326
fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Clauses<'tcx> {
@@ -307,7 +362,6 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
307362
tcx: TyCtxt<'a, 'tcx, 'tcx>,
308363
def_id: DefId,
309364
) -> Clauses<'tcx> {
310-
311365
// Rule WellFormed-Type
312366
//
313367
// `struct Ty<P1..Pn> where WC1, ..., WCm`
@@ -328,7 +382,10 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
328382
let well_formed = ProgramClause {
329383
goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
330384
hypotheses: tcx.mk_goals(
331-
where_clauses.iter().cloned().map(|wc| Goal::from_poly_domain_goal(wc, tcx))
385+
where_clauses
386+
.iter()
387+
.cloned()
388+
.map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
332389
),
333390
};
334391

@@ -459,7 +516,8 @@ impl<'a, 'tcx> ClauseDumper<'a, 'tcx> {
459516
}
460517

461518
if let Some(clauses) = clauses {
462-
let mut err = self.tcx
519+
let mut err = self
520+
.tcx
463521
.sess
464522
.struct_span_err(attr.span, "program clause dump");
465523

0 commit comments

Comments
 (0)