Skip to content

Commit

Permalink
introduce PredicateKind<'tcx> and construct predicates via tcx
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Sep 13, 2017
1 parent 2dd5bb2 commit 8cea848
Show file tree
Hide file tree
Showing 35 changed files with 443 additions and 413 deletions.
18 changes: 9 additions & 9 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,29 +206,29 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for ty::Pr
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
ty::Predicate::Trait(ref pred) => {
match self.kind {
ty::PredicateKind::Trait(ref pred) => {
pred.hash_stable(hcx, hasher);
}
ty::Predicate::Subtype(ref pred) => {
ty::PredicateKind::Subtype(ref pred) => {
pred.hash_stable(hcx, hasher);
}
ty::Predicate::RegionOutlives(ref pred) => {
ty::PredicateKind::RegionOutlives(ref pred) => {
pred.hash_stable(hcx, hasher);
}
ty::Predicate::TypeOutlives(ref pred) => {
ty::PredicateKind::TypeOutlives(ref pred) => {
pred.hash_stable(hcx, hasher);
}
ty::Predicate::Projection(ref pred) => {
ty::PredicateKind::Projection(ref pred) => {
pred.hash_stable(hcx, hasher);
}
ty::Predicate::WellFormed(ty) => {
ty::PredicateKind::WellFormed(ty) => {
ty.hash_stable(hcx, hasher);
}
ty::Predicate::ObjectSafe(def_id) => {
ty::PredicateKind::ObjectSafe(def_id) => {
def_id.hash_stable(hcx, hasher);
}
ty::Predicate::ClosureKind(def_id, closure_kind) => {
ty::PredicateKind::ClosureKind(def_id, closure_kind) => {
def_id.hash_stable(hcx, hasher);
closure_kind.hash_stable(hcx, hasher);
}
Expand Down
9 changes: 5 additions & 4 deletions src/librustc/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use ty::{self, Ty, TyCtxt};
use ty::error::TypeError;
use ty::relate::{self, Relate, RelateResult, TypeRelation};
use ty::subst::Substs;
use traits::{Obligation, PredicateObligations};
use traits::{PredicateObligations};

use syntax::ast;
use syntax_pos::Span;
Expand Down Expand Up @@ -204,6 +204,7 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
-> RelateResult<'tcx, ()>
{
use self::RelationDir::*;
let tcx = self.tcx();

// Get the actual variable that b_vid has been inferred to
debug_assert!(self.infcx.type_variables.borrow_mut().probe(b_vid).is_unknown());
Expand All @@ -227,9 +228,9 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
self.infcx.type_variables.borrow_mut().instantiate(b_vid, b_ty);

if needs_wf {
self.obligations.push(Obligation::new(self.trace.cause.clone(),
param_env,
ty::Predicate::WellFormed(b_ty)));
self.obligations.push(tcx.predicate_obligation(self.trace.cause.clone(),
param_env,
ty::PredicateKind::WellFormed(b_ty)));
}

// Finally, relate `b_ty` to `a_ty`, as described in previous comment.
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/infer/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use super::SubregionOrigin;
use super::combine::{CombineFields, RelationDir};

use traits::Obligation;
use ty::{self, Ty, TyCtxt};
use ty::TyVar;
use ty::fold::TypeFoldable;
Expand Down Expand Up @@ -80,6 +79,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
if a == b { return Ok(a); }

let infcx = self.fields.infcx;
let tcx = infcx.tcx;
let a = infcx.type_variables.borrow_mut().replace_if_possible(a);
let b = infcx.type_variables.borrow_mut().replace_if_possible(b);
match (&a.sty, &b.sty) {
Expand All @@ -97,10 +97,10 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
// is important to the occurs check later on.
infcx.type_variables.borrow_mut().sub(a_vid, b_vid);
self.fields.obligations.push(
Obligation::new(
tcx.predicate_obligation(
self.fields.trace.cause.clone(),
self.param_env,
ty::Predicate::Subtype(
ty::PredicateKind::Subtype(
ty::Binder(ty::SubtypePredicate {
a_is_expected: self.a_is_expected,
a,
Expand Down
18 changes: 9 additions & 9 deletions src/librustc/middle/free_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,17 @@ impl<'tcx> FreeRegionMap<'tcx> {
predicates: &[ty::Predicate<'tcx>]) {
debug!("relate_free_regions_from_predicates(predicates={:?})", predicates);
for predicate in predicates {
match *predicate {
ty::Predicate::Projection(..) |
ty::Predicate::Trait(..) |
ty::Predicate::Subtype(..) |
ty::Predicate::WellFormed(..) |
ty::Predicate::ObjectSafe(..) |
ty::Predicate::ClosureKind(..) |
ty::Predicate::TypeOutlives(..) => {
match predicate.kind {
ty::PredicateKind::Projection(..) |
ty::PredicateKind::Trait(..) |
ty::PredicateKind::Subtype(..) |
ty::PredicateKind::WellFormed(..) |
ty::PredicateKind::ObjectSafe(..) |
ty::PredicateKind::ClosureKind(..) |
ty::PredicateKind::TypeOutlives(..) => {
// No region bounds here
}
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
ty::PredicateKind::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r_a, r_b))) => {
self.relate_regions(r_b, r_a);
}
}
Expand Down
48 changes: 23 additions & 25 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
return true
}

let (cond, error) = match (cond, error) {
(&ty::Predicate::Trait(..), &ty::Predicate::Trait(error))
let (cond, error) = match (&cond.kind, &error.kind) {
(&ty::PredicateKind::Trait(..), &ty::PredicateKind::Trait(error))
=> (cond, error),
_ => {
// FIXME: make this work in other cases too.
Expand All @@ -133,7 +133,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
};

for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) {
if let ty::Predicate::Trait(implication) = implication {
if let ty::PredicateKind::Trait(implication) = implication.kind {
// FIXME: I'm just not taking associated types at all here.
// Eventually I'll need to implement param-env-aware
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
Expand Down Expand Up @@ -191,7 +191,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
//
// this can fail if the problem was higher-ranked, in which
// cause I have no idea for a good error message.
if let ty::Predicate::Projection(ref data) = predicate {
if let ty::PredicateKind::Projection(ref data) = predicate.kind {
let mut selcx = SelectionContext::new(self);
let (data, _) = self.replace_late_bound_regions_with_fresh_var(
obligation.cause.span,
Expand Down Expand Up @@ -546,8 +546,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
.emit();
return;
}
match obligation.predicate {
ty::Predicate::Trait(ref trait_ref) => {
match obligation.predicate.kind {
ty::PredicateKind::Trait(ref trait_ref) => {
let trait_ref = self.resolve_type_vars_if_possible(trait_ref);

if self.tcx.sess.has_errors() && trait_ref.references_error() {
Expand All @@ -569,7 +569,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
"{}",
message.unwrap_or_else(|| {
format!("the trait bound `{}` is not satisfied{}",
trait_ref.to_predicate(), post_message)
trait_ref.to_predicate(self.tcx), post_message)
}));

if let Some(ref s) = label {
Expand Down Expand Up @@ -599,7 +599,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// "the type `T` can't be frobnicated"
// which is somewhat confusing.
err.help(&format!("consider adding a `where {}` bound",
trait_ref.to_predicate()));
trait_ref.to_predicate(self.tcx)));
} else if !have_alt_message {
// Can't show anything else useful, try to find similar impls.
let impl_candidates = self.find_similar_impl_candidates(trait_ref);
Expand All @@ -609,14 +609,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
err
}

ty::Predicate::Subtype(ref predicate) => {
ty::PredicateKind::Subtype(ref predicate) => {
// Errors for Subtype predicates show up as
// `FulfillmentErrorCode::CodeSubtypeError`,
// not selection error.
span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate)
}

ty::Predicate::RegionOutlives(ref predicate) => {
ty::PredicateKind::RegionOutlives(ref predicate) => {
let predicate = self.resolve_type_vars_if_possible(predicate);
let err = self.region_outlives_predicate(&obligation.cause,
obligation.param_env,
Expand All @@ -626,22 +626,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
predicate, err)
}

ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
ty::PredicateKind::Projection(..) | ty::PredicateKind::TypeOutlives(..) => {
let predicate =
self.resolve_type_vars_if_possible(&obligation.predicate);
struct_span_err!(self.tcx.sess, span, E0280,
"the requirement `{}` is not satisfied",
predicate)
}

ty::Predicate::ObjectSafe(trait_def_id) => {
ty::PredicateKind::ObjectSafe(trait_def_id) => {
let violations = self.tcx.object_safety_violations(trait_def_id);
self.tcx.report_object_safety_error(span,
trait_def_id,
violations)
}

ty::Predicate::ClosureKind(closure_def_id, kind) => {
ty::PredicateKind::ClosureKind(closure_def_id, kind) => {
let found_kind = self.closure_kind(closure_def_id).unwrap();
let closure_span = self.tcx.hir.span_if_local(closure_def_id).unwrap();
let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap();
Expand Down Expand Up @@ -680,7 +680,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
return;
}

ty::Predicate::WellFormed(ty) => {
ty::PredicateKind::WellFormed(ty) => {
// WF predicates cannot themselves make
// errors. They can only block due to
// ambiguity; otherwise, they always
Expand Down Expand Up @@ -876,8 +876,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
return;
}

match predicate {
ty::Predicate::Trait(trait_ref) => {
match predicate.kind {
ty::PredicateKind::Trait(trait_ref) => {
let self_ty = trait_ref.self_ty();
if predicate.references_error() {
return;
Expand Down Expand Up @@ -924,15 +924,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
}

ty::Predicate::WellFormed(ty) => {
ty::PredicateKind::WellFormed(ty) => {
// Same hacky approach as above to avoid deluging user
// with error messages.
if !ty.references_error() && !self.tcx.sess.has_errors() {
self.need_type_info(body_id, span, ty);
}
}

ty::Predicate::Subtype(ref data) => {
ty::PredicateKind::Subtype(ref data) => {
if data.references_error() || self.tcx.sess.has_errors() {
// no need to overload user in such cases
} else {
Expand Down Expand Up @@ -1007,11 +1007,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
&cleaned_pred
).value;

let obligation = Obligation::new(
ObligationCause::dummy(),
param_env,
cleaned_pred.to_predicate()
);
let obligation = self.tcx.predicate_obligation(ObligationCause::dummy(),
param_env,
cleaned_pred);

selcx.evaluate_obligation(&obligation)
})
Expand Down Expand Up @@ -1118,7 +1116,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
err.note(&format!("required because it appears within the type `{}`",
parent_trait_ref.self_ty()));
let parent_predicate = parent_trait_ref.to_predicate();
let parent_predicate = parent_trait_ref.to_predicate(self.tcx);
self.note_obligation_cause_code(err,
&parent_predicate,
&data.parent_code);
Expand All @@ -1129,7 +1127,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
&format!("required because of the requirements on the impl of `{}` for `{}`",
parent_trait_ref,
parent_trait_ref.self_ty()));
let parent_predicate = parent_trait_ref.to_predicate();
let parent_predicate = parent_trait_ref.to_predicate(self.tcx);
self.note_obligation_cause_code(err,
&parent_predicate,
&data.parent_code);
Expand Down
20 changes: 10 additions & 10 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
cause,
recursion_depth: 0,
param_env,
predicate: trait_ref.to_predicate()
predicate: trait_ref.to_predicate(infcx.tcx)
});
}

Expand Down Expand Up @@ -356,8 +356,8 @@ fn process_predicate<'a, 'gcx, 'tcx>(
obligation.predicate = selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate);
}

match obligation.predicate {
ty::Predicate::Trait(trait_ref) => {
match obligation.predicate.kind {
ty::PredicateKind::Trait(trait_ref) => {
let trait_obligation = obligation.with(trait_ref.clone());

if trait_ref.is_global() {
Expand Down Expand Up @@ -414,7 +414,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
}
}

ty::Predicate::RegionOutlives(ref binder) => {
ty::PredicateKind::RegionOutlives(ref binder) => {
match selcx.infcx().region_outlives_predicate(&obligation.cause,
obligation.param_env,
binder) {
Expand All @@ -423,7 +423,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
}
}

ty::Predicate::TypeOutlives(ref binder) => {
ty::PredicateKind::TypeOutlives(ref binder) => {
// Check if there are higher-ranked regions.
match selcx.tcx().no_late_bound_regions(binder) {
// If there are, inspect the underlying type further.
Expand Down Expand Up @@ -459,7 +459,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
}
}

ty::Predicate::Projection(ref data) => {
ty::PredicateKind::Projection(ref data) => {
let project_obligation = obligation.with(data.clone());
match project::poly_project_and_unify_type(selcx, &project_obligation) {
Ok(None) => {
Expand All @@ -473,15 +473,15 @@ fn process_predicate<'a, 'gcx, 'tcx>(
}
}

ty::Predicate::ObjectSafe(trait_def_id) => {
ty::PredicateKind::ObjectSafe(trait_def_id) => {
if !selcx.tcx().is_object_safe(trait_def_id) {
Err(CodeSelectionError(Unimplemented))
} else {
Ok(Some(Vec::new()))
}
}

ty::Predicate::ClosureKind(closure_def_id, kind) => {
ty::PredicateKind::ClosureKind(closure_def_id, kind) => {
match selcx.infcx().closure_kind(closure_def_id) {
Some(closure_kind) => {
if closure_kind.extends(kind) {
Expand All @@ -496,7 +496,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
}
}

ty::Predicate::WellFormed(ty) => {
ty::PredicateKind::WellFormed(ty) => {
match ty::wf::obligations(selcx.infcx(),
obligation.param_env,
obligation.cause.body_id,
Expand All @@ -509,7 +509,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
}
}

ty::Predicate::Subtype(ref subtype) => {
ty::PredicateKind::Subtype(ref subtype) => {
match selcx.infcx().subtype_predicate(&obligation.cause,
obligation.param_env,
subtype) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ pub fn type_known_to_meet_bound<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx
param_env,
cause: ObligationCause::misc(span, ast::DUMMY_NODE_ID),
recursion_depth: 0,
predicate: trait_ref.to_predicate(),
predicate: trait_ref.to_predicate(infcx.tcx),
};

let result = SelectionContext::new(infcx)
Expand Down
Loading

0 comments on commit 8cea848

Please sign in to comment.