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));
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)) => {
ty::Error |
ty::Never => {
let wf_clause = ProgramClause {
- goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
+ goal,
hypotheses: ty::List::empty(),
category: ProgramClauseCategory::WellFormed,
};
use rustc::infer::canonical::{Canonical, CanonicalVarValues};
use rustc::traits::{
DomainGoal,
+ WhereClause,
Goal,
GoalKind,
Clause,
})
);
+ // 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)
});
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)
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>,
);
}
- // 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
}
ty::RawPtr(..) |
ty::FnPtr(..) |
ty::Tuple(..) |
+ ty::Ref(..) |
ty::Never |
ty::Infer(..) |
ty::Placeholder(..) |
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
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). }