auto merge of #13461 : eddyb/rust/cleanup-at-fn, r=luqmana
This commit is contained in:
commit
96aeb7e3c3
@ -260,8 +260,7 @@ impl<'a> Visitor<()> for Context<'a> {
|
||||
|
||||
fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
|
||||
match t.node {
|
||||
ast::TyClosure(closure) if closure.onceness == ast::Once &&
|
||||
closure.sigil != ast::OwnedSigil => {
|
||||
ast::TyClosure(closure, _) if closure.onceness == ast::Once => {
|
||||
self.gate_feature("once_fns", t.span,
|
||||
"once functions are \
|
||||
experimental and likely to be removed");
|
||||
|
@ -137,15 +137,6 @@ pub fn parse_substs_data(data: &[u8], crate_num: ast::CrateNum, pos: uint, tcx:
|
||||
parse_substs(&mut st, conv)
|
||||
}
|
||||
|
||||
fn parse_sigil(st: &mut PState) -> ast::Sigil {
|
||||
match next(st) {
|
||||
'@' => ast::ManagedSigil,
|
||||
'~' => ast::OwnedSigil,
|
||||
'&' => ast::BorrowedSigil,
|
||||
c => st.tcx.sess.bug(format!("parse_sigil(): bad input '{}'", c))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_vstore<M>(st: &mut PState, conv: conv_did,
|
||||
parse_mut: |&mut PState| -> M) -> ty::Vstore<M> {
|
||||
assert_eq!(next(st), '/');
|
||||
@ -476,17 +467,15 @@ fn parse_onceness(c: char) -> ast::Onceness {
|
||||
}
|
||||
|
||||
fn parse_closure_ty(st: &mut PState, conv: conv_did) -> ty::ClosureTy {
|
||||
let sigil = parse_sigil(st);
|
||||
let fn_style = parse_fn_style(next(st));
|
||||
let onceness = parse_onceness(next(st));
|
||||
let region = parse_region(st, |x,y| conv(x,y));
|
||||
let store = parse_trait_store(st, |x,y| conv(x,y));
|
||||
let bounds = parse_bounds(st, |x,y| conv(x,y));
|
||||
let sig = parse_sig(st, |x,y| conv(x,y));
|
||||
ty::ClosureTy {
|
||||
fn_style: fn_style,
|
||||
sigil: sigil,
|
||||
onceness: onceness,
|
||||
region: region,
|
||||
store: store,
|
||||
bounds: bounds.builtin_bounds,
|
||||
sig: sig
|
||||
}
|
||||
|
@ -327,14 +327,6 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_sigil(w: &mut MemWriter, sigil: Sigil) {
|
||||
match sigil {
|
||||
ManagedSigil => mywrite!(w, "@"),
|
||||
OwnedSigil => mywrite!(w, "~"),
|
||||
BorrowedSigil => mywrite!(w, "&"),
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_fn_style(w: &mut MemWriter, p: FnStyle) {
|
||||
match p {
|
||||
NormalFn => mywrite!(w, "n"),
|
||||
@ -363,10 +355,9 @@ pub fn enc_bare_fn_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::BareFnTy) {
|
||||
}
|
||||
|
||||
fn enc_closure_ty(w: &mut MemWriter, cx: &ctxt, ft: &ty::ClosureTy) {
|
||||
enc_sigil(w, ft.sigil);
|
||||
enc_fn_style(w, ft.fn_style);
|
||||
enc_onceness(w, ft.onceness);
|
||||
enc_region(w, cx, ft.region);
|
||||
enc_trait_store(w, cx, ft.store);
|
||||
let bounds = ty::ParamBounds {builtin_bounds: ft.bounds,
|
||||
trait_bounds: Vec::new()};
|
||||
enc_bounds(w, cx, &bounds);
|
||||
|
@ -897,10 +897,9 @@ impl<'a> ebml_writer_helpers for Encoder<'a> {
|
||||
fn emit_auto_adjustment(&mut self, ecx: &e::EncodeContext, adj: &ty::AutoAdjustment) {
|
||||
self.emit_enum("AutoAdjustment", |this| {
|
||||
match *adj {
|
||||
ty::AutoAddEnv(region, sigil) => {
|
||||
this.emit_enum_variant("AutoAddEnv", 0, 2, |this| {
|
||||
this.emit_enum_variant_arg(0, |this| region.encode(this));
|
||||
this.emit_enum_variant_arg(1, |this| sigil.encode(this))
|
||||
ty::AutoAddEnv(store) => {
|
||||
this.emit_enum_variant("AutoAddEnv", 0, 1, |this| {
|
||||
this.emit_enum_variant_arg(0, |this| store.encode(this))
|
||||
})
|
||||
}
|
||||
|
||||
@ -1270,12 +1269,10 @@ impl<'a> ebml_decoder_decoder_helpers for reader::Decoder<'a> {
|
||||
this.read_enum_variant(variants, |this, i| {
|
||||
Ok(match i {
|
||||
0 => {
|
||||
let region: ty::Region =
|
||||
let store: ty::TraitStore =
|
||||
this.read_enum_variant_arg(0, |this| Decodable::decode(this)).unwrap();
|
||||
let sigil: ast::Sigil =
|
||||
this.read_enum_variant_arg(1, |this| Decodable::decode(this)).unwrap();
|
||||
|
||||
ty:: AutoAddEnv(region.tr(xcx), sigil)
|
||||
ty:: AutoAddEnv(store.tr(xcx))
|
||||
}
|
||||
1 => {
|
||||
let auto_deref_ref: ty::AutoDerefRef =
|
||||
|
@ -451,17 +451,8 @@ impl<'a> GatherLoanCtxt<'a> {
|
||||
r,
|
||||
AutoRef)
|
||||
}
|
||||
ty::AutoBorrowFn(r) => {
|
||||
let cmt_deref = mc.cat_deref_fn_or_obj(expr, cmt, 0);
|
||||
self.guarantee_valid(expr.id,
|
||||
expr.span,
|
||||
cmt_deref,
|
||||
ast::MutImmutable,
|
||||
r,
|
||||
AutoRef)
|
||||
}
|
||||
ty::AutoBorrowObj(r, m) => {
|
||||
let cmt_deref = mc.cat_deref_fn_or_obj(expr, cmt, 0);
|
||||
let cmt_deref = mc.cat_deref_obj(expr, cmt);
|
||||
self.guarantee_valid(expr.id,
|
||||
expr.span,
|
||||
cmt_deref,
|
||||
|
@ -620,7 +620,7 @@ impl<'a> BorrowckCtxt<'a> {
|
||||
fn move_suggestion(tcx: &ty::ctxt, ty: ty::t, default_msg: &'static str)
|
||||
-> &'static str {
|
||||
match ty::get(ty).sty {
|
||||
ty::ty_closure(ref cty) if cty.sigil == ast::BorrowedSigil =>
|
||||
ty::ty_closure(~ty::ClosureTy { 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) =>
|
||||
|
@ -197,27 +197,13 @@ fn with_appropriate_checker(cx: &Context,
|
||||
let fty = ty::node_id_to_type(cx.tcx, id);
|
||||
match ty::get(fty).sty {
|
||||
ty::ty_closure(~ty::ClosureTy {
|
||||
sigil: OwnedSigil,
|
||||
bounds: bounds,
|
||||
..
|
||||
}) => {
|
||||
b(|cx, fv| check_for_uniq(cx, fv, bounds))
|
||||
}
|
||||
store: ty::UniqTraitStore, bounds, ..
|
||||
}) => b(|cx, fv| check_for_uniq(cx, fv, bounds)),
|
||||
|
||||
ty::ty_closure(~ty::ClosureTy {
|
||||
sigil: ManagedSigil,
|
||||
..
|
||||
}) => {
|
||||
// can't happen
|
||||
fail!("internal error: saw closure with managed sigil (@fn)");
|
||||
}
|
||||
ty::ty_closure(~ty::ClosureTy {
|
||||
sigil: BorrowedSigil,
|
||||
bounds: bounds,
|
||||
region: region,
|
||||
..
|
||||
}) => {
|
||||
b(|cx, fv| check_for_block(cx, fv, bounds, region))
|
||||
}
|
||||
store: ty::RegionTraitStore(region, _), bounds, ..
|
||||
}) => b(|cx, fv| check_for_block(cx, fv, bounds, region)),
|
||||
|
||||
ty::ty_bare_fn(_) => {
|
||||
b(check_for_bare)
|
||||
}
|
||||
|
@ -919,10 +919,8 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
|
||||
}
|
||||
ty::ty_uniq(_) | ty::ty_str(ty::VstoreUniq) |
|
||||
ty::ty_vec(_, ty::VstoreUniq) |
|
||||
ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) => {
|
||||
n_uniq += 1;
|
||||
}
|
||||
ty::ty_closure(ref c) if c.sigil == ast::OwnedSigil => {
|
||||
ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
|
||||
ty::ty_closure(~ty::ClosureTy { store: ty::UniqTraitStore, .. }) => {
|
||||
n_uniq += 1;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ use syntax::parse::token;
|
||||
pub enum categorization {
|
||||
cat_rvalue(ty::Region), // temporary val, argument is its scope
|
||||
cat_static_item,
|
||||
cat_copied_upvar(CopiedUpvar), // upvar copied into @fn or ~fn env
|
||||
cat_copied_upvar(CopiedUpvar), // upvar copied into proc env
|
||||
cat_upvar(ty::UpvarId, ty::UpvarBorrow), // by ref upvar from stack closure
|
||||
cat_local(ast::NodeId), // local variable
|
||||
cat_arg(ast::NodeId), // formal argument
|
||||
@ -172,7 +172,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
|
||||
ty::ty_vec(_, ty::VstoreUniq) |
|
||||
ty::ty_str(ty::VstoreUniq) |
|
||||
ty::ty_closure(~ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
|
||||
Some(deref_ptr(OwnedPtr))
|
||||
}
|
||||
|
||||
@ -187,8 +187,7 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
|
||||
}
|
||||
|
||||
ty::ty_str(ty::VstoreSlice(r, ())) |
|
||||
ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil,
|
||||
region: r, ..}) => {
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(r, _), ..}) => {
|
||||
Some(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
|
||||
}
|
||||
|
||||
@ -540,15 +539,14 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
||||
// Decide whether to use implicit reference or by copy/move
|
||||
// capture for the upvar. This, combined with the onceness,
|
||||
// determines whether the closure can move out of it.
|
||||
let var_is_refd = match (closure_ty.sigil, closure_ty.onceness) {
|
||||
let var_is_refd = match (closure_ty.store, closure_ty.onceness) {
|
||||
// Many-shot stack closures can never move out.
|
||||
(ast::BorrowedSigil, ast::Many) => true,
|
||||
(ty::RegionTraitStore(..), ast::Many) => true,
|
||||
// 1-shot stack closures can move out.
|
||||
(ast::BorrowedSigil, ast::Once) => false,
|
||||
(ty::RegionTraitStore(..), ast::Once) => false,
|
||||
// Heap closures always capture by copy/move, and can
|
||||
// move out if they are once.
|
||||
(ast::OwnedSigil, _) |
|
||||
(ast::ManagedSigil, _) => false,
|
||||
(ty::UniqTraitStore, _) => false,
|
||||
|
||||
};
|
||||
if var_is_refd {
|
||||
@ -688,19 +686,8 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cat_deref_fn_or_obj<N:ast_node>(&mut self,
|
||||
node: &N,
|
||||
base_cmt: cmt,
|
||||
deref_cnt: uint)
|
||||
-> cmt {
|
||||
// Bit of a hack: the "dereference" of a function pointer like
|
||||
// `@fn()` is a mere logical concept. We interpret it as
|
||||
// dereferencing the environment pointer; of course, we don't
|
||||
// know what type lies at the other end, so we just call it
|
||||
// `()` (the empty tuple).
|
||||
|
||||
let opaque_ty = ty::mk_tup(self.tcx(), Vec::new());
|
||||
self.cat_deref_common(node, base_cmt, deref_cnt, opaque_ty)
|
||||
pub fn cat_deref_obj<N:ast_node>(&mut self, node: &N, base_cmt: cmt) -> cmt {
|
||||
self.cat_deref_common(node, base_cmt, 0, ty::mk_nil())
|
||||
}
|
||||
|
||||
fn cat_deref<N:ast_node>(&mut self,
|
||||
@ -1105,7 +1092,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
||||
~"static item"
|
||||
}
|
||||
cat_copied_upvar(_) => {
|
||||
~"captured outer variable in a heap closure"
|
||||
~"captured outer variable in a proc"
|
||||
}
|
||||
cat_rvalue(..) => {
|
||||
~"non-lvalue"
|
||||
|
@ -650,30 +650,30 @@ impl<'a> VisitContext<'a> {
|
||||
let _indenter = indenter();
|
||||
|
||||
let fn_ty = ty::node_id_to_type(self.tcx, fn_expr_id);
|
||||
let sigil = ty::ty_closure_sigil(fn_ty);
|
||||
let freevars = freevars::get_freevars(self.tcx, fn_expr_id);
|
||||
let v = if sigil == BorrowedSigil {
|
||||
// || captures everything by ref
|
||||
freevars.iter()
|
||||
.map(|fvar| CaptureVar {def: fvar.def, span: fvar.span, mode: CapRef})
|
||||
.collect()
|
||||
} else {
|
||||
// @fn() and ~fn() capture by copy or by move depending on type
|
||||
freevars.iter()
|
||||
.map(|fvar| {
|
||||
let fvar_def_id = ast_util::def_id_of_def(fvar.def).node;
|
||||
let fvar_ty = ty::node_id_to_type(self.tcx, fvar_def_id);
|
||||
debug!("fvar_def_id={:?} fvar_ty={}",
|
||||
fvar_def_id, ppaux::ty_to_str(self.tcx, fvar_ty));
|
||||
let mode = if ty::type_moves_by_default(self.tcx, fvar_ty) {
|
||||
CapMove
|
||||
} else {
|
||||
CapCopy
|
||||
};
|
||||
CaptureVar {def: fvar.def, span: fvar.span, mode:mode}
|
||||
|
||||
Rc::new(match ty::ty_closure_store(fn_ty) {
|
||||
ty::RegionTraitStore(..) => {
|
||||
// || captures everything by ref
|
||||
freevars.iter()
|
||||
.map(|fvar| CaptureVar {def: fvar.def, span: fvar.span, mode: CapRef})
|
||||
.collect()
|
||||
}
|
||||
ty::UniqTraitStore => {
|
||||
// proc captures by copy or by move depending on type
|
||||
freevars.iter()
|
||||
.map(|fvar| {
|
||||
let fvar_def_id = ast_util::def_id_of_def(fvar.def).node;
|
||||
let fvar_ty = ty::node_id_to_type(self.tcx, fvar_def_id);
|
||||
debug!("fvar_def_id={:?} fvar_ty={}",
|
||||
fvar_def_id, ppaux::ty_to_str(self.tcx, fvar_ty));
|
||||
let mode = if ty::type_moves_by_default(self.tcx, fvar_ty) {
|
||||
CapMove
|
||||
} else {
|
||||
CapCopy
|
||||
};
|
||||
CaptureVar {def: fvar.def, span: fvar.span, mode:mode}
|
||||
}).collect()
|
||||
};
|
||||
Rc::new(v)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -4274,7 +4274,7 @@ impl<'a> Resolver<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
TyClosure(c) => {
|
||||
TyClosure(c, _) | TyProc(c) => {
|
||||
c.bounds.as_ref().map(|bounds| {
|
||||
for bound in bounds.iter() {
|
||||
self.resolve_type_parameter_bound(ty.id, bound);
|
||||
|
@ -112,7 +112,9 @@ impl<'a, 'b> Visitor<Scope<'a>> for LifetimeContext<'b> {
|
||||
|
||||
fn visit_ty(&mut self, ty: &ast::Ty, scope: Scope<'a>) {
|
||||
match ty.node {
|
||||
ast::TyClosure(c) => push_fn_scope(self, ty, scope, &c.lifetimes),
|
||||
ast::TyClosure(c, _) | ast::TyProc(c) => {
|
||||
push_fn_scope(self, ty, scope, &c.lifetimes);
|
||||
}
|
||||
ast::TyBareFn(c) => push_fn_scope(self, ty, scope, &c.lifetimes),
|
||||
_ => visit::walk_ty(self, ty, scope),
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
|
||||
// noalias because the actual object pointer is nested.
|
||||
ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
|
||||
ty::ty_vec(_, ty::VstoreUniq) | ty::ty_str(ty::VstoreUniq) |
|
||||
ty::ty_closure(~ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::UniqTraitStore, ..}) => {
|
||||
unsafe {
|
||||
llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
|
||||
}
|
||||
|
@ -38,17 +38,14 @@ use syntax::ast_util;
|
||||
// roughly as follows:
|
||||
//
|
||||
// struct rust_opaque_box { // see rust_internal.h
|
||||
// unsigned ref_count; // only used for @fn()
|
||||
// type_desc *tydesc; // describes closure_data struct
|
||||
// rust_opaque_box *prev; // (used internally by memory alloc)
|
||||
// rust_opaque_box *next; // (used internally by memory alloc)
|
||||
// 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 {
|
||||
// type_desc *bound_tdescs[]; // bound descriptors
|
||||
// struct {
|
||||
// upvar1_t upvar1;
|
||||
// ...
|
||||
// upvarN_t upvarN;
|
||||
// } bound_data;
|
||||
// upvar1_t upvar1;
|
||||
// ...
|
||||
// upvarN_t upvarN;
|
||||
// }
|
||||
// };
|
||||
//
|
||||
@ -158,24 +155,21 @@ fn tuplify_box_ty(tcx: &ty::ctxt, t: ty::t) -> ty::t {
|
||||
}
|
||||
|
||||
fn allocate_cbox<'a>(bcx: &'a Block<'a>,
|
||||
sigil: ast::Sigil,
|
||||
store: ty::TraitStore,
|
||||
cdata_ty: ty::t)
|
||||
-> Result<'a> {
|
||||
let _icx = push_ctxt("closure::allocate_cbox");
|
||||
let tcx = bcx.tcx();
|
||||
|
||||
// Allocate and initialize the box:
|
||||
match sigil {
|
||||
ast::ManagedSigil => {
|
||||
tcx.sess.bug("trying to trans allocation of @fn")
|
||||
}
|
||||
ast::OwnedSigil => {
|
||||
match store {
|
||||
ty::UniqTraitStore => {
|
||||
let ty = type_of(bcx.ccx(), cdata_ty);
|
||||
let size = llsize_of(bcx.ccx(), ty);
|
||||
// we treat proc as @ here, which isn't ideal
|
||||
malloc_raw_dyn_managed(bcx, cdata_ty, ClosureExchangeMallocFnLangItem, size)
|
||||
}
|
||||
ast::BorrowedSigil => {
|
||||
ty::RegionTraitStore(..) => {
|
||||
let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
|
||||
let llbox = alloc_ty(bcx, cbox_ty, "__closure");
|
||||
rslt(bcx, llbox)
|
||||
@ -196,7 +190,7 @@ pub struct ClosureResult<'a> {
|
||||
pub fn store_environment<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
bound_values: Vec<EnvValue> ,
|
||||
sigil: ast::Sigil)
|
||||
store: ty::TraitStore)
|
||||
-> ClosureResult<'a> {
|
||||
let _icx = push_ctxt("closure::store_environment");
|
||||
let ccx = bcx.ccx();
|
||||
@ -220,7 +214,7 @@ pub fn store_environment<'a>(
|
||||
}
|
||||
|
||||
// allocate closure in the heap
|
||||
let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, sigil, cdata_ty);
|
||||
let Result {bcx: bcx, val: llbox} = allocate_cbox(bcx, store, cdata_ty);
|
||||
|
||||
let llbox = PointerCast(bcx, llbox, llboxptr_ty);
|
||||
debug!("tuplify_box_ty = {}", ty_to_str(tcx, cbox_ty));
|
||||
@ -254,7 +248,7 @@ pub fn store_environment<'a>(
|
||||
// collects the upvars and packages them up for store_environment.
|
||||
fn build_closure<'a>(bcx0: &'a Block<'a>,
|
||||
cap_vars: &[moves::CaptureVar],
|
||||
sigil: ast::Sigil)
|
||||
store: ty::TraitStore)
|
||||
-> ClosureResult<'a> {
|
||||
let _icx = push_ctxt("closure::build_closure");
|
||||
|
||||
@ -268,7 +262,11 @@ fn build_closure<'a>(bcx0: &'a Block<'a>,
|
||||
let datum = expr::trans_local_var(bcx, cap_var.def);
|
||||
match cap_var.mode {
|
||||
moves::CapRef => {
|
||||
assert_eq!(sigil, ast::BorrowedSigil);
|
||||
let is_region_closure = match store {
|
||||
ty::RegionTraitStore(..) => true,
|
||||
ty::UniqTraitStore => false
|
||||
};
|
||||
assert!(is_region_closure);
|
||||
env_vals.push(EnvValue {action: EnvRef,
|
||||
datum: datum});
|
||||
}
|
||||
@ -283,7 +281,7 @@ fn build_closure<'a>(bcx0: &'a Block<'a>,
|
||||
}
|
||||
}
|
||||
|
||||
return store_environment(bcx, env_vals, sigil);
|
||||
store_environment(bcx, env_vals, store)
|
||||
}
|
||||
|
||||
// Given an enclosing block context, a new function context, a closure type,
|
||||
@ -291,7 +289,7 @@ fn build_closure<'a>(bcx0: &'a Block<'a>,
|
||||
// with the upvars and type descriptors.
|
||||
fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
|
||||
cap_vars: &[moves::CaptureVar],
|
||||
sigil: ast::Sigil) -> &'a Block<'a> {
|
||||
store: ty::TraitStore) -> &'a Block<'a> {
|
||||
let _icx = push_ctxt("closure::load_environment");
|
||||
|
||||
// Don't bother to create the block if there's nothing to load
|
||||
@ -316,9 +314,9 @@ fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
|
||||
let mut i = 0u;
|
||||
for cap_var in cap_vars.iter() {
|
||||
let mut upvarptr = GEPi(bcx, llcdata, [0u, i]);
|
||||
match sigil {
|
||||
ast::BorrowedSigil => { upvarptr = Load(bcx, upvarptr); }
|
||||
ast::ManagedSigil | ast::OwnedSigil => {}
|
||||
match store {
|
||||
ty::RegionTraitStore(..) => { upvarptr = Load(bcx, upvarptr); }
|
||||
ty::UniqTraitStore => {}
|
||||
}
|
||||
let def_id = ast_util::def_id_of_def(cap_var.def);
|
||||
|
||||
@ -331,7 +329,7 @@ fn load_environment<'a>(bcx: &'a Block<'a>, cdata_ty: ty::t,
|
||||
cdata_ty,
|
||||
env_pointer_alloca,
|
||||
i,
|
||||
sigil,
|
||||
store,
|
||||
cap_var.span);
|
||||
}
|
||||
|
||||
@ -349,7 +347,7 @@ fn fill_fn_pair(bcx: &Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef)
|
||||
|
||||
pub fn trans_expr_fn<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
sigil: ast::Sigil,
|
||||
store: ty::TraitStore,
|
||||
decl: &ast::FnDecl,
|
||||
body: &ast::Block,
|
||||
id: ast::NodeId,
|
||||
@ -359,7 +357,7 @@ pub fn trans_expr_fn<'a>(
|
||||
*
|
||||
* Translates the body of a closure expression.
|
||||
*
|
||||
* - `sigil`
|
||||
* - `store`
|
||||
* - `decl`
|
||||
* - `body`
|
||||
* - `id`: The id of the closure expression.
|
||||
@ -399,11 +397,11 @@ pub fn trans_expr_fn<'a>(
|
||||
|
||||
let cap_vars = ccx.maps.capture_map.borrow().get_copy(&id);
|
||||
let ClosureResult {llbox, cdata_ty, bcx} =
|
||||
build_closure(bcx, cap_vars.as_slice(), sigil);
|
||||
build_closure(bcx, cap_vars.as_slice(), store);
|
||||
trans_closure(ccx, decl, body, llfn,
|
||||
bcx.fcx.param_substs, id,
|
||||
[], ty::ty_fn_ret(fty),
|
||||
|bcx| load_environment(bcx, cdata_ty, cap_vars.as_slice(), sigil));
|
||||
|bcx| load_environment(bcx, cdata_ty, cap_vars.as_slice(), store));
|
||||
fill_fn_pair(bcx, dest_addr, llfn, llbox);
|
||||
|
||||
bcx
|
||||
|
@ -191,7 +191,7 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
|
||||
None => { }
|
||||
Some(adj) => {
|
||||
match *adj {
|
||||
ty::AutoAddEnv(ty::ReStatic, ast::BorrowedSigil) => {
|
||||
ty::AutoAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
|
||||
let def = ty::resolve_expr(cx.tcx(), e);
|
||||
let wrapper = closure::get_wrapper_for_bare_fn(cx,
|
||||
ety_adjusted,
|
||||
@ -200,13 +200,11 @@ pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef
|
||||
is_local);
|
||||
llconst = C_struct(cx, [wrapper, C_null(Type::i8p(cx))], false)
|
||||
}
|
||||
ty::AutoAddEnv(ref r, ref s) => {
|
||||
ty::AutoAddEnv(store) => {
|
||||
cx.sess()
|
||||
.span_bug(e.span,
|
||||
format!("unexpected static function: region \
|
||||
{:?} sigil {:?}",
|
||||
*r,
|
||||
*s))
|
||||
format!("unexpected static function: {:?}",
|
||||
store))
|
||||
}
|
||||
ty::AutoObject(..) => {
|
||||
cx.sess()
|
||||
|
@ -394,7 +394,7 @@ pub fn create_captured_var_metadata(bcx: &Block,
|
||||
env_data_type: ty::t,
|
||||
env_pointer: ValueRef,
|
||||
env_index: uint,
|
||||
closure_sigil: ast::Sigil,
|
||||
closure_store: ty::TraitStore,
|
||||
span: Span) {
|
||||
if fn_should_be_ignored(bcx.fcx) {
|
||||
return;
|
||||
@ -443,11 +443,11 @@ pub fn create_captured_var_metadata(bcx: &Block,
|
||||
llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref())]
|
||||
};
|
||||
|
||||
let address_op_count = match closure_sigil {
|
||||
ast::BorrowedSigil => {
|
||||
let address_op_count = match closure_store {
|
||||
ty::RegionTraitStore(..) => {
|
||||
address_operations.len()
|
||||
}
|
||||
ast::ManagedSigil | ast::OwnedSigil => {
|
||||
ty::UniqTraitStore => {
|
||||
address_operations.len() - 1
|
||||
}
|
||||
};
|
||||
|
@ -62,7 +62,7 @@ use middle::trans::type_of;
|
||||
use middle::trans::write_guard;
|
||||
use middle::ty::struct_fields;
|
||||
use middle::ty::{AutoBorrowObj, AutoDerefRef, AutoAddEnv, AutoObject, AutoUnsafe};
|
||||
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn};
|
||||
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef};
|
||||
use middle::ty;
|
||||
use middle::typeck::MethodCall;
|
||||
use util::common::indenter;
|
||||
@ -200,14 +200,6 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
|
||||
Some(AutoBorrowVecRef(..)) => {
|
||||
unpack_datum!(bcx, auto_slice_and_ref(bcx, expr, datum))
|
||||
}
|
||||
Some(AutoBorrowFn(..)) => {
|
||||
let adjusted_ty = ty::adjust_ty(bcx.tcx(), expr.span, expr.id, datum.ty,
|
||||
Some(adjustment), |method_call| {
|
||||
bcx.ccx().maps.method_map.borrow()
|
||||
.find(&method_call).map(|method| method.ty)
|
||||
});
|
||||
unpack_datum!(bcx, auto_borrow_fn(bcx, adjusted_ty, datum))
|
||||
}
|
||||
Some(AutoBorrowObj(..)) => {
|
||||
unpack_datum!(bcx, auto_borrow_obj(bcx, expr, datum))
|
||||
}
|
||||
@ -225,20 +217,6 @@ fn apply_adjustments<'a>(bcx: &'a Block<'a>,
|
||||
debug!("after adjustments, datum={}", datum.to_str(bcx.ccx()));
|
||||
return DatumBlock {bcx: bcx, datum: datum};
|
||||
|
||||
fn auto_borrow_fn<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
adjusted_ty: ty::t,
|
||||
datum: Datum<Expr>)
|
||||
-> DatumBlock<'a, Expr> {
|
||||
// Currently, all closure types are represented precisely the
|
||||
// same, so no runtime adjustment is required, but we still
|
||||
// must patchup the type.
|
||||
DatumBlock {bcx: bcx,
|
||||
datum: Datum {val: datum.val,
|
||||
ty: adjusted_ty,
|
||||
kind: datum.kind}}
|
||||
}
|
||||
|
||||
fn auto_slice<'a>(
|
||||
bcx: &'a Block<'a>,
|
||||
expr: &ast::Expr,
|
||||
@ -731,10 +709,10 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
ast::ExprFnBlock(decl, body) |
|
||||
ast::ExprProc(decl, body) => {
|
||||
let expr_ty = expr_ty(bcx, expr);
|
||||
let sigil = ty::ty_closure_sigil(expr_ty);
|
||||
let store = ty::ty_closure_store(expr_ty);
|
||||
debug!("translating block function {} with type {}",
|
||||
expr_to_str(expr), expr_ty.repr(tcx));
|
||||
closure::trans_expr_fn(bcx, sigil, decl, body, expr.id, dest)
|
||||
closure::trans_expr_fn(bcx, store, decl, body, expr.id, dest)
|
||||
}
|
||||
ast::ExprCall(f, ref args) => {
|
||||
callee::trans_call(bcx, expr, f, callee::ArgExprs(args.as_slice()), dest)
|
||||
|
@ -323,7 +323,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
|
||||
bcx
|
||||
})
|
||||
}
|
||||
ty::ty_closure(ref f) if f.sigil == ast::OwnedSigil => {
|
||||
ty::ty_closure(ref f) if f.store == ty::UniqTraitStore => {
|
||||
let box_cell_v = GEPi(bcx, v0, [0u, abi::fn_field_box]);
|
||||
let env = Load(bcx, box_cell_v);
|
||||
let env_ptr_ty = Type::at_box(bcx.ccx(), Type::i8(bcx.ccx())).ptr_to();
|
||||
|
@ -218,7 +218,10 @@ impl<'a> Reflector<'a> {
|
||||
// FIXME (#4809): visitor should break out bare fns from other fns
|
||||
ty::ty_closure(ref fty) => {
|
||||
let pureval = ast_fn_style_constant(fty.fn_style);
|
||||
let sigilval = ast_sigil_constant(fty.sigil);
|
||||
let sigilval = match fty.store {
|
||||
ty::UniqTraitStore => 2u,
|
||||
ty::RegionTraitStore(..) => 4u,
|
||||
};
|
||||
let retval = if ty::type_is_bot(fty.sig.output) {0u} else {1u};
|
||||
let extra = vec!(self.c_uint(pureval),
|
||||
self.c_uint(sigilval),
|
||||
@ -397,14 +400,6 @@ pub fn emit_calls_to_trait_visit_ty<'a>(
|
||||
return final;
|
||||
}
|
||||
|
||||
pub fn ast_sigil_constant(sigil: ast::Sigil) -> uint {
|
||||
match sigil {
|
||||
ast::OwnedSigil => 2u,
|
||||
ast::ManagedSigil => 3u,
|
||||
ast::BorrowedSigil => 4u,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ast_fn_style_constant(fn_style: ast::FnStyle) -> uint {
|
||||
match fn_style {
|
||||
ast::UnsafeFn => 1u,
|
||||
|
@ -214,7 +214,7 @@ pub enum Variance {
|
||||
}
|
||||
|
||||
pub enum AutoAdjustment {
|
||||
AutoAddEnv(ty::Region, ast::Sigil),
|
||||
AutoAddEnv(ty::TraitStore),
|
||||
AutoDerefRef(AutoDerefRef),
|
||||
AutoObject(ty::TraitStore,
|
||||
ty::BuiltinBounds,
|
||||
@ -239,9 +239,6 @@ pub enum AutoRef {
|
||||
/// Convert from ~[]/&[] to &&[] (or str)
|
||||
AutoBorrowVecRef(Region, ast::Mutability),
|
||||
|
||||
/// Convert from @fn()/~fn()/|| to ||
|
||||
AutoBorrowFn(Region),
|
||||
|
||||
/// Convert from T to *T
|
||||
AutoUnsafe(ast::Mutability),
|
||||
|
||||
@ -430,9 +427,8 @@ pub struct BareFnTy {
|
||||
#[deriving(Clone, Eq, TotalEq, Hash)]
|
||||
pub struct ClosureTy {
|
||||
pub fn_style: ast::FnStyle,
|
||||
pub sigil: ast::Sigil,
|
||||
pub onceness: ast::Onceness,
|
||||
pub region: Region,
|
||||
pub store: TraitStore,
|
||||
pub bounds: BuiltinBounds,
|
||||
pub sig: FnSig,
|
||||
}
|
||||
@ -801,7 +797,7 @@ pub enum type_err {
|
||||
terr_onceness_mismatch(expected_found<Onceness>),
|
||||
terr_abi_mismatch(expected_found<abi::Abi>),
|
||||
terr_mutability,
|
||||
terr_sigil_mismatch(expected_found<ast::Sigil>),
|
||||
terr_sigil_mismatch(expected_found<TraitStore>),
|
||||
terr_box_mutability,
|
||||
terr_ptr_mutability,
|
||||
terr_ref_mutability,
|
||||
@ -1204,11 +1200,13 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
|
||||
&ty_param(_) => flags |= has_params as uint,
|
||||
&ty_infer(_) => flags |= needs_infer as uint,
|
||||
&ty_self(_) => flags |= has_self as uint,
|
||||
&ty_enum(_, ref substs) | &ty_struct(_, ref substs) |
|
||||
&ty_trait(~ty::TyTrait { ref substs, .. }) => {
|
||||
&ty_enum(_, ref substs) | &ty_struct(_, ref substs) => {
|
||||
flags |= sflags(substs);
|
||||
match st {
|
||||
ty_trait(~ty::TyTrait { store: RegionTraitStore(r, _), .. }) => {
|
||||
}
|
||||
&ty_trait(~ty::TyTrait { ref substs, store, .. }) => {
|
||||
flags |= sflags(substs);
|
||||
match store {
|
||||
RegionTraitStore(r, _) => {
|
||||
flags |= rflags(r);
|
||||
}
|
||||
_ => {}
|
||||
@ -1232,7 +1230,12 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
|
||||
flags &= !(has_ty_bot as uint);
|
||||
}
|
||||
&ty_closure(ref f) => {
|
||||
flags |= rflags(f.region);
|
||||
match f.store {
|
||||
RegionTraitStore(r, _) => {
|
||||
flags |= rflags(r);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
for a in f.sig.inputs.iter() { flags |= get(*a).flags; }
|
||||
flags |= get(f.sig.output).flags;
|
||||
// T -> _|_ is *not* _|_ !
|
||||
@ -2217,17 +2220,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
fn closure_contents(cx: &ctxt, cty: &ClosureTy) -> TypeContents {
|
||||
// Closure contents are just like trait contents, but with potentially
|
||||
// even more stuff.
|
||||
let st = match cty.sigil {
|
||||
ast::BorrowedSigil =>
|
||||
object_contents(cx, RegionTraitStore(cty.region, MutMutable), cty.bounds),
|
||||
ast::OwnedSigil => object_contents(cx, UniqTraitStore, cty.bounds),
|
||||
ast::ManagedSigil => unreachable!()
|
||||
};
|
||||
|
||||
// FIXME(#3569): This borrowed_contents call should be taken care of in
|
||||
// object_contents, after ~Traits and @Traits can have region bounds too.
|
||||
// This one here is redundant for &fns but important for ~fns and @fns.
|
||||
let rt = borrowed_contents(cty.region, ast::MutImmutable);
|
||||
let st = object_contents(cx, cty.store, cty.bounds);
|
||||
|
||||
// This also prohibits "@once fn" from being copied, which allows it to
|
||||
// be called. Neither way really makes much sense.
|
||||
@ -2236,7 +2229,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
|
||||
ast::Many => TC::None,
|
||||
};
|
||||
|
||||
st | rt | ot
|
||||
st | ot
|
||||
}
|
||||
|
||||
fn object_contents(cx: &ctxt,
|
||||
@ -2696,11 +2689,11 @@ pub fn ty_fn_args(fty: t) -> Vec<t> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ty_closure_sigil(fty: t) -> Sigil {
|
||||
pub fn ty_closure_store(fty: t) -> TraitStore {
|
||||
match get(fty).sty {
|
||||
ty_closure(ref f) => f.sigil,
|
||||
ty_closure(ref f) => f.store,
|
||||
ref s => {
|
||||
fail!("ty_closure_sigil() called on non-closure type: {:?}", s)
|
||||
fail!("ty_closure_store() called on non-closure type: {:?}", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2838,15 +2831,14 @@ pub fn adjust_ty(cx: &ctxt,
|
||||
return match adjustment {
|
||||
Some(adjustment) => {
|
||||
match *adjustment {
|
||||
AutoAddEnv(r, s) => {
|
||||
AutoAddEnv(store) => {
|
||||
match ty::get(unadjusted_ty).sty {
|
||||
ty::ty_bare_fn(ref b) => {
|
||||
ty::mk_closure(
|
||||
cx,
|
||||
ty::ClosureTy {fn_style: b.fn_style,
|
||||
sigil: s,
|
||||
onceness: ast::Many,
|
||||
region: r,
|
||||
store: store,
|
||||
bounds: ty::AllBuiltinBounds(),
|
||||
sig: b.sig.clone()})
|
||||
}
|
||||
@ -2911,10 +2903,6 @@ pub fn adjust_ty(cx: &ctxt,
|
||||
})
|
||||
}
|
||||
|
||||
AutoBorrowFn(r) => {
|
||||
borrow_fn(cx, span, r, adjusted_ty)
|
||||
}
|
||||
|
||||
AutoUnsafe(m) => {
|
||||
mk_ptr(cx, mt {ty: adjusted_ty, mutbl: m})
|
||||
}
|
||||
@ -2956,25 +2944,6 @@ pub fn adjust_ty(cx: &ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
fn borrow_fn(cx: &ctxt, span: Span, r: Region, ty: ty::t) -> ty::t {
|
||||
match get(ty).sty {
|
||||
ty_closure(ref fty) => {
|
||||
ty::mk_closure(cx, ClosureTy {
|
||||
sigil: BorrowedSigil,
|
||||
region: r,
|
||||
..(**fty).clone()
|
||||
})
|
||||
}
|
||||
|
||||
ref s => {
|
||||
cx.sess.span_bug(
|
||||
span,
|
||||
format!("borrow-fn associated with bad sty: {:?}",
|
||||
s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn borrow_obj(cx: &ctxt, span: Span, r: Region,
|
||||
m: ast::Mutability, ty: ty::t) -> ty::t {
|
||||
match get(ty).sty {
|
||||
@ -2998,7 +2967,6 @@ impl AutoRef {
|
||||
ty::AutoPtr(r, m) => ty::AutoPtr(f(r), m),
|
||||
ty::AutoBorrowVec(r, m) => ty::AutoBorrowVec(f(r), m),
|
||||
ty::AutoBorrowVecRef(r, m) => ty::AutoBorrowVecRef(f(r), m),
|
||||
ty::AutoBorrowFn(r) => ty::AutoBorrowFn(f(r)),
|
||||
ty::AutoUnsafe(m) => ty::AutoUnsafe(m),
|
||||
ty::AutoBorrowObj(r, m) => ty::AutoBorrowObj(f(r), m),
|
||||
}
|
||||
@ -4278,20 +4246,6 @@ pub fn eval_repeat_count<T: ExprTyProvider>(tcx: &T, count_expr: &ast::Expr) ->
|
||||
}
|
||||
}
|
||||
|
||||
// Determine what the style to check a nested function under
|
||||
pub fn determine_inherited_style(parent: (ast::FnStyle, ast::NodeId),
|
||||
child: (ast::FnStyle, ast::NodeId),
|
||||
child_sigil: ast::Sigil)
|
||||
-> (ast::FnStyle, ast::NodeId) {
|
||||
// If the closure is a stack closure and hasn't had some non-standard
|
||||
// style inferred for it, then check it under its parent's style.
|
||||
// Otherwise, use its own
|
||||
match child_sigil {
|
||||
ast::BorrowedSigil if child.val0() == ast::NormalFn => parent,
|
||||
_ => child
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over a type parameter's bounded traits and any supertraits
|
||||
// of those traits, ignoring kinds.
|
||||
// Here, the supertraits are the transitive closure of the supertrait
|
||||
@ -4640,10 +4594,16 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
|
||||
ty_closure(ref c) => {
|
||||
byte!(15);
|
||||
hash!(c.fn_style);
|
||||
hash!(c.sigil);
|
||||
hash!(c.onceness);
|
||||
hash!(c.bounds);
|
||||
region(&mut state, c.region);
|
||||
match c.store {
|
||||
UniqTraitStore => byte!(0),
|
||||
RegionTraitStore(r, m) => {
|
||||
byte!(1)
|
||||
region(&mut state, r);
|
||||
assert_eq!(m, ast::MutMutable);
|
||||
}
|
||||
}
|
||||
}
|
||||
ty_trait(~ty::TyTrait { def_id: d, store, bounds, .. }) => {
|
||||
byte!(17);
|
||||
|
@ -56,10 +56,9 @@ pub trait TypeFolder {
|
||||
fty: &ty::ClosureTy)
|
||||
-> ty::ClosureTy {
|
||||
ty::ClosureTy {
|
||||
region: self.fold_region(fty.region),
|
||||
store: self.fold_trait_store(fty.store),
|
||||
sig: self.fold_sig(&fty.sig),
|
||||
fn_style: fty.fn_style,
|
||||
sigil: fty.sigil,
|
||||
onceness: fty.onceness,
|
||||
bounds: fty.bounds,
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime)
|
||||
r
|
||||
}
|
||||
|
||||
fn opt_ast_region_to_region<AC:AstConv,RS:RegionScope>(
|
||||
pub fn opt_ast_region_to_region<AC:AstConv,RS:RegionScope>(
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
default_span: Span,
|
||||
@ -516,33 +516,42 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:RegionScope>(
|
||||
ty::mk_bare_fn(tcx, ty_of_bare_fn(this, ast_ty.id, bf.fn_style,
|
||||
bf.abi, bf.decl))
|
||||
}
|
||||
ast::TyClosure(ref f) => {
|
||||
if f.sigil == ast::ManagedSigil {
|
||||
tcx.sess.span_err(ast_ty.span,
|
||||
"managed closures are not supported");
|
||||
}
|
||||
ast::TyClosure(ref f, ref region) => {
|
||||
|
||||
// resolve the function bound region in the original region
|
||||
// scope `rscope`, not the scope of the function parameters
|
||||
let bound_region = opt_ast_region_to_region(this, rscope,
|
||||
ast_ty.span, region);
|
||||
|
||||
let store = ty::RegionTraitStore(bound_region, ast::MutMutable);
|
||||
|
||||
// Use corresponding trait store to figure out default bounds
|
||||
// if none were specified.
|
||||
let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, store);
|
||||
|
||||
let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, match f.sigil {
|
||||
// Use corresponding trait store to figure out default bounds
|
||||
// if none were specified.
|
||||
ast::BorrowedSigil => {
|
||||
// dummy region
|
||||
ty::RegionTraitStore(ty::ReEmpty, ast::MutMutable)
|
||||
}
|
||||
ast::OwnedSigil => ty::UniqTraitStore,
|
||||
ast::ManagedSigil => return ty::mk_err()
|
||||
});
|
||||
let fn_decl = ty_of_closure(this,
|
||||
rscope,
|
||||
ast_ty.id,
|
||||
f.sigil,
|
||||
f.fn_style,
|
||||
f.onceness,
|
||||
bounds,
|
||||
&f.region,
|
||||
store,
|
||||
f.decl,
|
||||
None,
|
||||
ast_ty.span);
|
||||
None);
|
||||
ty::mk_closure(tcx, fn_decl)
|
||||
}
|
||||
ast::TyProc(ref f) => {
|
||||
// Use corresponding trait store to figure out default bounds
|
||||
// if none were specified.
|
||||
let bounds = conv_builtin_bounds(this.tcx(), &f.bounds, ty::UniqTraitStore);
|
||||
|
||||
let fn_decl = ty_of_closure(this,
|
||||
ast_ty.id,
|
||||
f.fn_style,
|
||||
f.onceness,
|
||||
bounds,
|
||||
ty::UniqTraitStore,
|
||||
f.decl,
|
||||
None);
|
||||
ty::mk_closure(tcx, fn_decl)
|
||||
}
|
||||
ast::TyPath(ref path, ref bounds, id) => {
|
||||
@ -728,43 +737,19 @@ fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn ty_of_closure<AC:AstConv,RS:RegionScope>(
|
||||
pub fn ty_of_closure<AC:AstConv>(
|
||||
this: &AC,
|
||||
rscope: &RS,
|
||||
id: ast::NodeId,
|
||||
sigil: ast::Sigil,
|
||||
fn_style: ast::FnStyle,
|
||||
onceness: ast::Onceness,
|
||||
bounds: ty::BuiltinBounds,
|
||||
opt_lifetime: &Option<ast::Lifetime>,
|
||||
store: ty::TraitStore,
|
||||
decl: &ast::FnDecl,
|
||||
expected_sig: Option<ty::FnSig>,
|
||||
span: Span)
|
||||
expected_sig: Option<ty::FnSig>)
|
||||
-> ty::ClosureTy
|
||||
{
|
||||
debug!("ty_of_fn_decl");
|
||||
|
||||
// resolve the function bound region in the original region
|
||||
// scope `rscope`, not the scope of the function parameters
|
||||
let bound_region = match opt_lifetime {
|
||||
&Some(ref lifetime) => {
|
||||
ast_region_to_region(this.tcx(), lifetime)
|
||||
}
|
||||
&None => {
|
||||
match sigil {
|
||||
ast::OwnedSigil | ast::ManagedSigil => {
|
||||
// @fn(), ~fn() default to static as the bound
|
||||
// on their upvars:
|
||||
ty::ReStatic
|
||||
}
|
||||
ast::BorrowedSigil => {
|
||||
// || defaults as normal for an omitted lifetime:
|
||||
opt_ast_region_to_region(this, rscope, span, opt_lifetime)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// new region names that appear inside of the fn decl are bound to
|
||||
// that function type
|
||||
let rb = rscope::BindingRscope::new(id);
|
||||
@ -791,9 +776,8 @@ pub fn ty_of_closure<AC:AstConv,RS:RegionScope>(
|
||||
|
||||
ty::ClosureTy {
|
||||
fn_style: fn_style,
|
||||
sigil: sigil,
|
||||
onceness: onceness,
|
||||
region: bound_region,
|
||||
store: store,
|
||||
bounds: bounds,
|
||||
sig: ty::FnSig {binder_id: id,
|
||||
inputs: input_tys,
|
||||
|
@ -2116,7 +2116,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
|
||||
fn check_expr_fn(fcx: &FnCtxt,
|
||||
expr: &ast::Expr,
|
||||
ast_sigil_opt: Option<ast::Sigil>,
|
||||
store: ty::TraitStore,
|
||||
decl: &ast::FnDecl,
|
||||
body: ast::P<ast::Block>,
|
||||
fn_kind: FnKind,
|
||||
@ -2126,18 +2126,11 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
// Find the expected input/output types (if any). Substitute
|
||||
// fresh bound regions for any bound regions we find in the
|
||||
// expected types so as to avoid capture.
|
||||
//
|
||||
// Also try to pick up inferred style and sigil, defaulting
|
||||
// to impure and block. Note that we only will use those for
|
||||
// block syntax lambdas; that is, lambdas without explicit
|
||||
// sigils.
|
||||
let expected_sty = unpack_expected(fcx,
|
||||
expected,
|
||||
|x| Some((*x).clone()));
|
||||
let error_happened = false;
|
||||
let (expected_sig,
|
||||
expected_style,
|
||||
expected_sigil,
|
||||
expected_onceness,
|
||||
expected_bounds) = {
|
||||
match expected_sty {
|
||||
@ -2146,47 +2139,32 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
replace_late_bound_regions_in_fn_sig(
|
||||
tcx, &cenv.sig,
|
||||
|_| fcx.inh.infcx.fresh_bound_region(expr.id));
|
||||
(Some(sig), cenv.fn_style, cenv.sigil,
|
||||
cenv.onceness, cenv.bounds)
|
||||
(Some(sig), cenv.onceness, cenv.bounds)
|
||||
}
|
||||
_ => {
|
||||
// Not an error! Means we're inferring the closure type
|
||||
let mut sigil = ast::BorrowedSigil;
|
||||
let mut onceness = ast::Many;
|
||||
let mut bounds = ty::EmptyBuiltinBounds();
|
||||
match expr.node {
|
||||
let onceness = match expr.node {
|
||||
ast::ExprProc(..) => {
|
||||
sigil = ast::OwnedSigil;
|
||||
onceness = ast::Once;
|
||||
bounds.add(ty::BoundSend);
|
||||
ast::Once
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
(None, ast::NormalFn, sigil,
|
||||
onceness, bounds)
|
||||
_ => ast::Many
|
||||
};
|
||||
(None, onceness, bounds)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// If the proto is specified, use that, otherwise select a
|
||||
// proto based on inference.
|
||||
let (sigil, fn_style) = match ast_sigil_opt {
|
||||
Some(p) => (p, ast::NormalFn),
|
||||
None => (expected_sigil, expected_style)
|
||||
};
|
||||
|
||||
// construct the function type
|
||||
let fn_ty = astconv::ty_of_closure(fcx,
|
||||
fcx.infcx(),
|
||||
expr.id,
|
||||
sigil,
|
||||
fn_style,
|
||||
ast::NormalFn,
|
||||
expected_onceness,
|
||||
expected_bounds,
|
||||
&None,
|
||||
store,
|
||||
decl,
|
||||
expected_sig,
|
||||
expr.span);
|
||||
expected_sig);
|
||||
|
||||
let fty_sig;
|
||||
let fty = if error_happened {
|
||||
@ -2198,9 +2176,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
};
|
||||
ty::mk_err()
|
||||
} else {
|
||||
let fn_ty_copy = fn_ty.clone();
|
||||
fty_sig = fn_ty.sig.clone();
|
||||
ty::mk_closure(tcx, fn_ty_copy)
|
||||
ty::mk_closure(tcx, fn_ty.clone())
|
||||
};
|
||||
|
||||
debug!("check_expr_fn_with_unifier fty={}",
|
||||
@ -2208,11 +2185,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
|
||||
fcx.write_ty(expr.id, fty);
|
||||
|
||||
let (inherited_style, id) =
|
||||
ty::determine_inherited_style((fcx.ps.borrow().fn_style,
|
||||
fcx.ps.borrow().def),
|
||||
(fn_style, expr.id),
|
||||
sigil);
|
||||
// If the closure is a stack closure and hasn't had some non-standard
|
||||
// style inferred for it, then check it under its parent's style.
|
||||
// Otherwise, use its own
|
||||
let (inherited_style, id) = match store {
|
||||
ty::RegionTraitStore(..) => (fcx.ps.borrow().fn_style,
|
||||
fcx.ps.borrow().def),
|
||||
ty::UniqTraitStore => (ast::NormalFn, expr.id)
|
||||
};
|
||||
|
||||
check_fn(fcx.ccx, inherited_style, &fty_sig,
|
||||
decl, id, body, fn_kind, fcx.inh);
|
||||
@ -2856,9 +2836,13 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
_match::check_match(fcx, expr, discrim, arms.as_slice());
|
||||
}
|
||||
ast::ExprFnBlock(decl, body) => {
|
||||
let region = astconv::opt_ast_region_to_region(fcx,
|
||||
fcx.infcx(),
|
||||
expr.span,
|
||||
&None);
|
||||
check_expr_fn(fcx,
|
||||
expr,
|
||||
Some(ast::BorrowedSigil),
|
||||
ty::RegionTraitStore(region, ast::MutMutable),
|
||||
decl,
|
||||
body,
|
||||
Vanilla,
|
||||
@ -2867,7 +2851,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
ast::ExprProc(decl, body) => {
|
||||
check_expr_fn(fcx,
|
||||
expr,
|
||||
Some(ast::OwnedSigil),
|
||||
ty::UniqTraitStore,
|
||||
decl,
|
||||
body,
|
||||
Vanilla,
|
||||
|
@ -133,7 +133,6 @@ use middle::typeck::MethodCall;
|
||||
use middle::pat_util;
|
||||
use util::ppaux::{ty_to_str, region_to_str, Repr};
|
||||
|
||||
use syntax::ast::{ManagedSigil, OwnedSigil, BorrowedSigil};
|
||||
use syntax::ast::{DefArg, DefBinding, DefLocal, DefUpvar};
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
@ -175,9 +174,9 @@ fn region_of_def(fcx: &FnCtxt, def: ast::Def) -> ty::Region {
|
||||
tcx.region_maps.var_region(node_id)
|
||||
}
|
||||
DefUpvar(_, subdef, closure_id, body_id) => {
|
||||
match ty::ty_closure_sigil(fcx.node_ty(closure_id)) {
|
||||
BorrowedSigil => region_of_def(fcx, *subdef),
|
||||
ManagedSigil | OwnedSigil => ReScope(body_id)
|
||||
match ty::ty_closure_store(fcx.node_ty(closure_id)) {
|
||||
ty::RegionTraitStore(..) => region_of_def(fcx, *subdef),
|
||||
ty::UniqTraitStore => ReScope(body_id)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -611,7 +610,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
let function_type = rcx.resolve_node_type(expr.id);
|
||||
match ty::get(function_type).sty {
|
||||
ty::ty_closure(~ty::ClosureTy {
|
||||
sigil: ast::BorrowedSigil, region: region, ..}) => {
|
||||
store: ty::RegionTraitStore(region, _), ..}) => {
|
||||
let freevars = freevars::get_freevars(tcx, expr.id);
|
||||
if freevars.is_empty() {
|
||||
// No free variables means that the environment
|
||||
@ -635,7 +634,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
|
||||
rcx.set_repeating_scope(repeating_scope);
|
||||
|
||||
match ty::get(function_type).sty {
|
||||
ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil, ..}) => {
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(..), ..}) => {
|
||||
let freevars = freevars::get_freevars(tcx, expr.id);
|
||||
propagate_upupvar_borrow_kind(rcx, expr, freevars);
|
||||
}
|
||||
@ -749,8 +748,12 @@ fn constrain_callee(rcx: &mut Rcx,
|
||||
match ty::get(callee_ty).sty {
|
||||
ty::ty_bare_fn(..) => { }
|
||||
ty::ty_closure(ref closure_ty) => {
|
||||
let region = match closure_ty.store {
|
||||
ty::RegionTraitStore(r, _) => r,
|
||||
ty::UniqTraitStore => ty::ReStatic
|
||||
};
|
||||
rcx.fcx.mk_subr(true, infer::InvokeClosure(callee_expr.span),
|
||||
call_region, closure_ty.region);
|
||||
call_region, region);
|
||||
}
|
||||
_ => {
|
||||
// this should not happen, but it does if the program is
|
||||
@ -1120,13 +1123,8 @@ fn link_autoref(rcx: &mut Rcx,
|
||||
link_region(mc.typer, expr.span, r, m, cmt_index);
|
||||
}
|
||||
|
||||
ty::AutoBorrowFn(r) => {
|
||||
let cmt_deref = mc.cat_deref_fn_or_obj(expr, expr_cmt, 0);
|
||||
link_region(mc.typer, expr.span, r, ast::MutImmutable, cmt_deref);
|
||||
}
|
||||
|
||||
ty::AutoBorrowObj(r, m) => {
|
||||
let cmt_deref = mc.cat_deref_fn_or_obj(expr, expr_cmt, 0);
|
||||
let cmt_deref = mc.cat_deref_obj(expr, expr_cmt);
|
||||
link_region(mc.typer, expr.span, r, m, cmt_deref);
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,11 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
|
||||
|
||||
Some(adjustment) => {
|
||||
match *adjustment {
|
||||
ty::AutoAddEnv(r, s) => {
|
||||
ty::AutoAddEnv(store) => {
|
||||
let r = match store {
|
||||
ty::RegionTraitStore(r, _) => r,
|
||||
ty::UniqTraitStore => ty::ReStatic
|
||||
};
|
||||
match resolve_region(fcx.infcx(),
|
||||
r,
|
||||
resolve_all | force_all) {
|
||||
@ -166,7 +170,12 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
|
||||
"cannot coerce non-statically resolved bare fn")
|
||||
}
|
||||
|
||||
let resolved_adj = @ty::AutoAddEnv(r1, s);
|
||||
let resolved_adj = @ty::AutoAddEnv(match store {
|
||||
ty::RegionTraitStore(..) => {
|
||||
ty::RegionTraitStore(r1, ast::MutMutable)
|
||||
}
|
||||
ty::UniqTraitStore => ty::UniqTraitStore
|
||||
});
|
||||
debug!("Adjustments for node {}: {:?}",
|
||||
id, resolved_adj);
|
||||
tcx.adjustments.borrow_mut().insert(id, resolved_adj);
|
||||
|
@ -65,8 +65,7 @@ we may want to adjust precisely when coercions occur.
|
||||
*/
|
||||
|
||||
|
||||
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowFn, AutoBorrowObj};
|
||||
use middle::ty::{AutoDerefRef};
|
||||
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowObj, AutoDerefRef};
|
||||
use middle::ty::{VstoreSlice, VstoreUniq};
|
||||
use middle::ty::{mt};
|
||||
use middle::ty;
|
||||
@ -120,7 +119,7 @@ impl<'f> Coerce<'f> {
|
||||
});
|
||||
}
|
||||
|
||||
ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil, ..}) => {
|
||||
ty::ty_closure(~ty::ClosureTy {store: ty::RegionTraitStore(..), ..}) => {
|
||||
return self.unpack_actual_value(a, |sty_a| {
|
||||
self.coerce_borrowed_fn(a, sty_a, b)
|
||||
});
|
||||
@ -342,33 +341,14 @@ impl<'f> Coerce<'f> {
|
||||
a.inf_str(self.get_ref().infcx), sty_a,
|
||||
b.inf_str(self.get_ref().infcx));
|
||||
|
||||
let fn_ty = match *sty_a {
|
||||
ty::ty_closure(ref f) if f.sigil == ast::ManagedSigil ||
|
||||
f.sigil == ast::OwnedSigil => {
|
||||
(*f).clone()
|
||||
}
|
||||
match *sty_a {
|
||||
ty::ty_bare_fn(ref f) => {
|
||||
return self.coerce_from_bare_fn(a, f, b);
|
||||
self.coerce_from_bare_fn(a, f, b)
|
||||
}
|
||||
_ => {
|
||||
return self.subtype(a, b);
|
||||
self.subtype(a, b)
|
||||
}
|
||||
};
|
||||
|
||||
let r_borrow = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
|
||||
let a_borrowed = ty::mk_closure(
|
||||
self.get_ref().infcx.tcx,
|
||||
ty::ClosureTy {
|
||||
sigil: ast::BorrowedSigil,
|
||||
region: r_borrow,
|
||||
.. *fn_ty
|
||||
});
|
||||
|
||||
if_ok!(self.subtype(a_borrowed, b));
|
||||
Ok(Some(@AutoDerefRef(AutoDerefRef {
|
||||
autoderefs: 0,
|
||||
autoref: Some(AutoBorrowFn(r_borrow))
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
fn coerce_from_bare_fn(&self, a: ty::t, fn_ty_a: &ty::BareFnTy, b: ty::t)
|
||||
@ -393,7 +373,7 @@ impl<'f> Coerce<'f> {
|
||||
_ => return self.subtype(a, b)
|
||||
};
|
||||
|
||||
let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
|
||||
let adj = @ty::AutoAddEnv(fn_ty_b.store);
|
||||
let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
|
||||
ty::ClosureTy {
|
||||
sig: fn_ty_a.sig.clone(),
|
||||
|
@ -205,18 +205,32 @@ pub trait Combine {
|
||||
fn closure_tys(&self, a: &ty::ClosureTy,
|
||||
b: &ty::ClosureTy) -> cres<ty::ClosureTy> {
|
||||
|
||||
let p = if_ok!(self.sigils(a.sigil, b.sigil));
|
||||
let r = if_ok!(self.contraregions(a.region, b.region));
|
||||
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 = if_ok!(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 fn_style = if_ok!(self.fn_styles(a.fn_style, b.fn_style));
|
||||
let onceness = if_ok!(self.oncenesses(a.onceness, b.onceness));
|
||||
let bounds = if_ok!(self.bounds(a.bounds, b.bounds));
|
||||
let sig = if_ok!(self.fn_sigs(&a.sig, &b.sig));
|
||||
Ok(ty::ClosureTy {fn_style: fn_style,
|
||||
sigil: p,
|
||||
onceness: onceness,
|
||||
region: r,
|
||||
bounds: bounds,
|
||||
sig: sig})
|
||||
Ok(ty::ClosureTy {
|
||||
fn_style: fn_style,
|
||||
onceness: onceness,
|
||||
store: store,
|
||||
bounds: bounds,
|
||||
sig: sig
|
||||
})
|
||||
}
|
||||
|
||||
fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig>;
|
||||
@ -238,14 +252,6 @@ pub trait Combine {
|
||||
self.contratys(a, b).and_then(|t| Ok(t))
|
||||
}
|
||||
|
||||
fn sigils(&self, p1: ast::Sigil, p2: ast::Sigil) -> cres<ast::Sigil> {
|
||||
if p1 == p2 {
|
||||
Ok(p1)
|
||||
} else {
|
||||
Err(ty::terr_sigil_mismatch(expected_found(self, p1, p2)))
|
||||
}
|
||||
}
|
||||
|
||||
fn fn_styles(&self, a: FnStyle, b: FnStyle) -> cres<FnStyle>;
|
||||
|
||||
fn abi(&self, a: abi::Abi, b: abi::Abi) -> cres<abi::Abi> {
|
||||
|
@ -704,11 +704,13 @@ impl<'a> ConstraintContext<'a> {
|
||||
self.add_constraint(index, variance);
|
||||
}
|
||||
|
||||
ty::ty_bare_fn(ty::BareFnTy { sig: ref sig, .. }) => {
|
||||
ty::ty_bare_fn(ty::BareFnTy { ref sig, .. }) |
|
||||
ty::ty_closure(~ty::ClosureTy { ref sig, store: ty::UniqTraitStore, .. }) => {
|
||||
self.add_constraints_from_sig(sig, variance);
|
||||
}
|
||||
|
||||
ty::ty_closure(~ty::ClosureTy { sig: ref sig, region, .. }) => {
|
||||
ty::ty_closure(~ty::ClosureTy { ref sig,
|
||||
store: ty::RegionTraitStore(region, _), .. }) => {
|
||||
let contra = self.contravariant(variance);
|
||||
self.add_constraints_from_region(region, contra);
|
||||
self.add_constraints_from_sig(sig, variance);
|
||||
|
@ -266,21 +266,11 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
|
||||
}
|
||||
|
||||
fn closure_to_str(cx: &ctxt, cty: &ty::ClosureTy) -> ~str {
|
||||
let is_proc =
|
||||
(cty.sigil, cty.onceness) == (ast::OwnedSigil, ast::Once);
|
||||
let is_borrowed_closure = cty.sigil == ast::BorrowedSigil;
|
||||
let mut s = StrBuf::new();
|
||||
|
||||
let mut s = if is_proc || is_borrowed_closure {
|
||||
StrBuf::new()
|
||||
} else {
|
||||
StrBuf::from_owned_str(cty.sigil.to_str())
|
||||
};
|
||||
|
||||
match (cty.sigil, cty.region) {
|
||||
(ast::ManagedSigil, ty::ReStatic) |
|
||||
(ast::OwnedSigil, ty::ReStatic) => {}
|
||||
|
||||
(_, region) => {
|
||||
match cty.store {
|
||||
ty::UniqTraitStore => {}
|
||||
ty::RegionTraitStore(region, _) => {
|
||||
s.push_str(region_to_str(cx, "", true, region));
|
||||
}
|
||||
}
|
||||
@ -293,40 +283,24 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
|
||||
}
|
||||
};
|
||||
|
||||
if is_proc {
|
||||
s.push_str("proc");
|
||||
} else {
|
||||
match cty.onceness {
|
||||
ast::Many => {}
|
||||
ast::Once => {
|
||||
s.push_str(cty.onceness.to_str());
|
||||
s.push_char(' ');
|
||||
match cty.store {
|
||||
ty::UniqTraitStore => {
|
||||
assert_eq!(cty.onceness, ast::Once);
|
||||
s.push_str("proc");
|
||||
push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
|
||||
}
|
||||
ty::RegionTraitStore(..) => {
|
||||
match cty.onceness {
|
||||
ast::Many => {}
|
||||
ast::Once => s.push_str("once ")
|
||||
}
|
||||
};
|
||||
|
||||
if !is_borrowed_closure {
|
||||
s.push_str("fn");
|
||||
push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
|
||||
}
|
||||
}
|
||||
|
||||
if !is_borrowed_closure {
|
||||
// Print bounds before `fn` if this is not a borrowed closure.
|
||||
if !cty.bounds.is_empty() {
|
||||
s.push_str(":");
|
||||
s.push_str(cty.bounds.repr(cx));
|
||||
}
|
||||
|
||||
push_sig_to_str(cx, &mut s, '(', ')', &cty.sig);
|
||||
} else {
|
||||
// Print bounds after the signature if this is a borrowed closure.
|
||||
push_sig_to_str(cx, &mut s, '|', '|', &cty.sig);
|
||||
|
||||
if is_borrowed_closure {
|
||||
if !cty.bounds.is_empty() {
|
||||
s.push_str(":");
|
||||
s.push_str(cty.bounds.repr(cx));
|
||||
}
|
||||
}
|
||||
if !cty.bounds.is_empty() {
|
||||
s.push_str(":");
|
||||
s.push_str(cty.bounds.repr(cx));
|
||||
}
|
||||
|
||||
s.into_owned()
|
||||
|
@ -474,8 +474,6 @@ impl Clean<Item> for doctree::Function {
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable)]
|
||||
pub struct ClosureDecl {
|
||||
pub sigil: ast::Sigil,
|
||||
pub region: Option<Lifetime>,
|
||||
pub lifetimes: Vec<Lifetime>,
|
||||
pub decl: FnDecl,
|
||||
pub onceness: ast::Onceness,
|
||||
@ -486,8 +484,6 @@ pub struct ClosureDecl {
|
||||
impl Clean<ClosureDecl> for ast::ClosureTy {
|
||||
fn clean(&self) -> ClosureDecl {
|
||||
ClosureDecl {
|
||||
sigil: self.sigil,
|
||||
region: self.region.clean(),
|
||||
lifetimes: self.lifetimes.clean().move_iter().collect(),
|
||||
decl: self.decl.clean(),
|
||||
onceness: self.onceness,
|
||||
@ -652,7 +648,8 @@ pub enum Type {
|
||||
Self(ast::NodeId),
|
||||
/// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
|
||||
Primitive(ast::PrimTy),
|
||||
Closure(~ClosureDecl),
|
||||
Closure(~ClosureDecl, Option<Lifetime>),
|
||||
Proc(~ClosureDecl),
|
||||
/// extern "ABI" fn
|
||||
BareFunction(~BareFunctionDecl),
|
||||
Tuple(Vec<Type> ),
|
||||
@ -706,7 +703,8 @@ impl Clean<Type> for ast::Ty {
|
||||
tpbs.clean().map(|x| x.move_iter().collect()),
|
||||
id)
|
||||
}
|
||||
TyClosure(ref c) => Closure(~c.clean()),
|
||||
TyClosure(ref c, region) => Closure(~c.clean(), region.clean()),
|
||||
TyProc(ref c) => Proc(~c.clean()),
|
||||
TyBareFn(ref barefn) => BareFunction(~barefn.clean()),
|
||||
TyBot => Bottom,
|
||||
ref x => fail!("Unimplemented type {:?}", x),
|
||||
|
@ -337,19 +337,24 @@ impl fmt::Show for clean::Type {
|
||||
};
|
||||
f.buf.write(s.as_bytes())
|
||||
}
|
||||
clean::Closure(ref decl) => {
|
||||
let region = match decl.region {
|
||||
clean::Closure(ref decl, ref region) => {
|
||||
let region = match *region {
|
||||
Some(ref region) => format!("{} ", *region),
|
||||
None => ~"",
|
||||
};
|
||||
|
||||
write!(f.buf, "{}{}{arrow, select, yes{ -> {ret}} other{}}",
|
||||
write!(f.buf, "{}{}|{}|{arrow, select, yes{ -> {ret}} other{}}",
|
||||
FnStyleSpace(decl.fn_style),
|
||||
match decl.sigil {
|
||||
ast::OwnedSigil => format!("proc({})", decl.decl.inputs),
|
||||
ast::BorrowedSigil => format!("{}|{}|", region, decl.decl.inputs),
|
||||
ast::ManagedSigil => format!("@{}fn({})", region, decl.decl.inputs),
|
||||
},
|
||||
region,
|
||||
decl.decl.inputs,
|
||||
arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
|
||||
ret = decl.decl.output)
|
||||
// FIXME: where are bounds and lifetimes printed?!
|
||||
}
|
||||
clean::Proc(ref decl) => {
|
||||
write!(f.buf, "{}proc({}){arrow, select, yes{ -> {ret}} other{}}",
|
||||
FnStyleSpace(decl.fn_style),
|
||||
decl.decl.inputs,
|
||||
arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
|
||||
ret = decl.decl.output)
|
||||
// FIXME: where are bounds and lifetimes printed?!
|
||||
|
@ -359,23 +359,6 @@ pub enum Mutability {
|
||||
MutImmutable,
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
|
||||
pub enum Sigil {
|
||||
BorrowedSigil,
|
||||
OwnedSigil,
|
||||
ManagedSigil
|
||||
}
|
||||
|
||||
impl fmt::Show for Sigil {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
BorrowedSigil => "&".fmt(f),
|
||||
OwnedSigil => "~".fmt(f),
|
||||
ManagedSigil => "@".fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
|
||||
pub enum ExprVstore {
|
||||
ExprVstoreUniq, // ~[1,2,3,4]
|
||||
@ -791,8 +774,6 @@ impl fmt::Show for Onceness {
|
||||
|
||||
#[deriving(Eq, TotalEq, Encodable, Decodable, Hash)]
|
||||
pub struct ClosureTy {
|
||||
pub sigil: Sigil,
|
||||
pub region: Option<Lifetime>,
|
||||
pub lifetimes: Vec<Lifetime>,
|
||||
pub fn_style: FnStyle,
|
||||
pub onceness: Onceness,
|
||||
@ -822,7 +803,8 @@ pub enum Ty_ {
|
||||
TyFixedLengthVec(P<Ty>, @Expr),
|
||||
TyPtr(MutTy),
|
||||
TyRptr(Option<Lifetime>, MutTy),
|
||||
TyClosure(@ClosureTy),
|
||||
TyClosure(@ClosureTy, Option<Lifetime>),
|
||||
TyProc(@ClosureTy),
|
||||
TyBareFn(@BareFnTy),
|
||||
TyTup(Vec<P<Ty>> ),
|
||||
TyPath(Path, Option<OwnedSlice<TyParamBound>>, NodeId), // for #7264; see above
|
||||
|
@ -155,11 +155,18 @@ pub trait Folder {
|
||||
TyRptr(ref region, ref mt) => {
|
||||
TyRptr(fold_opt_lifetime(region, self), fold_mt(mt, self))
|
||||
}
|
||||
TyClosure(ref f) => {
|
||||
TyClosure(ref f, ref region) => {
|
||||
TyClosure(@ClosureTy {
|
||||
sigil: f.sigil,
|
||||
fn_style: f.fn_style,
|
||||
region: fold_opt_lifetime(&f.region, self),
|
||||
onceness: f.onceness,
|
||||
bounds: fold_opt_bounds(&f.bounds, self),
|
||||
decl: self.fold_fn_decl(f.decl),
|
||||
lifetimes: f.lifetimes.iter().map(|l| fold_lifetime(l, self)).collect(),
|
||||
}, fold_opt_lifetime(region, self))
|
||||
}
|
||||
TyProc(ref f) => {
|
||||
TyProc(@ClosureTy {
|
||||
fn_style: f.fn_style,
|
||||
onceness: f.onceness,
|
||||
bounds: fold_opt_bounds(&f.bounds, self),
|
||||
decl: self.fold_fn_decl(f.decl),
|
||||
|
@ -11,7 +11,6 @@
|
||||
#![macro_escape]
|
||||
|
||||
use abi;
|
||||
use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil};
|
||||
use ast::{BareFnTy, ClosureTy};
|
||||
use ast::{RegionTyParamBound, TraitTyParamBound};
|
||||
use ast::{Provided, Public, FnStyle};
|
||||
@ -49,8 +48,8 @@ use ast::StrStyle;
|
||||
use ast::{SelfRegion, SelfStatic, SelfUniq, SelfValue};
|
||||
use ast::{TokenTree, TraitMethod, TraitRef, TTDelim, TTSeq, TTTok};
|
||||
use ast::{TTNonterminal, TupleVariantKind, Ty, Ty_, TyBot, TyBox};
|
||||
use ast::{TypeField, TyFixedLengthVec, TyClosure, TyBareFn, TyTypeof};
|
||||
use ast::{TyInfer, TypeMethod};
|
||||
use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn};
|
||||
use ast::{TyTypeof, TyInfer, TypeMethod};
|
||||
use ast::{TyNil, TyParam, TyParamBound, TyPath, TyPtr, TyRptr};
|
||||
use ast::{TyTup, TyU32, TyUniq, TyVec, UnUniq};
|
||||
use ast::{UnnamedField, UnsafeBlock, UnsafeFn, ViewItem};
|
||||
@ -923,9 +922,7 @@ impl<'a> Parser<'a> {
|
||||
cf: ret_style,
|
||||
variadic: variadic
|
||||
});
|
||||
TyClosure(@ClosureTy {
|
||||
sigil: OwnedSigil,
|
||||
region: None,
|
||||
TyProc(@ClosureTy {
|
||||
fn_style: NormalFn,
|
||||
onceness: Once,
|
||||
bounds: bounds,
|
||||
@ -984,14 +981,12 @@ impl<'a> Parser<'a> {
|
||||
});
|
||||
|
||||
TyClosure(@ClosureTy {
|
||||
sigil: BorrowedSigil,
|
||||
region: region,
|
||||
fn_style: fn_style,
|
||||
onceness: onceness,
|
||||
bounds: bounds,
|
||||
decl: decl,
|
||||
lifetimes: lifetimes,
|
||||
})
|
||||
}, region)
|
||||
}
|
||||
|
||||
pub fn parse_unsafety(&mut self) -> FnStyle {
|
||||
@ -1201,11 +1196,11 @@ impl<'a> Parser<'a> {
|
||||
} else if self.token == token::AT {
|
||||
// MANAGED POINTER
|
||||
self.bump();
|
||||
self.parse_box_or_uniq_pointee(ManagedSigil)
|
||||
TyBox(self.parse_ty(false))
|
||||
} else if self.token == token::TILDE {
|
||||
// OWNED POINTER
|
||||
self.bump();
|
||||
self.parse_box_or_uniq_pointee(OwnedSigil)
|
||||
TyUniq(self.parse_ty(false))
|
||||
} else if self.token == token::BINOP(token::STAR) {
|
||||
// STAR POINTER (bare pointer?)
|
||||
self.bump();
|
||||
@ -1271,21 +1266,6 @@ impl<'a> Parser<'a> {
|
||||
P(Ty {id: ast::DUMMY_NODE_ID, node: t, span: sp})
|
||||
}
|
||||
|
||||
// parse the type following a @ or a ~
|
||||
pub fn parse_box_or_uniq_pointee(&mut self,
|
||||
sigil: ast::Sigil)
|
||||
-> Ty_ {
|
||||
// other things are parsed as @/~ + a type. Note that constructs like
|
||||
// ~[] and ~str will be resolved during typeck to slices and so forth,
|
||||
// rather than boxed ptrs. But the special casing of str/vec is not
|
||||
// reflected in the AST type.
|
||||
if sigil == OwnedSigil {
|
||||
TyUniq(self.parse_ty(false))
|
||||
} else {
|
||||
TyBox(self.parse_ty(false))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_borrowed_pointee(&mut self) -> Ty_ {
|
||||
// look for `&'lt` or `&'foo ` and interpret `foo` as the region name:
|
||||
let opt_lifetime = self.parse_opt_lifetime();
|
||||
|
@ -483,14 +483,23 @@ impl<'a> State<'a> {
|
||||
f.fn_style, ast::Many, f.decl, None, &None,
|
||||
Some(&generics), None));
|
||||
}
|
||||
ast::TyClosure(f) => {
|
||||
ast::TyClosure(f, ref region) => {
|
||||
let generics = ast::Generics {
|
||||
lifetimes: f.lifetimes.clone(),
|
||||
ty_params: OwnedSlice::empty()
|
||||
};
|
||||
try!(self.print_ty_fn(None, Some(f.sigil), &f.region,
|
||||
f.fn_style, f.onceness, f.decl, None, &f.bounds,
|
||||
Some(&generics), None));
|
||||
try!(self.print_ty_fn(None, Some('&'), region, f.fn_style,
|
||||
f.onceness, f.decl, None, &f.bounds,
|
||||
Some(&generics), None));
|
||||
}
|
||||
ast::TyProc(f) => {
|
||||
let generics = ast::Generics {
|
||||
lifetimes: f.lifetimes.clone(),
|
||||
ty_params: OwnedSlice::empty()
|
||||
};
|
||||
try!(self.print_ty_fn(None, Some('~'), &None, f.fn_style,
|
||||
f.onceness, f.decl, None, &f.bounds,
|
||||
Some(&generics), None));
|
||||
}
|
||||
ast::TyPath(ref path, ref bounds, _) => {
|
||||
try!(self.print_bounded_path(path, bounds));
|
||||
@ -1716,8 +1725,7 @@ impl<'a> State<'a> {
|
||||
opt_explicit_self: Option<ast::ExplicitSelf_>,
|
||||
vis: ast::Visibility) -> IoResult<()> {
|
||||
try!(self.head(""));
|
||||
try!(self.print_fn_header_info(opt_explicit_self, fn_style, abi,
|
||||
ast::Many, None, vis));
|
||||
try!(self.print_fn_header_info(opt_explicit_self, fn_style, abi, vis));
|
||||
try!(self.nbsp());
|
||||
try!(self.print_ident(name));
|
||||
try!(self.print_generics(generics));
|
||||
@ -2023,7 +2031,7 @@ impl<'a> State<'a> {
|
||||
|
||||
pub fn print_ty_fn(&mut self,
|
||||
opt_abi: Option<abi::Abi>,
|
||||
opt_sigil: Option<ast::Sigil>,
|
||||
opt_sigil: Option<char>,
|
||||
opt_region: &Option<ast::Lifetime>,
|
||||
fn_style: ast::FnStyle,
|
||||
onceness: ast::Onceness,
|
||||
@ -2037,15 +2045,15 @@ impl<'a> State<'a> {
|
||||
|
||||
// Duplicates the logic in `print_fn_header_info()`. This is because that
|
||||
// function prints the sigil in the wrong place. That should be fixed.
|
||||
if opt_sigil == Some(ast::OwnedSigil) && onceness == ast::Once {
|
||||
if opt_sigil == Some('~') && onceness == ast::Once {
|
||||
try!(word(&mut self.s, "proc"));
|
||||
} else if opt_sigil == Some(ast::BorrowedSigil) {
|
||||
} else if opt_sigil == Some('&') {
|
||||
try!(self.print_extern_opt_abi(opt_abi));
|
||||
try!(self.print_fn_style(fn_style));
|
||||
try!(self.print_onceness(onceness));
|
||||
} else {
|
||||
assert!(opt_sigil.is_none());
|
||||
try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi));
|
||||
try!(self.print_opt_sigil(opt_sigil));
|
||||
try!(self.print_fn_style(fn_style));
|
||||
try!(self.print_onceness(onceness));
|
||||
try!(word(&mut self.s, "fn"));
|
||||
@ -2062,7 +2070,7 @@ impl<'a> State<'a> {
|
||||
match generics { Some(g) => try!(self.print_generics(g)), _ => () }
|
||||
try!(zerobreak(&mut self.s));
|
||||
|
||||
if opt_sigil == Some(ast::BorrowedSigil) {
|
||||
if opt_sigil == Some('&') {
|
||||
try!(word(&mut self.s, "|"));
|
||||
} else {
|
||||
try!(self.popen());
|
||||
@ -2070,7 +2078,7 @@ impl<'a> State<'a> {
|
||||
|
||||
try!(self.print_fn_args(decl, opt_explicit_self));
|
||||
|
||||
if opt_sigil == Some(ast::BorrowedSigil) {
|
||||
if opt_sigil == Some('&') {
|
||||
try!(word(&mut self.s, "|"));
|
||||
} else {
|
||||
if decl.variadic {
|
||||
@ -2327,22 +2335,10 @@ impl<'a> State<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_opt_sigil(&mut self,
|
||||
opt_sigil: Option<ast::Sigil>) -> IoResult<()> {
|
||||
match opt_sigil {
|
||||
Some(ast::BorrowedSigil) => word(&mut self.s, "&"),
|
||||
Some(ast::OwnedSigil) => word(&mut self.s, "~"),
|
||||
Some(ast::ManagedSigil) => word(&mut self.s, "@"),
|
||||
None => Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_fn_header_info(&mut self,
|
||||
_opt_explicit_self: Option<ast::ExplicitSelf_>,
|
||||
opt_fn_style: Option<ast::FnStyle>,
|
||||
abi: abi::Abi,
|
||||
onceness: ast::Onceness,
|
||||
opt_sigil: Option<ast::Sigil>,
|
||||
vis: ast::Visibility) -> IoResult<()> {
|
||||
try!(word(&mut self.s, visibility_qualified(vis, "")));
|
||||
|
||||
@ -2357,9 +2353,7 @@ impl<'a> State<'a> {
|
||||
try!(self.print_opt_fn_style(opt_fn_style));
|
||||
}
|
||||
|
||||
try!(self.print_onceness(onceness));
|
||||
try!(word(&mut self.s, "fn"));
|
||||
self.print_opt_sigil(opt_sigil)
|
||||
word(&mut self.s, "fn")
|
||||
}
|
||||
|
||||
pub fn print_fn_style(&mut self, s: ast::FnStyle) -> IoResult<()> {
|
||||
|
@ -328,7 +328,7 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
|
||||
visitor.visit_ty(tuple_element_type, env.clone())
|
||||
}
|
||||
}
|
||||
TyClosure(ref function_declaration) => {
|
||||
TyClosure(ref function_declaration, ref region) => {
|
||||
for argument in function_declaration.decl.inputs.iter() {
|
||||
visitor.visit_ty(argument.ty, env.clone())
|
||||
}
|
||||
@ -338,11 +338,22 @@ pub fn walk_ty<E: Clone, V: Visitor<E>>(visitor: &mut V, typ: &Ty, env: E) {
|
||||
}
|
||||
visitor.visit_opt_lifetime_ref(
|
||||
typ.span,
|
||||
&function_declaration.region,
|
||||
region,
|
||||
env.clone());
|
||||
walk_lifetime_decls(visitor, &function_declaration.lifetimes,
|
||||
env.clone());
|
||||
}
|
||||
TyProc(ref function_declaration) => {
|
||||
for argument in function_declaration.decl.inputs.iter() {
|
||||
visitor.visit_ty(argument.ty, env.clone())
|
||||
}
|
||||
visitor.visit_ty(function_declaration.decl.output, env.clone());
|
||||
for bounds in function_declaration.bounds.iter() {
|
||||
walk_ty_param_bounds(visitor, bounds, env.clone())
|
||||
}
|
||||
walk_lifetime_decls(visitor, &function_declaration.lifetimes,
|
||||
env.clone());
|
||||
}
|
||||
TyBareFn(ref function_declaration) => {
|
||||
for argument in function_declaration.decl.inputs.iter() {
|
||||
visitor.visit_ty(argument.ty, env.clone())
|
||||
|
Loading…
x
Reference in New Issue
Block a user