diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2015-01-02 04:09:35 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2015-01-03 07:01:21 -0500 |
| commit | 7474be066022d2cd0b0695a466651570c00f3700 (patch) | |
| tree | 83eb0f9d208ac3b3e14c81694ad348ee2b473923 | |
| parent | 83ef3042de889db07b819fc6b2802cd0ace7e21c (diff) | |
Make `ty::ParameterEnvironment`, not `ty::ctxt`, implement `Typer` and
`UnboxedClosureTyper`. This requires adding a `tcx` field to `ParameterEnvironment` but generally simplifies everything since we only need to pass along an `UnboxedClosureTyper` or `Typer`.
24 files changed, 288 insertions, 259 deletions
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 7952c99dd79..9cb8674c3e1 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -99,7 +99,7 @@ impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> { pub struct MatchCheckCtxt<'a, 'tcx: 'a> { pub tcx: &'a ty::ctxt<'tcx>, - pub param_env: ParameterEnvironment<'tcx>, + pub param_env: ParameterEnvironment<'a, 'tcx>, } #[deriving(Clone, PartialEq)] @@ -148,7 +148,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> { pub fn check_crate(tcx: &ty::ctxt) { visit::walk_crate(&mut MatchCheckCtxt { tcx: tcx, - param_env: ty::empty_parameter_environment(), + param_env: ty::empty_parameter_environment(tcx), }, tcx.map.krate()); tcx.sess.abort_if_errors(); } @@ -1061,8 +1061,7 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>, cx: cx, }; let mut visitor = ExprUseVisitor::new(&mut checker, - checker.cx.tcx, - &cx.param_env); + &checker.cx.param_env); visitor.walk_expr(guard); } diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs index 1a7a642f82a..c383b1579ef 100644 --- a/src/librustc/middle/check_rvalues.rs +++ b/src/librustc/middle/check_rvalues.rs @@ -41,7 +41,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { { let param_env = ParameterEnvironment::for_item(self.tcx, fn_id); let mut delegate = RvalueContextDelegate { tcx: self.tcx, param_env: ¶m_env }; - let mut euv = euv::ExprUseVisitor::new(&mut delegate, self.tcx, ¶m_env); + let mut euv = euv::ExprUseVisitor::new(&mut delegate, ¶m_env); euv.walk_fn(fd, b); } visit::walk_fn(self, fk, fd, b, s) @@ -50,7 +50,7 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> { struct RvalueContextDelegate<'a, 'tcx: 'a> { tcx: &'a ty::ctxt<'tcx>, - param_env: &'a ty::ParameterEnvironment<'tcx>, + param_env: &'a ty::ParameterEnvironment<'a,'tcx>, } impl<'a, 'tcx> euv::Delegate<'tcx> for RvalueContextDelegate<'a, 'tcx> { diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs index fb20df020ac..9c9e68002c9 100644 --- a/src/librustc/middle/check_static.rs +++ b/src/librustc/middle/check_static.rs @@ -54,7 +54,7 @@ struct CheckStaticVisitor<'a, 'tcx: 'a> { } struct GlobalVisitor<'a,'b,'tcx:'a+'b>( - euv::ExprUseVisitor<'a,'b,'tcx,ty::ctxt<'tcx>>); + euv::ExprUseVisitor<'a,'b,'tcx,ty::ParameterEnvironment<'b,'tcx>>); struct GlobalChecker { static_consumptions: NodeSet, const_borrows: NodeSet, @@ -70,8 +70,8 @@ pub fn check_crate(tcx: &ty::ctxt) { static_local_borrows: NodeSet::new(), }; { - let param_env = ty::empty_parameter_environment(); - let visitor = euv::ExprUseVisitor::new(&mut checker, tcx, ¶m_env); + let param_env = ty::empty_parameter_environment(tcx); + let visitor = euv::ExprUseVisitor::new(&mut checker, ¶m_env); visit::walk_crate(&mut GlobalVisitor(visitor), tcx.map.krate()); } visit::walk_crate(&mut CheckStaticVisitor { @@ -121,8 +121,8 @@ impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> { let mut fulfill_cx = traits::FulfillmentContext::new(); let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic); fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause); - let env = ty::empty_parameter_environment(); - match fulfill_cx.select_all_or_error(&infcx, &env, self.tcx) { + let env = ty::empty_parameter_environment(self.tcx); + match fulfill_cx.select_all_or_error(&infcx, &env) { Ok(()) => { }, Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors); diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index b2d866cf586..f5cf4af1230 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -23,7 +23,7 @@ use self::OverloadedCallType::*; use middle::{def, region, pat_util}; use middle::mem_categorization as mc; use middle::mem_categorization::Typer; -use middle::ty::{mod, ParameterEnvironment, Ty}; +use middle::ty::{mod}; use middle::ty::{MethodCall, MethodObject, MethodTraitObject}; use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam}; use middle::ty::{MethodStatic, MethodStaticUnboxedClosure}; @@ -299,7 +299,8 @@ pub struct ExprUseVisitor<'d,'t,'tcx:'t,TYPER:'t> { typer: &'t TYPER, mc: mc::MemCategorizationContext<'t,TYPER>, delegate: &'d mut (Delegate<'tcx>+'d), - param_env: &'t ParameterEnvironment<'tcx>, +} + // If the TYPER results in an error, it's because the type check // failed (or will fail, when the error is uncovered and reported // during writeback). In this case, we just ignore this part of the @@ -324,14 +325,12 @@ enum PassArgs { impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { pub fn new(delegate: &'d mut Delegate<'tcx>, - typer: &'t TYPER, - param_env: &'t ParameterEnvironment<'tcx>) + typer: &'t TYPER) -> ExprUseVisitor<'d,'t,'tcx,TYPER> { ExprUseVisitor { typer: typer, mc: mc::MemCategorizationContext::new(typer), delegate: delegate, - param_env: param_env, } } diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 89ffcbf37a9..2962b7b7c8e 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -41,7 +41,7 @@ struct IntrinsicCheckingVisitor<'a, 'tcx: 'a> { // environments for each function we encounter. When we find a // call to `transmute`, we can check it in the context of the top // of the stack (which ought not to be empty). - param_envs: Vec<ty::ParameterEnvironment<'tcx>>, + param_envs: Vec<ty::ParameterEnvironment<'a,'tcx>>, // Dummy sized/unsized types that use to substitute for type // parameters in order to estimate how big a type will be for any diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 59a9b73e978..722fe82d41c 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -272,7 +272,6 @@ pub type McResult<T> = Result<T, ()>; /// can be sure that only `Ok` results will occur. pub trait Typer<'tcx> : ty::UnboxedClosureTyper<'tcx> { fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>; - fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>; fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>; fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>>; fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool; @@ -1292,77 +1291,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { self.tcx().sess.span_bug(pat.span, "unexpanded macro"); } } - } - pub fn cmt_to_string(&self, cmt: &cmt_<'tcx>) -> String { - fn upvar_to_string(upvar: &Upvar, is_copy: bool) -> String { - if upvar.is_unboxed { - let kind = match upvar.kind { - ty::FnUnboxedClosureKind => "Fn", - ty::FnMutUnboxedClosureKind => "FnMut", - ty::FnOnceUnboxedClosureKind => "FnOnce" - }; - format!("captured outer variable in an `{}` closure", kind) - } else { - (match (upvar.kind, is_copy) { - (ty::FnOnceUnboxedClosureKind, true) => "captured outer variable in a proc", - _ => "captured outer variable" - }).to_string() - } - } - - match cmt.cat { - cat_static_item => { - "static item".to_string() - } - cat_rvalue(..) => { - "non-lvalue".to_string() - } - cat_local(vid) => { - match self.tcx().map.find(vid) { - Some(ast_map::NodeArg(_)) => { - "argument".to_string() - } - _ => "local variable".to_string() - } - } - cat_deref(_, _, pk) => { - let upvar = cmt.upvar(); - match upvar.as_ref().map(|i| &i.cat) { - Some(&cat_upvar(ref var)) => { - upvar_to_string(var, false) - } - Some(_) => unreachable!(), - None => { - match pk { - Implicit(..) => { - "dereference (dereference is implicit, due to indexing)".to_string() - } - Unique => format!("dereference of `{}`", ptr_sigil(pk)), - _ => format!("dereference of `{}`-pointer", ptr_sigil(pk)) - } - } - } - } - cat_interior(_, InteriorField(NamedField(_))) => { - "field".to_string() - } - cat_interior(_, InteriorField(PositionalField(_))) => { - "anonymous field".to_string() - } - cat_interior(_, InteriorElement(VecElement)) => { - "vec content".to_string() - } - cat_interior(_, InteriorElement(OtherElement)) => { - "indexed content".to_string() - } - cat_upvar(ref var) => { - upvar_to_string(var, true) - } - cat_downcast(ref cmt, _) => { - self.cmt_to_string(&**cmt) - } - } + Ok(()) } } @@ -1474,6 +1404,78 @@ impl<'tcx> cmt_<'tcx> { NoteNone => None } } + + + pub fn descriptive_string(&self, tcx: &ty::ctxt) -> String { + fn upvar_to_string(upvar: &Upvar, is_copy: bool) -> String { + if upvar.is_unboxed { + let kind = match upvar.kind { + ty::FnUnboxedClosureKind => "Fn", + ty::FnMutUnboxedClosureKind => "FnMut", + ty::FnOnceUnboxedClosureKind => "FnOnce" + }; + format!("captured outer variable in an `{}` closure", kind) + } else { + (match (upvar.kind, is_copy) { + (ty::FnOnceUnboxedClosureKind, true) => "captured outer variable in a proc", + _ => "captured outer variable" + }).to_string() + } + } + + match self.cat { + cat_static_item => { + "static item".to_string() + } + cat_rvalue(..) => { + "non-lvalue".to_string() + } + cat_local(vid) => { + match tcx.map.find(vid) { + Some(ast_map::NodeArg(_)) => { + "argument".to_string() + } + _ => "local variable".to_string() + } + } + cat_deref(_, _, pk) => { + let upvar = self.upvar(); + match upvar.as_ref().map(|i| &i.cat) { + Some(&cat_upvar(ref var)) => { + upvar_to_string(var, false) + } + Some(_) => unreachable!(), + None => { + match pk { + Implicit(..) => { + "dereference (dereference is implicit, due to indexing)".to_string() + } + Unique => format!("dereference of `{}`", ptr_sigil(pk)), + _ => format!("dereference of `{}`-pointer", ptr_sigil(pk)) + } + } + } + } + cat_interior(_, InteriorField(NamedField(_))) => { + "field".to_string() + } + cat_interior(_, InteriorField(PositionalField(_))) => { + "anonymous field".to_string() + } + cat_interior(_, InteriorElement(VecElement)) => { + "vec content".to_string() + } + cat_interior(_, InteriorElement(OtherElement)) => { + "indexed content".to_string() + } + cat_upvar(ref var) => { + upvar_to_string(var, true) + } + cat_downcast(ref cmt, _) => { + cmt.descriptive_string(tcx) + } + } + } } impl<'tcx> Repr<'tcx> for cmt_<'tcx> { diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 4aff36c2624..6a8b6d49cc0 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -42,8 +42,8 @@ pub fn impl_can_satisfy(infcx: &InferCtxt, // Determine whether `impl2` can provide an implementation for those // same types. - let param_env = ty::empty_parameter_environment(); - let mut selcx = SelectionContext::intercrate(infcx, ¶m_env, infcx.tcx); + let param_env = ty::empty_parameter_environment(infcx.tcx); + let mut selcx = SelectionContext::intercrate(infcx, ¶m_env); let obligation = Obligation::new(ObligationCause::dummy(), ty::Binder(ty::TraitPredicate { trait_ref: Rc::new(impl1_trait_ref), diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 2dbb15b215e..e8a22e3d1d8 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -109,7 +109,6 @@ impl<'tcx> FulfillmentContext<'tcx> { /// `projection_ty` again. pub fn normalize_projection_type<'a>(&mut self, infcx: &InferCtxt<'a,'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, typer: &ty::UnboxedClosureTyper<'tcx>, projection_ty: ty::ProjectionTy<'tcx>, cause: ObligationCause<'tcx>) @@ -122,7 +121,7 @@ impl<'tcx> FulfillmentContext<'tcx> { // FIXME(#20304) -- cache - let mut selcx = SelectionContext::new(infcx, param_env, typer); + let mut selcx = SelectionContext::new(infcx, typer); let normalized = project::normalize_projection_type(&mut selcx, projection_ty, cause, 0); for obligation in normalized.obligations.into_iter() { @@ -186,11 +185,10 @@ impl<'tcx> FulfillmentContext<'tcx> { pub fn select_all_or_error<'a>(&mut self, infcx: &InferCtxt<'a,'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, typer: &ty::UnboxedClosureTyper<'tcx>) -> Result<(),Vec<FulfillmentError<'tcx>>> { - try!(self.select_where_possible(infcx, param_env, typer)); + try!(self.select_where_possible(infcx, typer)); // Anything left is ambiguous. let errors: Vec<FulfillmentError> = @@ -212,21 +210,19 @@ impl<'tcx> FulfillmentContext<'tcx> { /// results in `O(n^2)` performance (#18208). pub fn select_new_obligations<'a>(&mut self, infcx: &InferCtxt<'a,'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, typer: &ty::UnboxedClosureTyper<'tcx>) -> Result<(),Vec<FulfillmentError<'tcx>>> { - let mut selcx = SelectionContext::new(infcx, param_env, typer); + let mut selcx = SelectionContext::new(infcx, typer); self.select(&mut selcx, true) } pub fn select_where_possible<'a>(&mut self, infcx: &InferCtxt<'a,'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, typer: &ty::UnboxedClosureTyper<'tcx>) -> Result<(),Vec<FulfillmentError<'tcx>>> { - let mut selcx = SelectionContext::new(infcx, param_env, typer); + let mut selcx = SelectionContext::new(infcx, typer); self.select(&mut selcx, false) } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index d09f2a250b0..7da33babaeb 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -46,7 +46,6 @@ use util::ppaux::Repr; pub struct SelectionContext<'cx, 'tcx:'cx> { infcx: &'cx InferCtxt<'cx, 'tcx>, - param_env: &'cx ty::ParameterEnvironment<'tcx>, closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+'cx), /// Freshener used specifically for skolemizing entries on the @@ -181,12 +180,10 @@ enum EvaluationResult<'tcx> { impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>, - param_env: &'cx ty::ParameterEnvironment<'tcx>, closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx: infcx, - param_env: param_env, closure_typer: closure_typer, freshener: infcx.freshener(), intercrate: false, @@ -194,12 +191,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>, - param_env: &'cx ty::ParameterEnvironment<'tcx>, closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx: infcx, - param_env: param_env, closure_typer: closure_typer, freshener: infcx.freshener(), intercrate: true, @@ -210,14 +205,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx } - pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'tcx> { - self.param_env - } - pub fn tcx(&self) -> &'cx ty::ctxt<'tcx> { self.infcx.tcx } + pub fn param_env(&self) -> &'cx ty::ParameterEnvironment<'cx, 'tcx> { + self.closure_typer.param_env() + } + /////////////////////////////////////////////////////////////////////////// // Selection // @@ -650,7 +645,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // it's not worth going to more trouble to increase the // hit-rate I don't think. if self.intercrate { - return &self.param_env.selection_cache; + return &self.param_env().selection_cache; } // If the trait refers to any parameters in scope, then use @@ -659,7 +654,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cache_fresh_trait_pred.0.input_types().iter().any( |&t| ty::type_has_self(t) || ty::type_has_params(t)) { - return &self.param_env.selection_cache; + return &self.param_env().selection_cache; } // If the trait refers to unbound type variables, and there @@ -668,11 +663,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // common case, then we can use the global environment. // See the discussion in doc.rs for more details. if - !self.param_env.caller_bounds.is_empty() && + !self.param_env().caller_bounds.is_empty() && cache_fresh_trait_pred.0.input_types().iter().any( |&t| ty::type_has_ty_infer(t)) { - return &self.param_env.selection_cache; + return &self.param_env().selection_cache; } // Otherwise, we can use the global cache. @@ -902,7 +897,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.repr(self.tcx())); let caller_trait_refs: Vec<_> = - self.param_env.caller_bounds.predicates.iter() + self.param_env().caller_bounds.predicates.iter() .filter_map(|o| o.to_opt_poly_trait_ref()) .collect(); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index fd32e798689..c720032bef2 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2058,7 +2058,9 @@ impl<'tcx> TraitRef<'tcx> { /// future I hope to refine the representation of types so as to make /// more distinctions clearer. #[deriving(Clone)] -pub struct ParameterEnvironment<'tcx> { +pub struct ParameterEnvironment<'a, 'tcx:'a> { + pub tcx: &'a ctxt<'tcx>, + /// A substitution that can be applied to move from /// the "outer" view of a type or method to the "inner" view. /// In general, this means converting from bound parameters to @@ -2082,8 +2084,8 @@ pub struct ParameterEnvironment<'tcx> { pub selection_cache: traits::SelectionCache<'tcx>, } -impl<'tcx> ParameterEnvironment<'tcx> { - pub fn for_item(cx: &ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'tcx> { +impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> { + pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx> { match cx.map.find(id) { Some(ast_map::NodeImplItem(ref impl_item)) => { match **impl_item { @@ -2272,6 +2274,8 @@ impl UnboxedClosureKind { } pub trait UnboxedClosureTyper<'tcx> { + fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>; + fn unboxed_closure_kind(&self, def_id: ast::DefId) -> ty::UnboxedClosureKind; @@ -2424,6 +2428,21 @@ impl<'tcx> ctxt<'tcx> { self.region_interner.borrow_mut().insert(region, region); region } + + pub fn unboxed_closure_kind(&self, + def_id: ast::DefId) + -> ty::UnboxedClosureKind + { + self.unboxed_closures.borrow()[def_id].kind + } + + pub fn unboxed_closure_type(&self, + def_id: ast::DefId, + substs: &subst::Substs<'tcx>) + -> ty::ClosureTy<'tcx> + { + self.unboxed_closures.borrow()[def_id].closure_type.subst(self, substs) + } } // Interns a type/name combination, stores the resulting box in cx.interner, @@ -3377,7 +3396,8 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { ty_unboxed_closure(did, r, substs) => { // FIXME(#14449): `borrowed_contents` below assumes `&mut` // unboxed closure. - let upvars = unboxed_closure_upvars(cx, did, substs).unwrap(); + let param_env = ty::empty_parameter_environment(cx); + let upvars = unboxed_closure_upvars(¶m_env, did, substs).unwrap(); TypeContents::union(upvars.as_slice(), |f| tc_ty(cx, f.ty, cache)) | borrowed_contents(*r, MutMutable) @@ -3526,12 +3546,12 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents { } } -fn type_impls_bound<'tcx>(cx: &ctxt<'tcx>, - cache: &RefCell<HashMap<Ty<'tcx>,bool>>, - param_env: &ParameterEnvironment<'tcx>, - ty: Ty<'tcx>, - bound: ty::BuiltinBound) - -> bool +fn type_impls_bound<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>, + cache: &RefCell<HashMap<Ty<'tcx>,bool>>, + ty: Ty<'tcx>, + bound: ty::BuiltinBound, + span: Span) + -> bool { assert!(!ty::type_needs_infer(ty)); @@ -3540,7 +3560,7 @@ fn type_impls_bound<'tcx>(cx: &ctxt<'tcx>, None => {} Some(&result) => { debug!("type_impls_bound({}, {}) = {} (cached)", - ty_to_string(cx, ty), + ty.repr(param_env.tcx), bound, result); return result @@ -3625,8 +3645,6 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool { ty_str | ty_bare_fn(..) | ty_closure(_) | - ty_infer(_) | - ty_err | ty_param(_) | ty_projection(_) | ty_vec(_, None) => { @@ -3659,9 +3677,12 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool { r } - ty_unboxed_closure(did, _, substs) => { - let upvars = unboxed_closure_upvars(cx, did, substs).unwrap(); - upvars.iter().any(|f| type_requires(cx, seen, r_ty, f.ty)) + ty_err | + ty_infer(_) | + ty_unboxed_closure(..) => { + // this check is run on type definitions, so we don't expect to see + // inference by-products or unboxed closure types + cx.sess.bug(format!("requires check invoked on inapplicable type: {}", ty)[]) } ty_tup(ref ts) => { @@ -3751,9 +3772,10 @@ pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>) find_nonrepresentable(cx, sp, seen, iter) } - ty_unboxed_closure(did, _, substs) => { - let upvars = unboxed_closure_upvars(cx, did, substs).unwrap(); - find_nonrepresentable(cx, sp, seen, upvars.iter().map(|f| f.ty)) + ty_unboxed_closure(..) => { + // this check is run on type definitions, so we don't expect to see + // unboxed closure types + cx.sess.bug(format!("requires check invoked on inapplicable type: {}", ty)[]) } _ => Representable, } @@ -6377,19 +6399,20 @@ impl Variance { /// Construct a parameter environment suitable for static contexts or other contexts where there /// are no free type/lifetime parameters in scope. -pub fn empty_parameter_environment<'tcx>() -> ParameterEnvironment<'tcx> { - ty::ParameterEnvironment { free_substs: Substs::empty(), +pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvironment<'a,'tcx> { + ty::ParameterEnvironment { tcx: cx, + free_substs: Substs::empty(), caller_bounds: GenericBounds::empty(), implicit_region_bound: ty::ReEmpty, selection_cache: traits::SelectionCache::new(), } } /// See `ParameterEnvironment` struct def'n for details -pub fn construct_parameter_environment<'tcx>( - tcx: &ctxt<'tcx>, +pub fn construct_parameter_environment<'a,'tcx>( + tcx: &'a ctxt<'tcx>, generics: &ty::Generics<'tcx>, free_id: ast::NodeId) - -> ParameterEnvironment<'tcx> + -> ParameterEnvironment<'a, 'tcx> { // @@ -6432,6 +6455,7 @@ pub fn construct_parameter_environment<'tcx>( bounds.repr(tcx)); return ty::ParameterEnvironment { + tcx: tcx, free_substs: free_substs, implicit_region_bound: ty::ReScope(free_id_scope), caller_bounds: bounds, @@ -6522,48 +6546,59 @@ impl BorrowKind { } } -impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> { - fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { - self +impl<'tcx> ctxt<'tcx> { + pub fn capture_mode(&self, closure_expr_id: ast::NodeId) + -> ast::CaptureClause { + self.capture_modes.borrow()[closure_expr_id].clone() + } + + pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool { + self.method_map.borrow().contains_key(&MethodCall::expr(expr_id)) } +} - fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { - ty::node_id_to_type(self, id) +impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> { + fn tcx(&self) -> &ty::ctxt<'tcx> { + self.tcx } - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> { - ty::expr_ty_adjusted(self, expr) + fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> { + Ok(ty::node_id_to_type(self.tcx, id)) + } + + fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> { + Ok(ty::expr_ty_adjusted(self.tcx, expr)) } fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> { - self.method_map.borrow().get(&method_call).map(|method| method.ty) + self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty) } fn node_method_origin(&self, method_call: ty::MethodCall) -> Option<ty::MethodOrigin<'tcx>> { - self.method_map.borrow().get(&method_call).map(|method| method.origin.clone()) + self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone()) } - fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> { - &self.adjustments + fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> { + &self.tcx.adjustments } fn is_method_call(&self, id: ast::NodeId) -> bool { - self.method_map.borrow().contains_key(&MethodCall::expr(id)) + self.tcx.is_method_call(id) } fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> { - self.region_maps.temporary_scope(rvalue_id) + self.tcx.region_maps.temporary_scope(rvalue_id) } fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> { - Some(self.upvar_borrow_map.borrow()[upvar_id].clone()) + Some(self.tcx.upvar_borrow_map.borrow()[upvar_id].clone()) } fn capture_mode(&self, closure_expr_id: ast::NodeId) -> ast::CaptureClause { - self.capture_modes.borrow()[closure_expr_id].clone() + self.tcx.capture_mode(closure_expr_id) } fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool { @@ -6571,12 +6606,16 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> { } } -impl<'tcx> UnboxedClosureTyper<'tcx> for ty::ctxt<'tcx> { +impl<'a,'tcx> UnboxedClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'tcx> { + fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { + self + } + fn unboxed_closure_kind(&self, def_id: ast::DefId) -> ty::UnboxedClosureKind { - self.unboxed_closures.borrow()[def_id].kind + self.tcx.unboxed_closure_kind(def_id) } fn unboxed_closure_type(&self, @@ -6584,7 +6623,7 @@ impl<'tcx> UnboxedClosureTyper<'tcx> for ty::ctxt<'tcx> { substs: &subst::Substs<'tcx>) -> ty::ClosureTy<'tcx> { - self.unboxed_closures.borrow()[def_id].closure_type.subst(self, substs) + self.tcx.unboxed_closure_type(def_id, substs) } fn unboxed_closure_upvars(&self, diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 2062685f4c8..17a3f4a88e5 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -87,7 +87,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> { dfcx_loans: &'a LoanDataFlow<'a, 'tcx>, move_data: move_data::FlowedMoveData<'a, 'tcx>, all_loans: &'a [Loan<'tcx>], - param_env: &'a ty::ParameterEnvironment<'tcx>, + param_env: &'a ty::ParameterEnvironment<'a, 'tcx>, } impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { @@ -208,9 +208,7 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, }; { - let mut euv = euv::ExprUseVisitor::new(&mut clcx, - bccx.tcx, - ¶m_env); + let mut euv = euv::ExprUseVisitor::new(&mut clcx, ¶m_env); euv.walk_fn(decl, body); } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 7854c8acb47..1e9e5b22aa0 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -51,9 +51,7 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, let param_env = ty::ParameterEnvironment::for_item(bccx.tcx, fn_id); { - let mut euv = euv::ExprUseVisitor::new(&mut glcx, - bccx.tcx, - ¶m_env); + let mut euv = euv::ExprUseVisitor::new(&mut glcx, ¶m_env); euv.walk_fn(decl, body); } @@ -485,13 +483,15 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> { /// This visitor walks static initializer's expressions and makes /// sure the loans being taken are sound. struct StaticInitializerCtxt<'a, 'tcx: 'a> { - bccx: &'a BorrowckCtxt<'a, 'tcx> + bccx: &'a BorrowckCtxt<'a, 'tcx>, } impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> { fn visit_expr(&mut self, ex: &Expr) { if let ast::ExprAddrOf(mutbl, ref base) = ex.node { - let base_cmt = self.bccx.cat_expr(&**base); + let param_env = ty::empty_parameter_environment(self.bccx.tcx); + let mc = mc::MemCategorizationContext::new(¶m_env); + let base_cmt = mc.cat_expr(&**base).unwrap(); let borrow_kind = ty::BorrowKind::from_mutbl(mutbl); // Check that we don't allow borrows of unsafe static items. if check_aliasability(self.bccx, ex.span, euv::AddrOf, diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index c27b7b30e13..d81974d1ae0 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -511,14 +511,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.tcx.region_maps.is_subregion_of(r_sub, r_sup) } - pub fn mc(&self) -> mc::MemCategorizationContext<'a, ty::ctxt<'tcx>> { - mc::MemCategorizationContext::new(self.tcx) - } - - pub fn cat_expr(&self, expr: &ast::Expr) -> mc::cmt<'tcx> { - self.mc().cat_expr(expr) - } - pub fn report(&self, err: BckError<'tcx>) { self.span_err( err.span, @@ -526,13 +518,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { self.note_and_explain_bckerr(err); } - pub fn report_use_of_moved_value(&self, - use_span: Span, - use_kind: MovedValueUseKind, - lp: &LoanPath<'tcx>, - the_move: &move_data::Move, - moved_lp: &LoanPath<'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>) { + pub fn report_use_of_moved_value<'b>(&self, + use_span: Span, + use_kind: MovedValueUseKind, + lp: &LoanPath<'tcx>, + the_move: &move_data::Move, + moved_lp: &LoanPath<'tcx>, + param_env: &ty::ParameterEnvironment<'b,'tcx>) { let verb = match use_kind { MovedInUse => "use", MovedInCapture => "capture", @@ -608,8 +600,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { r)[]) } }; - let (suggestion, _) = move_suggestion(self.tcx, param_env, expr_ty, - ("moved by default", "")); + let (suggestion, _) = + move_suggestion(param_env, expr_span, expr_ty, ("moved by default", "")); self.tcx.sess.span_note( expr_span, format!("`{}` moved here{} because it has type `{}`, which is {}", @@ -646,11 +638,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { r)[]) } }; - let (suggestion, help) = move_suggestion(self.tcx, - param_env, - expr_ty, - ("moved by default", "make a copy and \ - capture that instead to override")); + let (suggestion, help) = + move_suggestion(param_env, + expr_span, + expr_ty, + ("moved by default", + "make a copy and capture that instead to override")); self.tcx.sess.span_note( expr_span, format!("`{}` moved into closure environment here{} because it \ @@ -663,22 +656,27 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } } - fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, - ty: Ty<'tcx>, - default_msgs: (&'static str, &'static str)) - -> (&'static str, &'static str) { + fn move_suggestion<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx>, + span: Span, + ty: Ty<'tcx>, + default_msgs: (&'static str, &'static str)) + -> (&'static str, &'static str) { match ty.sty { ty::ty_closure(box ty::ClosureTy { - store: ty::RegionTraitStore(..), - .. - }) => + store: ty::RegionTraitStore(..), + .. + }) => { ("a non-copyable stack closure", - "capture it in a new closure, e.g. `|x| f(x)`, to override"), - _ if ty::type_moves_by_default(tcx, ty, param_env) => - ("non-copyable", - "perhaps you meant to use `clone()`?"), - _ => default_msgs, + "capture it in a new closure, e.g. `|x| f(x)`, to override") + } + _ => { + if ty::type_moves_by_default(param_env, span, ty) { + ("non-copyable", + "perhaps you meant to use `clone()`?") + } else { + default_msgs + } + } } } } @@ -991,7 +989,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> { } pub fn cmt_to_string(&self, cmt: &mc::cmt_<'tcx>) -> String { - self.mc().cmt_to_string(cmt) + cmt.descriptive_string(self.tcx) } } diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 0b1dfcb378b..19781a51d57 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -542,7 +542,7 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>( check_match::Constructor::Variant(def_id) }; - let param_env = ty::empty_parameter_environment(); + let param_env = ty::empty_parameter_environment(bcx.tcx()); let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx(), param_env: param_env, @@ -1008,7 +1008,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx(), - param_env: ty::empty_parameter_environment(), + param_env: ty::empty_parameter_environment(bcx.tcx()), }; let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) { let repr = adt::represent_type(bcx.ccx(), left_ty); @@ -1262,8 +1262,7 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool reassigned: false }; { - let param_env = ty::empty_parameter_environment(); - let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx, ¶m_env); + let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx); visitor.walk_expr(body); } rc.reassigned @@ -1321,7 +1320,7 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat, let variable_ty = node_id_type(bcx, p_id); let llvariable_ty = type_of::type_of(ccx, variable_ty); let tcx = bcx.tcx(); - let param_env = ty::empty_parameter_environment(); + let param_env = ty::empty_parameter_environment(tcx); let llmatch; let trmode; diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index 24a3bb42c90..85a7ec33069 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -61,7 +61,7 @@ use trans::datum; use trans::machine; use trans::type_::Type; use trans::type_of; -use middle::ty::{mod, Ty}; +use middle::ty::{mod, Ty, UnboxedClosureTyper}; use middle::ty::Disr; use syntax::ast; use syntax::attr; @@ -168,7 +168,8 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, Univariant(mk_struct(cx, ftys[], packed, t), dtor) } ty::ty_unboxed_closure(def_id, _, substs) => { - let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs).unwrap(); + let typer = NormalizingUnboxedClosureTyper::new(cx.tcx()); + let upvars = typer.unboxed_closure_upvars(def_id, substs).unwrap(); let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>(); Univariant(mk_struct(cx, upvar_types[], false, t), false) } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index bf53885e9e5..4c29467d93a 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -731,7 +731,8 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>, } ty::ty_unboxed_closure(def_id, _, substs) => { let repr = adt::represent_type(cx.ccx(), t); - let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs).unwrap(); + let typer = common::NormalizingUnboxedClosureTyper::new(cx.tcx()); + let upvars = typer.unboxed_closure_upvars(def_id, substs).unwrap(); for (i, upvar) in upvars.iter().enumerate() { let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i); cx = f(cx, llupvar, upvar.ty); @@ -1451,6 +1452,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, llfn: llfndecl, llenv: None, llretslotptr: Cell::new(None), + param_env: ty::empty_parameter_environment(ccx.tcx()), alloca_insert_pt: Cell::new(None), llreturn: Cell::new(None), needs_ret_allocas: nested_returns, diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 660b7aeeb00..6efdcc2f0fa 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -302,6 +302,9 @@ pub struct FunctionContext<'a, 'tcx: 'a> { // section of the executable we're generating. pub llfn: ValueRef, + // always an empty parameter-environment + pub param_env: ty::ParameterEnvironment<'a, 'tcx>, + // The environment argument in a closure. pub llenv: Option<ValueRef>, @@ -579,12 +582,12 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { self.tcx() } - fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { - node_id_type(self, id) + fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> { + Ok(node_id_type(self, id)) } - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> { - expr_ty_adjusted(self, expr) + fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> { + Ok(expr_ty_adjusted(self, expr)) } fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> { @@ -627,11 +630,15 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { } fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool { - self.param_env().type_moves_by_default(span, ty) + self.fcx.param_env.type_moves_by_default(span, ty) } } impl<'blk, 'tcx> ty::UnboxedClosureTyper<'tcx> for BlockS<'blk, 'tcx> { + fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx> { + &self.fcx.param_env + } + fn unboxed_closure_kind(&self, def_id: ast::DefId) -> ty::UnboxedClosureKind @@ -945,14 +952,10 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id()); let infcx = infer::new_infer_ctxt(tcx); - // Parameter environment is used to give details about type parameters, - // but since we are in trans, everything is fully monomorphized. - let param_env = ty::empty_parameter_environment(); - // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. - let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx); - let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env, &typer); + let typer = NormalizingUnboxedClosureTyper::new(tcx); + let mut selcx = traits::SelectionContext::new(&infcx, &typer); let obligation = traits::Obligation::new(traits::ObligationCause::dummy(), trait_ref.to_poly_trait_predicate()); let selection = match selcx.select(&obligation) { @@ -987,7 +990,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let vtable = selection.map_move_nested(|predicate| { fulfill_cx.register_predicate_obligation(&infcx, predicate); }); - let vtable = drain_fulfillment_cx(span, &infcx, ¶m_env, &mut fulfill_cx, &vtable); + let vtable = drain_fulfillment_cx(span, &infcx, &mut fulfill_cx, &vtable); info!("Cache miss: {}", trait_ref.repr(ccx.tcx())); ccx.trait_cache().borrow_mut().insert(trait_ref, @@ -997,21 +1000,27 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, } pub struct NormalizingUnboxedClosureTyper<'a,'tcx:'a> { - tcx: &'a ty::ctxt<'tcx> + param_env: ty::ParameterEnvironment<'a, 'tcx> } impl<'a,'tcx> NormalizingUnboxedClosureTyper<'a,'tcx> { pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingUnboxedClosureTyper<'a,'tcx> { - NormalizingUnboxedClosureTyper { tcx: tcx } + // Parameter environment is used to give details about type parameters, + // but since we are in trans, everything is fully monomorphized. + NormalizingUnboxedClosureTyper { param_env: ty::empty_parameter_environment(tcx) } } } impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<'a,'tcx> { + fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { + &self.param_env + } + fn unboxed_closure_kind(&self, def_id: ast::DefId) -> ty::UnboxedClosureKind { - self.tcx.unboxed_closure_kind(def_id) + self.param_env.tcx.unboxed_closure_kind(def_id) } fn unboxed_closure_type(&self, @@ -1021,8 +1030,8 @@ impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<' { // the substitutions in `substs` are already monomorphized, // but we still must normalize associated types - let closure_ty = self.tcx.unboxed_closure_type(def_id, substs); - monomorphize::normalize_associated_type(self.tcx, &closure_ty) + let closure_ty = self.param_env.tcx.unboxed_closure_type(def_id, substs); + monomorphize::normalize_associated_type(self.param_env.tcx, &closure_ty) } fn unboxed_closure_upvars(&self, @@ -1032,14 +1041,13 @@ impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<' { // the substitutions in `substs` are already monomorphized, // but we still must normalize associated types - let result = ty::unboxed_closure_upvars(self.tcx, def_id, substs); - monomorphize::normalize_associated_type(self.tcx, &result) + let result = ty::unboxed_closure_upvars(&self.param_env, def_id, substs); + monomorphize::normalize_associated_type(self.param_env.tcx, &result) } } pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span, infcx: &infer::InferCtxt<'a,'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, fulfill_cx: &mut traits::FulfillmentContext<'tcx>, result: &T) -> T @@ -1052,7 +1060,7 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span, // contains unbound type parameters. It could be a slight // optimization to stop iterating early. let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx); - match fulfill_cx.select_all_or_error(infcx, param_env, &typer) { + match fulfill_cx.select_all_or_error(infcx, &typer) { Ok(()) => { } Err(errors) => { if errors.iter().all(|e| e.is_overflow()) { diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index 0afe3a8ef8d..72074040a2c 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -28,6 +28,7 @@ use util::ppaux::{ty_to_string}; use std::fmt; use syntax::ast; +use syntax::codemap::DUMMY_SP; /// A `Datum` encapsulates the result of evaluating an expression. It /// describes where the value is stored, what Rust type the value has, diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 7c8ba08d987..cc259e6765c 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -322,9 +322,8 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T // FIXME(#20304) -- cache let infcx = infer::new_infer_ctxt(tcx); - let param_env = ty::empty_parameter_environment(); - let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx); - let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env, &typer); + let typer = NormalizingUnboxedClosureTyper::new(tcx); + let mut selcx = traits::SelectionContext::new(&infcx, &typer); let cause = traits::ObligationCause::dummy(); let traits::Normalized { value: result, obligations } = traits::normalize(&mut selcx, cause, value); @@ -337,7 +336,7 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T for obligation in obligations.into_iter() { fulfill_cx.register_predicate_obligation(&infcx, obligation); } - let result = drain_fulfillment_cx(DUMMY_SP, &infcx, ¶m_env, &mut fulfill_cx, &result); + let result = drain_fulfillment_cx(DUMMY_SP, &infcx, &mut fulfill_cx, &result); result } diff --git a/src/librustc_typeck/check/assoc.rs b/src/librustc_typeck/check/assoc.rs index 5e9843d0e00..6950850e5f3 100644 --- a/src/librustc_typeck/check/assoc.rs +++ b/src/librustc_typeck/check/assoc.rs @@ -18,7 +18,6 @@ use syntax::codemap::Span; use util::ppaux::Repr; pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, - param_env: &ty::ParameterEnvironment<'tcx>, typer: &(ty::UnboxedClosureTyper<'tcx>+'a), fulfillment_cx: &mut FulfillmentContext<'tcx>, span: Span, @@ -28,7 +27,7 @@ pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx> { debug!("normalize_associated_types_in(value={})", value.repr(infcx.tcx)); - let mut selcx = SelectionContext::new(infcx, param_env, typer); + let mut selcx = SelectionContext::new(infcx, typer); 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={}", diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 4e6593deddd..92b8c2bbcf7 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -169,9 +169,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>, poly_trait_ref.as_predicate()); // Now we want to know if this can be matched - let mut selcx = traits::SelectionContext::new(fcx.infcx(), - &fcx.inh.param_env, - fcx); + let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx); if !selcx.evaluate_obligation(&obligation) { debug!("--> Cannot match obligation"); return None; // Cannot be matched, no such method resolution is possible. diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 52860abb6f9..cd97d89b246 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -788,9 +788,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { debug!("impl_obligations={}", obligations.repr(self.tcx())); // Evaluate those obligations to see if they might possibly hold. - let mut selcx = traits::SelectionContext::new(self.infcx(), - &self.fcx.inh.param_env, - self.fcx); + let mut selcx = traits::SelectionContext::new(self.infcx(), self.fcx); obligations.all(|o| selcx.evaluate_obligation(o)) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 37ec24ae23b..ed4c55cea5d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -87,6 +87,7 @@ use middle::{const_eval, def}; use middle::infer; use middle::lang_items::IteratorItem; use middle::mem_categorization as mc; +use middle::mem_categorization::McResult; use middle::pat_util::{mod, pat_id_map}; use middle::region::CodeExtent; use middle::subst::{mod, Subst, Substs, VecPerParamSpace, ParamSpace}; @@ -146,7 +147,7 @@ mod callee; pub struct Inherited<'a, 'tcx: 'a> { infcx: infer::InferCtxt<'a, 'tcx>, locals: RefCell<NodeMap<Ty<'tcx>>>, - param_env: ty::ParameterEnvironment<'tcx>, + param_env: ty::ParameterEnvironment<'a, 'tcx>, // Temporary tables: node_types: RefCell<NodeMap<Ty<'tcx>>>, @@ -288,7 +289,6 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> { fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx } - fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> { fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> { let ty = self.node_ty(id); self.resolve_type_vars_or_error(&ty) @@ -322,7 +322,7 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> { self.inh.method_map.borrow().contains_key(&ty::MethodCall::expr(id)) } fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> { - self.tcx().temporary_scope(rvalue_id) + self.param_env().temporary_scope(rvalue_id) } fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> { self.inh.upvar_borrow_map.borrow().get(&upvar_id).cloned() @@ -334,6 +334,10 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> { } impl<'a, 'tcx> ty::UnboxedClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { + fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { + &self.inh.param_env + } + fn unboxed_closure_kind(&self, def_id: ast::DefId) -> ty::UnboxedClosureKind @@ -360,7 +364,7 @@ impl<'a, 'tcx> ty::UnboxedClosureTyper<'tcx> for FnCtxt<'a, 'tcx> { impl<'a, 'tcx> Inherited<'a, 'tcx> { fn new(tcx: &'a ty::ctxt<'tcx>, - param_env: ty::ParameterEnvironment<'tcx>) + param_env: ty::ParameterEnvironment<'a, 'tcx>) -> Inherited<'a, 'tcx> { Inherited { infcx: infer::new_infer_ctxt(tcx), @@ -388,7 +392,6 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { { let mut fulfillment_cx = self.fulfillment_cx.borrow_mut(); assoc::normalize_associated_types_in(&self.infcx, - &self.param_env, typer, &mut *fulfillment_cx, span, body_id, @@ -418,7 +421,7 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>) -> Inherited<'a, 'tcx> { // It's kind of a kludge to manufacture a fake function context // and statement context, but we might as well do write the code only once - let param_env = ty::empty_parameter_environment(); + let param_env = ty::empty_parameter_environment(ccx.tcx); Inherited::new(ccx.tcx, param_env) } @@ -462,7 +465,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, body: &ast::Block, id: ast::NodeId, raw_fty: Ty<'tcx>, - param_env: ty::ParameterEnvironment<'tcx>) { + param_env: ty::ParameterEnvironment<'a, 'tcx>) { match raw_fty.sty { ty::ty_bare_fn(_, ref fn_ty) => { let inh = Inherited::new(ccx.tcx, param_env); @@ -473,7 +476,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let fn_sig = liberate_late_bound_regions(ccx.tcx, CodeExtent::from_node_id(body.id), &fn_sig); let fn_sig = - inh.normalize_associated_types_in(ccx.tcx, body.span, body.id, &fn_sig); + inh.normalize_associated_types_in(&inh.param_env, body.span, body.id, &fn_sig); let fcx = check_fn(ccx, fn_ty.unsafety, id, &fn_sig, decl, id, body, &inh); @@ -1225,7 +1228,6 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, let impl_sig = assoc::normalize_associated_types_in(&infcx, &impl_param_env, - infcx.tcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -1246,7 +1248,6 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, let trait_sig = assoc::normalize_associated_types_in(&infcx, &impl_param_env, - infcx.tcx, &mut fulfillment_cx, impl_m_span, impl_m_body_id, @@ -1282,7 +1283,7 @@ fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>, // Run the fulfillment context to completion to accommodate any // associated type normalizations that may have occurred. - match fulfillment_cx.select_all_or_error(&infcx, &impl_param_env, tcx) { + match fulfillment_cx.select_all_or_error(&infcx, &impl_param_env) { Ok(()) => { } Err(errors) => { traits::report_fulfillment_errors(&infcx, &errors); @@ -1660,11 +1661,11 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx } - pub fn infcx(&self) -> &infer::InferCtxt<'a, 'tcx> { + pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> { &self.inh.infcx } - pub fn param_env(&self) -> &ty::ParameterEnvironment<'tcx> { + pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> { &self.inh.param_env } @@ -1835,7 +1836,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.inh.fulfillment_cx .borrow_mut() .normalize_projection_type(self.infcx(), - &self.inh.param_env, self, ty::ProjectionTy { trait_ref: trait_ref, diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 1ef6c114032..8566d1f1e12 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -287,9 +287,7 @@ pub fn select_all_fcx_obligations_or_error(fcx: &FnCtxt) { fcx.default_type_parameters(); let mut fulfillment_cx = fcx.inh.fulfillment_cx.borrow_mut(); - let r = fulfillment_cx.select_all_or_error(fcx.infcx(), - &fcx.inh.param_env, - fcx); + let r = fulfillment_cx.select_all_or_error(fcx.infcx(), fcx); match r { Ok(()) => { } Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); } @@ -302,7 +300,7 @@ pub fn select_fcx_obligations_where_possible(fcx: &FnCtxt) match fcx.inh.fulfillment_cx .borrow_mut() - .select_where_possible(fcx.infcx(), &fcx.inh.param_env, fcx) + .select_where_possible(fcx.infcx(), fcx) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); } @@ -316,7 +314,7 @@ pub fn select_new_fcx_obligations(fcx: &FnCtxt) { match fcx.inh.fulfillment_cx .borrow_mut() - .select_new_obligations(fcx.infcx(), &fcx.inh.param_env, fcx) + .select_new_obligations(fcx.infcx(), fcx) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(fcx.infcx(), &errors); } |
