Skip to content

Commit 60ea7cb

Browse files
committed
Gather region constraints not coming from unification
1 parent c3b33a7 commit 60ea7cb

File tree

4 files changed

+34
-57
lines changed

4 files changed

+34
-57
lines changed

src/librustc_traits/chalk_context/program_clauses.rs

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -326,15 +326,12 @@ fn wf_clause_for_ref<'tcx>(
326326
mutbl,
327327
});
328328

329-
let _outlives: DomainGoal<'_> = ty::OutlivesPredicate(ty, region).lower();
329+
let outlives: DomainGoal<'_> = ty::OutlivesPredicate(ty, region).lower();
330330
let wf_clause = ProgramClause {
331331
goal: DomainGoal::WellFormed(WellFormed::Ty(ref_ty)),
332-
hypotheses: ty::List::empty(),
333-
334-
// FIXME: restore this later once we get better at handling regions
335-
// hypotheses: tcx.mk_goals(
336-
// iter::once(tcx.mk_goal(outlives.into_goal()))
337-
// ),
332+
hypotheses: tcx.mk_goals(
333+
iter::once(tcx.mk_goal(outlives.into_goal()))
334+
),
338335
category: ProgramClauseCategory::WellFormed,
339336
};
340337
let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
@@ -432,22 +429,14 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
432429
clauses
433430
}
434431

435-
DomainGoal::Holds(RegionOutlives(..)) => {
436-
// These come from:
437-
// * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
438-
// * implied bounds from type definitions (rule `Implied-Bound-From-Type`)
439-
440-
// All of these rules are computed in the environment.
441-
vec![]
442-
}
443-
444-
DomainGoal::Holds(TypeOutlives(..)) => {
445-
// These come from:
446-
// * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
447-
// * implied bounds from type definitions (rule `Implied-Bound-From-Type`)
448-
449-
// All of these rules are computed in the environment.
450-
vec![]
432+
// For outlive requirements, just assume they hold. `ResolventOps::resolvent_clause`
433+
// will register them as actual region constraints later.
434+
DomainGoal::Holds(RegionOutlives(..)) | DomainGoal::Holds(TypeOutlives(..)) => {
435+
vec![Clause::Implies(ProgramClause {
436+
goal,
437+
hypotheses: ty::List::empty(),
438+
category: ProgramClauseCategory::Other,
439+
})]
451440
}
452441

453442
DomainGoal::WellFormed(WellFormed::Trait(trait_predicate)) => {
@@ -485,7 +474,7 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
485474
ty::Error |
486475
ty::Never => {
487476
let wf_clause = ProgramClause {
488-
goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
477+
goal,
489478
hypotheses: ty::List::empty(),
490479
category: ProgramClauseCategory::WellFormed,
491480
};

src/librustc_traits/chalk_context/resolvent_ops.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc::infer::{InferCtxt, LateBoundRegionConversionTime};
88
use rustc::infer::canonical::{Canonical, CanonicalVarValues};
99
use rustc::traits::{
1010
DomainGoal,
11+
WhereClause,
1112
Goal,
1213
GoalKind,
1314
Clause,
@@ -75,6 +76,23 @@ impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
7576
})
7677
);
7778

79+
// If we have a goal of the form `T: 'a` or `'a: 'b`, then just
80+
// assume it is true (no subgoals) and register it as a constraint
81+
// instead.
82+
match goal {
83+
DomainGoal::Holds(WhereClause::RegionOutlives(pred)) => {
84+
assert_eq!(ex_clause.subgoals.len(), 0);
85+
ex_clause.constraints.push(ty::OutlivesPredicate(pred.0.into(), pred.1));
86+
}
87+
88+
DomainGoal::Holds(WhereClause::TypeOutlives(pred)) => {
89+
assert_eq!(ex_clause.subgoals.len(), 0);
90+
ex_clause.constraints.push(ty::OutlivesPredicate(pred.0.into(), pred.1));
91+
}
92+
93+
_ => (),
94+
};
95+
7896
let canonical_ex_clause = self.canonicalize_ex_clause(&ex_clause);
7997
Ok(canonical_ex_clause)
8098
});
@@ -112,10 +130,8 @@ impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
112130
substitutor.relate(&answer_table_goal.value, &selected_goal)
113131
.map_err(|_| NoSolution)?;
114132

115-
let ex_clause = substitutor.ex_clause;
116-
117-
// FIXME: restore this later once we get better at handling regions
118-
// ex_clause.constraints.extend(answer_subst.constraints);
133+
let mut ex_clause = substitutor.ex_clause;
134+
ex_clause.constraints.extend(answer_subst.constraints);
119135

120136
debug!("apply_answer_subst: ex_clause = {:?}", ex_clause);
121137
Ok(ex_clause)

src/librustc_traits/lowering/environment.rs

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ use rustc::traits::{
1010
use rustc::ty::{self, TyCtxt, Ty};
1111
use rustc::hir::def_id::DefId;
1212
use rustc_data_structures::fx::FxHashSet;
13-
use super::Lower;
14-
use crate::generic_types;
15-
use std::iter;
1613

1714
struct ClauseVisitor<'set, 'a, 'tcx: 'a + 'set> {
1815
tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -38,30 +35,6 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
3835
);
3936
}
4037

41-
// forall<'a, T> { `Outlives(T: 'a) :- FromEnv(&'a T)` }
42-
ty::Ref(_, _, mutbl) => {
43-
let region = self.tcx.mk_region(
44-
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
45-
);
46-
let ty = generic_types::bound(self.tcx, 1);
47-
let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
48-
ty,
49-
mutbl,
50-
});
51-
52-
let from_env = DomainGoal::FromEnv(FromEnv::Ty(ref_ty));
53-
54-
let clause = ProgramClause {
55-
goal: ty::OutlivesPredicate(ty, region).lower(),
56-
hypotheses: self.tcx.mk_goals(
57-
iter::once(self.tcx.mk_goal(from_env.into_goal()))
58-
),
59-
category: ProgramClauseCategory::ImpliedBound,
60-
};
61-
let clause = Clause::ForAll(ty::Binder::bind(clause));
62-
self.round.insert(clause);
63-
}
64-
6538
ty::Dynamic(..) => {
6639
// FIXME: trait object rules are not yet implemented
6740
}
@@ -99,6 +72,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
9972
ty::RawPtr(..) |
10073
ty::FnPtr(..) |
10174
ty::Tuple(..) |
75+
ty::Ref(..) |
10276
ty::Never |
10377
ty::Infer(..) |
10478
ty::Placeholder(..) |

src/test/ui/chalkify/lower_env3.stderr

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error: program clause dump
44
LL | #[rustc_dump_env_program_clauses]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= note: forall<'^0, ^1> { TypeOutlives(^1: '^0) :- FromEnv(&^1). }
87
= note: forall<Self> { Implemented(Self: Foo) :- FromEnv(Self: Foo). }
98

109
error: program clause dump
@@ -13,7 +12,6 @@ error: program clause dump
1312
LL | #[rustc_dump_env_program_clauses]
1413
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1514
|
16-
= note: forall<'^0, ^1> { TypeOutlives(^1: '^0) :- FromEnv(&^1). }
1715
= note: forall<Self> { FromEnv(Self: std::marker::Sized) :- FromEnv(Self: std::clone::Clone). }
1816
= note: forall<Self> { Implemented(Self: std::clone::Clone) :- FromEnv(Self: std::clone::Clone). }
1917
= note: forall<Self> { Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized). }

0 commit comments

Comments
 (0)