Refactor the Typer interface to separate out UnboxedClosureTyper methods, which are

the only things that trait selection needs.
This commit is contained in:
Niko Matsakis 2015-01-01 16:04:51 -05:00
parent 7092af7ee3
commit 78f848cde5
11 changed files with 195 additions and 119 deletions

View File

@ -1229,7 +1229,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
// inferred by regionbk
let upvar_id = ty::UpvarId { var_id: id_var,
closure_expr_id: closure_expr.id };
let upvar_borrow = self.typer.upvar_borrow(upvar_id);
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();
self.delegate.borrow(closure_expr.id,
closure_expr.span,

View File

@ -111,7 +111,9 @@ use self::VarKind::*;
use middle::def::*;
use middle::mem_categorization::Typer;
use middle::{pat_util, ty};
use middle::pat_util;
use middle::ty;
use middle::ty::UnboxedClosureTyper;
use lint;
use util::nodemap::NodeMap;
@ -1515,16 +1517,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn fn_ret(&self, id: NodeId) -> ty::FnOutput<'tcx> {
let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
match fn_ty.sty {
ty::ty_unboxed_closure(closure_def_id, _, _) =>
self.ir.tcx.unboxed_closures()
.borrow()
.get(&closure_def_id)
.unwrap()
.closure_type
.sig
.0
.output,
_ => ty::ty_fn_ret(fn_ty)
ty::ty_unboxed_closure(closure_def_id, _, substs) =>
self.ir.tcx.unboxed_closure_type(closure_def_id, substs).sig.0.output,
_ =>
ty::ty_fn_ret(fn_ty),
}
}

View File

