diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 5aacaa04e46d049ec8e42c3882481db22f5b82ba..d18c12b308d48154eac347f90126a960a6e19b4c 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -243,19 +243,6 @@ fn parse_size(st: &mut PState) -> Option { } } -fn parse_trait_store_(st: &mut PState, conv: &mut F) -> ty::TraitStore where - F: FnMut(DefIdSource, ast::DefId) -> ast::DefId, -{ - match next(st) { - '~' => ty::UniqTraitStore, - '&' => ty::RegionTraitStore(parse_region_(st, conv), parse_mutability(st)), - c => { - st.tcx.sess.bug(&format!("parse_trait_store(): bad input '{}'", - c)[]) - } - } -} - fn parse_vec_per_param_space<'a, 'tcx, T, F>(st: &mut PState<'a, 'tcx>, mut f: F) -> VecPerParamSpace where @@ -662,14 +649,12 @@ fn parse_closure_ty_<'a, 'tcx, F>(st: &mut PState<'a, 'tcx>, { let unsafety = parse_unsafety(next(st)); let onceness = parse_onceness(next(st)); - let store = parse_trait_store_(st, conv); let bounds = parse_existential_bounds_(st, conv); let sig = parse_sig_(st, conv); let abi = parse_abi_set(st); ty::ClosureTy { unsafety: unsafety, onceness: onceness, - store: store, bounds: bounds, sig: sig, abi: abi, diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index bdd08ad6c4952038af1029b1982de787ee9c047b..4727c5dddf76829dbd9f4f902460123de9610629 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -305,17 +305,6 @@ pub fn enc_trait_ref<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, enc_substs(w, cx, s.substs); } -pub fn enc_trait_store(w: &mut SeekableMemWriter, cx: &ctxt, s: ty::TraitStore) { - match s { - ty::UniqTraitStore => mywrite!(w, "~"), - ty::RegionTraitStore(re, m) => { - mywrite!(w, "&"); - enc_region(w, cx, re); - enc_mutability(w, m); - } - } -} - fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) { match p { ast::Unsafety::Normal => mywrite!(w, "n"), @@ -347,7 +336,6 @@ pub fn enc_closure_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, ft: &ty::ClosureTy<'tcx>) { enc_unsafety(w, ft.unsafety); enc_onceness(w, ft.onceness); - enc_trait_store(w, cx, ft.store); enc_existential_bounds(w, cx, &ft.bounds); enc_fn_sig(w, cx, &ft.sig); enc_abi(w, ft.abi); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 550c0f34cafec6d53782098d387d566a15b9fd40..9fc445d9cb6a539c730633f49fc8aaae84d5cbc4 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -515,17 +515,6 @@ fn tr(&self, dcx: &DecodeContext) -> ty::BoundRegion { } } -impl tr for ty::TraitStore { - fn tr(&self, dcx: &DecodeContext) -> ty::TraitStore { - match *self { - ty::RegionTraitStore(r, m) => { - ty::RegionTraitStore(r.tr(dcx), m) - } - ty::UniqTraitStore => ty::UniqTraitStore - } - } -} - // ______________________________________________________________________ // Encoding and decoding of freevar information diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index 4a4328fa98bafbc059da8edf2e5223be23fdb986..3280769ff03866bedbb3ad4dd9c0271299674b34 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -202,39 +202,6 @@ fn bare_fn_tys(&self, a: &ty::BareFnTy<'tcx>, sig: sig}) } - fn closure_tys(&self, a: &ty::ClosureTy<'tcx>, - b: &ty::ClosureTy<'tcx>) -> cres<'tcx, ty::ClosureTy<'tcx>> { - - let store = match (a.store, b.store) { - (ty::RegionTraitStore(a_r, a_m), - ty::RegionTraitStore(b_r, b_m)) if a_m == b_m => { - let r = try!(self.contraregions(a_r, b_r)); - ty::RegionTraitStore(r, a_m) - } - - _ if a.store == b.store => { - a.store - } - - _ => { - return Err(ty::terr_sigil_mismatch(expected_found(self, a.store, b.store))) - } - }; - let unsafety = try!(self.unsafeties(a.unsafety, b.unsafety)); - let onceness = try!(self.oncenesses(a.onceness, b.onceness)); - let bounds = try!(self.existential_bounds(&a.bounds, &b.bounds)); - let sig = try!(self.binders(&a.sig, &b.sig)); - let abi = try!(self.abi(a.abi, b.abi)); - Ok(ty::ClosureTy { - unsafety: unsafety, - onceness: onceness, - store: store, - bounds: bounds, - sig: sig, - abi: abi, - }) - } - fn fn_sigs(&self, a: &ty::FnSig<'tcx>, b: &ty::FnSig<'tcx>) -> cres<'tcx, ty::FnSig<'tcx>> { if a.variadic != b.variadic { return Err(ty::terr_variadic_mismatch(expected_found(self, a.variadic, b.variadic))); @@ -356,31 +323,6 @@ fn contraregions(&self, a: ty::Region, b: ty::Region) fn regions(&self, a: ty::Region, b: ty::Region) -> cres<'tcx, ty::Region>; - fn trait_stores(&self, - vk: ty::terr_vstore_kind, - a: ty::TraitStore, - b: ty::TraitStore) - -> cres<'tcx, ty::TraitStore> { - debug!("{}.trait_stores(a={:?}, b={:?})", self.tag(), a, b); - - match (a, b) { - (ty::RegionTraitStore(a_r, a_m), - ty::RegionTraitStore(b_r, b_m)) if a_m == b_m => { - self.contraregions(a_r, b_r).and_then(|r| { - Ok(ty::RegionTraitStore(r, a_m)) - }) - } - - _ if a == b => { - Ok(a) - } - - _ => { - Err(ty::terr_trait_stores_differ(vk, expected_found(self, a, b))) - } - } - } - fn trait_refs(&self, a: &ty::TraitRef<'tcx>, b: &ty::TraitRef<'tcx>) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index be6c6b9d34f3784caf6f3713739855531a35fb8f..8d1a410859091cff82c692b0c58d0a45305e1a70 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -17,7 +17,6 @@ pub use self::InferRegion::*; pub use self::ImplOrTraitItemId::*; pub use self::UnboxedClosureKind::*; -pub use self::TraitStore::*; pub use self::ast_ty_to_ty_cache_entry::*; pub use self::Variance::*; pub use self::AutoAdjustment::*; @@ -61,7 +60,7 @@ use middle::ty_fold::{self, TypeFoldable, TypeFolder}; use middle::ty_walk::TypeWalker; use util::ppaux::{note_and_explain_region, bound_region_ptr_to_string}; -use util::ppaux::{trait_store_to_string, ty_to_string}; +use util::ppaux::ty_to_string; use util::ppaux::{Repr, UserString}; use util::common::{memoized, ErrorReported}; use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet}; @@ -247,14 +246,6 @@ pub struct mt<'tcx> { pub mutbl: ast::Mutability, } -#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Show)] -pub enum TraitStore { - /// Box - UniqTraitStore, - /// &Trait and &mut Trait - RegionTraitStore(Region, ast::Mutability), -} - #[derive(Clone, Copy, Show)] pub struct field_ty { pub name: Name, @@ -1042,7 +1033,6 @@ pub struct BareFnTy<'tcx> { pub struct ClosureTy<'tcx> { pub unsafety: ast::Unsafety, pub onceness: ast::Onceness, - pub store: TraitStore, pub bounds: ExistentialBounds<'tcx>, pub sig: PolyFnSig<'tcx>, pub abi: abi::Abi, @@ -1545,7 +1535,6 @@ pub enum type_err<'tcx> { terr_onceness_mismatch(expected_found), terr_abi_mismatch(expected_found), terr_mutability, - terr_sigil_mismatch(expected_found), terr_box_mutability, terr_ptr_mutability, terr_ref_mutability, @@ -1559,7 +1548,6 @@ pub enum type_err<'tcx> { terr_regions_no_overlap(Region, Region), terr_regions_insufficiently_polymorphic(BoundRegion, Region), terr_regions_overly_polymorphic(BoundRegion, Region), - terr_trait_stores_differ(terr_vstore_kind, expected_found), terr_sorts(expected_found>), terr_integer_as_char, terr_int_mismatch(expected_found), @@ -4194,19 +4182,6 @@ pub fn ty_fn_args<'tcx>(fty: Ty<'tcx>) -> ty::Binder>> { ty_fn_sig(fty).inputs() } -pub fn ty_closure_store(fty: Ty) -> TraitStore { - match fty.sty { - ty_unboxed_closure(..) => { - // Close enough for the purposes of all the callers of this - // function (which is soon to be deprecated anyhow). - UniqTraitStore - } - ref s => { - panic!("ty_closure_store() called on non-closure type: {:?}", s) - } - } -} - pub fn ty_fn_ret<'tcx>(fty: Ty<'tcx>) -> Binder> { match fty.sty { ty_bare_fn(_, ref f) => f.sig.output(), @@ -4751,13 +4726,6 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String { /// afterwards to present additional details, particularly when it comes to lifetime-related /// errors. pub fn type_err_to_str<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>) -> String { - fn tstore_to_closure(s: &TraitStore) -> String { - match s { - &UniqTraitStore => "proc".to_string(), - &RegionTraitStore(..) => "closure".to_string() - } - } - match *err { terr_cyclic_ty => "cyclic type of infinite size".to_string(), terr_mismatch => "types differ".to_string(), @@ -4776,11 +4744,6 @@ fn tstore_to_closure(s: &TraitStore) -> String { values.expected, values.found) } - terr_sigil_mismatch(values) => { - format!("expected {}, found {}", - tstore_to_closure(&values.expected), - tstore_to_closure(&values.found)) - } terr_mutability => "values differ in mutability".to_string(), terr_box_mutability => { "boxed values differ in mutability".to_string() @@ -4828,11 +4791,6 @@ fn tstore_to_closure(s: &TraitStore) -> String { found bound lifetime parameter {}", bound_region_ptr_to_string(cx, br)) } - terr_trait_stores_differ(_, ref values) => { - format!("trait storage differs: expected `{}`, found `{}`", - trait_store_to_string(cx, (*values).expected), - trait_store_to_string(cx, (*values).found)) - } terr_sorts(values) => { // A naive approach to making sure that we're not reporting silly errors such as: // (expected closure, found closure). @@ -7338,10 +7296,9 @@ fn references_error(&self) -> bool { impl<'tcx> Repr<'tcx> for ClosureTy<'tcx> { fn repr(&self, tcx: &ctxt<'tcx>) -> String { - format!("ClosureTy({},{},{:?},{},{},{})", + format!("ClosureTy({},{},{},{},{})", self.unsafety, self.onceness, - self.store, self.bounds.repr(tcx), self.sig.repr(tcx), self.abi) diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs index 37886b4a1e1f670681be6705676362901d458074..c2bbfca07bf304133f4fb3e0d390f92be1580921 100644 --- a/src/librustc/middle/ty_fold.rs +++ b/src/librustc/middle/ty_fold.rs @@ -124,10 +124,6 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region { r } - fn fold_trait_store(&mut self, s: ty::TraitStore) -> ty::TraitStore { - super_fold_trait_store(self, s) - } - fn fold_existential_bounds(&mut self, s: &ty::ExistentialBounds<'tcx>) -> ty::ExistentialBounds<'tcx> { super_fold_existential_bounds(self, s) @@ -225,12 +221,6 @@ fn fold_with>(&self, folder: &mut F) -> VecPerParamSpace } } -impl<'tcx> TypeFoldable<'tcx> for ty::TraitStore { - fn fold_with>(&self, folder: &mut F) -> ty::TraitStore { - folder.fold_trait_store(*self) - } -} - impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { fn fold_with>(&self, folder: &mut F) -> Ty<'tcx> { folder.fold_ty(*self) @@ -699,7 +689,6 @@ pub fn super_fold_closure_ty<'tcx, T: TypeFolder<'tcx>>(this: &mut T, -> ty::ClosureTy<'tcx> { ty::ClosureTy { - store: fty.store.fold_with(this), sig: fty.sig.fold_with(this), unsafety: fty.unsafety, onceness: fty.onceness, @@ -726,17 +715,6 @@ pub fn super_fold_mt<'tcx, T: TypeFolder<'tcx>>(this: &mut T, mutbl: mt.mutbl} } -pub fn super_fold_trait_store<'tcx, T: TypeFolder<'tcx>>(this: &mut T, - trait_store: ty::TraitStore) - -> ty::TraitStore { - match trait_store { - ty::UniqTraitStore => ty::UniqTraitStore, - ty::RegionTraitStore(r, m) => { - ty::RegionTraitStore(r.fold_with(this), m) - } - } -} - pub fn super_fold_existential_bounds<'tcx, T: TypeFolder<'tcx>>( this: &mut T, bounds: &ty::ExistentialBounds<'tcx>) diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index fb44d0cadfa6c8f50ba5965078236e948fc5b331..ba97331d183db07e9fbde9b2406ecf4fd32d6e47 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -237,15 +237,6 @@ pub fn mt_to_string<'tcx>(cx: &ctxt<'tcx>, m: &mt<'tcx>) -> String { ty_to_string(cx, m.ty)) } -pub fn trait_store_to_string(cx: &ctxt, s: ty::TraitStore) -> String { - match s { - ty::UniqTraitStore => "Box ".to_string(), - ty::RegionTraitStore(r, m) => { - format!("{}{}", region_ptr_to_string(cx, r), mutability_to_string(m)) - } - } -} - pub fn vec_map_to_string(ts: &[T], f: F) -> String where F: FnMut(&T) -> String, { @@ -303,13 +294,6 @@ fn bare_fn_to_string<'tcx>(cx: &ctxt<'tcx>, fn closure_to_string<'tcx>(cx: &ctxt<'tcx>, cty: &ty::ClosureTy<'tcx>) -> String { let mut s = String::new(); - match cty.store { - ty::UniqTraitStore => {} - ty::RegionTraitStore(region, _) => { - s.push_str(®ion_to_string(cx, "", true, region)[]); - } - } - match cty.unsafety { ast::Unsafety::Normal => {} ast::Unsafety::Unsafe => { @@ -320,22 +304,12 @@ fn closure_to_string<'tcx>(cx: &ctxt<'tcx>, cty: &ty::ClosureTy<'tcx>) -> String let bounds_str = cty.bounds.user_string(cx); - match cty.store { - ty::UniqTraitStore => { - assert_eq!(cty.onceness, ast::Once); - s.push_str("proc"); - push_sig_to_string(cx, &mut s, '(', ')', &cty.sig, - &bounds_str[]); - } - ty::RegionTraitStore(..) => { - match cty.onceness { - ast::Many => {} - ast::Once => s.push_str("once ") - } - push_sig_to_string(cx, &mut s, '|', '|', &cty.sig, - &bounds_str[]); - } + match cty.onceness { + ast::Many => {} + ast::Once => s.push_str("once ") } + push_sig_to_string(cx, &mut s, '|', '|', &cty.sig, + &bounds_str[]); s } @@ -1090,12 +1064,6 @@ fn repr(&self, tcx: &ctxt<'tcx>) -> String { } } -impl<'tcx> Repr<'tcx> for ty::TraitStore { - fn repr(&self, tcx: &ctxt) -> String { - trait_store_to_string(tcx, *self) - } -} - impl<'tcx> Repr<'tcx> for ty::BuiltinBound { fn repr(&self, _tcx: &ctxt) -> String { format!("{:?}", *self) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index eed61ae59a259557817c6a67bf6e57cb7739c01e..56fdab6e040699816baa1c2dc572c5957ce2adf8 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -362,18 +362,6 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId, } } -// Returns a pointer to the body for the box. The box may be an opaque -// box. The result will be casted to the type of body_t, if it is statically -// known. -pub fn at_box_body<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - body_t: Ty<'tcx>, boxptr: ValueRef) -> ValueRef { - let _icx = push_ctxt("at_box_body"); - let ccx = bcx.ccx(); - let ty = Type::at_box(ccx, type_of(ccx, body_t)); - let boxptr = PointerCast(bcx, boxptr, ty.ptr_to()); - GEPi(bcx, boxptr, &[0u, abi::BOX_FIELD_BODY]) -} - fn require_alloc_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, info_ty: Ty<'tcx>, it: LangItem) -> ast::DefId { match bcx.tcx().lang_items.require(it) { @@ -1832,7 +1820,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, .map(|arg| node_id_type(bcx, arg.id)) .collect::>(); let monomorphized_arg_types = match closure_env.kind { - closure::NotClosure | closure::BoxedClosure(..) => { + closure::NotClosure => { monomorphized_arg_types } @@ -1859,7 +1847,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, }; bcx = match closure_env.kind { - closure::NotClosure | closure::BoxedClosure(..) => { + closure::NotClosure => { copy_args_to_allocas(bcx, arg_scope, &decl.inputs[], diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index 8989dfd493236a80c186f4dcb5105b1d0819b7a8..7a6c0c50dd1ffed8223b22dc095396016fe1900f 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -10,270 +10,26 @@ pub use self::ClosureKind::*; -use back::abi; use back::link::mangle_internal_name_by_path_and_seq; -use llvm::ValueRef; use middle::mem_categorization::Typer; use trans::adt; use trans::base::*; use trans::build::*; use trans::cleanup::{CleanupMethods, ScopeId}; use trans::common::*; -use trans::datum::{Datum, Lvalue, rvalue_scratch_datum}; +use trans::datum::{Datum, rvalue_scratch_datum}; use trans::datum::{Rvalue, ByValue}; use trans::debuginfo; use trans::expr; use trans::monomorphize::{self, MonoId}; use trans::type_of::*; -use trans::type_::Type; -use middle::ty::{self, Ty, UnboxedClosureTyper}; +use middle::ty::{self, UnboxedClosureTyper}; use middle::subst::{Substs}; use session::config::FullDebugInfo; -use util::ppaux::ty_to_string; use syntax::ast; use syntax::ast_util; -// ___Good to know (tm)__________________________________________________ -// -// The layout of a closure environment in memory is -// roughly as follows: -// -// struct rust_opaque_box { // see rust_internal.h -// unsigned ref_count; // obsolete (part of @T's header) -// fn(void*) *drop_glue; // destructor (for proc) -// rust_opaque_box *prev; // obsolete (part of @T's header) -// rust_opaque_box *next; // obsolete (part of @T's header) -// struct closure_data { -// upvar1_t upvar1; -// ... -// upvarN_t upvarN; -// } -// }; -// -// Note that the closure is itself a rust_opaque_box. This is true -// even for ~fn and ||, because we wish to keep binary compatibility -// between all kinds of closures. The allocation strategy for this -// closure depends on the closure type. For a sendfn, the closure -// (and the referenced type descriptors) will be allocated in the -// exchange heap. For a fn, the closure is allocated in the task heap -// and is reference counted. For a block, the closure is allocated on -// the stack. -// -// ## Opaque closures and the embedded type descriptor ## -// -// One interesting part of closures is that they encapsulate the data -// that they close over. So when I have a ptr to a closure, I do not -// know how many type descriptors it contains nor what upvars are -// captured within. That means I do not know precisely how big it is -// nor where its fields are located. This is called an "opaque -// closure". -// -// Typically an opaque closure suffices because we only manipulate it -// by ptr. The routine Type::at_box().ptr_to() returns an appropriate -// type for such an opaque closure; it allows access to the box fields, -// but not the closure_data itself. -// -// But sometimes, such as when cloning or freeing a closure, we need -// to know the full information. That is where the type descriptor -// that defines the closure comes in handy. We can use its take and -// drop glue functions to allocate/free data as needed. -// -// ## Subtleties concerning alignment ## -// -// It is important that we be able to locate the closure data *without -// knowing the kind of data that is being bound*. This can be tricky -// because the alignment requirements of the bound data affects the -// alignment requires of the closure_data struct as a whole. However, -// right now this is a non-issue in any case, because the size of the -// rust_opaque_box header is always a multiple of 16-bytes, which is -// the maximum alignment requirement we ever have to worry about. -// -// The only reason alignment matters is that, in order to learn what data -// is bound, we would normally first load the type descriptors: but their -// location is ultimately depend on their content! There is, however, a -// workaround. We can load the tydesc from the rust_opaque_box, which -// describes the closure_data struct and has self-contained derived type -// descriptors, and read the alignment from there. It's just annoying to -// do. Hopefully should this ever become an issue we'll have monomorphized -// and type descriptors will all be a bad dream. -// -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#[derive(Copy)] -pub struct EnvValue<'tcx> { - action: ast::CaptureClause, - datum: Datum<'tcx, Lvalue> -} - -impl<'tcx> EnvValue<'tcx> { - pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String { - format!("{:?}({})", self.action, self.datum.to_string(ccx)) - } -} - -// Given a closure ty, emits a corresponding tuple ty -pub fn mk_closure_tys<'tcx>(tcx: &ty::ctxt<'tcx>, - bound_values: &[EnvValue<'tcx>]) - -> Ty<'tcx> { - // determine the types of the values in the env. Note that this - // is the actual types that will be stored in the map, not the - // logical types as the user sees them, so by-ref upvars must be - // converted to ptrs. - let bound_tys = bound_values.iter().map(|bv| { - match bv.action { - ast::CaptureByValue => bv.datum.ty, - ast::CaptureByRef => ty::mk_mut_ptr(tcx, bv.datum.ty) - } - }).collect(); - let cdata_ty = ty::mk_tup(tcx, bound_tys); - debug!("cdata_ty={}", ty_to_string(tcx, cdata_ty)); - return cdata_ty; -} - -fn tuplify_box_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> Ty<'tcx> { - let ptr = ty::mk_imm_ptr(tcx, tcx.types.i8); - ty::mk_tup(tcx, vec!(tcx.types.uint, ty::mk_nil_ptr(tcx), ptr, ptr, t)) -} - -pub struct ClosureResult<'blk, 'tcx: 'blk> { - llbox: ValueRef, // llvalue of ptr to closure - cdata_ty: Ty<'tcx>, // type of the closure data - bcx: Block<'blk, 'tcx> // final bcx -} - -// Given a block context and a list of tydescs and values to bind -// construct a closure out of them. If copying is true, it is a -// heap allocated closure that copies the upvars into environment. -// Otherwise, it is stack allocated and copies pointers to the upvars. -pub fn store_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - bound_values: Vec>) - -> ClosureResult<'blk, 'tcx> { - let _icx = push_ctxt("closure::store_environment"); - let ccx = bcx.ccx(); - let tcx = ccx.tcx(); - - // compute the type of the closure - let cdata_ty = mk_closure_tys(tcx, &bound_values[]); - - // cbox_ty has the form of a tuple: (a, b, c) we want a ptr to a - // tuple. This could be a ptr in uniq or a box or on stack, - // whatever. - let cbox_ty = tuplify_box_ty(tcx, cdata_ty); - let cboxptr_ty = ty::mk_ptr(tcx, ty::mt {ty:cbox_ty, mutbl:ast::MutImmutable}); - let llboxptr_ty = type_of(ccx, cboxptr_ty); - - // If there are no bound values, no point in allocating anything. - if bound_values.is_empty() { - return ClosureResult {llbox: C_null(llboxptr_ty), - cdata_ty: cdata_ty, - bcx: bcx}; - } - - // allocate closure in the heap - let llbox = alloc_ty(bcx, cbox_ty, "__closure"); - - let llbox = PointerCast(bcx, llbox, llboxptr_ty); - debug!("tuplify_box_ty = {}", ty_to_string(tcx, cbox_ty)); - - // Copy expr values into boxed bindings. - let mut bcx = bcx; - for (i, bv) in bound_values.into_iter().enumerate() { - debug!("Copy {} into closure", bv.to_string(ccx)); - - if ccx.sess().asm_comments() { - add_comment(bcx, &format!("Copy {} into closure", - bv.to_string(ccx))[]); - } - - let bound_data = GEPi(bcx, llbox, &[0u, abi::BOX_FIELD_BODY, i]); - - match bv.action { - ast::CaptureByValue => { - bcx = bv.datum.store_to(bcx, bound_data); - } - ast::CaptureByRef => { - Store(bcx, bv.datum.to_llref(), bound_data); - } - } - } - - ClosureResult { llbox: llbox, cdata_ty: cdata_ty, bcx: bcx } -} - -// Given a context and a list of upvars, build a closure. This just -// collects the upvars and packages them up for store_environment. -fn build_closure<'blk, 'tcx>(bcx0: Block<'blk, 'tcx>, - freevar_mode: ast::CaptureClause, - freevars: &Vec) - -> ClosureResult<'blk, 'tcx> { - let _icx = push_ctxt("closure::build_closure"); - - // If we need to, package up the iterator body to call - let bcx = bcx0; - - // Package up the captured upvars - let mut env_vals = Vec::new(); - for freevar in freevars.iter() { - let datum = expr::trans_local_var(bcx, freevar.def); - env_vals.push(EnvValue {action: freevar_mode, datum: datum}); - } - - store_environment(bcx, env_vals) -} - -// Given an enclosing block context, a new function context, a closure type, -// and a list of upvars, generate code to load and populate the environment -// with the upvars and type descriptors. -fn load_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - cdata_ty: Ty<'tcx>, - freevars: &[ty::Freevar], - store: ty::TraitStore) - -> Block<'blk, 'tcx> { - let _icx = push_ctxt("closure::load_environment"); - - // Load a pointer to the closure data, skipping over the box header: - let llcdata = at_box_body(bcx, cdata_ty, bcx.fcx.llenv.unwrap()); - - // Store the pointer to closure data in an alloca for debug info because that's what the - // llvm.dbg.declare intrinsic expects - let env_pointer_alloca = if bcx.sess().opts.debuginfo == FullDebugInfo { - let alloc = alloc_ty(bcx, ty::mk_mut_ptr(bcx.tcx(), cdata_ty), "__debuginfo_env_ptr"); - Store(bcx, llcdata, alloc); - Some(alloc) - } else { - None - }; - - // Populate the upvars from the environment - let mut i = 0u; - for freevar in freevars.iter() { - let mut upvarptr = GEPi(bcx, llcdata, &[0u, i]); - let captured_by_ref = match store { - ty::RegionTraitStore(..) => { - upvarptr = Load(bcx, upvarptr); - true - } - ty::UniqTraitStore => false - }; - let def_id = freevar.def.def_id(); - - bcx.fcx.llupvars.borrow_mut().insert(def_id.node, upvarptr); - if let Some(env_pointer_alloca) = env_pointer_alloca { - debuginfo::create_captured_var_metadata( - bcx, - def_id.node, - env_pointer_alloca, - i, - captured_by_ref, - freevar.span); - } - - i += 1u; - } - - bcx -} fn load_unboxed_closure_environment<'blk, 'tcx>( bcx: Block<'blk, 'tcx>, @@ -281,7 +37,7 @@ fn load_unboxed_closure_environment<'blk, 'tcx>( freevar_mode: ast::CaptureClause, freevars: &[ty::Freevar]) -> Block<'blk, 'tcx> { - let _icx = push_ctxt("closure::load_environment"); + let _icx = push_ctxt("closure::load_unboxed_closure_environment"); // Special case for small by-value selfs. let closure_id = ast_util::local_def(bcx.fcx.id); @@ -341,17 +97,9 @@ fn load_unboxed_closure_environment<'blk, 'tcx>( bcx } -fn fill_fn_pair(bcx: Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef) { - Store(bcx, llfn, GEPi(bcx, pair, &[0u, abi::FAT_PTR_ADDR])); - let llenvptr = PointerCast(bcx, llenvptr, Type::i8p(bcx.ccx())); - Store(bcx, llenvptr, GEPi(bcx, pair, &[0u, abi::FAT_PTR_EXTRA])); -} - #[derive(PartialEq)] pub enum ClosureKind<'tcx> { NotClosure, - // See load_environment. - BoxedClosure(Ty<'tcx>, ty::TraitStore), // See load_unboxed_closure_environment. UnboxedClosure(ast::CaptureClause) } @@ -379,9 +127,6 @@ pub fn load<'blk>(self, bcx: Block<'blk, 'tcx>, arg_scope: ScopeId) match self.kind { NotClosure => bcx, - BoxedClosure(cdata_ty, store) => { - load_environment(bcx, cdata_ty, self.freevars, store) - } UnboxedClosure(freevar_mode) => { load_unboxed_closure_environment(bcx, arg_scope, freevar_mode, self.freevars) } @@ -389,67 +134,6 @@ pub fn load<'blk>(self, bcx: Block<'blk, 'tcx>, arg_scope: ScopeId) } } -/// Translates the body of a closure expression. -/// -/// - `store` -/// - `decl` -/// - `body` -/// - `id`: The id of the closure expression. -/// - `cap_clause`: information about captured variables, if any. -/// - `dest`: where to write the closure value, which must be a -/// (fn ptr, env) pair -pub fn trans_expr_fn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - store: ty::TraitStore, - decl: &ast::FnDecl, - body: &ast::Block, - id: ast::NodeId, - dest: expr::Dest) - -> Block<'blk, 'tcx> { - let _icx = push_ctxt("closure::trans_expr_fn"); - - let dest_addr = match dest { - expr::SaveIn(p) => p, - expr::Ignore => { - return bcx; // closure construction is non-side-effecting - } - }; - - let ccx = bcx.ccx(); - let tcx = bcx.tcx(); - let fty = node_id_type(bcx, id); - let s = tcx.map.with_path(id, |path| { - mangle_internal_name_by_path_and_seq(path, "closure") - }); - let llfn = decl_internal_rust_fn(ccx, fty, &s[]); - - // set an inline hint for all closures - set_inline_hint(llfn); - - let freevar_mode = tcx.capture_mode(id); - let freevars: Vec = - ty::with_freevars(tcx, id, |fv| fv.iter().map(|&fv| fv).collect()); - - let ClosureResult { - llbox, - cdata_ty, - bcx - } = build_closure(bcx, freevar_mode, &freevars); - - trans_closure(ccx, - decl, - body, - llfn, - bcx.fcx.param_substs, - id, - &[], - ty::erase_late_bound_regions(ccx.tcx(), &ty::ty_fn_ret(fty)), - ty::ty_fn_abi(fty), - ClosureEnv::new(&freevars[], - BoxedClosure(cdata_ty, store))); - fill_fn_pair(bcx, dest_addr, llfn, llbox); - bcx -} - /// Returns the LLVM function declaration for an unboxed closure, creating it /// if necessary. If the ID does not correspond to a closure ID, returns None. pub fn get_or_create_declaration_if_unboxed_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 2f01f0328e28c21fb7ee45124db52cd07f6959af..a8a7b7243f1a9d23e5904a6380f459fd784b78d7 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -552,7 +552,6 @@ fn get_unique_type_id_of_closure_type<'a>(&mut self, unique_type_id: &mut String) { let ty::ClosureTy { unsafety, onceness, - store, ref bounds, ref sig, abi: _ } = closure_ty; @@ -564,15 +563,7 @@ fn get_unique_type_id_of_closure_type<'a>(&mut self, unique_type_id.push_str("once "); } - match store { - ty::UniqTraitStore => unique_type_id.push_str("~|"), - ty::RegionTraitStore(_, ast::MutMutable) => { - unique_type_id.push_str("&mut|") - } - ty::RegionTraitStore(_, ast::MutImmutable) => { - unique_type_id.push_str("&|") - } - }; + unique_type_id.push_str("|"); let sig = ty::erase_late_bound_regions(cx.tcx(), sig); diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 11d1c7e67968115382c32099a21e2ec514c756a5..da900f0a59eeb5af8fbbfac25d1dbd9dc5fee750 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -65,7 +65,6 @@ use trans::type_::Type; use syntax::{ast, ast_util, codemap}; -use syntax::print::pprust::{expr_to_string}; use syntax::ptr::P; use syntax::parse::token; use std::rc::Rc; @@ -1102,17 +1101,7 @@ fn make_field(field_name: &str, expr: P) -> ast::Field { // closure or an older, legacy style closure. Store this // into a variable to ensure the the RefCell-lock is // released before we recurse. - let is_unboxed_closure = - bcx.tcx().unboxed_closures.borrow().contains_key(&ast_util::local_def(expr.id)); - if is_unboxed_closure { - closure::trans_unboxed_closure(bcx, &**decl, &**body, expr.id, dest) - } else { - let expr_ty = expr_ty(bcx, expr); - let store = ty::ty_closure_store(expr_ty); - debug!("translating block function {} with type {}", - expr_to_string(expr), expr_ty.repr(tcx)); - closure::trans_expr_fn(bcx, store, &**decl, &**body, expr.id, dest) - } + closure::trans_unboxed_closure(bcx, &**decl, &**body, expr.id, dest) } ast::ExprCall(ref f, ref args) => { if bcx.tcx().is_method_call(expr.id) { diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index 07eb17e6300cdf9fcd424ef78ff8665b0b8ab5f9..5710fa24925d29e0b02ff5ea6140eab142aafac2 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -227,14 +227,6 @@ pub fn opaque_vec(ccx: &CrateContext) -> Type { Type::vec(ccx, &Type::i8(ccx)) } - // The box pointed to by @T. - pub fn at_box(ccx: &CrateContext, ty: Type) -> Type { - Type::struct_(ccx, &[ - ccx.int_type(), Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to(), - Type::i8p(ccx), Type::i8p(ccx), ty - ], false) - } - pub fn vtable_ptr(ccx: &CrateContext) -> Type { Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to().ptr_to() } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 42b12c158664ae2247d1e2a60744bda4f08ad8fc..44434c2e91b3546d616203f78cfcd02c82c4f45b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1459,7 +1459,6 @@ pub fn ty_of_closure<'tcx>( unsafety: ast::Unsafety, onceness: ast::Onceness, bounds: ty::ExistentialBounds<'tcx>, - store: ty::TraitStore, decl: &ast::FnDecl, abi: abi::Abi, expected_sig: Option>) @@ -1510,7 +1509,6 @@ pub fn ty_of_closure<'tcx>( ty::ClosureTy { unsafety: unsafety, onceness: onceness, - store: store, bounds: bounds, abi: abi, sig: ty::Binder(ty::FnSig {inputs: input_tys, diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index bfe43086aab10205a38022dc89129dfce5712fb1..4c1083c4b6332556d4e7e77f8eb223378f6c99fa 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -96,7 +96,6 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, // // FIXME(pcwalton): Refactor this API. ty::region_existential_bound(ty::ReStatic), - ty::RegionTraitStore(ty::ReStatic, ast::MutImmutable), decl, abi::RustCall,