diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index fe919775da0b4..a7997a291d201 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -404,43 +404,42 @@ impl fmt::Display for FixupError { /// Helper type of a temporary returned by tcx.infer_ctxt(). /// Necessary because we can't write the following bound: /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>). -pub struct InferCtxtBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { +pub struct InferCtxtBuilder<'a, 'gcx: 'a> { global_tcx: TyCtxt<'a, 'gcx, 'gcx>, arena: DroplessArena, - fresh_tables: Option>>, + fresh_table_owner: Option, } -impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { - pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> { +impl<'a, 'gcx> TyCtxt<'a, 'gcx, 'gcx> { + pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx> { InferCtxtBuilder { global_tcx: self, arena: DroplessArena::new(), - fresh_tables: None, - + fresh_table_owner: None, } } } -impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { +impl<'a, 'gcx> InferCtxtBuilder<'a, 'gcx> { /// Used only by `rustc_typeck` during body type-checking/inference, /// will initialize `in_progress_tables` with fresh `TypeckTables`. pub fn with_fresh_in_progress_tables(mut self, table_owner: DefId) -> Self { - self.fresh_tables = Some(RefCell::new(ty::TypeckTables::empty(Some(table_owner)))); + self.fresh_table_owner = Some(table_owner); self } - pub fn enter(&'tcx mut self, f: F) -> R - where F: for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R - { + pub fn enter<'tcx, R>(&'tcx mut self, f: impl FnOnce(&InferCtxt<'_, 'gcx, 'tcx>) -> R) -> R { let InferCtxtBuilder { global_tcx, ref arena, - ref fresh_tables, + fresh_table_owner, } = *self; - let in_progress_tables = fresh_tables.as_ref(); - global_tcx.enter_local(arena, |tcx| f(InferCtxt { + let in_progress_tables = fresh_table_owner.map(|table_owner| { + RefCell::new(ty::TypeckTables::empty(Some(table_owner))) + }); + global_tcx.enter_local(arena, |tcx| f(&InferCtxt { tcx, - in_progress_tables, + in_progress_tables: in_progress_tables.as_ref(), projection_cache: RefCell::new(traits::ProjectionCache::new()), type_variables: RefCell::new(type_variable::TypeVariableTable::new()), int_unification_table: RefCell::new(ut::UnificationTable::new()), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fd3465f59ebf2..0f72452df29c3 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1671,11 +1671,11 @@ pub mod tls { }) } - pub fn enter<'a, 'gcx: 'tcx, 'tcx, F, R>(gcx: &'a GlobalCtxt<'gcx>, - interners: &'a CtxtInterners<'tcx>, - f: F) -> R - where F: FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R - { + pub fn enter<'a, 'gcx: 'tcx, 'tcx, R>( + gcx: &'a GlobalCtxt<'gcx>, + interners: &'a CtxtInterners<'tcx>, + f: impl FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R, + ) -> R { let gcx_ptr = gcx as *const _ as *const ThreadLocalGlobalCtxt; let interners_ptr = interners as *const _ as *const ThreadLocalInterners; TLS_TCX.with(|tls| { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 18de8d1bee74e..5bfa7d0a1643d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -189,7 +189,7 @@ impl<'a, 'tcx> MaybeInProgressTables<'a, 'tcx> { /// `bar()` will each have their own `FnCtxt`, but they will /// share the inherited fields. pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - infcx: InferCtxt<'a, 'gcx, 'tcx>, + infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, tables: MaybeInProgressTables<'a, 'tcx>, @@ -587,14 +587,14 @@ impl<'a, 'gcx, 'tcx> Deref for FnCtxt<'a, 'gcx, 'tcx> { /// Helper type of a temporary returned by Inherited::build(...). /// Necessary because we can't write the following bound: /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(Inherited<'b, 'gcx, 'tcx>). -pub struct InheritedBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - infcx: infer::InferCtxtBuilder<'a, 'gcx, 'tcx>, +pub struct InheritedBuilder<'a, 'gcx: 'a> { + infcx: infer::InferCtxtBuilder<'a, 'gcx>, def_id: DefId, } impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { pub fn build(tcx: TyCtxt<'a, 'gcx, 'gcx>, def_id: DefId) - -> InheritedBuilder<'a, 'gcx, 'tcx> { + -> InheritedBuilder<'a, 'gcx> { let hir_id_root = if def_id.is_local() { let node_id = tcx.hir.as_local_node_id(def_id).unwrap(); let hir_id = tcx.hir.definitions().node_to_hir_id(node_id); @@ -610,17 +610,18 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx> InheritedBuilder<'a, 'gcx, 'tcx> { - fn enter(&'tcx mut self, f: F) -> R - where F: for<'b> FnOnce(Inherited<'b, 'gcx, 'tcx>) -> R - { +impl<'a, 'gcx> InheritedBuilder<'a, 'gcx> { + fn enter<'tcx, R>( + &'tcx mut self, + f: impl FnOnce(&Inherited<'_, 'gcx, 'tcx>) -> R, + ) -> R { let def_id = self.def_id; - self.infcx.enter(|infcx| f(Inherited::new(infcx, def_id))) + self.infcx.enter(|infcx| f(&Inherited::new(infcx, def_id))) } } impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> { - fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self { + fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> Self { let tcx = infcx.tcx; let item_id = tcx.hir.as_local_node_id(def_id); let body_id = item_id.and_then(|id| tcx.hir.maybe_body_owned_by(id)); diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d10ee358e0728..da82fbdabbc15 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -34,25 +34,28 @@ pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { /// Helper type of a temporary returned by .for_item(...). /// Necessary because we can't write the following bound: /// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>). -struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { - inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>, +struct CheckWfFcxBuilder<'a, 'gcx: 'a> { + inherited: super::InheritedBuilder<'a, 'gcx>, code: ObligationCauseCode<'gcx>, id: ast::NodeId, span: Span, - param_env: ty::ParamEnv<'tcx>, + param_env: ty::ParamEnv<'gcx>, } -impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { - fn with_fcx(&'tcx mut self, f: F) where - F: for<'b> FnOnce(&FnCtxt<'b, 'gcx, 'tcx>, - &mut CheckTypeWellFormedVisitor<'b, 'gcx>) -> Vec> - { +impl<'a, 'gcx> CheckWfFcxBuilder<'a, 'gcx> { + fn with_fcx<'tcx>( + &'tcx mut self, + f: impl for<'b> FnOnce( + &FnCtxt<'b, 'gcx, 'tcx>, + &mut CheckTypeWellFormedVisitor<'b, 'gcx>, + ) -> Vec>, + ) { let code = self.code.clone(); let id = self.id; let span = self.span; let param_env = self.param_env; self.inherited.enter(|inh| { - let fcx = FnCtxt::new(&inh, param_env, id); + let fcx = FnCtxt::new(inh, param_env, id); let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor { tcx: fcx.tcx.global_tcx(), code, @@ -203,13 +206,11 @@ impl<'a, 'gcx> CheckTypeWellFormedVisitor<'a, 'gcx> { }) } - fn for_item<'tcx>(&self, item: &hir::Item) - -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { + fn for_item(&self, item: &hir::Item) -> CheckWfFcxBuilder<'a, 'gcx> { self.for_id(item.id, item.span) } - fn for_id<'tcx>(&self, id: ast::NodeId, span: Span) - -> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { + fn for_id(&self, id: ast::NodeId, span: Span) -> CheckWfFcxBuilder<'a, 'gcx> { let def_id = self.tcx.hir.local_def_id(id); CheckWfFcxBuilder { inherited: Inherited::build(self.tcx, def_id), diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 964c0021133aa..342721ff4d973 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -88,6 +88,8 @@ This API is completely unstable and subject to change. #![feature(slice_patterns)] #![feature(i128_type)] #![cfg_attr(stage0, feature(never_type))] +#![feature(underscore_lifetimes)] +#![feature(universal_impl_trait)] #[macro_use] extern crate log; #[macro_use] extern crate syntax;