import trait engine to typeck
This commit is contained in:
parent
20703b3d09
commit
0c4062a94d
14 changed files with 38 additions and 35 deletions
|
@ -27,7 +27,7 @@ use ty::{self, Ty, TyCtxt};
|
|||
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
|
||||
use ty::fold::TypeFoldable;
|
||||
use ty::relate::RelateResult;
|
||||
use traits::{self, ObligationCause, PredicateObligations, TraitEngine};
|
||||
use traits::{self, ObligationCause, PredicateObligations};
|
||||
use rustc_data_structures::unify as ut;
|
||||
use std::cell::{Cell, RefCell, Ref, RefMut};
|
||||
use std::collections::BTreeMap;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
use infer::InferCtxt;
|
||||
use syntax::ast;
|
||||
use syntax::codemap::Span;
|
||||
use traits::FulfillmentContext;
|
||||
use traits::{FulfillmentContext, TraitEngine};
|
||||
use ty::{self, Ty, TypeFoldable};
|
||||
use ty::outlives::Component;
|
||||
use ty::wf;
|
||||
|
|
|
@ -16,13 +16,6 @@ use super::{FulfillmentContext, FulfillmentError};
|
|||
use super::{ObligationCause, PredicateObligation, PendingPredicateObligation};
|
||||
|
||||
pub trait TraitEngine<'tcx> {
|
||||
/// "Normalize" a projection type `<SomeType as SomeTrait>::X` by
|
||||
/// creating a fresh type variable `$0` as well as a projection
|
||||
/// predicate `<SomeType as SomeTrait>::X == $0`. When the
|
||||
/// inference engine runs, it will attempt to find an impl of
|
||||
/// `SomeTrait` or a where clause that lets us unify `$0` with
|
||||
/// something concrete. If this fails, we'll unify `$0` with
|
||||
/// `projection_ty` again.
|
||||
fn normalize_projection_type<'a, 'gcx>(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
|
@ -31,9 +24,6 @@ pub trait TraitEngine<'tcx> {
|
|||
cause: ObligationCause<'tcx>,
|
||||
) -> Ty<'tcx>;
|
||||
|
||||
/// Requires that `ty` must implement the trait with `def_id` in
|
||||
/// the given environment. This trait must not have any type
|
||||
/// parameters (except for `Self`).
|
||||
fn register_bound<'a, 'gcx>(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
|
@ -62,8 +52,19 @@ pub trait TraitEngine<'tcx> {
|
|||
fn pending_obligations(&self) -> Vec<PendingPredicateObligation<'tcx>>;
|
||||
}
|
||||
|
||||
impl<'tcx> dyn TraitEngine<'tcx> {
|
||||
pub fn new(_tcx: TyCtxt<'_, '_, 'tcx>) -> Box<Self> {
|
||||
Box::new(FulfillmentContext::new())
|
||||
}
|
||||
impl<'a, 'gcx, 'tcx> dyn TraitEngine<'tcx> +'tcx {
|
||||
pub fn new(_tcx: TyCtxt<'_, '_, 'tcx>) -> Box<Self + 'tcx>
|
||||
{
|
||||
Box::new(FulfillmentContext::new())
|
||||
}
|
||||
|
||||
pub fn register_predicate_obligations<I>(&mut self,
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
obligations: I)
|
||||
where I: IntoIterator<Item = PredicateObligation<'tcx>>
|
||||
{
|
||||
for obligation in obligations {
|
||||
self.register_predicate_obligation(infcx, obligation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
|
|||
register_region_obligations: false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn register_predicate_obligations<I>(&mut self,
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
obligations: I)
|
||||
|
@ -217,8 +217,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
|||
}
|
||||
|
||||
fn select_all_or_error<'a, 'gcx>(&mut self,
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>)
|
||||
-> Result<(),Vec<FulfillmentError<'tcx>>>
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>)
|
||||
-> Result<(),Vec<FulfillmentError<'tcx>>>
|
||||
{
|
||||
self.select_where_possible(infcx)?;
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
|
|||
pub use self::select::IntercrateAmbiguityCause;
|
||||
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
|
||||
pub use self::specialize::{SpecializesCache, find_associated_item};
|
||||
pub use self::engine::TraitEngine;
|
||||
pub use self::util::elaborate_predicates;
|
||||
pub use self::util::supertraits;
|
||||
pub use self::util::Supertraits;
|
||||
|
|
|
@ -26,7 +26,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
|||
use hir::def_id::DefId;
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use ty::subst::{Subst, Substs};
|
||||
use traits::{self, ObligationCause};
|
||||
use traits::{self, ObligationCause, TraitEngine};
|
||||
use traits::select::IntercrateAmbiguityCause;
|
||||
use ty::{self, TyCtxt, TypeFoldable};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
|
|
|
@ -18,7 +18,8 @@ use std::marker::PhantomData;
|
|||
use syntax_pos::DUMMY_SP;
|
||||
use infer::InferCtxt;
|
||||
use syntax_pos::Span;
|
||||
use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, TraitEngine, Vtable};
|
||||
use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext,
|
||||
TraitEngine, Vtable};
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::subst::{Subst, Substs};
|
||||
use ty::fold::TypeFoldable;
|
||||
|
|
|
@ -20,7 +20,7 @@ use dataflow::move_paths::MoveData;
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::{InferCtxt, InferOk, InferResult, LateBoundRegionConversionTime, UnitResult};
|
||||
use rustc::infer::region_constraints::{GenericKind, RegionConstraintData};
|
||||
use rustc::traits::{self, Normalized, FulfillmentContext};
|
||||
use rustc::traits::{self, Normalized, TraitEngine};
|
||||
use rustc::traits::query::NoSolution;
|
||||
use rustc::ty::error::TypeError;
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
|
@ -662,7 +662,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
where
|
||||
OP: FnOnce(&mut Self) -> InferResult<'tcx, R>,
|
||||
{
|
||||
let mut fulfill_cx = FulfillmentContext::new();
|
||||
let mut fulfill_cx = TraitEngine::new(self.infcx.tcx);
|
||||
let InferOk { value, obligations } = self.infcx.commit_if_ok(|_| op(self))?;
|
||||
fulfill_cx.register_predicate_obligations(self.infcx, obligations);
|
||||
if let Err(e) = fulfill_cx.select_all_or_error(self.infcx) {
|
||||
|
|
|
@ -21,7 +21,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::traits;
|
||||
use rustc::traits::{self, TraitEngine};
|
||||
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
|
||||
use rustc::ty::cast::CastTy;
|
||||
use rustc::ty::maps::Providers;
|
||||
|
|
|
@ -12,7 +12,7 @@ use rustc::infer::InferCtxt;
|
|||
use rustc::infer::canonical::{CanonicalVarValues, Canonicalize, Certainty, QueryRegionConstraints,
|
||||
QueryResult};
|
||||
use rustc::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use rustc::traits::FulfillmentContext;
|
||||
use rustc::traits::{FulfillmentContext, TraitEngine};
|
||||
use rustc::traits::query::NoSolution;
|
||||
use rustc::ty;
|
||||
use std::fmt::Debug;
|
||||
|
|
|
@ -16,7 +16,7 @@ use rustc::infer::outlives::env::OutlivesEnvironment;
|
|||
use rustc::middle::region;
|
||||
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::traits::{self, ObligationCause, TraitEngine};
|
||||
use rustc::traits::{ObligationCause, TraitEngine};
|
||||
use util::common::ErrorReported;
|
||||
|
||||
use syntax::ast;
|
||||
|
@ -84,7 +84,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
|
|||
tcx.infer_ctxt().enter(|ref infcx| {
|
||||
let impl_param_env = tcx.param_env(self_type_did);
|
||||
let tcx = infcx.tcx;
|
||||
let mut fulfillment_cx = TraitEngine::new();
|
||||
let mut fulfillment_cx = TraitEngine::new(tcx);
|
||||
|
||||
let named_type = tcx.type_of(self_type_did);
|
||||
|
||||
|
|
|
@ -95,8 +95,7 @@ use rustc::infer::type_variable::{TypeVariableOrigin};
|
|||
use rustc::middle::region;
|
||||
use rustc::mir::interpret::{GlobalId};
|
||||
use rustc::ty::subst::{Kind, Subst, Substs};
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode};
|
||||
use rustc::traits::engine::TraitEngine;
|
||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
|
||||
use rustc::ty::{self, Ty, TyCtxt, Visibility, ToPredicate};
|
||||
use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
|
@ -635,7 +634,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
|
|||
maybe_tables: infcx.in_progress_tables,
|
||||
},
|
||||
infcx,
|
||||
fulfillment_cx: RefCell::new(TraitEngine::new()),
|
||||
fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
|
||||
locals: RefCell::new(NodeMap()),
|
||||
deferred_call_resolutions: RefCell::new(DefIdMap()),
|
||||
deferred_cast_checks: RefCell::new(Vec::new()),
|
||||
|
@ -2883,7 +2882,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// is polymorphic) and the expected return type.
|
||||
// No argument expectations are produced if unification fails.
|
||||
let origin = self.misc(call_span);
|
||||
let ures = self.at(&origin, self.param_env).sup(ret_ty, formal_ret);
|
||||
let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
|
||||
|
||||
// FIXME(#27336) can't use ? here, Try::from_error doesn't default
|
||||
// to identity so the resulting type is not constrained.
|
||||
|
@ -2894,7 +2893,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// out unconstrained or ambiguous, as we're
|
||||
// just trying to get hints here.
|
||||
self.save_and_restore_in_snapshot_flag(|_| {
|
||||
let mut fulfill = TraitEngine::new();
|
||||
let mut fulfill = TraitEngine::new(self.tcx);
|
||||
for obligation in ok.obligations {
|
||||
fulfill.register_predicate_obligation(self, obligation);
|
||||
}
|
||||
|
|
|
@ -372,7 +372,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
}
|
||||
};
|
||||
|
||||
let mut fulfill_cx = TraitEngine::new();
|
||||
let mut fulfill_cx = TraitEngine::new(tcx);
|
||||
|
||||
// Register an obligation for `A: Trait<B>`.
|
||||
let cause = traits::ObligationCause::misc(span, impl_node_id);
|
||||
|
|
|
@ -88,6 +88,7 @@ This API is completely unstable and subject to change.
|
|||
#![feature(slice_patterns)]
|
||||
#![feature(i128_type)]
|
||||
#![cfg_attr(stage0, feature(never_type))]
|
||||
#![feature(dyn_trait)]
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
|
@ -111,7 +112,7 @@ use rustc::infer::InferOk;
|
|||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, TraitEngine};
|
||||
use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine};
|
||||
use session::{CompileIncomplete, config};
|
||||
use util::common::time;
|
||||
|
||||
|
@ -160,7 +161,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
-> bool {
|
||||
tcx.infer_ctxt().enter(|ref infcx| {
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let mut fulfill_cx = TraitEngine::new();
|
||||
let mut fulfill_cx = TraitEngine::new(infcx.tcx);
|
||||
match infcx.at(&cause, param_env).eq(expected, actual) {
|
||||
Ok(InferOk { obligations, .. }) => {
|
||||
fulfill_cx.register_predicate_obligations(infcx, obligations);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue