rustc_typeck: move some obligation methods to Inherited.
This commit is contained in:
parent
2ad196444b
commit
516570f2d6
@ -1,39 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::traits::{self, FulfillmentContext, Normalized, MiscObligation, SelectionContext,
|
||||
ObligationCause};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
||||
// FIXME(@jroesch): Ideally we should be able to drop the fulfillment_cx argument.
|
||||
pub fn normalize_associated_types_in<'a, 'gcx, 'tcx, T>(
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
fulfillment_cx: &mut FulfillmentContext<'tcx>,
|
||||
span: Span,
|
||||
body_id: ast::NodeId,
|
||||
value: &T) -> T
|
||||
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
debug!("normalize_associated_types_in(value={:?})", value);
|
||||
let mut selcx = SelectionContext::new(infcx);
|
||||
let cause = ObligationCause::new(span, body_id, MiscObligation);
|
||||
let Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, value);
|
||||
debug!("normalize_associated_types_in: result={:?} predicates={:?}",
|
||||
result,
|
||||
obligations);
|
||||
for obligation in obligations {
|
||||
fulfillment_cx.register_predicate_obligation(infcx, obligation);
|
||||
}
|
||||
result
|
||||
}
|
@ -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;
|
||||
|
||||
@ -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);
|
||||
@ -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
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
}
|
||||
@ -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
|
||||
@ -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 {:?}",
|
||||
@ -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.
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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()),
|
||||
@ -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> }
|
||||
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user