Skip to content

Commit

Permalink
rustc_typeck: move some obligation methods to Inherited.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Apr 15, 2017
1 parent 2ad1964 commit 516570f
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 113 deletions.
39 changes: 0 additions & 39 deletions src/librustc_typeck/check/assoc.rs

This file was deleted.

64 changes: 25 additions & 39 deletions src/librustc_typeck/check/compare_method.rs
Expand Up @@ -20,7 +20,6 @@ use rustc::util::common::ErrorReported;
use syntax::ast;
use syntax_pos::Span;

use super::assoc;
use super::{Inherited, FnCtxt};
use astconv::ExplicitSelf;

Expand Down Expand Up @@ -227,7 +226,6 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
tcx.infer_ctxt(trait_param_env, Reveal::UserFacing).enter(|infcx| {
let inh = Inherited::new(infcx);
let infcx = &inh.infcx;
let fulfillment_cx = &inh.fulfillment_cx;

debug!("compare_impl_method: caller_bounds={:?}",
infcx.parameter_environment.caller_bounds);
Expand All @@ -239,12 +237,11 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
infer::HigherRankedType,
&ty::Binder(impl_m_own_bounds.predicates));
for predicate in impl_m_own_bounds {
let traits::Normalized { value: predicate, .. } =
let traits::Normalized { value: predicate, obligations } =
traits::normalize(&mut selcx, normalize_cause.clone(), &predicate);

fulfillment_cx.borrow_mut().register_predicate_obligation(
&infcx,
traits::Obligation::new(cause.clone(), predicate));
inh.register_predicates(obligations);
inh.register_predicate(traits::Obligation::new(cause.clone(), predicate));
}

// We now need to check that the signature of the impl method is
Expand Down Expand Up @@ -277,11 +274,9 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let impl_sig =
impl_sig.subst(tcx, impl_to_skol_substs);
let impl_sig =
assoc::normalize_associated_types_in(&infcx,
&mut fulfillment_cx.borrow_mut(),
impl_m_span,
impl_m_body_id,
&impl_sig);
inh.normalize_associated_types_in(impl_m_span,
impl_m_body_id,
&impl_sig);
let impl_fty = tcx.mk_fn_ptr(ty::Binder(impl_sig));
debug!("compare_impl_method: impl_fty={:?}", impl_fty);

Expand All @@ -291,11 +286,9 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let trait_sig =
trait_sig.subst(tcx, trait_to_skol_substs);
let trait_sig =
assoc::normalize_associated_types_in(&infcx,
&mut fulfillment_cx.borrow_mut(),
impl_m_span,
impl_m_body_id,
&trait_sig);
inh.normalize_associated_types_in(impl_m_span,
impl_m_body_id,
&trait_sig);
let trait_fty = tcx.mk_fn_ptr(ty::Binder(trait_sig));

debug!("compare_impl_method: trait_fty={:?}", trait_fty);
Expand Down Expand Up @@ -344,7 +337,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

// Check that all obligations are satisfied by the implementation's
// version.
if let Err(ref errors) = fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
infcx.report_fulfillment_errors(errors);
return Err(ErrorReported);
}
Expand Down Expand Up @@ -731,7 +724,8 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
debug!("compare_const_impl(impl_trait_ref={:?})", impl_trait_ref);

tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
let mut fulfillment_cx = traits::FulfillmentContext::new();
let inh = Inherited::new(infcx);
let infcx = &inh.infcx;

// The below is for the most part highly similar to the procedure
// for methods above. It is simpler in many respects, especially
Expand Down Expand Up @@ -761,31 +755,21 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let trait_ty = tcx.item_type(trait_c.def_id).subst(tcx, trait_to_skol_substs);
let mut cause = ObligationCause::misc(impl_c_span, impl_c_node_id);

let err = infcx.commit_if_ok(|_| {
// There is no "body" here, so just pass dummy id.
let impl_ty = assoc::normalize_associated_types_in(&infcx,
&mut fulfillment_cx,
impl_c_span,
ast::CRATE_NODE_ID,
&impl_ty);
// There is no "body" here, so just pass dummy id.
let impl_ty = inh.normalize_associated_types_in(impl_c_span,
impl_c_node_id,
&impl_ty);

debug!("compare_const_impl: impl_ty={:?}", impl_ty);
debug!("compare_const_impl: impl_ty={:?}", impl_ty);

let trait_ty = assoc::normalize_associated_types_in(&infcx,
&mut fulfillment_cx,
impl_c_span,
ast::CRATE_NODE_ID,
&trait_ty);
let trait_ty = inh.normalize_associated_types_in(impl_c_span,
impl_c_node_id,
&trait_ty);

debug!("compare_const_impl: trait_ty={:?}", trait_ty);
debug!("compare_const_impl: trait_ty={:?}", trait_ty);

infcx.sub_types(false, &cause, impl_ty, trait_ty)
.map(|InferOk { obligations, value: () }| {
for obligation in obligations {
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
}
})
});
let err = infcx.sub_types(false, &cause, impl_ty, trait_ty)
.map(|ok| inh.register_infer_ok_obligations(ok));

if let Err(terr) = err {
debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}",
Expand Down Expand Up @@ -822,5 +806,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
&terr);
diag.emit();
}

// FIXME(#41323) Check the obligations in the fulfillment context.
});
}
78 changes: 43 additions & 35 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -129,7 +129,6 @@ use rustc_back::slice;
use rustc_const_eval::eval_length;
use rustc_const_math::ConstInt;

mod assoc;
mod autoderef;
pub mod dropck;
pub mod _match;
Expand Down Expand Up @@ -537,7 +536,7 @@ impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> {
}

impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>) -> Self {
Inherited {
infcx: infcx,
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()),
Expand All @@ -548,20 +547,55 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
}
}

fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
debug!("register_predicate({:?})", obligation);
if obligation.has_escaping_regions() {
span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
obligation);
}
self.fulfillment_cx
.borrow_mut()
.register_predicate_obligation(self, obligation);
}

fn register_predicates(&self, obligations: Vec<traits::PredicateObligation<'tcx>>) {
for obligation in obligations {
self.register_predicate(obligation);
}
}

fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
self.register_predicates(infer_ok.obligations);
infer_ok.value
}

fn normalize_associated_types_in<T>(&self,
span: Span,
body_id: ast::NodeId,
value: &T)
-> T
value: &T) -> T
where T : TypeFoldable<'tcx>
{
assoc::normalize_associated_types_in(self,
&mut self.fulfillment_cx.borrow_mut(),
span,
body_id,
value)
let ok = self.normalize_associated_types_in_as_infer_ok(span, body_id, value);
self.register_infer_ok_obligations(ok)
}

fn normalize_associated_types_in_as_infer_ok<T>(&self,
span: Span,
body_id: ast::NodeId,
value: &T)
-> InferOk<'tcx, T>
where T : TypeFoldable<'tcx>
{
debug!("normalize_associated_types_in(value={:?})", value);
let mut selcx = traits::SelectionContext::new(self);
let cause = ObligationCause::misc(span, body_id);
let traits::Normalized { value, obligations } =
traits::normalize(&mut selcx, cause, value);
debug!("normalize_associated_types_in: result={:?} predicates={:?}",
value,
obligations);
InferOk { value, obligations }
}
}

struct CheckItemTypesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx> }
Expand Down Expand Up @@ -1806,32 +1840,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
.register_bound(self, ty, def_id, cause);
}

pub fn register_predicate(&self,
obligation: traits::PredicateObligation<'tcx>)
{
debug!("register_predicate({:?})", obligation);
if obligation.has_escaping_regions() {
span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
obligation);
}
self.fulfillment_cx
.borrow_mut()
.register_predicate_obligation(self, obligation);
}

pub fn register_predicates(&self,
obligations: Vec<traits::PredicateObligation<'tcx>>)
{
for obligation in obligations {
self.register_predicate(obligation);
}
}

pub fn register_infer_ok_obligations<T>(&self, infer_ok: InferOk<'tcx, T>) -> T {
self.register_predicates(infer_ok.obligations);
infer_ok.value
}

pub fn to_ty(&self, ast_t: &hir::Ty) -> Ty<'tcx> {
let t = AstConv::ast_ty_to_ty(self, ast_t);
self.register_wf_obligation(t, ast_t.span, traits::MiscObligation);
Expand Down

0 comments on commit 516570f

Please sign in to comment.