From 0c4062a94d337a7482ebf1dbdc1ffa49f0a73b57 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Sun, 11 Mar 2018 14:01:01 +0000 Subject: [PATCH] import trait engine to typeck --- src/librustc/infer/mod.rs | 2 +- src/librustc/infer/outlives/bounds.rs | 2 +- src/librustc/traits/engine.rs | 29 ++++++++++--------- src/librustc/traits/fulfill.rs | 6 ++-- src/librustc/traits/mod.rs | 1 + src/librustc/traits/specialize/mod.rs | 2 +- src/librustc/traits/trans/mod.rs | 3 +- .../borrow_check/nll/type_check/mod.rs | 4 +-- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_traits/util.rs | 2 +- src/librustc_typeck/check/dropck.rs | 4 +-- src/librustc_typeck/check/mod.rs | 9 +++--- src/librustc_typeck/coherence/builtin.rs | 2 +- src/librustc_typeck/lib.rs | 5 ++-- 14 files changed, 38 insertions(+), 35 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index eb693ea3c6a5..fe919775da0b 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -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; diff --git a/src/librustc/infer/outlives/bounds.rs b/src/librustc/infer/outlives/bounds.rs index 8bb3f4158ff5..4bc64acc7630 100644 --- a/src/librustc/infer/outlives/bounds.rs +++ b/src/librustc/infer/outlives/bounds.rs @@ -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; diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs index 17cd7d8d9c7c..317fe2cc2739 100644 --- a/src/librustc/traits/engine.rs +++ b/src/librustc/traits/engine.rs @@ -16,13 +16,6 @@ use super::{FulfillmentContext, FulfillmentError}; use super::{ObligationCause, PredicateObligation, PendingPredicateObligation}; pub trait TraitEngine<'tcx> { - /// "Normalize" a projection type `::X` by - /// creating a fresh type variable `$0` as well as a projection - /// predicate `::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>; } -impl<'tcx> dyn TraitEngine<'tcx> { - pub fn new(_tcx: TyCtxt<'_, '_, 'tcx>) -> Box { - Box::new(FulfillmentContext::new()) - } +impl<'a, 'gcx, 'tcx> dyn TraitEngine<'tcx> +'tcx { + pub fn new(_tcx: TyCtxt<'_, '_, 'tcx>) -> Box + { + Box::new(FulfillmentContext::new()) + } + + pub fn register_predicate_obligations(&mut self, + infcx: &InferCtxt<'a, 'gcx, 'tcx>, + obligations: I) + where I: IntoIterator> + { + for obligation in obligations { + self.register_predicate_obligation(infcx, obligation); + } + } } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 3e4c4b2cae05..1c091d68a2ef 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -85,7 +85,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> { register_region_obligations: false } } - + pub fn register_predicate_obligations(&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>> + infcx: &InferCtxt<'a, 'gcx, 'tcx>) + -> Result<(),Vec>> { self.select_where_possible(infcx)?; diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 64b939dddc98..1d5d3e41c9c9 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -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; diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 5ea089abb8e8..a9d1c8bcc3d9 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -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; diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs index ba39d7961470..31e851126d76 100644 --- a/src/librustc/traits/trans/mod.rs +++ b/src/librustc/traits/trans/mod.rs @@ -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; diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 022831b5a925..b9ba0af2346b 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -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) { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 59a872a23b06..8fe9f6bad1b3 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -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; diff --git a/src/librustc_traits/util.rs b/src/librustc_traits/util.rs index 976eb442a0d1..bff070ab73de 100644 --- a/src/librustc_traits/util.rs +++ b/src/librustc_traits/util.rs @@ -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; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 3a13e2fe2944..d508b6df924c 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3ecdb4e5cece..2336742968b9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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); } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 9700aa6bc54a..8a1f827749a7 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -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`. let cause = traits::ObligationCause::misc(span, impl_node_id); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 7f61ecb83dbb..de81de59a053 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -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);