Skip to content

Commit

Permalink
just use full-normalization when for the impl trait ref
Browse files Browse the repository at this point in the history
This seems better because I want to avoid the situation where unresolved
inference variables make it into the environment.  On the other hand, I
am not 100% sure that this is correct. My assumption was that the WF
check should ensure that this normalization can succeed. But it occurs
to me that the WF checks may need to make use of the `specializes`
predicate themselves, and hence we may have a kind of cycle here (this
is a bigger problem with spec in any case that we need to resolve).

On the other hand, this should just cause extra errors I think, so it
seems like a safe thing to attempt. Certainly all tests pass.
  • Loading branch information
nikomatsakis committed Nov 2, 2016
1 parent d9bc860 commit b4f910d
Showing 1 changed file with 10 additions and 15 deletions.
25 changes: 10 additions & 15 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use hir::def_id::DefId;
use infer::{InferCtxt, TypeOrigin};
use middle::region;
use ty::subst::{Subst, Substs};
use traits::{self, Reveal, ObligationCause, Normalized};
use traits::{self, Reveal, ObligationCause};
use ty::{self, TyCtxt, TypeFoldable};
use syntax_pos::DUMMY_SP;

Expand Down Expand Up @@ -187,21 +187,16 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
.subst(tcx, &penv.free_substs);

// Create a infcx, taking the predicates of impl1 as assumptions:
let result = tcx.infer_ctxt(None, Some(penv), Reveal::ExactMatch).enter(|mut infcx| {
// Normalize the trait reference, adding any obligations
// that arise into the impl1 assumptions.
let Normalized { value: impl1_trait_ref, obligations: normalization_obligations } = {
let selcx = &mut SelectionContext::new(&infcx);
traits::normalize(selcx, ObligationCause::dummy(), &impl1_trait_ref)
};
infcx.parameter_environment.caller_bounds.extend(normalization_obligations.into_iter().map(|o| {
match tcx.lift_to_global(&o.predicate) {
Some(predicate) => predicate,
None => {
bug!("specializes: obligation `{:?}` has inference types/regions", o);
let result = tcx.infer_ctxt(None, Some(penv), Reveal::ExactMatch).enter(|infcx| {
// Normalize the trait reference. The WF rules ought to ensure
// that this always succeeds.
let impl1_trait_ref =
match traits::fully_normalize(&infcx, ObligationCause::dummy(), &impl1_trait_ref) {
Ok(impl1_trait_ref) => impl1_trait_ref,
Err(err) => {
bug!("failed to fully normalize {:?}: {:?}", impl1_trait_ref, err);
}
}
}));
};

// Attempt to prove that impl2 applies, given all of the above.
fulfill_implication(&infcx, impl1_trait_ref, impl2_def_id).is_ok()
Expand Down

0 comments on commit b4f910d

Please sign in to comment.