Skip to content

Commit

Permalink
Gather region constraints not coming from unification
Browse files Browse the repository at this point in the history
  • Loading branch information
scalexm committed Mar 20, 2019
1 parent c3b33a7 commit 60ea7cb
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 57 deletions.
37 changes: 13 additions & 24 deletions src/librustc_traits/chalk_context/program_clauses.rs
Expand Up @@ -326,15 +326,12 @@ fn wf_clause_for_ref<'tcx>(
mutbl,
});

let _outlives: DomainGoal<'_> = ty::OutlivesPredicate(ty, region).lower();
let outlives: DomainGoal<'_> = ty::OutlivesPredicate(ty, region).lower();
let wf_clause = ProgramClause {
goal: DomainGoal::WellFormed(WellFormed::Ty(ref_ty)),
hypotheses: ty::List::empty(),

// FIXME: restore this later once we get better at handling regions
// hypotheses: tcx.mk_goals(
// iter::once(tcx.mk_goal(outlives.into_goal()))
// ),
hypotheses: tcx.mk_goals(
iter::once(tcx.mk_goal(outlives.into_goal()))
),
category: ProgramClauseCategory::WellFormed,
};
let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
Expand Down Expand Up @@ -432,22 +429,14 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
clauses
}

DomainGoal::Holds(RegionOutlives(..)) => {
// These come from:
// * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
// * implied bounds from type definitions (rule `Implied-Bound-From-Type`)

// All of these rules are computed in the environment.
vec![]
}

DomainGoal::Holds(TypeOutlives(..)) => {
// These come from:
// * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
// * implied bounds from type definitions (rule `Implied-Bound-From-Type`)

// All of these rules are computed in the environment.
vec![]
// For outlive requirements, just assume they hold. `ResolventOps::resolvent_clause`
// will register them as actual region constraints later.
DomainGoal::Holds(RegionOutlives(..)) | DomainGoal::Holds(TypeOutlives(..)) => {
vec![Clause::Implies(ProgramClause {
goal,
hypotheses: ty::List::empty(),
category: ProgramClauseCategory::Other,
})]
}

DomainGoal::WellFormed(WellFormed::Trait(trait_predicate)) => {
Expand Down Expand Up @@ -485,7 +474,7 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
ty::Error |
ty::Never => {
let wf_clause = ProgramClause {
goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
goal,
hypotheses: ty::List::empty(),
category: ProgramClauseCategory::WellFormed,
};
Expand Down
24 changes: 20 additions & 4 deletions src/librustc_traits/chalk_context/resolvent_ops.rs
Expand Up @@ -8,6 +8,7 @@ use rustc::infer::{InferCtxt, LateBoundRegionConversionTime};
use rustc::infer::canonical::{Canonical, CanonicalVarValues};
use rustc::traits::{
DomainGoal,
WhereClause,
Goal,
GoalKind,
Clause,
Expand Down Expand Up @@ -75,6 +76,23 @@ impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
})
);

// If we have a goal of the form `T: 'a` or `'a: 'b`, then just
// assume it is true (no subgoals) and register it as a constraint
// instead.
match goal {
DomainGoal::Holds(WhereClause::RegionOutlives(pred)) => {
assert_eq!(ex_clause.subgoals.len(), 0);
ex_clause.constraints.push(ty::OutlivesPredicate(pred.0.into(), pred.1));
}

DomainGoal::Holds(WhereClause::TypeOutlives(pred)) => {
assert_eq!(ex_clause.subgoals.len(), 0);
ex_clause.constraints.push(ty::OutlivesPredicate(pred.0.into(), pred.1));
}

_ => (),
};

let canonical_ex_clause = self.canonicalize_ex_clause(&ex_clause);
Ok(canonical_ex_clause)
});
Expand Down Expand Up @@ -112,10 +130,8 @@ impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
substitutor.relate(&answer_table_goal.value, &selected_goal)
.map_err(|_| NoSolution)?;

let ex_clause = substitutor.ex_clause;

// FIXME: restore this later once we get better at handling regions
// ex_clause.constraints.extend(answer_subst.constraints);
let mut ex_clause = substitutor.ex_clause;
ex_clause.constraints.extend(answer_subst.constraints);

debug!("apply_answer_subst: ex_clause = {:?}", ex_clause);
Ok(ex_clause)
Expand Down
28 changes: 1 addition & 27 deletions src/librustc_traits/lowering/environment.rs
Expand Up @@ -10,9 +10,6 @@ use rustc::traits::{
use rustc::ty::{self, TyCtxt, Ty};
use rustc::hir::def_id::DefId;
use rustc_data_structures::fx::FxHashSet;
use super::Lower;
use crate::generic_types;
use std::iter;

struct ClauseVisitor<'set, 'a, 'tcx: 'a + 'set> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
Expand All @@ -38,30 +35,6 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
);
}

// forall<'a, T> { `Outlives(T: 'a) :- FromEnv(&'a T)` }
ty::Ref(_, _, mutbl) => {
let region = self.tcx.mk_region(
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
);
let ty = generic_types::bound(self.tcx, 1);
let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
ty,
mutbl,
});

let from_env = DomainGoal::FromEnv(FromEnv::Ty(ref_ty));

let clause = ProgramClause {
goal: ty::OutlivesPredicate(ty, region).lower(),
hypotheses: self.tcx.mk_goals(
iter::once(self.tcx.mk_goal(from_env.into_goal()))
),
category: ProgramClauseCategory::ImpliedBound,
};
let clause = Clause::ForAll(ty::Binder::bind(clause));
self.round.insert(clause);
}

ty::Dynamic(..) => {
// FIXME: trait object rules are not yet implemented
}
Expand Down Expand Up @@ -99,6 +72,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
ty::RawPtr(..) |
ty::FnPtr(..) |
ty::Tuple(..) |
ty::Ref(..) |
ty::Never |
ty::Infer(..) |
ty::Placeholder(..) |
Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/chalkify/lower_env3.stderr
Expand Up @@ -4,7 +4,6 @@ error: program clause dump
LL | #[rustc_dump_env_program_clauses]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: forall<'^0, ^1> { TypeOutlives(^1: '^0) :- FromEnv(&^1). }
= note: forall<Self> { Implemented(Self: Foo) :- FromEnv(Self: Foo). }

error: program clause dump
Expand All @@ -13,7 +12,6 @@ error: program clause dump
LL | #[rustc_dump_env_program_clauses]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: forall<'^0, ^1> { TypeOutlives(^1: '^0) :- FromEnv(&^1). }
= note: forall<Self> { FromEnv(Self: std::marker::Sized) :- FromEnv(Self: std::clone::Clone). }
= note: forall<Self> { Implemented(Self: std::clone::Clone) :- FromEnv(Self: std::clone::Clone). }
= note: forall<Self> { Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized). }
Expand Down

0 comments on commit 60ea7cb

Please sign in to comment.