@ -74,7 +74,7 @@ pub use self::categorization::*;
use middle::def;
use middle::region;
use middle::ty::{mod, Ty};
use util::nodemap::{DefIdMap, NodeMap};
use util::nodemap::{NodeMap};
use util::ppaux::{ty_to_string, Repr};
use syntax::ast::{MutImmutable, MutMutable};
@ -280,7 +280,7 @@ impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
/// In the borrow checker, in contrast, type checking is complete and we
/// know that no errors have occurred, so we simply consult the tcx and we
/// can be sure that only `Ok` results will occur.
pub trait Typer<'tcx> {
pub trait Typer<'tcx> : ty::UnboxedClosureTyper<'tcx> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx>;
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx>;
@ -290,11 +290,9 @@ pub trait Typer<'tcx> {
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn is_method_call(&self, id: ast::NodeId) -> bool;
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow>;
fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> ast::CaptureClause;
fn unboxed_closures<'a>(&'a self)
-> &'a RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>>;
}
impl MutabilityCategory {
@ -622,8 +620,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, false)
}
ty::ty_unboxed_closure(closure_id, _, _) => {
let unboxed_closures = self.typer.unboxed_closures().borrow();
let kind = (*unboxed_closures)[closure_id].kind;
let kind = self.typer.unboxed_closure_kind(closure_id);
let mode = self.typer.capture_mode(fn_node_id);
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, true)
}
@ -800,7 +797,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
}
// Look up upvar borrow so we can get its region
let upvar_borrow = self.typer.upvar_borrow(upvar_id);
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();
let ptr = BorrowedPtr(upvar_borrow.kind, upvar_borrow.region);
Rc::new(cmt_ {

View File

@ -110,7 +110,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn normalize_projection_type<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &Typer<'tcx>,
typer: &ty::UnboxedClosureTyper<'tcx>,
projection_ty: ty::ProjectionTy<'tcx>,
cause: ObligationCause<'tcx>)
-> Ty<'tcx>
@ -187,7 +187,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn select_all_or_error<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &Typer<'tcx>)
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
try!(self.select_where_possible(infcx, param_env, typer));
@ -213,7 +213,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn select_new_obligations<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &Typer<'tcx>)
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
let mut selcx = SelectionContext::new(infcx, param_env, typer);
@ -223,7 +223,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
pub fn select_where_possible<'a>(&mut self,
infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &Typer<'tcx>)
typer: &ty::UnboxedClosureTyper<'tcx>)
-> Result<(),Vec<FulfillmentError<'tcx>>>
{
let mut selcx = SelectionContext::new(infcx, param_env, typer);

View File

@ -45,7 +45,7 @@ use util::ppaux::Repr;
pub struct SelectionContext<'cx, 'tcx:'cx> {
infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
typer: &'cx (Typer<'tcx>+'cx),
closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+'cx),
/// Freshener used specifically for skolemizing entries on the
/// obligation stack. This ensures that all entries on the stack
@ -178,12 +178,12 @@ enum EvaluationResult<'tcx> {
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
typer: &'cx Typer<'tcx>)
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
-> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx: infcx,
param_env: param_env,
typer: typer,
closure_typer: closure_typer,
freshener: infcx.freshener(),
intercrate: false,
}
@ -191,12 +191,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
param_env: &'cx ty::ParameterEnvironment<'tcx>,
typer: &'cx Typer<'tcx>)
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
-> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx: infcx,
param_env: param_env,
typer: typer,
closure_typer: closure_typer,
freshener: infcx.freshener(),
intercrate: true,
}
@ -919,15 +919,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
kind,
obligation.repr(self.tcx()));
let closure_kind = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
Some(closure) => closure.kind,
None => {
self.tcx().sess.span_bug(
obligation.cause.span,
format!("No entry for unboxed closure: {}",
closure_def_id.repr(self.tcx()))[]);
}
};
let closure_kind = self.closure_typer.unboxed_closure_kind(closure_def_id);
debug!("closure_kind = {}", closure_kind);
@ -1399,32 +1391,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
return Ok(ParameterBuiltin);
}
match self.tcx().freevars.borrow().get(&def_id.node) {
None => {
// No upvars.
Ok(If(Vec::new()))
match self.closure_typer.unboxed_closure_upvars(def_id, substs) {
Some(upvars) => {
Ok(If(upvars.iter().map(|c| c.ty).collect()))
}
Some(freevars) => {
let tys: Vec<Ty> =
freevars
.iter()
.map(|freevar| {
let freevar_def_id = freevar.def.def_id();
self.typer.node_ty(freevar_def_id.node).subst(self.tcx(), substs)
})
.collect();
Ok(If(tys))
None => {
Ok(AmbiguousBuiltin)
}
}
}
ty::ty_struct(def_id, substs) => {
let types: Vec<Ty> =
ty::struct_fields(self.tcx(), def_id, substs)
.iter()
.map(|f| f.mt.ty)
.collect();
ty::struct_fields(self.tcx(), def_id, substs).iter()
.map(|f| f.mt.ty)
.collect();
nominal(self, bound, def_id, types)
}
@ -1799,27 +1780,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
closure_def_id.repr(self.tcx()),
substs.repr(self.tcx()));
let closure_type = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
Some(closure) => closure.closure_type.clone(),
None => {
self.tcx().sess.span_bug(
obligation.cause.span,
format!("No entry for unboxed closure: {}",
closure_def_id.repr(self.tcx()))[]);
}
};
let closure_type = self.closure_typer.unboxed_closure_type(closure_def_id, substs);
let closure_sig = &closure_type.sig;
let arguments_tuple = closure_sig.0.inputs[0];
let substs =
let trait_substs =
Substs::new_trait(
vec![arguments_tuple.subst(self.tcx(), substs),
closure_sig.0.output.unwrap().subst(self.tcx(), substs)],
vec![arguments_tuple, closure_sig.0.output.unwrap()],
vec![],
obligation.self_ty());
let trait_ref = ty::Binder(Rc::new(ty::TraitRef {
def_id: obligation.predicate.def_id(),
substs: self.tcx().mk_substs(substs),
substs: self.tcx().mk_substs(trait_substs),
}));
debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",

View File

@ -2259,6 +2259,23 @@ impl UnboxedClosureKind {
}
}
pub trait UnboxedClosureTyper<'tcx> {
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind;
fn unboxed_closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>;
// Returns `None` if the upvar types cannot yet be definitively determined.
fn unboxed_closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>;
}
impl<'tcx> CommonTypes<'tcx> {
fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
@ -3345,7 +3362,7 @@ 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);
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
TypeContents::union(upvars.as_slice(),
|f| tc_ty(cx, f.ty, cache))
| borrowed_contents(*r, MutMutable)
@ -3625,7 +3642,7 @@ pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
}
ty_unboxed_closure(did, _, substs) => {
let upvars = unboxed_closure_upvars(cx, did, substs);
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
upvars.iter().any(|f| type_requires(cx, seen, r_ty, f.ty))
}
@ -3717,7 +3734,7 @@ 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);
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
find_nonrepresentable(cx, sp, seen, upvars.iter().map(|f| f.ty))
}
_ => Representable,
@ -5656,38 +5673,67 @@ pub struct UnboxedClosureUpvar<'tcx> {
}
// Returns a list of `UnboxedClosureUpvar`s for each upvar.
pub fn unboxed_closure_upvars<'tcx>(tcx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &Substs<'tcx>)
-> Vec<UnboxedClosureUpvar<'tcx>> {
pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
closure_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>
{
// Presently an unboxed closure type cannot "escape" out of a
// function, so we will only encounter ones that originated in the
// local crate or were inlined into it along with some function.
// This may change if abstract return types of some sort are
// implemented.
assert!(closure_id.krate == ast::LOCAL_CRATE);
let tcx = typer.tcx();
let capture_mode = tcx.capture_modes.borrow()[closure_id.node].clone();
match tcx.freevars.borrow().get(&closure_id.node) {
None => vec![],
None => Some(vec![]),
Some(ref freevars) => {
freevars.iter().map(|freevar| {
let freevar_def_id = freevar.def.def_id();
let freevar_ty = node_id_to_type(tcx, freevar_def_id.node);
let mut freevar_ty = freevar_ty.subst(tcx, substs);
if capture_mode == ast::CaptureByRef {
let borrow = tcx.upvar_borrow_map.borrow()[ty::UpvarId {
var_id: freevar_def_id.node,
closure_expr_id: closure_id.node
}].clone();
freevar_ty = mk_rptr(tcx, tcx.mk_region(borrow.region), ty::mt {
ty: freevar_ty,
mutbl: borrow.kind.to_mutbl_lossy()
});
}
UnboxedClosureUpvar {
def: freevar.def,
span: freevar.span,
ty: freevar_ty
}
}).collect()
freevars.iter()
.map(|freevar| {
let freevar_def_id = freevar.def.def_id();
let freevar_ty = typer.node_ty(freevar_def_id.node);
let freevar_ty = freevar_ty.subst(tcx, substs);
match capture_mode {
ast::CaptureByValue => {
Some(UnboxedClosureUpvar { def: freevar.def,
span: freevar.span,
ty: freevar_ty })
}
ast::CaptureByRef => {
let upvar_id = ty::UpvarId {
var_id: freevar_def_id.node,
closure_expr_id: closure_id.node
};
// FIXME
let freevar_ref_ty = match typer.upvar_borrow(upvar_id) {
Some(borrow) => {
mk_rptr(tcx,
tcx.mk_region(borrow.region),
ty::mt {
ty: freevar_ty,
mutbl: borrow.kind.to_mutbl_lossy(),
})
}
None => {
// TODO we should really return None here;
// but that requires better inference integration,
// for now gin up something.
freevar_ty
}
};
Some(UnboxedClosureUpvar {
def: freevar.def,
span: freevar.span,
ty: freevar_ref_ty,
})
}
}
})
.collect()
}
}
}
@ -6501,21 +6547,42 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> {
self.region_maps.temporary_scope(rvalue_id)
}
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
self.upvar_borrow_map.borrow()[upvar_id].clone()
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
Some(self.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()
}
}
fn unboxed_closures<'a>(&'a self)
-> &'a RefCell<DefIdMap<UnboxedClosure<'tcx>>> {
&self.unboxed_closures
impl<'tcx> UnboxedClosureTyper<'tcx> for ty::ctxt<'tcx> {
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind
{
self.unboxed_closures.borrow()[def_id].kind
}
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)
}
fn unboxed_closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>
{
unboxed_closure_upvars(self, def_id, substs)
}
}
/// The category of explicit self.
#[deriving(Clone, Copy, Eq, PartialEq, Show)]
pub enum ExplicitSelfCategory {

View File

@ -168,7 +168,7 @@ 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);
let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs).unwrap();
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
Univariant(mk_struct(cx, upvar_types[], false, t), false)
}

View File

@ -729,7 +729,7 @@ 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);
let upvars = ty::unboxed_closure_upvars(cx.tcx(), 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);

View File

@ -39,7 +39,7 @@ use middle::ty::{mod, HasProjectionTypes, Ty};
use middle::ty_fold;
use middle::ty_fold::{TypeFolder, TypeFoldable};
use util::ppaux::Repr;
use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
use util::nodemap::{FnvHashMap, NodeMap};
use arena::TypedArena;
use libc::{c_uint, c_char};
@ -617,13 +617,8 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
self.tcx().region_maps.temporary_scope(rvalue_id)
}
fn unboxed_closures<'a>(&'a self)
-> &'a RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>> {
&self.tcx().unboxed_closures
}
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
self.tcx().upvar_borrow_map.borrow()[upvar_id].clone()
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
Some(self.tcx().upvar_borrow_map.borrow()[upvar_id].clone())
}
fn capture_mode(&self, closure_expr_id: ast::NodeId)
@ -632,6 +627,35 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
}
}
impl<'blk, 'tcx> ty::UnboxedClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind
{
self.tcx().unboxed_closure_kind(def_id)
}
fn unboxed_closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
// the substitutions in `substs` are already monomorphized, so we can
// ignore `param_substs`
self.tcx().unboxed_closure_type(def_id, substs)
}
fn unboxed_closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
{
// the substitutions in `substs` are already monomorphized, so we can
// ignore `param_substs`
ty::unboxed_closure_upvars(self.tcx(), def_id, substs)
}
}
pub struct Result<'blk, 'tcx: 'blk> {
pub bcx: Block<'blk, 'tcx>,
pub val: ValueRef

View File

@ -9,7 +9,6 @@
// except according to those terms.
use middle::infer::InferCtxt;
use middle::mem_categorization as mc;
use middle::traits::{mod, FulfillmentContext, Normalized, MiscObligation,
SelectionContext, ObligationCause};
use middle::ty::{mod, HasProjectionTypes};
@ -20,7 +19,7 @@ use util::ppaux::Repr;
pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
param_env: &ty::ParameterEnvironment<'tcx>,
typer: &(mc::Typer<'tcx>+'a),
typer: &(ty::UnboxedClosureTyper<'tcx>+'a),
fulfillment_cx: &mut FulfillmentContext<'tcx>,
span: Span,
body_id: ast::NodeId,

View File

@ -319,15 +319,37 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
self.tcx().temporary_scope(rvalue_id)
}
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
self.inh.upvar_borrow_map.borrow()[upvar_id].clone()
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
self.inh.upvar_borrow_map.borrow().get(&upvar_id).cloned()
}
fn capture_mode(&self, closure_expr_id: ast::NodeId)
-> ast::CaptureClause {
self.ccx.tcx.capture_mode(closure_expr_id)
}
fn unboxed_closures(&self) -> &RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>> {
&self.inh.unboxed_closures
}
impl<'a, 'tcx> ty::UnboxedClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
fn unboxed_closure_kind(&self,
def_id: ast::DefId)
-> ty::UnboxedClosureKind
{
self.inh.unboxed_closures.borrow()[def_id].kind
}
fn unboxed_closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
self.inh.unboxed_closures.borrow()[def_id].closure_type.subst(self.tcx(), substs)
}
fn unboxed_closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
{
ty::unboxed_closure_upvars(self, def_id, substs)
}
}
@ -352,7 +374,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> {
}
fn normalize_associated_types_in<T>(&self,
typer: &mc::Typer<'tcx>,
typer: &ty::UnboxedClosureTyper<'tcx>,
span: Span,
body_id: ast::NodeId,
value: &T)