]> git.lizzy.rs Git - rust.git/commitdiff
Demote self to an (almost) regular argument and remove the env param.
authorEduard Burtescu <edy.burt@gmail.com>
Mon, 27 Jan 2014 12:18:36 +0000 (14:18 +0200)
committerEduard Burtescu <edy.burt@gmail.com>
Mon, 27 Jan 2014 12:31:24 +0000 (14:31 +0200)
Fixes #10667 and closes #10259.

88 files changed:
src/libextra/test.rs
src/librustc/metadata/common.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tyencode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/borrowck/check_loans.rs
src/librustc/middle/borrowck/gather_loans/gather_moves.rs
src/librustc/middle/borrowck/gather_loans/lifetime.rs
src/librustc/middle/borrowck/gather_loans/restrictions.rs
src/librustc/middle/borrowck/mod.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/dataflow.rs
src/librustc/middle/effect.rs
src/librustc/middle/freevars.rs
src/librustc/middle/kind.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/moves.rs
src/librustc/middle/privacy.rs
src/librustc/middle/region.rs
src/librustc/middle/resolve.rs
src/librustc/middle/trans/_match.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/builder.rs
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/cleanup.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/foreign.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/inline.rs
src/librustc/middle/trans/intrinsic.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/reflect.rs
src/librustc/middle/trans/type_.rs
src/librustc/middle/trans/type_of.rs
src/librustc/middle/ty.rs
src/librustc/middle/ty_fold.rs
src/librustc/middle/typeck/astconv.rs
src/librustc/middle/typeck/check/method.rs
src/librustc/middle/typeck/check/mod.rs
src/librustc/middle/typeck/check/regionck.rs
src/librustc/middle/typeck/check/regionmanip.rs
src/librustc/middle/typeck/check/vtable.rs
src/librustc/middle/typeck/check/writeback.rs
src/librustc/middle/typeck/coherence.rs
src/librustc/middle/typeck/collect.rs
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/middle/typeck/infer/mod.rs
src/librustc/middle/typeck/infer/sub.rs
src/librustc/middle/typeck/mod.rs
src/librustc/middle/typeck/variance.rs
src/librustc/util/ppaux.rs
src/librustdoc/clean.rs
src/librustdoc/html/render.rs
src/librustuv/net.rs
src/librustuv/pipe.rs
src/libstd/io/buffered.rs
src/libstd/reflect.rs
src/libstd/repr.rs
src/libstd/unstable/intrinsics.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map.rs
src/libsyntax/ast_util.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/generic.rs
src/libsyntax/ext/deriving/ty.rs
src/libsyntax/fold.rs
src/libsyntax/parse/classify.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/visit.rs
src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs [new file with mode: 0644]
src/test/compile-fail/issue-6642.rs
src/test/compile-fail/lint-unused-mut-self.rs [new file with mode: 0644]
src/test/compile-fail/trait-impl-different-num-params.rs
src/test/run-pass/coerce-to-closure-and-proc.rs [new file with mode: 0644]
src/test/run-pass/expr-block-fn.rs
src/test/run-pass/reflect-visit-data.rs
src/test/run-pass/reflect-visit-type.rs

index a54f3110cd63bb84f20993272a1fc0f3c75fb976..c621461fc36a05a20df443345664d89340b6f737 100644 (file)
@@ -895,7 +895,7 @@ fn run_test_inner(desc: TestDesc,
             return;
         }
         StaticBenchFn(benchfn) => {
-            let bs = ::test::bench::benchmark(benchfn);
+            let bs = ::test::bench::benchmark(|harness| benchfn(harness));
             monitor_ch.send((desc, TrBench(bs)));
             return;
         }
index 09531e80ae59cf1d038f609195102ce8aa1c2800..e8cfa97c0e1c881bc1fe0e3a1ae2d2119feb0f12 100644 (file)
@@ -176,24 +176,23 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
 
 pub static tag_item_method_tps: uint = 0x7b;
 pub static tag_item_method_fty: uint = 0x7c;
-pub static tag_item_method_transformed_self_ty: uint = 0x7d;
 
-pub static tag_mod_child: uint = 0x7e;
-pub static tag_misc_info: uint = 0x7f;
-pub static tag_misc_info_crate_items: uint = 0x80;
+pub static tag_mod_child: uint = 0x7d;
+pub static tag_misc_info: uint = 0x7e;
+pub static tag_misc_info_crate_items: uint = 0x7f;
 
-pub static tag_item_method_provided_source: uint = 0x81;
-pub static tag_item_impl_vtables: uint = 0x82;
+pub static tag_item_method_provided_source: uint = 0x80;
+pub static tag_item_impl_vtables: uint = 0x81;
 
-pub static tag_impls: uint = 0x83;
-pub static tag_impls_impl: uint = 0x84;
+pub static tag_impls: uint = 0x82;
+pub static tag_impls_impl: uint = 0x83;
 
-pub static tag_items_data_item_inherent_impl: uint = 0x85;
-pub static tag_items_data_item_extension_impl: uint = 0x86;
+pub static tag_items_data_item_inherent_impl: uint = 0x84;
+pub static tag_items_data_item_extension_impl: uint = 0x85;
 
-pub static tag_path_elem_pretty_name: uint = 0x87;
-pub static tag_path_elem_pretty_name_ident: uint = 0x88;
-pub static tag_path_elem_pretty_name_extra: uint = 0x89;
+pub static tag_path_elem_pretty_name: uint = 0x86;
+pub static tag_path_elem_pretty_name_ident: uint = 0x87;
+pub static tag_path_elem_pretty_name_extra: uint = 0x88;
 
 pub static tag_region_param_def: uint = 0x100;
 pub static tag_region_param_def_ident: uint = 0x101;
index a7e5082bcbbf6b875e502f90abec7ea78eaa58f2..11fab9cced7f7ac240ac1fcc967fd65c0e1b6daa 100644 (file)
@@ -227,16 +227,6 @@ fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: Cmd) -> ty::BareFnTy {
                           |_, did| translate_def_id(cdata, did))
 }
 
-fn doc_transformed_self_ty(doc: ebml::Doc,
-                           tcx: ty::ctxt,
-                           cdata: Cmd) -> Option<ty::t>
-{
-    reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map(|tp| {
-        parse_ty_data(tp.data, cdata.cnum, tp.start, tcx,
-                      |_, did| translate_def_id(cdata, did))
-    })
-}
-
 pub fn item_type(_item_id: ast::DefId, item: ebml::Doc,
                  tcx: ty::ctxt, cdata: Cmd) -> ty::t {
     doc_type(item, tcx, cdata)
@@ -781,9 +771,9 @@ fn get_mutability(ch: u8) -> ast::Mutability {
     let explicit_self_kind = string[0];
     match explicit_self_kind as char {
         's' => ast::SelfStatic,
-        'v' => ast::SelfValue(get_mutability(string[1])),
+        'v' => ast::SelfValue,
         '@' => ast::SelfBox,
-        '~' => ast::SelfUniq(get_mutability(string[1])),
+        '~' => ast::SelfUniq,
         // FIXME(#4846) expl. region
         '&' => ast::SelfRegion(None, get_mutability(string[1])),
         _ => fail!("unknown self type code: `{}`", explicit_self_kind as char)
@@ -847,7 +837,6 @@ pub fn get_method(intr: @IdentInterner, cdata: Cmd, id: ast::NodeId,
     let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
                                              tag_item_method_tps);
     let rp_defs = item_region_param_defs(method_doc, tcx, cdata);
-    let transformed_self_ty = doc_transformed_self_ty(method_doc, tcx, cdata);
     let fty = doc_method_fty(method_doc, tcx, cdata);
     let vis = item_visibility(method_doc);
     let explicit_self = get_explicit_self(method_doc);
@@ -859,7 +848,6 @@ pub fn get_method(intr: @IdentInterner, cdata: Cmd, id: ast::NodeId,
             type_param_defs: type_param_defs,
             region_param_defs: rp_defs,
         },
-        transformed_self_ty,
         fty,
         explicit_self,
         vis,
index c7d238dac18e9d5e31775c52befaa26f47f1513d..8a2c56cbcd35ab3baae8889d9781412eb6f5029f 100644 (file)
@@ -261,16 +261,6 @@ fn encode_type(ecx: &EncodeContext,
     ebml_w.end_tag();
 }
 
-fn encode_transformed_self_ty(ecx: &EncodeContext,
-                              ebml_w: &mut writer::Encoder,
-                              opt_typ: Option<ty::t>) {
-    for &typ in opt_typ.iter() {
-        ebml_w.start_tag(tag_item_method_transformed_self_ty);
-        write_type(ecx, ebml_w, typ);
-        ebml_w.end_tag();
-    }
-}
-
 fn encode_method_fty(ecx: &EncodeContext,
                      ebml_w: &mut writer::Encoder,
                      typ: &ty::BareFnTy) {
@@ -679,23 +669,13 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
 
     // Encode the base self type.
     match explicit_self {
-        SelfStatic => {
-            ebml_w.writer.write(&[ 's' as u8 ]);
-        }
-        SelfValue(m) => {
-            ebml_w.writer.write(&[ 'v' as u8 ]);
-            encode_mutability(ebml_w, m);
-        }
+        SelfStatic => ebml_w.writer.write(&[ 's' as u8 ]),
+        SelfValue  => ebml_w.writer.write(&[ 'v' as u8 ]),
+        SelfBox    => ebml_w.writer.write(&[ '@' as u8 ]),
+        SelfUniq   => ebml_w.writer.write(&[ '~' as u8 ]),
         SelfRegion(_, m) => {
             // FIXME(#4846) encode custom lifetime
-            ebml_w.writer.write(&[ '&' as u8 ]);
-            encode_mutability(ebml_w, m);
-        }
-        SelfBox => {
-            ebml_w.writer.write(&[ '@' as u8 ]);
-        }
-        SelfUniq(m) => {
-            ebml_w.writer.write(&[ '~' as u8 ]);
+            ebml_w.writer.write(&['&' as u8]);
             encode_mutability(ebml_w, m);
         }
     }
@@ -807,7 +787,6 @@ fn encode_method_ty_fields(ecx: &EncodeContext,
     encode_ty_type_param_defs(ebml_w, ecx,
                               method_ty.generics.type_param_defs,
                               tag_item_method_tps);
-    encode_transformed_self_ty(ecx, ebml_w, method_ty.transformed_self_ty);
     encode_method_fty(ecx, ebml_w, &method_ty.fty);
     encode_visibility(ebml_w, method_ty.vis);
     encode_explicit_self(ebml_w, method_ty.explicit_self);
index 4f19d461c854c7216d0f42fc67a8d4407e0f6199..a40ba4a44a5db62904d70f5d96e4cc477e6df6fd 100644 (file)
@@ -374,10 +374,6 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t {
         return ty::mk_bare_fn(st.tcx, parse_bare_fn_ty(st, |x,y| conv(x,y)));
       }
       'Y' => return ty::mk_type(st.tcx),
-      'C' => {
-        let sigil = parse_sigil(st);
-        return ty::mk_opaque_closure_ptr(st.tcx, sigil);
-      }
       '#' => {
         let pos = parse_hex(st);
         assert_eq!(next(st), ':');
index 965aab31f142682272e137bdd637d64aa3ac8146..23e96110c066568dd1e32f341f3501d15a5bf7f2 100644 (file)
@@ -327,10 +327,6 @@ fn enc_sty(w: &mut MemWriter, cx: @ctxt, st: &ty::sty) {
             mywrite!(w, "s{}|", (cx.ds)(did));
         }
         ty::ty_type => mywrite!(w, "Y"),
-        ty::ty_opaque_closure_ptr(p) => {
-            mywrite!(w, "C&");
-            enc_sigil(w, p);
-        }
         ty::ty_struct(def, ref substs) => {
             mywrite!(w, "a[{}|", (cx.ds)(def));
             enc_substs(w, cx, substs);
index b990c5073d12b05984ba0296804c98dc61f531ca..a601b624c1979f6f6185350b94219380641bceb5 100644 (file)
@@ -435,7 +435,6 @@ fn tr(&self, xcx: @ExtendedDecodeContext) -> ast::Def {
             ast::DefMethod(did0.tr(xcx), did1.map(|did1| did1.tr(xcx)))
           }
           ast::DefSelfTy(nid) => { ast::DefSelfTy(xcx.tr_id(nid)) }
-          ast::DefSelf(nid, m) => { ast::DefSelf(xcx.tr_id(nid), m) }
           ast::DefMod(did) => { ast::DefMod(did.tr(xcx)) }
           ast::DefForeignMod(did) => { ast::DefForeignMod(did.tr(xcx)) }
           ast::DefStatic(did, m) => { ast::DefStatic(did.tr(xcx), m) }
@@ -579,16 +578,8 @@ fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
                              -> method_map_entry;
 }
 
-fn encode_method_map_entry(ecx: &e::EncodeContext,
-                           ebml_w: &mut writer::Encoder,
-                           mme: method_map_entry) {
+fn encode_method_map_entry(ebml_w: &mut writer::Encoder, mme: method_map_entry) {
     ebml_w.emit_struct("method_map_entry", 3, |ebml_w| {
-        ebml_w.emit_struct_field("self_ty", 0u, |ebml_w| {
-            ebml_w.emit_ty(ecx, mme.self_ty);
-        });
-        ebml_w.emit_struct_field("explicit_self", 2u, |ebml_w| {
-            mme.explicit_self.encode(ebml_w);
-        });
         ebml_w.emit_struct_field("origin", 1u, |ebml_w| {
             mme.origin.encode(ebml_w);
         });
@@ -600,15 +591,6 @@ fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
                              -> method_map_entry {
         self.read_struct("method_map_entry", 3, |this| {
             method_map_entry {
-                self_ty: this.read_struct_field("self_ty", 0u, |this| {
-                    this.read_ty(xcx)
-                }),
-                explicit_self: this.read_struct_field("explicit_self",
-                                                      2,
-                                                      |this| {
-                    let explicit_self: ast::ExplicitSelf_ = Decodable::decode(this);
-                    explicit_self
-                }),
                 origin: this.read_struct_field("origin", 1, |this| {
                     let method_origin: method_origin =
                         Decodable::decode(this);
@@ -1043,7 +1025,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
             ebml_w.tag(c::tag_table_method_map, |ebml_w| {
                 ebml_w.id(id);
                 ebml_w.tag(c::tag_table_val, |ebml_w| {
-                    encode_method_map_entry(ecx, ebml_w, *mme)
+                    encode_method_map_entry(ebml_w, *mme)
                 })
             })
         }
index 0fd92079489ae152565dc4958742777192cf1e93..59310d722e426441f3f5a3ae93acc72b463cec61 100644 (file)
@@ -371,9 +371,7 @@ fn mark_variable_as_used_mut(this: &CheckLoanCtxt,
                 debug!("mark_writes_through_upvars_as_used_mut(cmt={})",
                        cmt.repr(this.tcx()));
                 match cmt.cat {
-                    mc::cat_local(id) |
-                    mc::cat_arg(id) |
-                    mc::cat_self(id) => {
+                    mc::cat_local(id) | mc::cat_arg(id) => {
                         let mut used_mut_nodes = this.tcx()
                                                      .used_mut_nodes
                                                      .borrow_mut();
@@ -459,7 +457,6 @@ fn check_for_aliasability_violation(this: &CheckLoanCtxt,
                     mc::cat_rvalue(..) |
                     mc::cat_local(..) |
                     mc::cat_arg(_) |
-                    mc::cat_self(..) |
                     mc::cat_deref(_, _, mc::unsafe_ptr(..)) |
                     mc::cat_static_item(..) |
                     mc::cat_deref(_, _, mc::gc_ptr) |
@@ -790,7 +787,6 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
 
     let method_map = this.bccx.method_map.borrow();
     match expr.node {
-      ast::ExprSelf |
       ast::ExprPath(..) => {
           if !this.move_data.is_assignee(expr.id) {
               let cmt = this.bccx.cat_expr_unadjusted(expr);
@@ -808,32 +804,24 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
       ast::ExprCall(f, ref args, _) => {
         this.check_call(expr, Some(f), f.id, f.span, *args);
       }
-      ast::ExprMethodCall(callee_id, _, _, _, ref args, _) => {
+      ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
         this.check_call(expr, None, callee_id, expr.span, *args);
       }
       ast::ExprIndex(callee_id, _, rval) |
       ast::ExprBinary(callee_id, _, _, rval)
       if method_map.get().contains_key(&expr.id) => {
-        this.check_call(expr,
-                        None,
-                        callee_id,
-                        expr.span,
-                        [rval]);
+        this.check_call(expr, None, callee_id, expr.span, [rval]);
       }
       ast::ExprUnary(callee_id, _, _) | ast::ExprIndex(callee_id, _, _)
       if method_map.get().contains_key(&expr.id) => {
-        this.check_call(expr,
-                        None,
-                        callee_id,
-                        expr.span,
-                        []);
+        this.check_call(expr, None, callee_id, expr.span, []);
       }
       ast::ExprInlineAsm(ref ia) => {
           for &(_, out) in ia.outputs.iter() {
               this.check_assignment(out);
           }
       }
-      _ => { }
+      _ => {}
     }
 }
 
index 9ba8e00dc8ecbbbd9221148ffd81f2e9bc80b701..78350a993b483c205c72d31db9794d7445f60581 100644 (file)
@@ -133,8 +133,7 @@ fn check_is_legal_to_move_from(bccx: &BorrowckCtxt,
 
         mc::cat_rvalue(..) |
         mc::cat_local(..) |
-        mc::cat_arg(..) |
-        mc::cat_self(..) => {
+        mc::cat_arg(..) => {
             true
         }
 
index 9a4869fb6d1d02ce80b957254594e9aed1435d72..4c2f0986d9cc21e5ff7180ed618929d053a6a468 100644 (file)
@@ -76,7 +76,6 @@ fn check(&self, cmt: mc::cmt, discr_scope: Option<ast::NodeId>) -> R {
             mc::cat_copied_upvar(..) |                  // L-Local
             mc::cat_local(..) |                         // L-Local
             mc::cat_arg(..) |                           // L-Local
-            mc::cat_self(..) |                          // L-Local
             mc::cat_deref(_, _, mc::region_ptr(..)) |   // L-Deref-Borrowed
             mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
                 let scope = self.scope(cmt);
@@ -261,7 +260,6 @@ fn is_moved(&self, cmt: mc::cmt) -> bool {
 
         match cmt.guarantor().cat {
             mc::cat_local(id) |
-            mc::cat_self(id) |
             mc::cat_arg(id) => {
                 let moved_variables_set = self.bccx
                                               .moved_variables_set
@@ -303,8 +301,7 @@ fn scope(&self, cmt: mc::cmt) -> ty::Region {
                 ty::ReStatic
             }
             mc::cat_local(local_id) |
-            mc::cat_arg(local_id) |
-            mc::cat_self(local_id) => {
+            mc::cat_arg(local_id) => {
                 ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
             }
             mc::cat_deref(_, _, mc::unsafe_ptr(..)) => {
index 50b437e95d5d16f5e94064a99b6fb9f6bd556bf7..22e64064c9ce56ec46200ac3dae42888104c3bdd 100644 (file)
@@ -74,8 +74,7 @@ fn restrict(&self,
             }
 
             mc::cat_local(local_id) |
-            mc::cat_arg(local_id) |
-            mc::cat_self(local_id) => {
+            mc::cat_arg(local_id) => {
                 // R-Variable
                 let lp = @LpVar(local_id);
                 SafeIf(lp, ~[Restriction {loan_path: lp,
index 002f263209a5bc2b16f84dafb6daff33408354e3..90c9a61b18b170266a3aa69286a8546070bce9fd 100644 (file)
@@ -25,6 +25,7 @@
 use std::result::{Result};
 use syntax::ast;
 use syntax::ast_map;
+use syntax::ast_util;
 use syntax::codemap::Span;
 use syntax::parse::token;
 use syntax::visit;
@@ -294,9 +295,7 @@ pub fn opt_loan_path(cmt: mc::cmt) -> Option<@LoanPath> {
             None
         }
 
-        mc::cat_local(id) |
-        mc::cat_arg(id) |
-        mc::cat_self(id) => {
+        mc::cat_local(id) | mc::cat_arg(id) => {
             Some(@LpVar(id))
         }
 
@@ -771,8 +770,18 @@ pub fn append_loan_path_to_str(&self,
         match *loan_path {
             LpVar(id) => {
                 match self.tcx.items.find(id) {
-                    Some(ast_map::NodeLocal(ref ident, _)) => {
-                        out.push_str(token::ident_to_str(ident));
+                    Some(ast_map::NodeLocal(pat)) => {
+                        match pat.node {
+                            ast::PatIdent(_, ref path, _) => {
+                                let ident = ast_util::path_to_ident(path);
+                                out.push_str(token::ident_to_str(&ident));
+                            }
+                            _ => {
+                                self.tcx.sess.bug(
+                                    format!("Loan path LpVar({:?}) maps to {:?}, not local",
+                                        id, pat));
+                            }
+                        }
                     }
                     r => {
                         self.tcx.sess.bug(
index dc0b700da522a7d7b9a772e7b18622bb0e862427..923e5eba109473d6d30089abada9a7b90780c8da 100644 (file)
@@ -355,8 +355,8 @@ fn expr(&mut self, expr: @ast::Expr, pred: CFGIndex) -> CFGIndex {
                 self.call(expr, pred, func, *args)
             }
 
-            ast::ExprMethodCall(_, rcvr, _, _, ref args, _) => {
-                self.call(expr, pred, rcvr, *args)
+            ast::ExprMethodCall(_, _, _, ref args, _) => {
+                self.call(expr, pred, args[0], args.slice_from(1))
             }
 
             ast::ExprIndex(_, l, r) |
@@ -410,7 +410,6 @@ fn expr(&mut self, expr: @ast::Expr, pred: CFGIndex) -> CFGIndex {
             ast::ExprLogLevel |
             ast::ExprMac(..) |
             ast::ExprInlineAsm(..) |
-            ast::ExprSelf |
             ast::ExprFnBlock(..) |
             ast::ExprProc(..) |
             ast::ExprLit(..) |
index 9115125324c38a7fbd391d6f6d5c2e0da3c5abcc..a0ef6e503a1271cd48866d6b70d6a84b6470b678 100644 (file)
@@ -668,24 +668,21 @@ fn walk_expr(&mut self,
             }
 
             ast::ExprCall(f, ref args, _) => {
-                self.walk_call(f.id, expr.id,
-                               f, *args, in_out, loop_scopes);
+                self.walk_expr(f, in_out, loop_scopes);
+                self.walk_call(f.id, expr.id, *args, in_out, loop_scopes);
             }
 
-            ast::ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => {
-                self.walk_call(callee_id, expr.id,
-                               rcvr, *args, in_out, loop_scopes);
+            ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
+                self.walk_call(callee_id, expr.id, *args, in_out, loop_scopes);
             }
 
             ast::ExprIndex(callee_id, l, r) |
             ast::ExprBinary(callee_id, _, l, r) if self.is_method_call(expr) => {
-                self.walk_call(callee_id, expr.id,
-                               l, [r], in_out, loop_scopes);
+                self.walk_call(callee_id, expr.id, [l, r], in_out, loop_scopes);
             }
 
             ast::ExprUnary(callee_id, _, e) if self.is_method_call(expr) => {
-                self.walk_call(callee_id, expr.id,
-                               e, [], in_out, loop_scopes);
+                self.walk_call(callee_id, expr.id, [e], in_out, loop_scopes);
             }
 
             ast::ExprTup(ref exprs) => {
@@ -706,9 +703,7 @@ fn walk_expr(&mut self,
 
             ast::ExprLogLevel |
             ast::ExprLit(..) |
-            ast::ExprPath(..) |
-            ast::ExprSelf => {
-            }
+            ast::ExprPath(..) => {}
 
             ast::ExprAddrOf(_, e) |
             ast::ExprDoBody(e) |
@@ -813,11 +808,9 @@ fn walk_opt_expr(&mut self,
     fn walk_call(&mut self,
                  _callee_id: ast::NodeId,
                  call_id: ast::NodeId,
-                 arg0: &ast::Expr,
                  args: &[@ast::Expr],
                  in_out: &mut [uint],
                  loop_scopes: &mut ~[LoopScope]) {
-        self.walk_expr(arg0, in_out, loop_scopes);
         self.walk_exprs(args, in_out, loop_scopes);
 
         // FIXME(#6268) nested method calls
index e291d2595a0b2cde584098833cbdeb12605d5463..36dd46388c6243691db329282c292b62c270607f 100644 (file)
@@ -120,7 +120,7 @@ fn visit_block(&mut self, block: &ast::Block, _:()) {
 
     fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
         match expr.node {
-            ast::ExprMethodCall(callee_id, _, _, _, _, _) => {
+            ast::ExprMethodCall(callee_id, _, _, _, _) => {
                 let base_type = ty::node_id_to_type(self.tcx, callee_id);
                 debug!("effect: method call case, base type is {}",
                        ppaux::ty_to_str(self.tcx, base_type));
index 4ee8eb4108d1643801a774d2c527cf94dc55a114..635fbf7eea81662007f59469dae7a86a0b832dd2 100644 (file)
@@ -48,7 +48,7 @@ fn visit_expr(&mut self, expr: &ast::Expr, depth: int) {
             ast::ExprFnBlock(..) | ast::ExprProc(..) => {
                 visit::walk_expr(self, expr, depth + 1)
             }
-            ast::ExprPath(..) | ast::ExprSelf => {
+            ast::ExprPath(..) => {
                 let mut i = 0;
                 let def_map = self.def_map.borrow();
                 match def_map.get().find(&expr.id) {
index fde3e4809c39abb2d9c30b491fb74d0d182032f9..81a00e27fa05615b08dda5013070a8298afe1dc2 100644 (file)
@@ -454,9 +454,8 @@ fn check_imm_free_var(cx: &Context, def: Def, sp: Span) {
                 sp,
                 "mutable variables cannot be implicitly captured");
         }
-        DefLocal(..) | DefArg(..) => { /* ok */ }
+        DefLocal(..) | DefArg(..) | DefBinding(..) => { /* ok */ }
         DefUpvar(_, def1, _, _) => { check_imm_free_var(cx, *def1, sp); }
-        DefBinding(..) | DefSelf(..) => { /*ok*/ }
         _ => {
             cx.tcx.sess.span_bug(
                 sp,
index 180b97ce270c29aa551329984ce15a071d82a802..dfe9af9f3f039a0f38854af2820bf4d94486edb8 100644 (file)
@@ -405,20 +405,6 @@ fn visit_fn(v: &mut LivenessVisitor,
         })
     };
 
-    // Add `this`, whether explicit or implicit.
-    match *fk {
-        visit::FkMethod(_, _, method) => {
-            match method.explicit_self.node {
-                SelfValue(_) | SelfRegion(..) | SelfBox | SelfUniq(_) => {
-                    fn_maps.add_variable(Arg(method.self_id,
-                                             special_idents::self_));
-                }
-                SelfStatic => {}
-            }
-        }
-        visit::FkItemFn(..) | visit::FkFnBlock(..) => {}
-    }
-
     // gather up the various local variables, significant expressions,
     // and so forth:
     visit::walk_fn(v, fk, decl, body, sp, id, fn_maps);
@@ -493,7 +479,7 @@ fn visit_arm(v: &mut LivenessVisitor, arm: &Arm, this: @IrMaps) {
 fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
     match expr.node {
       // live nodes required for uses or definitions of variables:
-      ExprPath(_) | ExprSelf => {
+      ExprPath(_) => {
         let def_map = this.tcx.def_map.borrow();
         let def = def_map.get().get_copy(&expr.id);
         debug!("expr {}: path that leads to {:?}", expr.id, def);
@@ -1050,7 +1036,7 @@ pub fn propagate_through_expr(&self, expr: @Expr, succ: LiveNode)
         match expr.node {
           // Interesting cases with control flow or which gen/kill
 
-          ExprPath(_) | ExprSelf => {
+          ExprPath(_) => {
               self.access_path(expr, succ, ACC_READ | ACC_USE)
           }
 
@@ -1229,14 +1215,13 @@ pub fn propagate_through_expr(&self, expr: @Expr, succ: LiveNode)
             self.propagate_through_expr(f, succ)
           }
 
-          ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => {
+          ExprMethodCall(callee_id, _, _, ref args, _) => {
             // calling a method with bot return type means that the method
             // will fail, and hence the successors can be ignored
             let t_ret = ty::ty_fn_ret(ty::node_id_to_type(self.tcx, callee_id));
             let succ = if ty::type_is_bot(t_ret) {self.s.exit_ln}
                        else {succ};
-            let succ = self.propagate_through_exprs(*args, succ);
-            self.propagate_through_expr(rcvr, succ)
+            self.propagate_through_exprs(*args, succ)
           }
 
           ExprTup(ref exprs) => {
@@ -1549,7 +1534,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
       ExprAgain(..) | ExprLit(_) | ExprBlock(..) |
       ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
       ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprPath(..) |
-      ExprSelf(..) | ExprBox(..) => {
+      ExprBox(..) => {
         visit::walk_expr(this, expr, ());
       }
       ExprForLoop(..) => fail!("non-desugared expr_for_loop")
@@ -1694,9 +1679,13 @@ pub fn warn_about_unused_args(&self, decl: &FnDecl, entry_ln: LiveNode) {
         for arg in decl.inputs.iter() {
             pat_util::pat_bindings(self.tcx.def_map,
                                    arg.pat,
-                                   |_bm, p_id, sp, _n| {
+                                   |_bm, p_id, sp, path| {
                 let var = self.variable(p_id, sp);
-                self.warn_about_unused(sp, p_id, entry_ln, var);
+                // Ignore unused self.
+                let ident = ast_util::path_to_ident(path);
+                if ident.name != special_idents::self_.name {
+                    self.warn_about_unused(sp, p_id, entry_ln, var);
+                }
             })
         }
     }
index 70d4f63a16449942ce484033f1b95c347df2f00e..b6271b68046ad9b769a14d27ac1cebf9b3a830d9 100644 (file)
@@ -70,7 +70,6 @@ pub enum categorization {
     cat_interior(cmt, InteriorKind),   // something interior: field, tuple, etc
     cat_downcast(cmt),                 // selects a particular enum variant (..)
     cat_discr(cmt, ast::NodeId),       // match discriminant (see preserve())
-    cat_self(ast::NodeId),             // explicit `self`
 
     // (..) downcast is only required if the enum has more than one variant
 }
@@ -426,7 +425,7 @@ pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> cmt {
             self.cat_index(expr, base_cmt, 0)
           }
 
-          ast::ExprPath(_) | ast::ExprSelf => {
+          ast::ExprPath(_) => {
             let def_map = self.tcx.def_map.borrow();
             let def = def_map.get().get_copy(&expr.id);
             self.cat_def(expr.id, expr.span, expr_ty, def)
@@ -503,16 +502,6 @@ pub fn cat_def(&self,
             }
           }
 
-          ast::DefSelf(self_id, mutbl) => {
-            @cmt_ {
-                id:id,
-                span:span,
-                cat:cat_self(self_id),
-                mutbl: if mutbl { McDeclared } else { McImmutable },
-                ty:expr_ty
-            }
-          }
-
           ast::DefUpvar(upvar_id, inner, fn_node_id, _) => {
               let ty = ty::node_id_to_type(self.tcx, fn_node_id);
               match ty::get(ty).sty {
@@ -1032,9 +1021,6 @@ pub fn cmt_to_str(&self, cmt: cmt) -> ~str {
           cat_local(_) => {
               ~"local variable"
           }
-          cat_self(_) => {
-              ~"self value"
-          }
           cat_arg(..) => {
               ~"argument"
           }
@@ -1129,7 +1115,6 @@ pub fn guarantor(@self) -> cmt {
             cat_static_item |
             cat_copied_upvar(..) |
             cat_local(..) |
-            cat_self(..) |
             cat_arg(..) |
             cat_deref(_, _, unsafe_ptr(..)) |
             cat_deref(_, _, gc_ptr) |
@@ -1165,7 +1150,6 @@ pub fn freely_aliasable(&self) -> Option<AliasableReason> {
             cat_rvalue(..) |
             cat_local(..) |
             cat_arg(_) |
-            cat_self(..) |
             cat_deref(_, _, unsafe_ptr(..)) | // of course it is aliasable, but...
             cat_deref(_, _, region_ptr(MutMutable, _)) => {
                 None
@@ -1212,7 +1196,6 @@ fn repr(&self, tcx: ty::ctxt) -> ~str {
             cat_rvalue(..) |
             cat_copied_upvar(..) |
             cat_local(..) |
-            cat_self(..) |
             cat_arg(..) => {
                 format!("{:?}", *self)
             }
index e0146694881b7d5d04e61e201b390a1f327d85c9..054e2936439371f9b28b05db9e78b196199b77b4 100644 (file)
@@ -227,10 +227,9 @@ pub fn compute_moves(tcx: ty::ctxt,
 
 pub fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
     match def {
-      DefBinding(nid, _) |
-      DefArg(nid, _) |
-      DefLocal(nid, _) |
-      DefSelf(nid, _) => Some(nid),
+        DefBinding(nid, _) |
+        DefArg(nid, _) |
+        DefLocal(nid, _) => Some(nid),
 
       _ => None
     }
@@ -344,7 +343,7 @@ pub fn use_expr(&mut self,
         debug!("comp_mode = {:?}", comp_mode);
 
         match expr.node {
-            ExprPath(..) | ExprSelf => {
+            ExprPath(..) => {
                 match comp_mode {
                     Move => {
                         let def_map = self.tcx.def_map.borrow();
@@ -413,10 +412,7 @@ pub fn use_expr(&mut self,
                 self.use_fn_args(callee.id, *args);
             }
 
-            ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => { // callee.m(args)
-                // Implicit self is equivalent to & mode, but every
-                // other kind should be + mode.
-                self.use_receiver(rcvr);
+            ExprMethodCall(callee_id, _, _, ref args, _) => { // callee.m(args)
                 self.use_fn_args(callee_id, *args);
             }
 
@@ -620,7 +616,7 @@ pub fn use_overloaded_operator(&mut self,
             return false;
         }
 
-        self.use_receiver(receiver_expr);
+        self.use_fn_arg(receiver_expr);
 
         // for overloaded operatrs, we are always passing in a
         // reference, so it's always read mode:
@@ -675,11 +671,6 @@ pub fn use_pat(&mut self, pat: @Pat) {
         })
     }
 
-    pub fn use_receiver(&mut self,
-                        receiver_expr: @Expr) {
-        self.use_fn_arg(receiver_expr);
-    }
-
     pub fn use_fn_args(&mut self,
                        _: NodeId,
                        arg_exprs: &[@Expr]) {
index 052a6ad898fd63ce55e8d234e1beee492153c135..2562c34b54b00e4661de9362727a93abbce3400c 100644 (file)
@@ -688,9 +688,9 @@ fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
                     _ => {}
                 }
             }
-            ast::ExprMethodCall(_, base, ident, _, _, _) => {
+            ast::ExprMethodCall(_, ident, _, ref args, _) => {
                 // see above
-                let t = ty::type_autoderef(ty::expr_ty(self.tcx, base));
+                let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
                 match ty::get(t).sty {
                     ty::ty_enum(_, _) | ty::ty_struct(_, _) => {
                         let method_map = self.method_map.borrow();
index c202684c7abff850b8bda193579a63158132bd70..4ebbd097f2922b693b6931d546217991bb48b175 100644 (file)
@@ -820,12 +820,6 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
     // The arguments and `self` are parented to the body of the fn.
     let decl_cx = Context {parent: Some(body.id),
                            var_parent: Some(body.id)};
-    match *fk {
-        visit::FkMethod(_, _, method) => {
-            visitor.region_maps.record_var_scope(method.self_id, body.id);
-        }
-        _ => {}
-    }
     visit::walk_fn_decl(visitor, decl, decl_cx);
 
     // The body of the fn itself is either a root scope (top-level fn)
index b6a4a55186c320398bfa07a674cb282fec0aa834..dab9c7c71d9685f3047148fa062197366c5cfc3b 100644 (file)
@@ -130,11 +130,6 @@ enum NameDefinition {
     ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
 }
 
-enum SelfBinding {
-    NoSelfBinding,
-    HasSelfBinding(NodeId, ExplicitSelf)
-}
-
 impl Visitor<()> for Resolver {
     fn visit_item(&mut self, item: &Item, _: ()) {
         self.resolve_item(item);
@@ -258,12 +253,6 @@ enum ModulePrefixResult {
     PrefixFound(@Module, uint)
 }
 
-#[deriving(Eq)]
-enum AllowCapturingSelfFlag {
-    AllowCapturingSelf,         //< The "self" definition can be captured.
-    DontAllowCapturingSelf,     //< The "self" definition cannot be captured.
-}
-
 #[deriving(Eq)]
 enum NameSearchType {
     /// We're doing a name search in order to resolve a `use` directive.
@@ -294,7 +283,6 @@ enum DuplicateCheckingMode {
 /// One local scope.
 struct Rib {
     bindings: RefCell<HashMap<Name, DefLike>>,
-    self_binding: RefCell<Option<DefLike>>,
     kind: RibKind,
 }
 
@@ -302,7 +290,6 @@ impl Rib {
     fn new(kind: RibKind) -> Rib {
         Rib {
             bindings: RefCell::new(HashMap::new()),
-            self_binding: RefCell::new(None),
             kind: kind
         }
     }
@@ -1746,8 +1733,8 @@ trait method '{}'",
                       ignoring {:?}", def);
               // Ignored; handled elsewhere.
           }
-          DefSelf(..) | DefArg(..) | DefLocal(..) |
-          DefPrimTy(..) | DefTyParam(..) | DefBinding(..) |
+          DefArg(..) | DefLocal(..) | DefPrimTy(..) |
+          DefTyParam(..) | DefBinding(..) |
           DefUse(..) | DefUpvar(..) | DefRegion(..) |
           DefTyParamBinder(..) | DefLabel(..) | DefSelfTy(..) => {
             fail!("didn't expect `{:?}`", def);
@@ -3469,8 +3456,7 @@ fn upvarify(&mut self,
                     ribs: &mut ~[@Rib],
                     rib_index: uint,
                     def_like: DefLike,
-                    span: Span,
-                    allow_capturing_self: AllowCapturingSelfFlag)
+                    span: Span)
                     -> Option<DefLike> {
         let mut def;
         let is_ty_param;
@@ -3485,11 +3471,6 @@ fn upvarify(&mut self,
                 def = d;
                 is_ty_param = true;
             }
-            DlDef(d @ DefSelf(..))
-                    if allow_capturing_self == DontAllowCapturingSelf => {
-                def = d;
-                is_ty_param = false;
-            }
             _ => {
                 return Some(def_like);
             }
@@ -3589,8 +3570,7 @@ fn upvarify(&mut self,
     fn search_ribs(&mut self,
                        ribs: &mut ~[@Rib],
                        name: Name,
-                       span: Span,
-                       allow_capturing_self: AllowCapturingSelfFlag)
+                       span: Span)
                        -> Option<DefLike> {
         // FIXME #4950: This should not use a while loop.
         // FIXME #4950: Try caching?
@@ -3604,8 +3584,7 @@ fn search_ribs(&mut self,
             };
             match binding_opt {
                 Some(def_like) => {
-                    return self.upvarify(ribs, i, def_like, span,
-                                         allow_capturing_self);
+                    return self.upvarify(ribs, i, def_like, span);
                 }
                 None => {
                     // Continue.
@@ -3786,8 +3765,7 @@ fn resolve_item(&mut self, item: &Item) {
                                          item.id,
                                          0,
                                          OpaqueFunctionRibKind),
-                                      block,
-                                      NoSelfBinding);
+                                      block);
             }
 
             ItemStatic(..) => {
@@ -3883,11 +3861,10 @@ fn with_constant_rib(&mut self, f: |&mut Resolver|) {
     }
 
     fn resolve_function(&mut self,
-                            rib_kind: RibKind,
-                            optional_declaration: Option<P<FnDecl>>,
-                            type_parameters: TypeParameters,
-                            block: P<Block>,
-                            self_binding: SelfBinding) {
+                        rib_kind: RibKind,
+                        optional_declaration: Option<P<FnDecl>>,
+                        type_parameters: TypeParameters,
+                        block: P<Block>) {
         // Create a value rib for the function.
         let function_value_rib = @Rib::new(rib_kind);
         {
@@ -3914,21 +3891,6 @@ fn resolve_function(&mut self,
                 }
             }
 
-            // Add self to the rib, if necessary.
-            match self_binding {
-                NoSelfBinding => {
-                    // Nothing to do.
-                }
-                HasSelfBinding(self_node_id, explicit_self) => {
-                    let mutable = match explicit_self.node {
-                        SelfUniq(m) | SelfValue(m) if m == MutMutable => true,
-                        _ => false
-                    };
-                    let def_like = DlDef(DefSelf(self_node_id, mutable));
-                    function_value_rib.self_binding.set(Some(def_like));
-                }
-            }
-
             // Add each argument to the rib.
             match optional_declaration {
                 None => {
@@ -4050,26 +4012,17 @@ fn resolve_struct(&mut self,
     // Does this really need to take a RibKind or is it always going
     // to be NormalRibKind?
     fn resolve_method(&mut self,
-                          rib_kind: RibKind,
-                          method: @Method,
-                          outer_type_parameter_count: uint) {
+                      rib_kind: RibKind,
+                      method: @Method,
+                      outer_type_parameter_count: uint) {
         let method_generics = &method.generics;
         let type_parameters =
             HasTypeParameters(method_generics,
                               method.id,
                               outer_type_parameter_count,
                               rib_kind);
-        // we only have self ty if it is a non static method
-        let self_binding = match method.explicit_self.node {
-            SelfStatic => NoSelfBinding,
-            _ => HasSelfBinding(method.self_id, method.explicit_self)
-        };
 
-        self.resolve_function(rib_kind,
-                              Some(method.decl),
-                              type_parameters,
-                              method.body,
-                              self_binding);
+        self.resolve_function(rib_kind, Some(method.decl), type_parameters, method.body);
     }
 
     fn resolve_implementation(&mut self,
@@ -4135,9 +4088,7 @@ fn resolve_implementation(&mut self,
                                              method.id,
                                              outer_type_parameter_count,
                                              NormalRibKind),
-                                          method.body,
-                                          HasSelfBinding(method.self_id),
-                                          visitor);
+                                          method.body);
 */
             }
 
@@ -4974,16 +4925,14 @@ fn resolve_identifier_in_local_ribs(&mut self,
                 let mut value_ribs = self.value_ribs.borrow_mut();
                 search_result = self.search_ribs(value_ribs.get(),
                                                  renamed,
-                                                 span,
-                                                 DontAllowCapturingSelf);
+                                                 span);
             }
             TypeNS => {
                 let name = ident.name;
                 let mut type_ribs = self.type_ribs.borrow_mut();
                 search_result = self.search_ribs(type_ribs.get(),
                                                  name,
-                                                 span,
-                                                 AllowCapturingSelf);
+                                                 span);
             }
         }
 
@@ -5001,46 +4950,6 @@ fn resolve_identifier_in_local_ribs(&mut self,
         }
     }
 
-    fn resolve_self_value_in_local_ribs(&mut self, span: Span)
-                                            -> Option<Def> {
-        // FIXME #4950: This should not use a while loop.
-        let mut i = {
-            let value_ribs = self.value_ribs.borrow();
-            value_ribs.get().len()
-        };
-        while i != 0 {
-            i -= 1;
-            let self_binding_opt = {
-                let value_ribs = self.value_ribs.borrow();
-                value_ribs.get()[i].self_binding.get()
-            };
-            match self_binding_opt {
-                Some(def_like) => {
-                    let mut value_ribs = self.value_ribs.borrow_mut();
-                    match self.upvarify(value_ribs.get(),
-                                        i,
-                                        def_like,
-                                        span,
-                                        DontAllowCapturingSelf) {
-                        Some(DlDef(def)) => return Some(def),
-                        _ => {
-                            if self.session.has_errors() {
-                                // May happen inside a nested fn item, cf #6642.
-                                return None;
-                            } else {
-                                self.session.span_bug(span,
-                                        "self wasn't mapped to a def?!")
-                            }
-                        }
-                    }
-                }
-                None => {}
-            }
-        }
-
-        None
-    }
-
     fn resolve_item_by_identifier_in_lexical_scope(&mut self,
                                                    ident: Ident,
                                                    namespace: Namespace)
@@ -5224,10 +5133,8 @@ fn resolve_expr(&mut self, expr: &Expr) {
             ExprFnBlock(fn_decl, block) |
             ExprProc(fn_decl, block) => {
                 self.resolve_function(FunctionRibKind(expr.id, block.id),
-                                      Some(fn_decl),
-                                      NoTypeParameters,
-                                      block,
-                                      NoSelfBinding);
+                                      Some(fn_decl), NoTypeParameters,
+                                      block);
             }
 
             ExprStruct(ref path, _, _) => {
@@ -5274,8 +5181,7 @@ fn resolve_expr(&mut self, expr: &Expr) {
 
             ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
                 let mut label_ribs = self.label_ribs.borrow_mut();
-                match self.search_ribs(label_ribs.get(), label, expr.span,
-                                       DontAllowCapturingSelf) {
+                match self.search_ribs(label_ribs.get(), label, expr.span) {
                     None =>
                         self.resolve_error(expr.span,
                                               format!("use of undeclared label \
@@ -5293,17 +5199,6 @@ fn resolve_expr(&mut self, expr: &Expr) {
                 }
             }
 
-            ExprSelf => {
-                match self.resolve_self_value_in_local_ribs(expr.span) {
-                    None => {
-                        self.resolve_error(expr.span,
-                                              "`self` is not allowed in \
-                                               this context")
-                    }
-                    Some(def) => self.record_def(expr.id, (def, AllPublic)),
-                }
-            }
-
             _ => {
                 visit::walk_expr(self, expr, ());
             }
@@ -5320,7 +5215,7 @@ fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) {
                 let traits = self.search_for_traits_containing_method(ident);
                 self.trait_map.insert(expr.id, @RefCell::new(traits));
             }
-            ExprMethodCall(_, _, ident, _, _, _) => {
+            ExprMethodCall(_, ident, _, _, _) => {
                 debug!("(recording candidate traits for expr) recording \
                         traits for {}",
                        expr.id);
index c8d2cf36938007b2ce106e6e3413fcdaae4c251f..d5022b2a4df16830e4d9c6fbf01ff53cf8638daa 100644 (file)
@@ -337,8 +337,8 @@ fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> {
             return adt::trans_case(bcx, repr, disr_val);
         }
         range(l1, l2) => {
-            let (l1, _) = consts::const_expr(ccx, l1);
-            let (l2, _) = consts::const_expr(ccx, l2);
+            let (l1, _) = consts::const_expr(ccx, l1, true);
+            let (l2, _) = consts::const_expr(ccx, l2, true);
             return range_result(rslt(bcx, l1), rslt(bcx, l2));
         }
         vec_len(n, vec_len_eq, _) => {
index 9744c395b7c193aa44999801380ce9c6da635591..c71469f0c3db0817d3c18eae33a1b43e78ec8f3a 100644 (file)
@@ -240,7 +240,7 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
         }
     }
 
-    let f = decl_rust_fn(ccx, None, inputs, output, name);
+    let f = decl_rust_fn(ccx, false, inputs, output, name);
     csearch::get_item_attrs(ccx.tcx.cstore, did, |meta_items| {
         set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x)).to_owned_vec(), f)
     });
@@ -250,16 +250,15 @@ fn get_extern_rust_fn(ccx: &CrateContext, inputs: &[ty::t], output: ty::t,
     f
 }
 
-fn decl_rust_fn(ccx: &CrateContext,
-                self_ty: Option<ty::t>,
-                inputs: &[ty::t],
-                output: ty::t,
-                name: &str) -> ValueRef {
-    let llfty = type_of_rust_fn(ccx, self_ty, inputs, output);
+pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
+                    inputs: &[ty::t], output: ty::t,
+                    name: &str) -> ValueRef {
+    let llfty = type_of_rust_fn(ccx, has_env, inputs, output);
     let llfn = decl_cdecl_fn(ccx.llmod, name, llfty, output);
 
     let uses_outptr = type_of::return_uses_outptr(ccx, output);
-    let offset = if uses_outptr { 2 } else { 1 };
+    let offset = if uses_outptr { 1 } else { 0 };
+    let offset = if has_env { offset + 1 } else { offset };
 
     for (i, &arg_ty) in inputs.iter().enumerate() {
         let llarg = unsafe { llvm::LLVMGetParam(llfn, (offset + i) as c_uint) };
@@ -292,10 +291,10 @@ fn decl_rust_fn(ccx: &CrateContext,
     llfn
 }
 
-pub fn decl_internal_rust_fn(ccx: &CrateContext,
-                             self_ty: Option<ty::t>, inputs: &[ty::t],
-                             output: ty::t, name: &str) -> ValueRef {
-    let llfn = decl_rust_fn(ccx, self_ty, inputs, output, name);
+pub fn decl_internal_rust_fn(ccx: &CrateContext, has_env: bool,
+                             inputs: &[ty::t], output: ty::t,
+                             name: &str) -> ValueRef {
+    let llfn = decl_rust_fn(ccx, has_env, inputs, output, name);
     lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
     llfn
 }
@@ -318,14 +317,10 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
 // 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.
-//
-// The runtime equivalent is box_body() in "rust_internal.h".
-pub fn opaque_box_body(bcx: &Block, body_t: ty::t, boxptr: ValueRef)
-                       -> ValueRef {
-    let _icx = push_ctxt("opaque_box_body");
+pub fn at_box_body(bcx: &Block, body_t: ty::t, boxptr: ValueRef) -> ValueRef {
+    let _icx = push_ctxt("at_box_body");
     let ccx = bcx.ccx();
-    let ty = type_of(ccx, body_t);
-    let ty = Type::smart_ptr(ccx, &ty);
+    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])
 }
@@ -882,10 +877,6 @@ pub fn fail_if_zero<'a>(
     })
 }
 
-pub fn null_env_ptr(ccx: &CrateContext) -> ValueRef {
-    C_null(Type::opaque_box(ccx).ptr_to())
-}
-
 pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> ValueRef {
     let name = csearch::get_symbol(ccx.sess.cstore, did);
     match ty::get(t).sty {
@@ -898,7 +889,7 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
                 Some(..) | None => {
                     let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
                     let cconv = c.unwrap_or(lib::llvm::CCallConv);
-                    let llty = type_of_fn_from_ty(ccx, None, t);
+                    let llty = type_of_fn_from_ty(ccx, t);
                     let mut externs = ccx.externs.borrow_mut();
                     get_extern_fn(externs.get(), ccx.llmod, name,
                                   cconv, llty, fn_ty.sig.output)
@@ -1241,6 +1232,7 @@ pub fn new_fn_ctxt_detailed(ccx: @CrateContext,
                             path: ast_map::Path,
                             llfndecl: ValueRef,
                             id: ast::NodeId,
+                            has_env: bool,
                             output_type: ty::t,
                             param_substs: Option<@param_substs>,
                             sp: Option<Span>)
@@ -1263,33 +1255,33 @@ pub fn new_fn_ctxt_detailed(ccx: @CrateContext,
     let uses_outptr = type_of::return_uses_outptr(ccx, substd_output_type);
     let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl);
 
-    let fcx = FunctionContext {
-          llfn: llfndecl,
-          llenv: unsafe {
-              Cell::new(llvm::LLVMGetUndef(Type::i8p().to_ref()))
-          },
-          llretptr: Cell::new(None),
-          entry_bcx: RefCell::new(None),
-          alloca_insert_pt: Cell::new(None),
-          llreturn: Cell::new(None),
-          llself: Cell::new(None),
-          personality: Cell::new(None),
-          caller_expects_out_pointer: uses_outptr,
-          llargs: RefCell::new(HashMap::new()),
-          lllocals: RefCell::new(HashMap::new()),
-          llupvars: RefCell::new(HashMap::new()),
-          id: id,
-          param_substs: param_substs,
-          span: sp,
-          path: path,
-          block_arena: TypedArena::new(),
-          ccx: ccx,
-          debug_context: debug_context,
-          scopes: RefCell::new(~[])
+    let mut fcx = FunctionContext {
+        llfn: llfndecl,
+        llenv: None,
+        llretptr: Cell::new(None),
+        entry_bcx: RefCell::new(None),
+        alloca_insert_pt: Cell::new(None),
+        llreturn: Cell::new(None),
+        personality: Cell::new(None),
+        caller_expects_out_pointer: uses_outptr,
+        llargs: RefCell::new(HashMap::new()),
+        lllocals: RefCell::new(HashMap::new()),
+        llupvars: RefCell::new(HashMap::new()),
+        id: id,
+        param_substs: param_substs,
+        span: sp,
+        path: path,
+        block_arena: TypedArena::new(),
+        ccx: ccx,
+        debug_context: debug_context,
+        scopes: RefCell::new(~[])
     };
-    fcx.llenv.set(unsafe {
-          llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint)
-    });
+
+    if has_env {
+        fcx.llenv = Some(unsafe {
+            llvm::LLVMGetParam(fcx.llfn, fcx.env_arg_pos() as c_uint)
+        });
+    }
 
     fcx
 }
@@ -1301,14 +1293,16 @@ pub fn init_function<'a>(
                      skip_retptr: bool,
                      output_type: ty::t,
                      param_substs: Option<@param_substs>) {
-    unsafe {
-        let entry_bcx = fcx.new_temp_block("entry-block");
-        Load(entry_bcx, C_null(Type::i8p()));
+    let entry_bcx = fcx.new_temp_block("entry-block");
 
-        fcx.entry_bcx.set(Some(entry_bcx));
-        fcx.alloca_insert_pt.set(Some(
-                llvm::LLVMGetFirstInstruction(entry_bcx.llbb)));
-    }
+    fcx.entry_bcx.set(Some(entry_bcx));
+
+    // Use a dummy instruction as the insertion point for all allocas.
+    // This is later removed in FunctionContext::cleanup.
+    fcx.alloca_insert_pt.set(Some(unsafe {
+        Load(entry_bcx, C_null(Type::i8p()));
+        llvm::LLVMGetFirstInstruction(entry_bcx.llbb)
+    }));
 
     let substd_output_type = match param_substs {
         None => output_type,
@@ -1327,8 +1321,7 @@ pub fn init_function<'a>(
             // Otherwise, we normally allocate the llretptr, unless we
             // have been instructed to skip it for immediate return
             // values.
-            fcx.llretptr.set(Some(make_return_pointer(fcx,
-                                                      substd_output_type)));
+            fcx.llretptr.set(Some(make_return_pointer(fcx, substd_output_type)));
         }
     }
 }
@@ -1336,12 +1329,13 @@ pub fn init_function<'a>(
 pub fn new_fn_ctxt(ccx: @CrateContext,
                    path: ast_map::Path,
                    llfndecl: ValueRef,
+                   has_env: bool,
                    output_type: ty::t,
                    sp: Option<Span>)
                    -> FunctionContext {
     // FIXME(#11385): Do not call `init_function` here; it will typecheck
     // but segfault.
-    new_fn_ctxt_detailed(ccx, path, llfndecl, -1, output_type, None, sp)
+    new_fn_ctxt_detailed(ccx, path, llfndecl, -1, has_env, output_type, None, sp)
 }
 
 // NB: must keep 4 fns in sync:
@@ -1363,35 +1357,28 @@ fn arg_kind(cx: &FunctionContext, t: ty::t) -> datum::Rvalue {
 type RvalueDatum = datum::Datum<datum::Rvalue>;
 type LvalueDatum = datum::Datum<datum::Lvalue>;
 
-// create_datums_for_fn_args: creates rvalue datums for `self` and each of the
+// create_datums_for_fn_args: creates rvalue datums for each of the
 // incoming function arguments. These will later be stored into
 // appropriate lvalue datums.
-fn create_datums_for_fn_args(cx: &FunctionContext,
-                             self_arg: Option<ty::t>,
-                             arg_tys: &[ty::t])
-                             -> (Option<RvalueDatum>, ~[RvalueDatum]) {
+pub fn create_datums_for_fn_args(fcx: &FunctionContext,
+                                 arg_tys: &[ty::t])
+                                 -> ~[RvalueDatum] {
     let _icx = push_ctxt("create_datums_for_fn_args");
 
-    let self_datum = self_arg.map(
-        |t| datum::Datum(cx.llenv.get(), t, arg_kind(cx, t)));
-
     // Return an array wrapping the ValueRefs that we get from
     // llvm::LLVMGetParam for each argument into datums.
-    let arg_datums = arg_tys.iter().enumerate().map(|(i, &arg_ty)| {
-            let llarg = unsafe {
-                llvm::LLVMGetParam(cx.llfn, cx.arg_pos(i) as c_uint)
-            };
-            datum::Datum(llarg, arg_ty, arg_kind(cx, arg_ty))
-        }).collect();
-
-    (self_datum, arg_datums)
+    arg_tys.iter().enumerate().map(|(i, &arg_ty)| {
+        let llarg = unsafe {
+            llvm::LLVMGetParam(fcx.llfn, fcx.arg_pos(i) as c_uint)
+        };
+        datum::Datum(llarg, arg_ty, arg_kind(fcx, arg_ty))
+    }).collect()
 }
 
 fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
                             arg_scope: cleanup::CustomScopeIndex,
                             bcx: &'a Block<'a>,
                             args: &[ast::Arg],
-                            self_datum: Option<RvalueDatum>,
                             arg_datums: ~[RvalueDatum])
                             -> &'a Block<'a> {
     debug!("copy_args_to_allocas");
@@ -1400,18 +1387,6 @@ fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
     let mut bcx = bcx;
 
     let arg_scope_id = cleanup::CustomScope(arg_scope);
-    match self_datum {
-        Some(slf_rv) => {
-            let slf = unpack_datum!(
-                bcx, slf_rv.to_lvalue_datum_in_scope(bcx, "__self",
-                                                     arg_scope_id));
-            fcx.llself.set(Some(slf));
-            if fcx.ccx.sess.opts.extra_debuginfo {
-                debuginfo::create_self_argument_metadata(bcx, slf.ty, slf.val);
-            }
-        }
-        _ => {}
-    }
 
     for (i, arg_datum) in arg_datums.move_iter().enumerate() {
         // For certain mode/type combinations, the raw llarg values are passed
@@ -1429,7 +1404,7 @@ fn copy_args_to_allocas<'a>(fcx: &FunctionContext<'a>,
         }
     }
 
-    return bcx;
+    bcx
 }
 
 // Ties up the llstaticallocas -> llloadenv -> lltop edges,
@@ -1488,7 +1463,6 @@ pub fn trans_closure(ccx: @CrateContext,
                      decl: &ast::FnDecl,
                      body: &ast::Block,
                      llfndecl: ValueRef,
-                     self_arg: Option<ty::t>,
                      param_substs: Option<@param_substs>,
                      id: ast::NodeId,
                      _attributes: &[ast::Attribute],
@@ -1502,13 +1476,13 @@ pub fn trans_closure(ccx: @CrateContext,
     debug!("trans_closure(..., param_substs={})",
            param_substs.repr(ccx.tcx));
 
-    let fcx = new_fn_ctxt_detailed(ccx,
-                                   path,
-                                   llfndecl,
-                                   id,
-                                   output_type,
-                                   param_substs,
-                                   Some(body.span));
+    let has_env = match ty::get(ty::node_id_to_type(ccx.tcx, id)).sty {
+        ty::ty_closure(_) => true,
+        _ => false
+    };
+
+    let fcx = new_fn_ctxt_detailed(ccx, path, llfndecl, id, has_env, output_type,
+                                   param_substs, Some(body.span));
     init_function(&fcx, false, output_type, param_substs);
 
     // cleanup scope for the incoming arguments
@@ -1522,11 +1496,9 @@ pub fn trans_closure(ccx: @CrateContext,
 
     // Set up arguments to the function.
     let arg_tys = ty::ty_fn_args(node_id_type(bcx, id));
-    let (self_datum, arg_datums) =
-        create_datums_for_fn_args(&fcx, self_arg, arg_tys);
+    let arg_datums = create_datums_for_fn_args(&fcx, arg_tys);
 
-    bcx = copy_args_to_allocas(&fcx, arg_scope, bcx,
-                               decl.inputs, self_datum, arg_datums);
+    bcx = copy_args_to_allocas(&fcx, arg_scope, bcx, decl.inputs, arg_datums);
 
     maybe_load_env(&fcx);
 
@@ -1578,15 +1550,12 @@ pub fn trans_fn(ccx: @CrateContext,
                 decl: &ast::FnDecl,
                 body: &ast::Block,
                 llfndecl: ValueRef,
-                self_arg: Option<ty::t>,
                 param_substs: Option<@param_substs>,
                 id: ast::NodeId,
                 attrs: &[ast::Attribute]) {
     let the_path_str = path_str(ccx.sess, path);
     let _s = StatRecorder::new(ccx, the_path_str);
-    debug!("trans_fn(self_arg={:?}, param_substs={})",
-           self_arg,
-           param_substs.repr(ccx.tcx));
+    debug!("trans_fn(param_substs={})", param_substs.repr(ccx.tcx));
     let _icx = push_ctxt("trans_fn");
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id));
     trans_closure(ccx,
@@ -1594,7 +1563,6 @@ pub fn trans_fn(ccx: @CrateContext,
                   decl,
                   body,
                   llfndecl,
-                  self_arg,
                   param_substs,
                   id,
                   attrs,
@@ -1664,18 +1632,13 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: @CrateContext,
                  ty_to_str(ccx.tcx, ctor_ty)))
     };
 
-    let fcx = new_fn_ctxt_detailed(ccx,
-                                   ~[],
-                                   llfndecl,
-                                   ctor_id,
-                                   result_ty,
-                                   param_substs,
-                                   None);
+    let fcx = new_fn_ctxt_detailed(ccx, ~[], llfndecl, ctor_id, false,
+                                   result_ty, param_substs, None);
     init_function(&fcx, false, result_ty, param_substs);
 
     let arg_tys = ty::ty_fn_args(ctor_ty);
 
-    let (_, arg_datums) = create_datums_for_fn_args(&fcx, None, arg_tys);
+    let arg_datums = create_datums_for_fn_args(&fcx, arg_tys);
 
     let bcx = fcx.entry_bcx.get().unwrap();
 
@@ -1750,16 +1713,9 @@ pub fn trans_item(ccx: @CrateContext, item: &ast::Item) {
                 llfndecl,
                 item.id);
         } else if !generics.is_type_parameterized() {
-            let llfndecl = get_item_val(ccx, item.id);
-            trans_fn(ccx,
-                     vec::append_one((*path).clone(), PathName(item.ident)),
-                     decl,
-                     body,
-                     llfndecl,
-                     None,
-                     None,
-                     item.id,
-                     item.attrs);
+            let path = vec::append_one((*path).clone(), PathName(item.ident));
+            let llfn = get_item_val(ccx, item.id);
+            trans_fn(ccx, path, decl, body, llfn, None, item.id, item.attrs);
         } else {
             // Be sure to travel more than just one layer deep to catch nested
             // items in blocks and such.
@@ -1874,8 +1830,7 @@ fn register_fn(ccx: @CrateContext,
                sp: Span,
                sym: ~str,
                node_id: ast::NodeId,
-               node_type: ty::t,
-               self_ty: Option<ty::t>)
+               node_type: ty::t)
                -> ValueRef {
     let f = match ty::get(node_type).sty {
         ty::ty_bare_fn(ref f) => {
@@ -1885,7 +1840,7 @@ fn register_fn(ccx: @CrateContext,
         _ => fail!("expected bare rust fn or an intrinsic")
     };
 
-    let llfn = decl_rust_fn(ccx, self_ty, f.sig.inputs, f.sig.output, sym);
+    let llfn = decl_rust_fn(ccx, false, f.sig.inputs, f.sig.output, sym);
     finish_register_fn(ccx, sp, sym, node_id, llfn);
     llfn
 }
@@ -1963,7 +1918,6 @@ fn create_entry_fn(ccx: @CrateContext,
                     });
 
                     ~[
-                        C_null(Type::opaque_box(ccx).ptr_to()),
                         opaque_rust_main,
                         llvm::LLVMGetParam(llfn, 0),
                         llvm::LLVMGetParam(llfn, 1)
@@ -1973,7 +1927,6 @@ fn create_entry_fn(ccx: @CrateContext,
             } else {
                 debug!("using user-defined start fn");
                 let args = ~[
-                    C_null(Type::opaque_box(ccx).ptr_to()),
                     llvm::LLVMGetParam(llfn, 0 as c_uint),
                     llvm::LLVMGetParam(llfn, 1 as c_uint)
                 ];
@@ -1990,18 +1943,6 @@ fn create_entry_fn(ccx: @CrateContext,
     }
 }
 
-pub fn fill_fn_pair(bcx: &Block,
-                    pair: ValueRef,
-                    llfn: ValueRef,
-                    llenvptr: ValueRef) {
-    let ccx = bcx.ccx();
-    let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]);
-    Store(bcx, llfn, code_cell);
-    let env_cell = GEPi(bcx, pair, [0u, abi::fn_field_box]);
-    let llenvblobptr = PointerCast(bcx, llenvptr, Type::opaque_box(ccx).ptr_to());
-    Store(bcx, llenvblobptr, env_cell);
-}
-
 pub fn item_path(ccx: &CrateContext, id: &ast::NodeId) -> ast_map::Path {
     ty::item_path(ccx.tcx, ast_util::local_def(*id))
 }
@@ -2049,22 +1990,22 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
                             // using the current crate's name/version
                             // information in the hash of the symbol
                             debug!("making {}", sym);
-                            let sym = {
+                            let (sym, is_local) = {
                                 let external_srcs = ccx.external_srcs
                                                        .borrow();
                                 match external_srcs.get().find(&i.id) {
                                     Some(&did) => {
                                         debug!("but found in other crate...");
-                                        csearch::get_symbol(ccx.sess.cstore,
-                                                            did)
+                                        (csearch::get_symbol(ccx.sess.cstore,
+                                                             did), false)
                                     }
-                                    None => sym
+                                    None => (sym, true)
                                 }
                             };
 
                             // We need the translated value here, because for enums the
                             // LLVM type is not fully determined by the Rust type.
-                            let (v, inlineable) = consts::const_expr(ccx, expr);
+                            let (v, inlineable) = consts::const_expr(ccx, expr, is_local);
                             {
                                 let mut const_values = ccx.const_values
                                                           .borrow_mut();
@@ -2142,7 +2083,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
 
                         ast::ItemFn(_, purity, _, _, _) => {
                             let llfn = if purity != ast::ExternFn {
-                                register_fn(ccx, i.span, sym, i.id, ty, None)
+                                register_fn(ccx, i.span, sym, i.id, ty)
                             } else {
                                 foreign::register_rust_fn_with_foreign_abi(ccx,
                                                                            i.span,
@@ -2246,7 +2187,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
 
                             llfn = match enm.node {
                                 ast::ItemEnum(_, _) => {
-                                    register_fn(ccx, (*v).span, sym, id, ty, None)
+                                    register_fn(ccx, (*v).span, sym, id, ty)
                                 }
                                 _ => fail!("NodeVariant, shouldn't happen")
                             };
@@ -2271,7 +2212,7 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
                             let sym = exported_name(ccx, (*struct_path).clone(), ty,
                                                     struct_item.attrs);
                             let llfn = register_fn(ccx, struct_item.span,
-                                                   sym, ctor_id, ty, None);
+                                                   sym, ctor_id, ty);
                             set_inline_hint(llfn);
                             llfn
                         }
@@ -2312,11 +2253,7 @@ fn register_method(ccx: @CrateContext,
 
     let sym = exported_name(ccx, path, mty, m.attrs);
 
-    let self_ty = match m.explicit_self.node {
-        ast::SelfStatic => None,
-        _ => Some(ty::node_id_to_type(ccx.tcx, m.self_id))
-    };
-    let llfn = register_fn(ccx, m.span, sym, id, mty, self_ty);
+    let llfn = register_fn(ccx, m.span, sym, id, mty);
     set_llvm_fn_attrs(m.attrs, llfn);
     llfn
 }
index c4beb935ffecfc96512fe3454f809a99aa00bb38..71b25b79feb4af5fd0e99b819b9d960636913bff 100644 (file)
@@ -797,6 +797,11 @@ pub fn inline_asm_call(&self, asm: *c_char, cons: *c_char,
     pub fn call(&self, llfn: ValueRef, args: &[ValueRef],
                 attributes: &[(uint, lib::llvm::Attribute)]) -> ValueRef {
         self.count_insn("call");
+
+        debug!("Call {} with args ({})",
+               self.ccx.tn.val_to_str(llfn),
+               args.map(|&v| self.ccx.tn.val_to_str(v)).connect(", "));
+
         unsafe {
             let v = llvm::LLVMBuildCall(self.llbuilder, llfn, args.as_ptr(),
                                         args.len() as c_uint, noname());
index 229a1b3662defea610468d6cdfd6c67b0ed63a78..e10c7af7f313d0c168ab8d981400a9a56af341eb 100644 (file)
 use syntax::abi::AbiSet;
 use syntax::ast_map;
 
-// Represents a (possibly monomorphized) top-level fn item or method
-// item.  Note that this is just the fn-ptr and is not a Rust closure
-// value (which is a pair).
-pub struct FnData {
-    llfn: ValueRef,
-}
-
 pub struct MethodData {
     llfn: ValueRef,
     llself: ValueRef,
@@ -66,8 +59,13 @@ pub struct MethodData {
 
 pub enum CalleeData {
     Closure(Datum<Lvalue>),
-    Fn(FnData),
-    Method(MethodData)
+
+    // Represents a (possibly monomorphized) top-level fn item or method
+    // item. Note that this is just the fn-ptr and is not a Rust closure
+    // value (which is a pair).
+    Fn(/* llfn */ ValueRef),
+
+    TraitMethod(MethodData)
 }
 
 pub struct Callee<'a> {
@@ -95,7 +93,7 @@ fn datum_callee<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
         match ty::get(datum.ty).sty {
             ty::ty_bare_fn(..) => {
                 let llval = datum.to_llscalarish(bcx);
-                return Callee {bcx: bcx, data: Fn(FnData {llfn: llval})};
+                return Callee {bcx: bcx, data: Fn(llval)};
             }
             ty::ty_closure(..) => {
                 let datum = unpack_datum!(
@@ -111,8 +109,8 @@ fn datum_callee<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
         }
     }
 
-    fn fn_callee<'a>(bcx: &'a Block<'a>, fd: FnData) -> Callee<'a> {
-        return Callee {bcx: bcx, data: Fn(fd)};
+    fn fn_callee<'a>(bcx: &'a Block<'a>, llfn: ValueRef) -> Callee<'a> {
+        return Callee {bcx: bcx, data: Fn(llfn)};
     }
 
     fn trans_def<'a>(bcx: &'a Block<'a>, def: ast::Def, ref_expr: &ast::Expr)
@@ -143,8 +141,7 @@ fn trans_def<'a>(bcx: &'a Block<'a>, def: ast::Def, ref_expr: &ast::Expr)
             ast::DefArg(..) |
             ast::DefLocal(..) |
             ast::DefBinding(..) |
-            ast::DefUpvar(..) |
-            ast::DefSelf(..) => {
+            ast::DefUpvar(..) => {
                 datum_callee(bcx, ref_expr)
             }
             ast::DefMod(..) | ast::DefForeignMod(..) | ast::DefTrait(..) |
@@ -171,7 +168,7 @@ pub fn trans_fn_ref_to_callee<'a>(
 }
 
 pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, ref_id: ast::NodeId)
-                    -> FnData {
+                    -> ValueRef {
     /*!
      *
      * Translates a reference (with id `ref_id`) to the fn/method
@@ -248,7 +245,7 @@ pub fn trans_fn_ref_with_vtables(
         ref_id: ast::NodeId,  // node id of use of fn; may be zero if N/A
         type_params: &[ty::t], // values for fn's ty params
         vtables: Option<typeck::vtable_res>) // vtables for the call
-     -> FnData {
+     -> ValueRef {
     /*!
      * Translates a reference to a fn/method item, monomorphizing and
      * inlining as it goes.
@@ -399,9 +396,9 @@ pub fn trans_fn_ref_with_vtables(
             let ref_ty = common::node_id_type(bcx, ref_id);
 
             val = PointerCast(
-                bcx, val, type_of::type_of_fn_from_ty(ccx, None, ref_ty).ptr_to());
+                bcx, val, type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to());
         }
-        return FnData {llfn: val};
+        return val;
     }
 
     // Find the actual function pointer.
@@ -438,13 +435,13 @@ pub fn trans_fn_ref_with_vtables(
     // This can occur on either a crate-local or crate-external
     // reference. It also occurs when testing libcore and in some
     // other weird situations. Annoying.
-    let llty = type_of::type_of_fn_from_ty(ccx, None, fn_tpt.ty);
+    let llty = type_of::type_of_fn_from_ty(ccx, fn_tpt.ty);
     let llptrty = llty.ptr_to();
     if val_ty(val) != llptrty {
         val = BitCast(bcx, val, llptrty);
     }
 
-    return FnData {llfn: val};
+    val
 }
 
 // ______________________________________________________________________
@@ -465,8 +462,7 @@ pub fn trans_call<'a>(
                      node_id_type(in_cx, id),
                      |cx, _| trans(cx, f),
                      args,
-                     Some(dest),
-                     DontAutorefArg).bcx
+                     Some(dest)).bcx
 }
 
 pub fn trans_method_call<'a>(
@@ -478,9 +474,7 @@ pub fn trans_method_call<'a>(
                          dest: expr::Dest)
                          -> &'a Block<'a> {
     let _icx = push_ctxt("trans_method_call");
-    debug!("trans_method_call(call_ex={}, rcvr={})",
-           call_ex.repr(in_cx.tcx()),
-           rcvr.repr(in_cx.tcx()));
+    debug!("trans_method_call(call_ex={})", call_ex.repr(in_cx.tcx()));
     trans_call_inner(
         in_cx,
         Some(common::expr_info(call_ex)),
@@ -509,8 +503,7 @@ pub fn trans_method_call<'a>(
             }
         },
         args,
-        Some(dest),
-        DontAutorefArg).bcx
+        Some(dest)).bcx
 }
 
 pub fn trans_lang_call<'a>(
@@ -537,8 +530,7 @@ pub fn trans_lang_call<'a>(
                                                                     None)
                              },
                              ArgVals(args),
-                             dest,
-                             DontAutorefArg)
+                             dest)
 }
 
 pub fn trans_lang_call_with_type_params<'a>(
@@ -569,20 +561,20 @@ pub fn trans_lang_call_with_type_params<'a>(
 
             let new_llval;
             match callee.data {
-                Fn(fn_data) => {
+                Fn(llfn) => {
                     let substituted = ty::subst_tps(callee.bcx.tcx(),
                                                     type_params,
                                                     None,
                                                     fty);
                     let llfnty = type_of::type_of(callee.bcx.ccx(),
                                                       substituted);
-                    new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty);
+                    new_llval = PointerCast(callee.bcx, llfn, llfnty);
                 }
                 _ => fail!()
             }
-            Callee { bcx: callee.bcx, data: Fn(FnData { llfn: new_llval }) }
+            Callee { bcx: callee.bcx, data: Fn(new_llval) }
         },
-        ArgVals(args), Some(dest), DontAutorefArg).bcx;
+        ArgVals(args), Some(dest)).bcx;
 }
 
 pub fn trans_call_inner<'a>(
@@ -594,8 +586,7 @@ pub fn trans_call_inner<'a>(
                                      arg_cleanup_scope: cleanup::ScopeId|
                                      -> Callee<'a>,
                         args: CallArgs,
-                        dest: Option<expr::Dest>,
-                        autoref_arg: AutorefArg)
+                        dest: Option<expr::Dest>)
                         -> Result<'a> {
     /*!
      * This behemoth of a function translates function calls.
@@ -627,25 +618,22 @@ pub fn trans_call_inner<'a>(
     let callee = get_callee(bcx, cleanup::CustomScope(arg_cleanup_scope));
     let mut bcx = callee.bcx;
 
-    let (llfn, llenv) = unsafe {
-        match callee.data {
-            Fn(d) => {
-                (d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to().to_ref()))
-            }
-            Method(d) => {
-                // Weird but true: we pass self in the *environment* slot!
-                (d.llfn, d.llself)
-            }
-            Closure(d) => {
-                // Closures are represented as (llfn, llclosure) pair:
-                // load the requisite values out.
-                let pair = d.to_llref();
-                let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
-                let llfn = Load(bcx, llfn);
-                let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
-                let llenv = Load(bcx, llenv);
-                (llfn, llenv)
-            }
+    let (llfn, llenv, llself) = match callee.data {
+        Fn(llfn) => {
+            (llfn, None, None)
+        }
+        TraitMethod(d) => {
+            (d.llfn, None, Some(d.llself))
+        }
+        Closure(d) => {
+            // Closures are represented as (llfn, llclosure) pair:
+            // load the requisite values out.
+            let pair = d.to_llref();
+            let llfn = GEPi(bcx, pair, [0u, abi::fn_field_code]);
+            let llfn = Load(bcx, llfn);
+            let llenv = GEPi(bcx, pair, [0u, abi::fn_field_box]);
+            let llenv = Load(bcx, llenv);
+            (llfn, Some(llenv), None)
         }
     };
 
@@ -694,13 +682,17 @@ pub fn trans_call_inner<'a>(
             llargs.push(opt_llretslot.unwrap());
         }
 
-        // Push the environment.
-        llargs.push(llenv);
+        // Push the environment (or a trait object's self).
+        match (llenv, llself) {
+            (Some(llenv), None) => llargs.push(llenv),
+            (None, Some(llself)) => llargs.push(llself),
+            _ => {}
+        }
 
         // Push the arguments.
-        bcx = trans_args(bcx, args, callee_ty,
-                         autoref_arg, &mut llargs,
-                         cleanup::CustomScope(arg_cleanup_scope));
+        bcx = trans_args(bcx, args, callee_ty, &mut llargs,
+                         cleanup::CustomScope(arg_cleanup_scope),
+                         llself.is_some());
 
         fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
 
@@ -718,11 +710,10 @@ pub fn trans_call_inner<'a>(
         match ty::get(ret_ty).sty {
             // `~` pointer return values never alias because ownership
             // is transferred
-            ty::ty_uniq(..) |
-                ty::ty_vec(_, ty::vstore_uniq) => {
+            ty::ty_uniq(..) | ty::ty_vec(_, ty::vstore_uniq) => {
                 attrs.push((0, NoAliasAttribute));
             }
-            _ => ()
+            _ => {}
         }
 
         // Invoke the actual rust fn and update bcx/llresult.
@@ -748,13 +739,12 @@ pub fn trans_call_inner<'a>(
         assert!(dest.is_some());
 
         let mut llargs = ~[];
-        bcx = trans_args(bcx, args, callee_ty,
-                         autoref_arg, &mut llargs,
-                         cleanup::CustomScope(arg_cleanup_scope));
+        bcx = trans_args(bcx, args, callee_ty, &mut llargs,
+                         cleanup::CustomScope(arg_cleanup_scope), false);
         fcx.pop_custom_cleanup_scope(arg_cleanup_scope);
         let arg_tys = match args {
             ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, *x)).collect(),
-            ArgVals(_) => fail!("expected arg exprs.")
+            _ => fail!("expected arg exprs.")
         };
         bcx = foreign::trans_native_call(bcx, callee_ty,
                                          llfn, opt_llretslot.unwrap(), llargs, arg_tys);
@@ -782,18 +772,18 @@ pub fn trans_call_inner<'a>(
 
 pub enum CallArgs<'a> {
     ArgExprs(&'a [@ast::Expr]),
+    // HACK used only by trans_overloaded_op.
+    ArgAutorefSecond(&'a ast::Expr, Option<&'a ast::Expr>),
     ArgVals(&'a [ValueRef])
 }
 
-pub fn trans_args<'a>(
-                  cx: &'a Block<'a>,
+fn trans_args<'a>(cx: &'a Block<'a>,
                   args: CallArgs,
                   fn_ty: ty::t,
-                  autoref_arg: AutorefArg,
                   llargs: &mut ~[ValueRef],
-                  arg_cleanup_scope: cleanup::ScopeId)
-                  -> &'a Block<'a>
-{
+                  arg_cleanup_scope: cleanup::ScopeId,
+                  ignore_self: bool)
+                  -> &'a Block<'a> {
     let _icx = push_ctxt("trans_args");
     let arg_tys = ty::ty_fn_args(fn_ty);
     let variadic = ty::fn_is_variadic(fn_ty);
@@ -804,28 +794,50 @@ pub fn trans_args<'a>(
     // This will be needed if this is a generic call, because the callee has
     // to cast her view of the arguments to the caller's view.
     match args {
-      ArgExprs(arg_exprs) => {
-        let num_formal_args = arg_tys.len();
-        for (i, arg_expr) in arg_exprs.iter().enumerate() {
-            let arg_ty = if i >= num_formal_args {
-                assert!(variadic);
-                expr_ty_adjusted(cx, *arg_expr)
-            } else {
-                arg_tys[i]
-            };
-            let arg_val = unpack_result!(bcx, {
-                trans_arg_expr(bcx,
-                               arg_ty,
-                               *arg_expr,
+        ArgExprs(arg_exprs) => {
+            let num_formal_args = arg_tys.len();
+            for (i, arg_expr) in arg_exprs.iter().enumerate() {
+                if i == 0 && ignore_self {
+                    continue;
+                }
+                let arg_ty = if i >= num_formal_args {
+                    assert!(variadic);
+                    expr_ty_adjusted(cx, *arg_expr)
+                } else {
+                    arg_tys[i]
+                };
+                llargs.push(unpack_result!(bcx, {
+                    trans_arg_expr(bcx, arg_ty, *arg_expr,
+                                   arg_cleanup_scope,
+                                   DontAutorefArg)
+                }));
+            }
+        }
+        ArgAutorefSecond(arg_expr, arg2) => {
+            assert!(!variadic);
+
+            llargs.push(unpack_result!(bcx, {
+                trans_arg_expr(bcx, arg_tys[0], arg_expr,
                                arg_cleanup_scope,
-                               autoref_arg)
-            });
-            llargs.push(arg_val);
+                               DontAutorefArg)
+            }));
+
+            match arg2 {
+                Some(arg2_expr) => {
+                    assert_eq!(arg_tys.len(), 2);
+
+                    llargs.push(unpack_result!(bcx, {
+                        trans_arg_expr(bcx, arg_tys[1], arg2_expr,
+                                       arg_cleanup_scope,
+                                       DoAutorefArg)
+                    }));
+                }
+                None => assert_eq!(arg_tys.len(), 1)
+            }
+        }
+        ArgVals(vs) => {
+            llargs.push_all(vs);
         }
-      }
-      ArgVals(vs) => {
-        llargs.push_all(vs);
-      }
     }
 
     bcx
index 020b840e5b2ef01d3e7e50eb2a0c45d75d2922ba..6e92ea9f11e51b3607263e829302faea69f59944 100644 (file)
@@ -680,7 +680,7 @@ fn get_or_create_landing_pad(&self) -> BasicBlockRef {
 
         // The exception handling personality function.
         let def_id = common::langcall(pad_bcx, None, "", EhPersonalityLangItem);
-        let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, 0).llfn;
+        let llpersonality = callee::trans_fn_ref(pad_bcx, def_id, 0);
 
         // The only landing pad clause will be 'cleanup'
         let llretval = build::LandingPad(pad_bcx, llretty, llpersonality, 1u);
index 21091c4f88ea8d61abeb3129a3a6b22e75127415..4d171bc86b1b01067c79b0d824bdeb3555421dbe 100644 (file)
 
 
 use back::abi;
-use back::link::{mangle_internal_name_by_path_and_seq};
+use back::link::mangle_internal_name_by_path_and_seq;
 use lib::llvm::ValueRef;
 use middle::moves;
 use middle::trans::base::*;
 use middle::trans::build::*;
 use middle::trans::common::*;
-use middle::trans::datum::{Datum, Lvalue};
+use middle::trans::datum::{Datum, DatumBlock, Expr, Lvalue, rvalue_scratch_datum};
 use middle::trans::debuginfo;
 use middle::trans::expr;
-use middle::trans::glue;
 use middle::trans::type_of::*;
+use middle::trans::type_::Type;
 use middle::ty;
+use util::ppaux::Repr;
 use util::ppaux::ty_to_str;
 
 use std::vec;
@@ -69,9 +70,9 @@
 // closure".
 //
 // Typically an opaque closure suffices because we only manipulate it
-// by ptr.  The routine Type::opaque_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.
+// 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
@@ -244,8 +245,7 @@ pub fn store_environment<'a>(
 
 // Given a context and a list of upvars, build a closure. This just
 // collects the upvars and packages them up for store_environment.
-pub fn build_closure<'a>(
-                     bcx0: &'a Block<'a>,
+fn build_closure<'a>(bcx0: &'a Block<'a>,
                      cap_vars: &[moves::CaptureVar],
                      sigil: ast::Sigil)
                      -> ClosureResult<'a> {
@@ -282,10 +282,8 @@ pub fn build_closure<'a>(
 // 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.
-pub fn load_environment(fcx: &FunctionContext,
-                        cdata_ty: ty::t,
-                        cap_vars: &[moves::CaptureVar],
-                        sigil: ast::Sigil) {
+fn load_environment(fcx: &FunctionContext, cdata_ty: ty::t,
+                    cap_vars: &[moves::CaptureVar], sigil: ast::Sigil) {
     let _icx = push_ctxt("closure::load_environment");
 
     // Don't bother to create the block if there's nothing to load
@@ -296,7 +294,7 @@ pub fn load_environment(fcx: &FunctionContext,
     let bcx = fcx.entry_bcx.get().unwrap();
 
     // Load a pointer to the closure data, skipping over the box header:
-    let llcdata = opaque_box_body(bcx, cdata_ty, fcx.llenv.get());
+    let llcdata = at_box_body(bcx, cdata_ty, 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
@@ -338,6 +336,12 @@ pub fn load_environment(fcx: &FunctionContext,
     }
 }
 
+fn fill_fn_pair(bcx: &Block, pair: ValueRef, llfn: ValueRef, llenvptr: ValueRef) {
+    Store(bcx, llfn, GEPi(bcx, pair, [0u, abi::fn_field_code]));
+    let llenvptr = PointerCast(bcx, llenvptr, Type::i8p());
+    Store(bcx, llenvptr, GEPi(bcx, pair, [0u, abi::fn_field_box]));
+}
+
 pub fn trans_expr_fn<'a>(
                      bcx: &'a Block<'a>,
                      sigil: ast::Sigil,
@@ -388,115 +392,119 @@ pub fn trans_expr_fn<'a>(
     let s = mangle_internal_name_by_path_and_seq(ccx,
                                                  sub_path.clone(),
                                                  "expr_fn");
-    let llfn = decl_internal_rust_fn(ccx, None, f.sig.inputs, f.sig.output, s);
+    let llfn = decl_internal_rust_fn(ccx, true, f.sig.inputs, f.sig.output, s);
 
     // set an inline hint for all closures
     set_inline_hint(llfn);
 
-    let Result {bcx: bcx, val: closure} = match sigil {
-        ast::BorrowedSigil | ast::ManagedSigil | ast::OwnedSigil => {
-            let cap_vars = {
-                let capture_map = ccx.maps.capture_map.borrow();
-                capture_map.get().get_copy(&user_id)
-            };
-            let ClosureResult {llbox, cdata_ty, bcx}
-                = build_closure(bcx, cap_vars, sigil);
-            trans_closure(ccx,
-                          sub_path,
-                          decl,
-                          body,
-                          llfn,
-                          None,
-                          bcx.fcx.param_substs,
-                          user_id,
-                          [],
-                          ty::ty_fn_ret(fty),
-                          |fcx| load_environment(fcx, cdata_ty, cap_vars, sigil));
-            rslt(bcx, llbox)
-        }
+    let cap_vars = {
+        let capture_map = ccx.maps.capture_map.borrow();
+        capture_map.get().get_copy(&user_id)
     };
-    fill_fn_pair(bcx, dest_addr, llfn, closure);
-
-    return bcx;
+    let ClosureResult {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, sigil);
+    trans_closure(ccx, sub_path, decl, body, llfn,
+                    bcx.fcx.param_substs, user_id,
+                    [], ty::ty_fn_ret(fty),
+                    |fcx| load_environment(fcx, cdata_ty, cap_vars, sigil));
+    fill_fn_pair(bcx, dest_addr, llfn, llbox);
+
+    bcx
 }
 
-pub fn make_closure_glue<'a>(
-                         cx: &'a Block<'a>,
-                         v: ValueRef,
-                         t: ty::t,
-                         glue_fn: |&'a Block<'a>, v: ValueRef, t: ty::t|
-                                   -> &'a Block<'a>)
-                         -> &'a Block<'a> {
-    let _icx = push_ctxt("closure::make_closure_glue");
-    let bcx = cx;
-    let tcx = cx.tcx();
-
-    let sigil = ty::ty_closure_sigil(t);
-    match sigil {
-        ast::BorrowedSigil => bcx,
-        ast::OwnedSigil | ast::ManagedSigil => {
-            let box_cell_v = GEPi(cx, v, [0u, abi::fn_field_box]);
-            let box_ptr_v = Load(cx, box_cell_v);
-            with_cond(cx, IsNotNull(cx, box_ptr_v), |bcx| {
-                let closure_ty = ty::mk_opaque_closure_ptr(tcx, sigil);
-                glue_fn(bcx, box_cell_v, closure_ty)
-            })
+pub fn get_wrapper_for_bare_fn(ccx: @CrateContext,
+                               closure_ty: ty::t,
+                               def: ast::Def,
+                               fn_ptr: ValueRef,
+                               is_local: bool) -> ValueRef {
+
+    let def_id = match def {
+        ast::DefFn(did, _) | ast::DefStaticMethod(did, _, _) |
+        ast::DefVariant(_, did, _) | ast::DefStruct(did) => did,
+        _ => {
+            ccx.sess.bug(format!("get_wrapper_for_bare_fn: \
+                                  expected a statically resolved fn, got {:?}",
+                                  def));
         }
-    }
-}
+    };
 
-pub fn make_opaque_cbox_drop_glue<'a>(
-                                  bcx: &'a Block<'a>,
-                                  sigil: ast::Sigil,
-                                  cboxptr: ValueRef)    // opaque closure ptr
-                                  -> &'a Block<'a> {
-    let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue");
-    match sigil {
-        ast::BorrowedSigil => bcx,
-        ast::ManagedSigil => {
-            bcx.tcx().sess.bug("trying to trans drop glue of @fn")
-        }
-        ast::OwnedSigil => {
-            glue::make_free_glue(
-                bcx, cboxptr,
-                ty::mk_opaque_closure_ptr(bcx.tcx(), sigil))
+    {
+        let cache = ccx.closure_bare_wrapper_cache.borrow();
+        match cache.get().find(&fn_ptr) {
+            Some(&llval) => return llval,
+            None => {}
         }
     }
-}
 
-/// `cbox` is a pointer to a pointer to an opaque closure.
-pub fn make_opaque_cbox_free_glue<'a>(
-                                  bcx: &'a Block<'a>,
-                                  sigil: ast::Sigil,
-                                  cbox: ValueRef)
-                                  -> &'a Block<'a> {
-    let _icx = push_ctxt("closure::make_opaque_cbox_free_glue");
-    match sigil {
-        ast::BorrowedSigil => {
-            return bcx;
+    let tcx = ccx.tcx;
+
+    debug!("get_wrapper_for_bare_fn(closure_ty={})", closure_ty.repr(tcx));
+
+    let f = match ty::get(closure_ty).sty {
+        ty::ty_closure(ref f) => f,
+        _ => {
+            ccx.sess.bug(format!("get_wrapper_for_bare_fn: \
+                                  expected a closure ty, got {}",
+                                  closure_ty.repr(tcx)));
         }
-        ast::ManagedSigil | ast::OwnedSigil => {
-            /* hard cases: fallthrough to code below */
+    };
+
+    let path = ty::item_path(tcx, def_id);
+    let name = mangle_internal_name_by_path_and_seq(ccx, path, "as_closure");
+    let llfn = if is_local {
+        decl_internal_rust_fn(ccx, true, f.sig.inputs, f.sig.output, name)
+    } else {
+        decl_rust_fn(ccx, true, f.sig.inputs, f.sig.output, name)
+    };
+
+    {
+        let mut cache = ccx.closure_bare_wrapper_cache.borrow_mut();
+        cache.get().insert(fn_ptr, llfn);
+    }
+
+    // This is only used by statics inlined from a different crate.
+    if !is_local {
+        // Don't regenerate the wrapper, just reuse the original one.
+        return llfn;
+    }
+
+    let _icx = push_ctxt("closure::get_wrapper_for_bare_fn");
+
+    let fcx = new_fn_ctxt(ccx, ~[], llfn, true, f.sig.output, None);
+    init_function(&fcx, true, f.sig.output, None);
+    let bcx = fcx.entry_bcx.get().unwrap();
+
+    let args = create_datums_for_fn_args(&fcx, ty::ty_fn_args(closure_ty));
+    let mut llargs = ~[];
+    match fcx.llretptr.get() {
+        Some(llretptr) => {
+            llargs.push(llretptr);
         }
+        None => {}
     }
+    llargs.extend(&mut args.iter().map(|arg| arg.val));
 
-    let ccx = bcx.ccx();
-    with_cond(bcx, IsNotNull(bcx, cbox), |bcx| {
-        // Load the type descr found in the cbox
-        let lltydescty = ccx.tydesc_type.ptr_to();
-        let cbox = Load(bcx, cbox);
-        let tydescptr = GEPi(bcx, cbox, [0u, abi::box_field_tydesc]);
-        let tydesc = Load(bcx, tydescptr);
-        let tydesc = PointerCast(bcx, tydesc, lltydescty);
-
-        // Drop the tuple data then free the descriptor
-        let cdata = GEPi(bcx, cbox, [0u, abi::box_field_body]);
-        glue::call_tydesc_glue_full(bcx, cdata, tydesc,
-                                    abi::tydesc_field_drop_glue, None);
-
-        // Free the ty descr (if necc) and the box itself
-        glue::trans_exchange_free(bcx, cbox);
-
-        bcx
-    })
+    let retval = Call(bcx, fn_ptr, llargs, []);
+    if type_is_zero_size(ccx, f.sig.output) || fcx.llretptr.get().is_some() {
+        RetVoid(bcx);
+    } else {
+        Ret(bcx, retval);
+    }
+
+    // HACK(eddyb) finish_fn cannot be used here, we returned directly.
+    debuginfo::clear_source_location(&fcx);
+    fcx.cleanup();
+
+    llfn
+}
+
+pub fn make_closure_from_bare_fn<'a>(bcx: &'a Block<'a>,
+                                     closure_ty: ty::t,
+                                     def: ast::Def,
+                                     fn_ptr: ValueRef)
+                                     -> DatumBlock<'a, Expr>  {
+    let scratch = rvalue_scratch_datum(bcx, closure_ty, "__adjust");
+    let wrapper = get_wrapper_for_bare_fn(bcx.ccx(), closure_ty, def, fn_ptr, true);
+    fill_fn_pair(bcx, scratch.val, wrapper, C_null(Type::i8p()));
+
+    DatumBlock(bcx, scratch.to_expr_datum())
 }
index e466e4da38d72f779eb5c0f00c681d8dde0667fa..45f5d84eb8ae4c65ded9f5861e6ab3622ff664e3 100644 (file)
@@ -230,9 +230,8 @@ pub struct FunctionContext<'a> {
     // section of the executable we're generating.
     llfn: ValueRef,
 
-    // The implicit environment argument that arrives in the function we're
-    // creating.
-    llenv: Cell<ValueRef>,
+    // The environment argument in a closure.
+    llenv: Option<ValueRef>,
 
     // The place to store the return value. If the return type is immediate,
     // this is an alloca in the function. Otherwise, it's the hidden first
@@ -250,14 +249,6 @@ pub struct FunctionContext<'a> {
     alloca_insert_pt: Cell<Option<ValueRef>>,
     llreturn: Cell<Option<BasicBlockRef>>,
 
-    // The 'self' value currently in use in this function, if there
-    // is one.
-    //
-    // NB: This is the type of the self *variable*, not the self *type*. The
-    // self type is set only for default methods, while the self variable is
-    // set for all methods.
-    llself: Cell<Option<LvalueDatum>>,
-
     // The a value alloca'd for calls to upcalls.rust_personality. Used when
     // outputting the resume instruction.
     personality: Cell<Option<ValueRef>>,
@@ -305,10 +296,11 @@ pub struct FunctionContext<'a> {
 
 impl<'a> FunctionContext<'a> {
     pub fn arg_pos(&self, arg: uint) -> uint {
-        if self.caller_expects_out_pointer {
-            arg + 2u
+        let arg = self.env_arg_pos() + arg;
+        if self.llenv.is_some() {
+            arg + 1
         } else {
-            arg + 1u
+            arg
         }
     }
 
index a28cb1a030cddcf8dbe156ebd4e2d79f842a1dbb..da4be012dc0b343ac56a1fd74aa73b24a1990ba6 100644 (file)
@@ -19,6 +19,7 @@
 use middle::trans::adt;
 use middle::trans::base;
 use middle::trans::base::push_ctxt;
+use middle::trans::closure;
 use middle::trans::common::*;
 use middle::trans::consts;
 use middle::trans::expr;
@@ -85,11 +86,12 @@ pub fn const_ptrcast(cx: &CrateContext, a: ValueRef, t: Type) -> ValueRef {
     }
 }
 
-fn const_vec(cx: @CrateContext, e: &ast::Expr, es: &[@ast::Expr]) -> (ValueRef, Type, bool) {
+fn const_vec(cx: @CrateContext, e: &ast::Expr,
+             es: &[@ast::Expr], is_local: bool) -> (ValueRef, Type, bool) {
     let vec_ty = ty::expr_ty(cx.tcx, e);
     let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
     let llunitty = type_of::type_of(cx, unit_ty);
-    let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e)));
+    let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e, is_local)));
     // If the vector contains enums, an LLVM array won't work.
     let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
         C_struct(vs, false)
@@ -187,11 +189,12 @@ pub fn get_const_val(cx: @CrateContext,
      !non_inlineable_statics.get().contains(&def_id.node))
 }
 
-pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
-    let (llconst, inlineable) = const_expr_unadjusted(cx, e);
+pub fn const_expr(cx: @CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef, bool) {
+    let (llconst, inlineable) = const_expr_unadjusted(cx, e, is_local);
     let mut llconst = llconst;
     let mut inlineable = inlineable;
     let ety = ty::expr_ty(cx.tcx, e);
+    let ety_adjusted = ty::expr_ty_adjusted(cx.tcx, e);
     let adjustment = {
         let adjustments = cx.tcx.adjustments.borrow();
         adjustments.get().find_copy(&e.id)
@@ -201,10 +204,13 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
         Some(adj) => {
             match *adj {
                 ty::AutoAddEnv(ty::ReStatic, ast::BorrowedSigil) => {
-                    llconst = C_struct([
-                        llconst,
-                        C_null(Type::opaque_box(cx).ptr_to())
-                    ], false)
+                    let def = ty::resolve_expr(cx.tcx, e);
+                    let wrapper = closure::get_wrapper_for_bare_fn(cx,
+                                                                   ety_adjusted,
+                                                                   def,
+                                                                   llconst,
+                                                                   is_local);
+                    llconst = C_struct([wrapper, C_null(Type::i8p())], false)
                 }
                 ty::AutoAddEnv(ref r, ref s) => {
                     cx.sess
@@ -277,7 +283,6 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
         }
     }
 
-    let ety_adjusted = ty::expr_ty_adjusted(cx.tcx, e);
     let llty = type_of::sizing_type_of(cx, ety_adjusted);
     let csize = machine::llsize_of_alloc(cx, val_ty(llconst));
     let tsize = machine::llsize_of_alloc(cx, llty);
@@ -296,22 +301,21 @@ pub fn const_expr(cx: @CrateContext, e: &ast::Expr) -> (ValueRef, bool) {
 
 // the bool returned is whether this expression can be inlined into other crates
 // if it's assigned to a static.
-fn const_expr_unadjusted(cx: @CrateContext,
-                         e: &ast::Expr) -> (ValueRef, bool) {
-    fn map_list(cx: @CrateContext,
-                exprs: &[@ast::Expr]) -> (~[ValueRef], bool) {
-        exprs.iter().map(|&e| const_expr(cx, e))
+fn const_expr_unadjusted(cx: @CrateContext, e: &ast::Expr,
+                         is_local: bool) -> (ValueRef, bool) {
+    let map_list = |exprs: &[@ast::Expr]| {
+        exprs.iter().map(|&e| const_expr(cx, e, is_local))
              .fold((~[], true), |(L, all_inlineable), (val, inlineable)| {
-                    (vec::append_one(L, val), all_inlineable && inlineable)
+                (vec::append_one(L, val), all_inlineable && inlineable)
              })
-    }
+    };
     unsafe {
         let _icx = push_ctxt("const_expr");
         return match e.node {
           ast::ExprLit(lit) => (consts::const_lit(cx, e, *lit), true),
           ast::ExprBinary(_, b, e1, e2) => {
-            let (te1, _) = const_expr(cx, e1);
-            let (te2, _) = const_expr(cx, e2);
+            let (te1, _) = const_expr(cx, e1, is_local);
+            let (te2, _) = const_expr(cx, e2, is_local);
 
             let te2 = base::cast_shift_const_rhs(b, te1, te2);
 
@@ -392,7 +396,7 @@ fn map_list(cx: @CrateContext,
             }, true)
           },
           ast::ExprUnary(_, u, e) => {
-            let (te, _) = const_expr(cx, e);
+            let (te, _) = const_expr(cx, e, is_local);
             let ty = ty::expr_ty(cx.tcx, e);
             let is_float = ty::type_is_fp(ty);
             return (match u {
@@ -421,7 +425,7 @@ fn map_list(cx: @CrateContext,
           ast::ExprField(base, field, _) => {
               let bt = ty::expr_ty_adjusted(cx.tcx, base);
               let brepr = adt::represent_type(cx, bt);
-              let (bv, inlineable) = const_expr(cx, base);
+              let (bv, inlineable) = const_expr(cx, base, is_local);
               expr::with_field_tys(cx.tcx, bt, None, |discr, field_tys| {
                   let ix = ty::field_idx_strict(cx.tcx, field.name, field_tys);
                   (adt::const_get_field(cx, brepr, bv, discr, ix), inlineable)
@@ -430,7 +434,7 @@ fn map_list(cx: @CrateContext,
 
           ast::ExprIndex(_, base, index) => {
               let bt = ty::expr_ty_adjusted(cx.tcx, base);
-              let (bv, inlineable) = const_expr(cx, base);
+              let (bv, inlineable) = const_expr(cx, base, is_local);
               let iv = match const_eval::eval_const_expr(cx.tcx, index) {
                   const_eval::const_int(i) => i as u64,
                   const_eval::const_uint(u) => u,
@@ -471,7 +475,7 @@ fn map_list(cx: @CrateContext,
             let ety = ty::expr_ty(cx.tcx, e);
             let llty = type_of::type_of(cx, ety);
             let basety = ty::expr_ty(cx.tcx, base);
-            let (v, inlineable) = const_expr(cx, base);
+            let (v, inlineable) = const_expr(cx, base, is_local);
             return (match (expr::cast_type_kind(basety),
                            expr::cast_type_kind(ety)) {
 
@@ -522,13 +526,13 @@ fn map_list(cx: @CrateContext,
             }, inlineable)
           }
           ast::ExprAddrOf(ast::MutImmutable, sub) => {
-              let (e, _) = const_expr(cx, sub);
+              let (e, _) = const_expr(cx, sub, is_local);
               (const_addr_of(cx, e), false)
           }
           ast::ExprTup(ref es) => {
               let ety = ty::expr_ty(cx.tcx, e);
               let repr = adt::represent_type(cx, ety);
-              let (vals, inlineable) = map_list(cx, *es);
+              let (vals, inlineable) = map_list(*es);
               (adt::trans_const(cx, repr, 0, vals), inlineable)
           }
           ast::ExprStruct(_, ref fs, ref base_opt) => {
@@ -537,7 +541,7 @@ fn map_list(cx: @CrateContext,
               let tcx = cx.tcx;
 
               let base_val = match *base_opt {
-                Some(base) => Some(const_expr(cx, base)),
+                Some(base) => Some(const_expr(cx, base, is_local)),
                 None => None
               };
 
@@ -545,7 +549,7 @@ fn map_list(cx: @CrateContext,
                   let cs = field_tys.iter().enumerate()
                       .map(|(ix, &field_ty)| {
                       match fs.iter().find(|f| field_ty.ident.name == f.ident.node.name) {
-                          Some(f) => const_expr(cx, (*f).expr),
+                          Some(f) => const_expr(cx, (*f).expr, is_local),
                           None => {
                               match base_val {
                                 Some((bv, inlineable)) => {
@@ -563,19 +567,19 @@ fn map_list(cx: @CrateContext,
               })
           }
           ast::ExprVec(ref es, ast::MutImmutable) => {
-            let (v, _, inlineable) = const_vec(cx, e, *es);
+            let (v, _, inlineable) = const_vec(cx, e, *es, is_local);
             (v, inlineable)
           }
           ast::ExprVstore(sub, ast::ExprVstoreSlice) => {
             match sub.node {
               ast::ExprLit(ref lit) => {
                 match lit.node {
-                    ast::LitStr(..) => { const_expr(cx, sub) }
+                    ast::LitStr(..) => { const_expr(cx, sub, is_local) }
                     _ => { cx.sess.span_bug(e.span, "bad const-slice lit") }
                 }
               }
               ast::ExprVec(ref es, ast::MutImmutable) => {
-                let (cv, llunitty, _) = const_vec(cx, e, *es);
+                let (cv, llunitty, _) = const_vec(cx, e, *es, is_local);
                 let llty = val_ty(cv);
                 let gv = "const".with_c_str(|name| {
                     llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
@@ -598,7 +602,7 @@ fn map_list(cx: @CrateContext,
                 const_eval::const_uint(i) => i as uint,
                 _ => cx.sess.span_bug(count.span, "count must be integral const expression.")
             };
-            let vs = vec::from_elem(n, const_expr(cx, elem).first());
+            let vs = vec::from_elem(n, const_expr(cx, elem, is_local).first());
             let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
                 C_struct(vs, false)
             } else {
@@ -656,7 +660,7 @@ fn map_list(cx: @CrateContext,
                   Some(ast::DefStruct(_)) => {
                       let ety = ty::expr_ty(cx.tcx, e);
                       let repr = adt::represent_type(cx, ety);
-                      let (arg_vals, inlineable) = map_list(cx, *args);
+                      let (arg_vals, inlineable) = map_list(*args);
                       (adt::trans_const(cx, repr, 0, arg_vals), inlineable)
                   }
                   Some(ast::DefVariant(enum_did, variant_did, _)) => {
@@ -665,14 +669,14 @@ fn map_list(cx: @CrateContext,
                       let vinfo = ty::enum_variant_with_id(cx.tcx,
                                                            enum_did,
                                                            variant_did);
-                      let (arg_vals, inlineable) = map_list(cx, *args);
+                      let (arg_vals, inlineable) = map_list(*args);
                       (adt::trans_const(cx, repr, vinfo.disr_val, arg_vals),
                        inlineable)
                   }
                   _ => cx.sess.span_bug(e.span, "expected a struct or variant def")
               }
           }
-          ast::ExprParen(e) => { const_expr(cx, e) }
+          ast::ExprParen(e) => { const_expr(cx, e, is_local) }
           _ => cx.sess.span_bug(e.span,
                   "bad constant expression type in consts::const_expr")
         };
index 527308be0fffa8230fcd43e268318deff638c71e..010408246815e6ec6b8b1c39a1e0e3e447598a2f 100644 (file)
@@ -91,6 +91,9 @@ pub struct CrateContext {
 
      impl_method_cache: RefCell<HashMap<(ast::DefId, ast::Name), ast::DefId>>,
 
+     // Cache of closure wrappers for bare fn's.
+     closure_bare_wrapper_cache: RefCell<HashMap<ValueRef, ValueRef>>,
+
      module_data: RefCell<HashMap<~str, ValueRef>>,
      lltypes: RefCell<HashMap<ty::t, Type>>,
      llsizingtypes: RefCell<HashMap<ty::t, Type>>,
@@ -201,6 +204,7 @@ pub fn new(sess: session::Session,
                   const_values: RefCell::new(HashMap::new()),
                   extern_const_values: RefCell::new(HashMap::new()),
                   impl_method_cache: RefCell::new(HashMap::new()),
+                  closure_bare_wrapper_cache: RefCell::new(HashMap::new()),
                   module_data: RefCell::new(HashMap::new()),
                   lltypes: RefCell::new(HashMap::new()),
                   llsizingtypes: RefCell::new(HashMap::new()),
index ec47dbacb39c0eb85ebaa91fa16b2ea46f7b5b2c..8c8c6829e49fd6f5a46b71460ad4ac5f69934c5c 100644 (file)
@@ -309,7 +309,7 @@ pub fn trans_ret<'a>(bcx: &'a Block<'a>,
         Some(x) => {
             bcx = expr::trans_into(bcx, x, dest);
         }
-        _ => ()
+        _ => {}
     }
     let cleanup_llbb = fcx.return_exit_block();
     Br(bcx, cleanup_llbb);
index 4c5ed91e5f74750f1b94f37494778cae715548eb..c4fdc895670328cb92d0788bb0580efd2399a07e 100644 (file)
@@ -130,8 +130,6 @@ struct List {
 use lib::llvm::{ModuleRef, ContextRef, ValueRef};
 use lib::llvm::debuginfo::*;
 use middle::trans::adt;
-use middle::trans::base;
-use middle::trans::build;
 use middle::trans::common::*;
 use middle::trans::datum::{Datum, Lvalue};
 use middle::trans::machine;
@@ -328,8 +326,7 @@ pub fn create_captured_var_metadata(bcx: &Block,
         None => {
             cx.sess.span_bug(span, "debuginfo::create_captured_var_metadata() - NodeId not found");
         }
-        Some(ast_map::NodeLocal(ident, _)) => ident,
-        Some(ast_map::NodeArg(pat)) => {
+        Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
             match pat.node {
                 ast::PatIdent(_, ref path, _) => {
                     ast_util::path_to_ident(path)
@@ -410,83 +407,6 @@ pub fn create_match_binding_metadata(bcx: &Block,
                   span);
 }
 
-/// Creates debug information for the self argument of a method.
-///
-/// Adds the created metadata nodes directly to the crate's IR.
-pub fn create_self_argument_metadata(bcx: &Block,
-                                     type_of_self: ty::t,
-                                     llptr: ValueRef) {
-    if fn_should_be_ignored(bcx.fcx) {
-        return;
-    }
-
-    // Extract the span of the self argument from the method's AST
-    let fnitem = bcx.ccx().tcx.items.get(bcx.fcx.id);
-    let span = match fnitem {
-        ast_map::NodeMethod(method, _, _) => {
-            method.explicit_self.span
-        }
-        ast_map::NodeTraitMethod(trait_method, _, _) => {
-            match *trait_method {
-                ast::Provided(method) => method.explicit_self.span,
-                _ => {
-                    bcx.ccx()
-                       .sess
-                       .bug(format!("create_self_argument_metadata: \
-                                     unexpected sort of node: {:?}",
-                                     fnitem))
-                }
-            }
-        }
-        _ => bcx.ccx().sess.bug(
-                format!("create_self_argument_metadata: unexpected sort of node: {:?}", fnitem))
-    };
-
-    let scope_metadata = bcx.fcx.debug_context.get_ref(bcx.ccx(), span).fn_metadata;
-
-    let argument_index = {
-        let counter = &bcx.fcx.debug_context.get_ref(bcx.ccx(), span).argument_counter;
-        let argument_index = counter.get();
-        counter.set(argument_index + 1);
-        argument_index
-    };
-
-    let address_operations = &[unsafe { llvm::LLVMDIBuilderCreateOpDeref(Type::i64().to_ref()) }];
-
-    // The self argument comes in one of two forms:
-    // (1) For `&self`, `~self`, and `@self` it is an alloca containing a pointer to the data. That
-    //     is the `{&~@}self` pointer is contained by value in the alloca, and `type_of_self` will
-    //     be `{&~@}Self`
-    // (2) For by-value `self`, `llptr` will not be an alloca, but a pointer to the self-value. That
-    //     is by-value `self` is always implicitly passed by reference (sic!). So we have a couple
-    //     of problems here:
-    //     (a) There is no alloca to give to `llvm.dbg.declare` and
-    //     (b) `type_of_self` is `Self`, but `llptr` is of type `*Self`
-    //     In order to solve this problem, the else branch below creates a helper alloca which
-    //     contains a copy of `llptr`. We then describe the `self` parameter by pointing
-    //     `llvm.dbg.declare` to this helper alloca and tell it that the pointer there needs to be
-    //     dereferenced once to get to the actual data (similar to non-immediate by-value args).
-    let variable_access = if unsafe { llvm::LLVMIsAAllocaInst(llptr) } != ptr::null() {
-        DirectVariable { alloca: llptr }
-    } else {
-        // Create a helper alloca that allows us to track the self-argument properly. The alloca
-        // contains a pointer to the self-value.
-        let ptr_type = ty::mk_mut_ptr(bcx.tcx(), type_of_self);
-        let helper_alloca = base::alloc_ty(bcx, ptr_type, "__self");
-        build::Store(bcx, llptr, helper_alloca);
-
-        IndirectVariable { alloca: helper_alloca, address_operations: address_operations }
-    };
-
-    declare_local(bcx,
-                  special_idents::self_,
-                  type_of_self,
-                  scope_metadata,
-                  variable_access,
-                  ArgumentVariable(argument_index),
-                  span);
-}
-
 /// Creates debug information for the given function argument.
 ///
 /// Adds the created metadata nodes directly to the crate's IR.
@@ -1768,7 +1688,7 @@ fn boxed_type_metadata(cx: &CrateContext,
         None                    => ~"BoxedType"
     };
 
-    let box_llvm_type = Type::smart_ptr(cx, &content_llvm_type);
+    let box_llvm_type = Type::at_box(cx, content_llvm_type);
     let member_llvm_types = box_llvm_type.field_types();
     assert!(box_layout_is_correct(cx, member_llvm_types, content_llvm_type));
 
@@ -2584,11 +2504,10 @@ fn walk_expr(cx: &CrateContext,
 
         match exp.node {
             ast::ExprLogLevel |
-            ast::ExprSelf     |
             ast::ExprLit(_)   |
             ast::ExprBreak(_) |
             ast::ExprAgain(_) |
-            ast::ExprPath(_)  => (),
+            ast::ExprPath(_)  => {}
 
             ast::ExprVstore(sub_exp, _)   |
             ast::ExprCast(sub_exp, _)     |
@@ -2697,8 +2616,7 @@ fn walk_expr(cx: &CrateContext,
                 })
             }
 
-            // ast::expr_loop_body(inner_exp) |
-            ast::ExprDoBody(inner_exp)   => {
+            ast::ExprDoBody(inner_exp) => {
                 let inner_expr_is_expr_fn_block = match *inner_exp {
                     ast::Expr { node: ast::ExprFnBlock(..), .. } => true,
                     _ => false
@@ -2720,9 +2638,8 @@ fn walk_expr(cx: &CrateContext,
                 }
             }
 
-            ast::ExprMethodCall(node_id, receiver_exp, _, _, ref args, _) => {
+            ast::ExprMethodCall(node_id, _, _, ref args, _) => {
                 scope_map.insert(node_id, scope_stack.last().unwrap().scope_metadata);
-                walk_expr(cx, receiver_exp, scope_stack, scope_map);
 
                 for arg_exp in args.iter() {
                     walk_expr(cx, *arg_exp, scope_stack, scope_map);
index 36fc927b64c4546ba91468b8e82acab05d648404..8de2c1d4cb228c1c518cfe33a9ebcf1c863e084c 100644 (file)
@@ -42,7 +42,6 @@
 use middle::trans::base::*;
 use middle::trans::base;
 use middle::trans::build::*;
-use middle::trans::callee::DoAutorefArg;
 use middle::trans::callee;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
@@ -316,16 +315,10 @@ fn add_env<'a>(bcx: &'a Block<'a>,
         // code and keep it DRY that accommodates that use case at the
         // moment.
 
-        let tcx = bcx.tcx();
         let closure_ty = expr_ty_adjusted(bcx, expr);
-        debug!("add_env(closure_ty={})", closure_ty.repr(tcx));
-        let scratch = rvalue_scratch_datum(bcx, closure_ty, "__adjust");
-        let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]);
-        let llval = datum.to_llscalarish(bcx);
-        Store(bcx, llval, llfn);
-        let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]);
-        Store(bcx, base::null_env_ptr(bcx.ccx()), llenv);
-        DatumBlock(bcx, scratch.to_expr_datum())
+        let fn_ptr = datum.to_llscalarish(bcx);
+        let def = ty::resolve_expr(bcx.tcx(), expr);
+        closure::make_closure_from_bare_fn(bcx, closure_ty, def, fn_ptr)
     }
 
     fn auto_slice_and_ref<'a>(
@@ -517,7 +510,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
         ast::ExprParen(e) => {
             trans(bcx, e)
         }
-        ast::ExprPath(_) | ast::ExprSelf => {
+        ast::ExprPath(_) => {
             trans_def(bcx, expr, bcx.def(expr.id))
         }
         ast::ExprField(base, ident, _) => {
@@ -669,7 +662,8 @@ fn trans_def<'a>(bcx: &'a Block<'a>,
 
     let _icx = push_ctxt("trans_def_lvalue");
     match def {
-        ast::DefFn(..) | ast::DefStaticMethod(..) => {
+        ast::DefFn(..) | ast::DefStaticMethod(..) |
+        ast::DefStruct(_) | ast::DefVariant(..) => {
             trans_def_fn_unadjusted(bcx, ref_expr, def)
         }
         ast::DefStatic(did, _) => {
@@ -817,34 +811,33 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
 
     match expr.node {
         ast::ExprParen(e) => {
-            return trans_into(bcx, e, dest);
+            trans_into(bcx, e, dest)
         }
-        ast::ExprPath(_) | ast::ExprSelf => {
-            return trans_def_dps_unadjusted(bcx, expr,
-                                            bcx.def(expr.id), dest);
+        ast::ExprPath(_) => {
+            trans_def_dps_unadjusted(bcx, expr, bcx.def(expr.id), dest)
         }
         ast::ExprIf(cond, thn, els) => {
-            return controlflow::trans_if(bcx, expr.id, cond, thn, els, dest);
+            controlflow::trans_if(bcx, expr.id, cond, thn, els, dest)
         }
         ast::ExprMatch(discr, ref arms) => {
-            return _match::trans_match(bcx, expr, discr, *arms, dest);
+            _match::trans_match(bcx, expr, discr, *arms, dest)
         }
         ast::ExprBlock(blk) => {
             controlflow::trans_block(bcx, blk, dest)
         }
         ast::ExprStruct(_, ref fields, base) => {
-            return trans_rec_or_struct(bcx, (*fields), base, expr.span, expr.id, dest);
+            trans_rec_or_struct(bcx, (*fields), base, expr.span, expr.id, dest)
         }
         ast::ExprTup(ref args) => {
             let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr));
             let numbered_fields: ~[(uint, @ast::Expr)] =
                 args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
-            return trans_adt(bcx, repr, 0, numbered_fields, None, dest);
+            trans_adt(bcx, repr, 0, numbered_fields, None, dest)
         }
         ast::ExprLit(lit) => {
             match lit.node {
                 ast::LitStr(s, _) => {
-                    return tvec::trans_lit_str(bcx, expr, s, dest);
+                    tvec::trans_lit_str(bcx, expr, s, dest)
                 }
                 _ => {
                     bcx.tcx()
@@ -859,10 +852,10 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
         ast::ExprVstore(contents, ast::ExprVstoreMutSlice) => {
             fcx.push_ast_cleanup_scope(contents.id);
             bcx = tvec::trans_slice_vstore(bcx, expr, contents, dest);
-            return fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id);
+            fcx.pop_and_trans_ast_cleanup_scope(bcx, contents.id)
         }
         ast::ExprVec(..) | ast::ExprRepeat(..) => {
-            return tvec::trans_fixed_vstore(bcx, expr, expr, dest);
+            tvec::trans_fixed_vstore(bcx, expr, expr, dest)
         }
         ast::ExprFnBlock(decl, body) |
         ast::ExprProc(decl, body) => {
@@ -871,60 +864,41 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
             debug!("translating block function {} with type {}",
                    expr_to_str(expr, tcx.sess.intr()),
                    expr_ty.repr(tcx));
-            return closure::trans_expr_fn(bcx, sigil, decl, body,
-                                          expr.id, expr.id, dest);
+            closure::trans_expr_fn(bcx, sigil, decl, body,
+                                   expr.id, expr.id, dest)
         }
         ast::ExprDoBody(blk) => {
-            return trans_into(bcx, blk, dest);
+            trans_into(bcx, blk, dest)
         }
         ast::ExprCall(f, ref args, _) => {
-            return callee::trans_call(
-                bcx, expr, f, callee::ArgExprs(*args), expr.id, dest);
+            callee::trans_call(bcx, expr, f,
+                               callee::ArgExprs(*args), expr.id, dest)
         }
-        ast::ExprMethodCall(callee_id, rcvr, _, _, ref args, _) => {
-            return callee::trans_method_call(bcx,
-                                             expr,
-                                             callee_id,
-                                             rcvr,
-                                             callee::ArgExprs(*args),
-                                             dest);
+        ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
+            callee::trans_method_call(bcx, expr, callee_id, args[0],
+                                      callee::ArgExprs(*args), dest)
         }
         ast::ExprBinary(callee_id, _, lhs, rhs) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx,
-                                       expr,
-                                       callee_id,
-                                       lhs,
-                                       ~[rhs],
-                                       expr_ty(bcx, expr),
-                                       dest);
+            trans_overloaded_op(bcx, expr, callee_id, lhs,
+                                Some(&*rhs), expr_ty(bcx, expr), dest)
         }
         ast::ExprUnary(callee_id, _, subexpr) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx,
-                                       expr,
-                                       callee_id,
-                                       subexpr,
-                                       ~[],
-                                       expr_ty(bcx, expr),
-                                       dest);
+            trans_overloaded_op(bcx, expr, callee_id, subexpr,
+                                None, expr_ty(bcx, expr), dest)
         }
         ast::ExprIndex(callee_id, base, idx) => {
             // if not overloaded, would be RvalueDatumExpr
-            return trans_overloaded_op(bcx,
-                                       expr,
-                                       callee_id,
-                                       base,
-                                       ~[idx],
-                                       expr_ty(bcx, expr),
-                                       dest);
+            trans_overloaded_op(bcx, expr, callee_id, base,
+                                Some(&*idx), expr_ty(bcx, expr), dest)
         }
         ast::ExprCast(val, _) => {
             // DPS output mode means this is a trait cast:
             match ty::get(node_id_type(bcx, expr.id)).sty {
                 ty::ty_trait(..) => {
                     let datum = unpack_datum!(bcx, trans(bcx, val));
-                    return meth::trans_trait_cast(bcx, datum, expr.id, dest);
+                    meth::trans_trait_cast(bcx, datum, expr.id, dest)
                 }
                 _ => {
                     bcx.tcx().sess.span_bug(expr.span,
@@ -933,12 +907,12 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
             }
         }
         ast::ExprAssignOp(callee_id, op, dst, src) => {
-            return trans_assign_op(bcx, expr, callee_id, op, dst, src);
+            trans_assign_op(bcx, expr, callee_id, op, dst, src)
         }
         ast::ExprBox(_, contents) => {
             // Special case for `Gc<T>` for now. The other case, for unique
             // pointers, is handled in `trans_rvalue_datum_unadjusted`.
-            return trans_gc(bcx, expr, contents, dest)
+            trans_gc(bcx, expr, contents, dest)
         }
         _ => {
             bcx.tcx().sess.span_bug(
@@ -968,8 +942,8 @@ fn trans_def_dps_unadjusted<'a>(
             let variant_info = ty::enum_variant_with_id(ccx.tcx, tid, vid);
             if variant_info.args.len() > 0u {
                 // N-ary variant.
-                let fn_data = callee::trans_fn_ref(bcx, vid, ref_expr.id);
-                Store(bcx, fn_data.llfn, lldest);
+                let llfn = callee::trans_fn_ref(bcx, vid, ref_expr.id);
+                Store(bcx, llfn, lldest);
                 return bcx;
             } else {
                 // Nullary variant.
@@ -980,20 +954,16 @@ fn trans_def_dps_unadjusted<'a>(
                 return bcx;
             }
         }
-        ast::DefStruct(def_id) => {
+        ast::DefStruct(_) => {
             let ty = expr_ty(bcx, ref_expr);
             match ty::get(ty).sty {
                 ty::ty_struct(did, _) if ty::has_dtor(ccx.tcx, did) => {
                     let repr = adt::represent_type(ccx, ty);
                     adt::trans_start_init(bcx, repr, lldest, 0);
                 }
-                ty::ty_bare_fn(..) => {
-                    let fn_data = callee::trans_fn_ref(bcx, def_id, ref_expr.id);
-                    Store(bcx, fn_data.llfn, lldest);
-                }
-                _ => ()
+                _ => {}
             }
-            return bcx;
+            bcx
         }
         _ => {
             bcx.tcx().sess.span_bug(ref_expr.span, format!(
@@ -1009,16 +979,15 @@ fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>,
 {
     let _icx = push_ctxt("trans_def_datum_unadjusted");
 
-    let fn_data = match def {
+    let llfn = match def {
         ast::DefFn(did, _) |
+        ast::DefStruct(did) | ast::DefVariant(_, did, _) |
         ast::DefStaticMethod(did, ast::FromImpl(_), _) => {
             callee::trans_fn_ref(bcx, did, ref_expr.id)
         }
         ast::DefStaticMethod(impl_did, ast::FromTrait(trait_did), _) => {
-            meth::trans_static_method_callee(bcx,
-                                             impl_did,
-                                             trait_did,
-                                             ref_expr.id)
+            meth::trans_static_method_callee(bcx, impl_did,
+                                             trait_did, ref_expr.id)
         }
         _ => {
             bcx.tcx().sess.span_bug(ref_expr.span, format!(
@@ -1029,7 +998,7 @@ fn trans_def_fn_unadjusted<'a>(bcx: &'a Block<'a>,
     };
 
     let fn_ty = expr_ty(bcx, ref_expr);
-    DatumBlock(bcx, Datum(fn_data.llfn, fn_ty, RvalueExpr(Rvalue(ByValue))))
+    DatumBlock(bcx, Datum(llfn, fn_ty, RvalueExpr(Rvalue(ByValue))))
 }
 
 pub fn trans_local_var<'a>(bcx: &'a Block<'a>,
@@ -1063,21 +1032,6 @@ pub fn trans_local_var<'a>(bcx: &'a Block<'a>,
             let lllocals = bcx.fcx.lllocals.borrow();
             take_local(bcx, lllocals.get(), nid)
         }
-        ast::DefSelf(nid, _) => {
-            let self_info = match bcx.fcx.llself.get() {
-                Some(self_info) => self_info,
-                None => {
-                    bcx.sess().bug(format!(
-                        "trans_local_var: reference to self \
-                         out of context with id {:?}", nid));
-                }
-            };
-
-            debug!("def_self() reference, self_info.ty={}",
-                   self_info.ty.repr(bcx.tcx()));
-
-            self_info
-        }
         _ => {
             bcx.sess().unimpl(format!(
                 "unsupported def type in trans_local_var: {:?}", def));
@@ -1630,12 +1584,12 @@ fn trans_binary<'a>(
     }
 }
 
-fn trans_overloaded_op<'a>(
+fn trans_overloaded_op<'a, 'b>(
                        bcx: &'a Block<'a>,
                        expr: &ast::Expr,
                        callee_id: ast::NodeId,
-                       rcvr: &ast::Expr,
-                       args: ~[@ast::Expr],
+                       rcvr: &'b ast::Expr,
+                       arg: Option<&'b ast::Expr>,
                        ret_ty: ty::t,
                        dest: Dest)
                        -> &'a Block<'a> {
@@ -1655,9 +1609,8 @@ fn trans_overloaded_op<'a>(
                                                           origin,
                                                           arg_cleanup_scope)
                              },
-                             callee::ArgExprs(args),
-                             Some(dest),
-                             DoAutorefArg).bcx
+                             callee::ArgAutorefSecond(rcvr, arg),
+                             Some(dest)).bcx
 }
 
 fn int_cast(bcx: &Block,
index 2526d8e3fea27655410b3a47adb9ed67908361be..fd0d8a890e33313686272f0165d6a07d3bb3a413 100644 (file)
@@ -480,18 +480,10 @@ fn build_rust_fn(ccx: @CrateContext,
                id,
                t.repr(tcx));
 
-        let llfndecl = base::decl_internal_rust_fn(ccx, None, f.sig.inputs, f.sig.output, ps);
-        base::set_llvm_fn_attrs(attrs, llfndecl);
-        base::trans_fn(ccx,
-                       (*path).clone(),
-                       decl,
-                       body,
-                       llfndecl,
-                       None,
-                       None,
-                       id,
-                       []);
-        return llfndecl;
+        let llfn = base::decl_internal_rust_fn(ccx, false, f.sig.inputs, f.sig.output, ps);
+        base::set_llvm_fn_attrs(attrs, llfn);
+        base::trans_fn(ccx, (*path).clone(), decl, body, llfn, None, id, []);
+        llfn
     }
 
     unsafe fn build_wrap_fn(ccx: @CrateContext,
@@ -597,11 +589,6 @@ unsafe fn build_wrap_fn(ccx: @CrateContext,
             return_alloca = None;
         };
 
-        // Push an (null) env pointer
-        let env_pointer = base::null_env_ptr(ccx);
-        debug!("env pointer={}", ccx.tn.val_to_str(env_pointer));
-        llrust_args.push(env_pointer);
-
         // Build up the arguments to the call to the rust function.
         // Careful to adapt for cases where the native convention uses
         // a pointer and Rust does not or vice versa.
index ae03d48dbf0dc3d0d86e2ea5b97b150756a63af4..5004bcca91e3c1f34e3d428a9fcdf548e89aa949 100644 (file)
@@ -23,7 +23,6 @@
 use middle::trans::callee;
 use middle::trans::cleanup;
 use middle::trans::cleanup::CleanupMethods;
-use middle::trans::closure;
 use middle::trans::common::*;
 use middle::trans::build::*;
 use middle::trans::expr;
@@ -202,11 +201,8 @@ fn lazily_emit_tydesc_glue(ccx: @CrateContext, field: uint, ti: @tydesc_info) {
 }
 
 // See [Note-arg-mode]
-pub fn call_tydesc_glue_full(bcx: &Block,
-                             v: ValueRef,
-                             tydesc: ValueRef,
-                             field: uint,
-                             static_ti: Option<@tydesc_info>) {
+pub fn call_tydesc_glue_full(bcx: &Block, v: ValueRef, tydesc: ValueRef,
+                             field: uint, static_ti: Option<@tydesc_info>) {
     let _icx = push_ctxt("call_tydesc_glue_full");
     let ccx = bcx.ccx();
     // NB: Don't short-circuit even if this block is unreachable because
@@ -214,25 +210,25 @@ pub fn call_tydesc_glue_full(bcx: &Block,
     if bcx.unreachable.get() && !ccx.sess.no_landing_pads() { return; }
 
     let static_glue_fn = match static_ti {
-      None => None,
-      Some(sti) => {
-        lazily_emit_tydesc_glue(ccx, field, sti);
-        if field == abi::tydesc_field_take_glue {
-            sti.take_glue.get()
-        } else if field == abi::tydesc_field_drop_glue {
-            sti.drop_glue.get()
-        } else if field == abi::tydesc_field_visit_glue {
-            sti.visit_glue.get()
-        } else {
-            None
+        None => None,
+        Some(sti) => {
+            lazily_emit_tydesc_glue(ccx, field, sti);
+            if field == abi::tydesc_field_take_glue {
+                sti.take_glue.get()
+            } else if field == abi::tydesc_field_drop_glue {
+                sti.drop_glue.get()
+            } else if field == abi::tydesc_field_visit_glue {
+                sti.visit_glue.get()
+            } else {
+                None
+            }
         }
-      }
     };
 
     // When static type info is available, avoid casting parameter unless the
     // glue is using a simplified type, because the function already has the
     // right type. Otherwise cast to generic pointer.
-    let llrawptr = if static_ti.is_none() || static_glue_fn.is_none() {
+    let llrawptr = if static_glue_fn.is_none() {
         PointerCast(bcx, v, Type::i8p())
     } else {
         let ty = static_ti.unwrap().ty;
@@ -246,16 +242,16 @@ pub fn call_tydesc_glue_full(bcx: &Block,
 
     let llfn = {
         match static_glue_fn {
-          None => {
-            // Select out the glue function to call from the tydesc
-            let llfnptr = GEPi(bcx, tydesc, [0u, field]);
-            Load(bcx, llfnptr)
-          }
-          Some(sgf) => sgf
+            None => {
+                // Select out the glue function to call from the tydesc
+                let llfnptr = GEPi(bcx, tydesc, [0u, field]);
+                Load(bcx, llfnptr)
+            }
+            Some(sgf) => sgf
         }
     };
 
-    Call(bcx, llfn, [C_null(Type::nil().ptr_to()), llrawptr], []);
+    Call(bcx, llfn, [llrawptr], []);
 }
 
 // See [Note-arg-mode]
@@ -283,43 +279,7 @@ fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t)
     bcx
 }
 
-pub fn make_free_glue<'a>(bcx: &'a Block<'a>,
-                          v: ValueRef,
-                          t: ty::t)
-                          -> &'a Block<'a> {
-    // NB: v0 is an *alias* of type t here, not a direct value.
-    let _icx = push_ctxt("make_free_glue");
-    match ty::get(t).sty {
-      ty::ty_box(body_ty) => {
-        let v = Load(bcx, v);
-        let body = GEPi(bcx, v, [0u, abi::box_field_body]);
-        let bcx = drop_ty(bcx, body, body_ty);
-        trans_free(bcx, v)
-      }
-      ty::ty_uniq(content_ty) => {
-        let llbox = Load(bcx, v);
-        let not_null = IsNotNull(bcx, llbox);
-        with_cond(bcx, not_null, |bcx| {
-                    let bcx = drop_ty(bcx, llbox, content_ty);
-                    trans_exchange_free(bcx, llbox)
-                })
-      }
-      ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) |
-      ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
-        make_free_glue(bcx, v, tvec::expand_boxed_vec_ty(bcx.tcx(), t))
-      }
-      ty::ty_closure(_) => {
-        closure::make_closure_glue(bcx, v, t, make_free_glue)
-      }
-      ty::ty_opaque_closure_ptr(ck) => {
-        closure::make_opaque_cbox_free_glue(bcx, ck, v)
-      }
-      _ => bcx
-    }
-}
-
-pub fn trans_struct_drop_flag<'a>(
-                              bcx: &'a Block<'a>,
+fn trans_struct_drop_flag<'a>(bcx: &'a Block<'a>,
                               t: ty::t,
                               v0: ValueRef,
                               dtor_did: ast::DefId,
@@ -333,8 +293,7 @@ pub fn trans_struct_drop_flag<'a>(
     })
 }
 
-pub fn trans_struct_drop<'a>(
-                         bcx: &'a Block<'a>,
+fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
                          t: ty::t,
                          v0: ValueRef,
                          dtor_did: ast::DefId,
@@ -380,72 +339,99 @@ pub fn trans_struct_drop<'a>(
     bcx.fcx.pop_and_trans_custom_cleanup_scope(bcx, field_scope)
 }
 
-pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t)
-                      -> &'a Block<'a> {
+fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'a> {
     // NB: v0 is an *alias* of type t here, not a direct value.
     let _icx = push_ctxt("make_drop_glue");
     let ccx = bcx.ccx();
     match ty::get(t).sty {
-      ty::ty_box(_) |
-      ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) => {
-        decr_refcnt_maybe_free(bcx, v0, Some(t))
-      }
-      ty::ty_uniq(_) |
-      ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
-        make_free_glue(bcx, v0, t)
-      }
-      ty::ty_unboxed_vec(_) => {
-        tvec::make_drop_glue_unboxed(bcx, v0, t)
-      }
-      ty::ty_struct(did, ref substs) => {
-        let tcx = bcx.tcx();
-        match ty::ty_dtor(tcx, did) {
-          ty::TraitDtor(dtor, true) => {
-            trans_struct_drop_flag(bcx, t, v0, dtor, did, substs)
-          }
-          ty::TraitDtor(dtor, false) => {
-            trans_struct_drop(bcx, t, v0, dtor, did, substs)
-          }
-          ty::NoDtor => {
-            // No dtor? Just the default case
-            iter_structural_ty(bcx, v0, t, drop_ty)
-          }
+        ty::ty_box(body_ty) => {
+            decr_refcnt_maybe_free(bcx, v0, Some(body_ty))
+        }
+        ty::ty_str(ty::vstore_box) | ty::ty_vec(_, ty::vstore_box) => {
+            let unit_ty = ty::sequence_element_type(ccx.tcx, t);
+            let unboxed_vec_ty = ty::mk_mut_unboxed_vec(ccx.tcx, unit_ty);
+            decr_refcnt_maybe_free(bcx, v0, Some(unboxed_vec_ty))
+        }
+        ty::ty_uniq(content_ty) => {
+            let llbox = Load(bcx, v0);
+            let not_null = IsNotNull(bcx, llbox);
+            with_cond(bcx, not_null, |bcx| {
+                let bcx = drop_ty(bcx, llbox, content_ty);
+                trans_exchange_free(bcx, llbox)
+            })
+        }
+        ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
+            make_drop_glue(bcx, v0, tvec::expand_boxed_vec_ty(bcx.tcx(), t))
+        }
+        ty::ty_unboxed_vec(_) => {
+            tvec::make_drop_glue_unboxed(bcx, v0, t)
+        }
+        ty::ty_struct(did, ref substs) => {
+            let tcx = bcx.tcx();
+            match ty::ty_dtor(tcx, did) {
+                ty::TraitDtor(dtor, true) => {
+                    trans_struct_drop_flag(bcx, t, v0, dtor, did, substs)
+                }
+                ty::TraitDtor(dtor, false) => {
+                    trans_struct_drop(bcx, t, v0, dtor, did, substs)
+                }
+                ty::NoDtor => {
+                    // No dtor? Just the default case
+                    iter_structural_ty(bcx, v0, t, drop_ty)
+                }
+            }
+        }
+        ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
+            let llbox_ptr = GEPi(bcx, v0, [0u, abi::trt_field_box]);
+            decr_refcnt_maybe_free(bcx, llbox_ptr, None)
+        }
+        ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
+            let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
+            // Only drop the value when it is non-null
+            with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
+                let llvtable = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
+
+                // Cast the vtable to a pointer to a pointer to a tydesc.
+                let llvtable = PointerCast(bcx, llvtable,
+                                           ccx.tydesc_type.ptr_to().ptr_to());
+                let lltydesc = Load(bcx, llvtable);
+                call_tydesc_glue_full(bcx,
+                                      lluniquevalue,
+                                      lltydesc,
+                                      abi::tydesc_field_drop_glue,
+                                      None);
+                bcx
+            })
+        }
+        ty::ty_closure(ref f) if f.sigil == ast::OwnedSigil => {
+            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(ccx, Type::i8()).ptr_to();
+            let env = PointerCast(bcx, env, env_ptr_ty);
+            with_cond(bcx, IsNotNull(bcx, env), |bcx| {
+                // Load the type descr found in the env
+                let lltydescty = ccx.tydesc_type.ptr_to();
+                let tydescptr = GEPi(bcx, env, [0u, abi::box_field_tydesc]);
+                let tydesc = Load(bcx, tydescptr);
+                let tydesc = PointerCast(bcx, tydesc, lltydescty);
+
+                // Drop the tuple data then free the descriptor
+                let cdata = GEPi(bcx, env, [0u, abi::box_field_body]);
+                call_tydesc_glue_full(bcx, cdata, tydesc,
+                                      abi::tydesc_field_drop_glue, None);
+
+                // Free the ty descr (if necc) and the env itself
+                trans_exchange_free(bcx, env)
+            })
+        }
+        _ => {
+            if ty::type_needs_drop(ccx.tcx, t) &&
+                ty::type_is_structural(t) {
+                iter_structural_ty(bcx, v0, t, drop_ty)
+            } else {
+                bcx
+            }
         }
-      }
-      ty::ty_closure(_) => {
-        closure::make_closure_glue(bcx, v0, t, drop_ty)
-      }
-      ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
-          let llbox_ptr = GEPi(bcx, v0, [0u, abi::trt_field_box]);
-          decr_refcnt_maybe_free(bcx, llbox_ptr, None)
-      }
-      ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
-          let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
-          // Only drop the value when it is non-null
-          with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
-              let llvtable = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable]));
-
-              // Cast the vtable to a pointer to a pointer to a tydesc.
-              let llvtable = PointerCast(bcx, llvtable,
-                                         ccx.tydesc_type.ptr_to().ptr_to());
-              let lltydesc = Load(bcx, llvtable);
-              call_tydesc_glue_full(bcx,
-                                    lluniquevalue,
-                                    lltydesc,
-                                    abi::tydesc_field_drop_glue,
-                                    None);
-              bcx
-          })
-      }
-      ty::ty_opaque_closure_ptr(ck) => {
-        closure::make_opaque_cbox_drop_glue(bcx, ck, v0)
-      }
-      _ => {
-        if ty::type_needs_drop(ccx.tcx, t) &&
-            ty::type_is_structural(t) {
-            iter_structural_ty(bcx, v0, t, drop_ty)
-        } else { bcx }
-      }
     }
 }
 
@@ -468,18 +454,19 @@ fn decr_refcnt_maybe_free<'a>(bcx: &'a Block<'a>, box_ptr_ptr: ValueRef,
     Store(decr_bcx, rc, rc_ptr);
     CondBr(decr_bcx, IsNull(decr_bcx, rc), free_bcx.llbb, next_bcx.llbb);
 
+    let v = Load(free_bcx, box_ptr_ptr);
+    let body = GEPi(free_bcx, v, [0u, abi::box_field_body]);
     let free_bcx = match t {
-        Some(t) => make_free_glue(free_bcx, box_ptr_ptr, t),
+        Some(t) => drop_ty(free_bcx, body, t),
         None => {
-            let v = Load(free_bcx, box_ptr_ptr);
-            let td = Load(free_bcx, GEPi(free_bcx, v, [0u, abi::box_field_tydesc]));
-            let valptr = GEPi(free_bcx, v, [0u, abi::box_field_body]);
             // Generate code that, dynamically, indexes into the
             // tydesc and calls the drop glue that got set dynamically
-            call_tydesc_glue_full(free_bcx, valptr, td, abi::tydesc_field_drop_glue, None);
-            trans_free(free_bcx, v)
+            let td = Load(free_bcx, GEPi(free_bcx, v, [0u, abi::box_field_tydesc]));
+            call_tydesc_glue_full(free_bcx, body, td, abi::tydesc_field_drop_glue, None);
+            free_bcx
         }
     };
+    let free_bcx = trans_free(free_bcx, v);
     Br(free_bcx, next_bcx.llbb);
 
     next_bcx
@@ -489,40 +476,39 @@ fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) -> &'a Block<'a
     let _icx = push_ctxt("make_take_glue");
     // NB: v is a *pointer* to type t here, not a direct value.
     match ty::get(t).sty {
-      ty::ty_box(_) |
-      ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
-        incr_refcnt_of_boxed(bcx, Load(bcx, v)); bcx
-      }
-      ty::ty_vec(_, ty::vstore_slice(_))
-      | ty::ty_str(ty::vstore_slice(_)) => {
-        bcx
-      }
-      ty::ty_closure(_) => bcx,
-      ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
-        let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]));
-        incr_refcnt_of_boxed(bcx, llbox);
-        bcx
-      }
-      ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
-          let lluniquevalue = GEPi(bcx, v, [0, abi::trt_field_box]);
-          let llvtable = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_vtable]));
-
-          // Cast the vtable to a pointer to a pointer to a tydesc.
-          let llvtable = PointerCast(bcx, llvtable,
-                                     bcx.ccx().tydesc_type.ptr_to().ptr_to());
-          let lltydesc = Load(bcx, llvtable);
-          call_tydesc_glue_full(bcx,
-                                lluniquevalue,
-                                lltydesc,
-                                abi::tydesc_field_take_glue,
-                                None);
-          bcx
-      }
-      ty::ty_opaque_closure_ptr(_) => bcx,
-      _ if ty::type_is_structural(t) => {
-        iter_structural_ty(bcx, v, t, take_ty)
-      }
-      _ => bcx
+        ty::ty_box(_) |
+        ty::ty_vec(_, ty::vstore_box) | ty::ty_str(ty::vstore_box) => {
+            incr_refcnt_of_boxed(bcx, Load(bcx, v)); bcx
+        }
+        ty::ty_vec(_, ty::vstore_slice(_))
+        | ty::ty_str(ty::vstore_slice(_)) => {
+            bcx
+        }
+        ty::ty_closure(_) => bcx,
+        ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
+            let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]));
+            incr_refcnt_of_boxed(bcx, llbox);
+            bcx
+        }
+        ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
+            let lluniquevalue = GEPi(bcx, v, [0, abi::trt_field_box]);
+            let llvtable = Load(bcx, GEPi(bcx, v, [0, abi::trt_field_vtable]));
+
+            // Cast the vtable to a pointer to a pointer to a tydesc.
+            let llvtable = PointerCast(bcx, llvtable,
+                                       bcx.ccx().tydesc_type.ptr_to().ptr_to());
+            let lltydesc = Load(bcx, llvtable);
+            call_tydesc_glue_full(bcx,
+                                  lluniquevalue,
+                                  lltydesc,
+                                  abi::tydesc_field_take_glue,
+                                  None);
+            bcx
+        }
+        _ if ty::type_is_structural(t) => {
+            iter_structural_ty(bcx, v, t, take_ty)
+        }
+        _ => bcx
     }
 }
 
@@ -595,7 +581,7 @@ fn make_generic_glue(ccx: @CrateContext, t: ty::t, llfn: ValueRef,
     let glue_name = format!("glue {} {}", name, ty_to_short_str(ccx.tcx, t));
     let _s = StatRecorder::new(ccx, glue_name);
 
-    let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None);
+    let fcx = new_fn_ctxt(ccx, ~[], llfn, false, ty::mk_nil(), None);
     init_function(&fcx, false, ty::mk_nil(), None);
 
     lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
index 98e3593a9f15f6f01d984a99010f9771b3f040ff..3a0b97813df50b19b135f925fe24a7fc690cdbbd 100644 (file)
@@ -14,7 +14,6 @@
 use middle::trans::base::{push_ctxt, trans_item, get_item_val, trans_fn};
 use middle::trans::common::*;
 use middle::ty;
-use util::ppaux::ty_to_str;
 
 use std::vec;
 use syntax::ast;
@@ -160,25 +159,7 @@ pub fn maybe_instantiate_inline(ccx: @CrateContext, fn_id: ast::DefId)
               let llfn = get_item_val(ccx, mth.id);
               let path = vec::append_one(
                   ty::item_path(ccx.tcx, impl_did), PathName(mth.ident));
-              let self_kind = match mth.explicit_self.node {
-                  ast::SelfStatic => None,
-                  _ => {
-                      let self_ty = ty::node_id_to_type(ccx.tcx,
-                                                        mth.self_id);
-                      debug!("calling inline trans_fn with self_ty {}",
-                             ty_to_str(ccx.tcx, self_ty));
-                      Some(self_ty)
-                  }
-              };
-              trans_fn(ccx,
-                       path,
-                       mth.decl,
-                       mth.body,
-                       llfn,
-                       self_kind,
-                       None,
-                       mth.id,
-                       []);
+              trans_fn(ccx, path, mth.decl, mth.body, llfn, None, mth.id, []);
           }
           local_def(mth.id)
         }
index fe2b3578a052f0024cfa4744d6211ac113c3d452..eb71f6b8f198d12699f8bc7c3b82b879e937da57 100644 (file)
@@ -153,13 +153,8 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
 
     let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id));
 
-    let fcx = new_fn_ctxt_detailed(ccx,
-                                   path,
-                                   decl,
-                                   item.id,
-                                   output_type,
-                                   Some(substs),
-                                   Some(item.span));
+    let fcx = new_fn_ctxt_detailed(ccx, path, decl, item.id, false, output_type,
+                                   Some(substs), Some(item.span));
     init_function(&fcx, true, output_type, Some(substs));
 
     set_always_inline(fcx.llfn);
@@ -420,7 +415,7 @@ fn count_zeros_intrinsic(bcx: &Block, name: &'static str) {
             // FIXME This is a hack to grab the address of this particular
             // native function. There should be a general in-language
             // way to do this
-            let llfty = type_of_rust_fn(bcx.ccx(), None, [], ty::mk_nil());
+            let llfty = type_of_rust_fn(bcx.ccx(), false, [], ty::mk_nil());
             let morestack_addr = decl_cdecl_fn(bcx.ccx().llmod, "__morestack",
                                                llfty, ty::mk_nil());
             let morestack_addr = PointerCast(bcx, morestack_addr,
index 338b487de46824d4d8ca008ade47262e9a01dbef..0301bbf5979abe8a7743ac19ca0519f57541aa0c 100644 (file)
@@ -51,7 +51,7 @@ pub fn trans_impl(ccx: @CrateContext,
                   methods: &[@ast::Method],
                   generics: &ast::Generics,
                   id: ast::NodeId) {
-    let _icx = push_ctxt("impl::trans_impl");
+    let _icx = push_ctxt("meth::trans_impl");
     let tcx = ccx.tcx;
 
     debug!("trans_impl(path={}, name={}, id={:?})",
@@ -73,11 +73,8 @@ pub fn trans_impl(ccx: @CrateContext,
             let path = vec::append_one(sub_path.clone(),
                                        PathName(method.ident));
 
-            trans_method(ccx,
-                         path,
-                         *method,
-                         None,
-                         |_| llfn);
+            trans_fn(ccx, path, method.decl, method.body,
+                     llfn, None, method.id, []);
         } else {
             let mut v = TransItemVisitor{ ccx: ccx };
             visit::walk_method_helper(&mut v, *method, ());
@@ -91,49 +88,15 @@ pub fn trans_impl(ccx: @CrateContext,
 /// * `path`: the path to the method
 /// * `method`: the AST node for the method
 /// * `param_substs`: if this is a generic method, the current values for
-///   type parameters and so forth, else none
-/// * `llfn`: a closure returning the LLVM ValueRef for the method
-/// * `impl_id`: the node ID of the impl this method is inside
+///   type parameters and so forth, else None
+/// * `llfn`: the LLVM ValueRef for the method
 ///
 /// FIXME(pcwalton) Can we take `path` by reference?
-pub fn trans_method(ccx: @CrateContext,
-                    path: Path,
-                    method: &ast::Method,
+pub fn trans_method(ccx: @CrateContext, path: Path, method: &ast::Method,
                     param_substs: Option<@param_substs>,
-                    llfn_with_self: |Option<ty::t>| -> ValueRef) -> ValueRef {
-    // figure out how self is being passed
-    let self_ty = match method.explicit_self.node {
-      ast::SelfStatic => None,
-      _ => {
-        // determine the (monomorphized) type that `self` maps to for
-        // this method
-        let self_ty = ty::node_id_to_type(ccx.tcx, method.self_id);
-        let self_ty = match param_substs {
-            None => self_ty,
-            Some(param_substs) => {
-                ty::subst_tps(ccx.tcx,
-                              param_substs.tys,
-                              param_substs.self_ty,
-                              self_ty)
-            }
-        };
-        debug!("calling trans_fn with self_ty {}", self_ty.repr(ccx.tcx));
-        Some(self_ty)
-      }
-    };
-
-    let llfn = llfn_with_self(self_ty);
-
-    // generate the actual code
-    trans_fn(ccx,
-             path,
-             method.decl,
-             method.body,
-             llfn,
-             self_ty,
-             param_substs,
-             method.id,
-             []);
+                    llfn: ValueRef) -> ValueRef {
+    trans_fn(ccx, path, method.decl, method.body,
+             llfn, param_substs, method.id, []);
     llfn
 }
 
@@ -144,31 +107,17 @@ pub fn trans_method_callee<'a>(
                            mentry: typeck::method_map_entry,
                            arg_cleanup_scope: cleanup::ScopeId)
                            -> Callee<'a> {
-    let _icx = push_ctxt("impl::trans_method_callee");
+    let _icx = push_ctxt("meth::trans_method_callee");
 
-    debug!("trans_method_callee(callee_id={:?}, this={}, mentry={})",
+    debug!("trans_method_callee(callee_id={:?}, mentry={})",
            callee_id,
-           bcx.expr_to_str(this),
            mentry.repr(bcx.tcx()));
 
     match mentry.origin {
         typeck::method_static(did) => {
-            let self_ty = monomorphize_type(bcx, mentry.self_ty);
-            let Result {bcx, val} = trans_arg_expr(bcx, self_ty, this,
-                                                   arg_cleanup_scope,
-                                                   DontAutorefArg);
-            // HACK should not need the pointer cast, eventually trans_fn_ref
-            // should return a function type with the right type for self.
-            let callee_fn = callee::trans_fn_ref(bcx, did, callee_id);
-            let fn_ty = node_id_type(bcx, callee_id);
-            let llfn_ty = type_of_fn_from_ty(bcx.ccx(), Some(self_ty), fn_ty).ptr_to();
-            let llfn_val = PointerCast(bcx, callee_fn.llfn, llfn_ty);
             Callee {
                 bcx: bcx,
-                data: Method(MethodData {
-                    llfn: llfn_val,
-                    llself: val,
-                })
+                data: Fn(callee::trans_fn_ref(bcx, did, callee_id))
             }
         }
         typeck::method_param(typeck::method_param {
@@ -184,9 +133,8 @@ pub fn trans_method_callee<'a>(
                         trait_id);
 
                     let vtbl = find_vtable(bcx.tcx(), substs, p, b);
-                    trans_monomorphized_callee(bcx, callee_id, this, mentry,
-                                               trait_id, off, vtbl,
-                                               arg_cleanup_scope)
+                    trans_monomorphized_callee(bcx, callee_id,
+                                               trait_id, off, vtbl)
                 }
                 // how to get rid of this?
                 None => fail!("trans_method_callee: missing param_substs")
@@ -207,8 +155,8 @@ pub fn trans_static_method_callee(bcx: &Block,
                                   method_id: ast::DefId,
                                   trait_id: ast::DefId,
                                   callee_id: ast::NodeId)
-                                  -> FnData {
-    let _icx = push_ctxt("impl::trans_static_method_callee");
+                                  -> ValueRef {
+    let _icx = push_ctxt("meth::trans_static_method_callee");
     let ccx = bcx.ccx();
 
     debug!("trans_static_method_callee(method_id={:?}, trait_id={}, \
@@ -271,16 +219,13 @@ pub fn trans_static_method_callee(bcx: &Block,
                     bcx, mth_id, callee_id,
                     *rcvr_substs, rcvr_origins);
 
-            let FnData {llfn: lval} =
-                trans_fn_ref_with_vtables(bcx,
-                                          mth_id,
-                                          callee_id,
-                                          callee_substs,
-                                          Some(callee_origins));
+            let llfn = trans_fn_ref_with_vtables(bcx, mth_id, callee_id,
+                                                 callee_substs,
+                                                 Some(callee_origins));
 
             let callee_ty = node_id_type(bcx, callee_id);
-            let llty = type_of_fn_from_ty(ccx, None, callee_ty).ptr_to();
-            FnData {llfn: PointerCast(bcx, lval, llty)}
+            let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to();
+            PointerCast(bcx, llfn, llty)
         }
         _ => {
             fail!("vtable_param left in monomorphized \
@@ -312,29 +257,19 @@ pub fn method_with_name(ccx: &CrateContext,
     meth.def_id
 }
 
-pub fn trans_monomorphized_callee<'a>(
-                                  bcx: &'a Block<'a>,
+fn trans_monomorphized_callee<'a>(bcx: &'a Block<'a>,
                                   callee_id: ast::NodeId,
-                                  base: &ast::Expr,
-                                  mentry: typeck::method_map_entry,
                                   trait_id: ast::DefId,
                                   n_method: uint,
-                                  vtbl: typeck::vtable_origin,
-                                  arg_cleanup_scope: cleanup::ScopeId)
+                                  vtbl: typeck::vtable_origin)
                                   -> Callee<'a> {
-    let _icx = push_ctxt("impl::trans_monomorphized_callee");
+    let _icx = push_ctxt("meth::trans_monomorphized_callee");
     return match vtbl {
       typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
           let ccx = bcx.ccx();
           let mname = ty::trait_method(ccx.tcx, trait_id, n_method).ident;
           let mth_id = method_with_name(bcx.ccx(), impl_did, mname.name);
 
-          // obtain the `self` value:
-          let self_ty = monomorphize_type(bcx, mentry.self_ty);
-          let Result {bcx, val} = trans_arg_expr(bcx, self_ty, base,
-                                                 arg_cleanup_scope,
-                                                 DontAutorefArg);
-
           // create a concatenated set of substitutions which includes
           // those from the impl and those from the method:
           let (callee_substs, callee_origins) =
@@ -343,26 +278,13 @@ pub fn trans_monomorphized_callee<'a>(
                   *rcvr_substs, rcvr_origins);
 
           // translate the function
-          let callee = trans_fn_ref_with_vtables(bcx,
-                                                 mth_id,
-                                                 callee_id,
-                                                 callee_substs,
-                                                 Some(callee_origins));
+          let llfn = trans_fn_ref_with_vtables(bcx,
+                                               mth_id,
+                                               callee_id,
+                                               callee_substs,
+                                               Some(callee_origins));
 
-          // create a llvalue that represents the fn ptr
-          // HACK should not need the pointer cast (add self in trans_fn_ref_with_vtables).
-          let fn_ty = node_id_type(bcx, callee_id);
-          let llfn_ty = type_of_fn_from_ty(ccx, Some(self_ty), fn_ty).ptr_to();
-          let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty);
-
-          // combine the self environment with the rest
-          Callee {
-              bcx: bcx,
-              data: Method(MethodData {
-                  llfn: llfn_val,
-                  llself: val,
-              })
-          }
+          Callee { bcx: bcx, data: Fn(llfn) }
       }
       typeck::vtable_param(..) => {
           fail!("vtable_param left in monomorphized function's vtable substs");
@@ -420,8 +342,7 @@ pub fn combine_impl_and_methods_tps(bcx: &Block,
     return (ty_substs, vtables);
 }
 
-pub fn trans_trait_callee<'a>(
-                          bcx: &'a Block<'a>,
+fn trans_trait_callee<'a>(bcx: &'a Block<'a>,
                           callee_id: ast::NodeId,
                           n_method: uint,
                           self_expr: &ast::Expr,
@@ -436,7 +357,7 @@ pub fn trans_trait_callee<'a>(
      * pair.
      */
 
-    let _icx = push_ctxt("impl::trans_trait_callee");
+    let _icx = push_ctxt("meth::trans_trait_callee");
     let mut bcx = bcx;
 
     // Translate self_datum and take ownership of the value by
@@ -469,18 +390,26 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
      * a by-ref pointer to the object pair.
      */
 
-    let _icx = push_ctxt("impl::trans_trait_callee");
+    let _icx = push_ctxt("meth::trans_trait_callee");
     let ccx = bcx.ccx();
 
     // Load the data pointer from the object.
     debug!("(translating trait callee) loading second index from pair");
     let llboxptr = GEPi(bcx, llpair, [0u, abi::trt_field_box]);
     let llbox = Load(bcx, llboxptr);
-    let llself = PointerCast(bcx, llbox, Type::opaque_box(ccx).ptr_to());
+    let llself = PointerCast(bcx, llbox, Type::i8p());
 
     // Load the function from the vtable and cast it to the expected type.
     debug!("(translating trait callee) loading method");
-    let llcallee_ty = type_of_fn_from_ty(ccx, None, callee_ty);
+    // Replace the self type (&Self or ~Self) with an opaque pointer.
+    let llcallee_ty = match ty::get(callee_ty).sty {
+        ty::ty_bare_fn(ref f) if f.abis.is_rust() => {
+            type_of_rust_fn(ccx, true, f.sig.inputs.slice_from(1), f.sig.output)
+        }
+        _ => {
+            ccx.sess.bug("meth::trans_trait_callee given non-bare-rust-fn");
+        }
+    };
     let llvtable = Load(bcx,
                         PointerCast(bcx,
                                     GEPi(bcx, llpair,
@@ -491,7 +420,7 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
 
     return Callee {
         bcx: bcx,
-        data: Method(MethodData {
+        data: TraitMethod(MethodData {
             llfn: mptr,
             llself: llself,
         })
@@ -528,7 +457,7 @@ pub fn get_vtable(bcx: &Block,
                   origins: typeck::vtable_param_res)
                   -> ValueRef {
     let ccx = bcx.ccx();
-    let _icx = push_ctxt("impl::get_vtable");
+    let _icx = push_ctxt("meth::get_vtable");
 
     // Check the cache.
     let hash_id = (self_ty, vtable_id(ccx, &origins[0]));
@@ -567,7 +496,7 @@ pub fn make_vtable(ccx: &CrateContext,
                    ptrs: &[ValueRef])
                    -> ValueRef {
     unsafe {
-        let _icx = push_ctxt("impl::make_vtable");
+        let _icx = push_ctxt("meth::make_vtable");
 
         let mut components = ~[ tydesc.tydesc ];
         for &ptr in ptrs.iter() {
@@ -618,8 +547,7 @@ fn emit_vtable_methods(bcx: &Block,
                    tcx.sess.str_of(ident));
             C_null(Type::nil().ptr_to())
         } else {
-            trans_fn_ref_with_vtables(bcx, m_id, 0,
-                                      substs, Some(vtables)).llfn
+            trans_fn_ref_with_vtables(bcx, m_id, 0, substs, Some(vtables))
         }
     })
 }
@@ -637,7 +565,7 @@ pub fn trans_trait_cast<'a>(bcx: &'a Block<'a>,
      */
 
     let mut bcx = bcx;
-    let _icx = push_ctxt("impl::trans_cast");
+    let _icx = push_ctxt("meth::trans_cast");
 
     let lldest = match dest {
         Ignore => {
index 5e3e323639422c5cc3c0bc45008183a39a17faab..678d23c0e1931348f04b372fc424be25efb9f60f 100644 (file)
@@ -213,8 +213,10 @@ pub fn monomorphic_fn(ccx: @CrateContext,
     let s = mangle_exported_name(ccx, pt.clone(), mono_ty);
     debug!("monomorphize_fn mangled to {}", s);
 
-    let mk_lldecl = |self_ty| {
-        let lldecl = decl_internal_rust_fn(ccx, self_ty, f.sig.inputs, f.sig.output, s);
+    let mk_lldecl = || {
+        let lldecl = decl_internal_rust_fn(ccx, false,
+                                           f.sig.inputs,
+                                           f.sig.output, s);
         let mut monomorphized = ccx.monomorphized.borrow_mut();
         monomorphized.get().insert(hash_id, lldecl);
         lldecl
@@ -227,17 +229,9 @@ pub fn monomorphic_fn(ccx: @CrateContext,
                 node: ast::ItemFn(decl, _, _, _, body),
                 ..
             } => {
-                let d = mk_lldecl(None);
+                let d = mk_lldecl();
                 set_llvm_fn_attrs(i.attrs, d);
-                trans_fn(ccx,
-                         pt,
-                         decl,
-                         body,
-                         d,
-                         None,
-                         Some(psubsts),
-                         fn_id.node,
-                         []);
+                trans_fn(ccx, pt, decl, body, d, Some(psubsts), fn_id.node, []);
                 d
             }
             _ => {
@@ -246,7 +240,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
           }
       }
       ast_map::NodeForeignItem(i, _, _, _) => {
-          let d = mk_lldecl(None);
+          let d = mk_lldecl();
           intrinsic::trans_intrinsic(ccx, d, i, pt, psubsts, i.attrs,
                                      ref_id);
           d
@@ -254,7 +248,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
       ast_map::NodeVariant(v, enum_item, _) => {
         let tvs = ty::enum_variants(ccx.tcx, local_def(enum_item.id));
         let this_tv = *tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
-        let d = mk_lldecl(None);
+        let d = mk_lldecl();
         set_inline_hint(d);
         match v.node.kind {
             ast::TupleVariantKind(ref args) => {
@@ -272,24 +266,19 @@ pub fn monomorphic_fn(ccx: @CrateContext,
         d
       }
       ast_map::NodeMethod(mth, _, _) => {
-        meth::trans_method(ccx, pt, mth, Some(psubsts), |self_ty| {
-            let d = mk_lldecl(self_ty);
-            set_llvm_fn_attrs(mth.attrs, d);
-            d
-        })
+        let d = mk_lldecl();
+        set_llvm_fn_attrs(mth.attrs, d);
+        trans_fn(ccx, pt, mth.decl, mth.body, d, Some(psubsts), mth.id, []);
+        d
       }
       ast_map::NodeTraitMethod(method, _, pt) => {
           match *method {
               ast::Provided(mth) => {
-                meth::trans_method(ccx,
-                                   (*pt).clone(),
-                                   mth,
-                                   Some(psubsts),
-                                   |self_ty| {
-                    let d = mk_lldecl(self_ty);
-                    set_llvm_fn_attrs(mth.attrs, d);
-                    d
-                })
+                  let d = mk_lldecl();
+                  set_llvm_fn_attrs(mth.attrs, d);
+                  trans_fn(ccx, (*pt).clone(), mth.decl, mth.body,
+                           d, Some(psubsts), mth.id, []);
+                  d
               }
               _ => {
                 ccx.tcx.sess.bug(format!("Can't monomorphize a {:?}",
@@ -298,7 +287,7 @@ pub fn monomorphic_fn(ccx: @CrateContext,
           }
       }
       ast_map::NodeStructCtor(struct_def, _, _) => {
-        let d = mk_lldecl(None);
+        let d = mk_lldecl();
         set_inline_hint(d);
         base::trans_tuple_struct(ccx,
                                  struct_def.fields,
index c13bb139da759482736df9793ddd8504307734d5..46086828329242183619feb6daa7daa489667cea 100644 (file)
@@ -13,7 +13,7 @@
 use middle::trans::adt;
 use middle::trans::base::*;
 use middle::trans::build::*;
-use middle::trans::callee::{ArgVals, DontAutorefArg};
+use middle::trans::callee::ArgVals;
 use middle::trans::callee;
 use middle::trans::common::*;
 use middle::trans::datum::*;
@@ -111,7 +111,7 @@ pub fn visit(&mut self, ty_name: &str, args: &[ValueRef]) {
                                                          mth_ty,
                                                          mth_idx,
                                                          v),
-            ArgVals(args), None, DontAutorefArg));
+            ArgVals(args), None));
         let result = bool_to_i1(bcx, result);
         let next_bcx = fcx.new_temp_block("next");
         CondBr(bcx, result, next_bcx.llbb, self.final_bcx.llbb);
@@ -292,12 +292,10 @@ pub fn visit_ty(&mut self, t: ty::t) {
                                                                sub_path,
                                                                "get_disr");
 
-                let llfdecl = decl_internal_rust_fn(ccx, None, [opaqueptrty], ty::mk_u64(), sym);
-                let fcx = new_fn_ctxt(ccx,
-                                      ~[],
-                                      llfdecl,
-                                      ty::mk_u64(),
-                                      None);
+                let llfdecl = decl_internal_rust_fn(ccx, false,
+                                                    [opaqueptrty],
+                                                    ty::mk_u64(), sym);
+                let fcx = new_fn_ctxt(ccx, ~[], llfdecl, false, ty::mk_u64(), None);
                 init_function(&fcx, false, ty::mk_u64(), None);
 
                 let arg = unsafe {
@@ -358,12 +356,7 @@ pub fn visit_ty(&mut self, t: ty::t) {
               self.visit("param", extra)
           }
           ty::ty_self(..) => self.leaf("self"),
-          ty::ty_type => self.leaf("type"),
-          ty::ty_opaque_closure_ptr(ck) => {
-              let ckval = ast_sigil_constant(ck);
-              let extra = ~[self.c_uint(ckval)];
-              self.visit("closure_ptr", extra)
-          }
+          ty::ty_type => self.leaf("type")
         }
     }
 
index 833a7848ad316a0f16cc11e34d9eb43ce58ba819..bbaf94afabe8cee95829596804c2532358d8f8dd 100644 (file)
@@ -160,10 +160,6 @@ pub fn variadic_func(args: &[Type], ret: &Type) -> Type {
                                    args.len() as c_uint, True))
     }
 
-    pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> Type {
-        Type::struct_([fn_ty.ptr_to(), Type::opaque_cbox_ptr(cx)], false)
-    }
-
     pub fn ptr(ty: Type) -> Type {
         ty!(llvm::LLVMPointerType(ty.to_ref(), 0 as c_uint))
     }
@@ -200,8 +196,7 @@ pub fn generic_glue_fn(cx: &CrateContext) -> Type {
     }
 
     pub fn glue_fn(t: Type) -> Type {
-        Type::func([ Type::nil().ptr_to(), t ],
-            &Type::void())
+        Type::func([t], &Type::void())
     }
 
     pub fn tydesc(arch: Architecture) -> Type {
@@ -213,7 +208,6 @@ pub fn tydesc(arch: Architecture) -> Type {
         // Must mirror:
         //
         // std::unstable::intrinsics::TyDesc
-        // type_desc in rt
 
         let elems = [int_ty,     // size
                      int_ty,     // align
@@ -244,38 +238,18 @@ pub fn opaque_vec(arch: Architecture) -> Type {
         Type::vec(arch, &Type::i8())
     }
 
-    #[inline]
-    pub fn box_header_fields(ctx: &CrateContext) -> ~[Type] {
-        ~[
+    // The box pointed to by @T.
+    pub fn at_box(ctx: &CrateContext, ty: Type) -> Type {
+        Type::struct_([
             ctx.int_type, ctx.tydesc_type.ptr_to(),
-            Type::i8().ptr_to(), Type::i8().ptr_to()
-        ]
-    }
-
-    pub fn box_header(ctx: &CrateContext) -> Type {
-        Type::struct_(Type::box_header_fields(ctx), false)
-    }
-
-    pub fn smart_ptr(ctx: &CrateContext, ty: &Type) -> Type {
-        Type::struct_(Type::box_header_fields(ctx) + &[*ty], false)
-    }
-
-    pub fn opaque() -> Type {
-        Type::i8()
-    }
-
-    pub fn opaque_box(ctx: &CrateContext) -> Type {
-        Type::smart_ptr(ctx, &Type::opaque())
-    }
-
-    pub fn opaque_cbox_ptr(cx: &CrateContext) -> Type {
-        Type::opaque_box(cx).ptr_to()
+            Type::i8p(), Type::i8p(), ty
+        ], false)
     }
 
     pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type {
         let tydesc_ptr = ctx.tydesc_type.ptr_to();
         let box_ty = match store {
-            ty::BoxTraitStore => Type::opaque_box(ctx),
+            ty::BoxTraitStore => Type::at_box(ctx, Type::i8()),
             ty::UniqTraitStore => Type::i8(),
             ty::RegionTraitStore(..) => Type::i8()
         };
index 4db89fbeccec7497d20f810f66edf8a4efeb6a8c..a4228fbd17b3db731e4d2d953e9efba90ebec34a 100644 (file)
@@ -38,15 +38,8 @@ pub fn type_of_explicit_arg(ccx: &CrateContext, arg_ty: ty::t) -> Type {
     }
 }
 
-pub fn type_of_explicit_args(ccx: &CrateContext,
-                             inputs: &[ty::t]) -> ~[Type] {
-    inputs.map(|&arg_ty| type_of_explicit_arg(ccx, arg_ty))
-}
-
-pub fn type_of_rust_fn(cx: &CrateContext,
-                       self_ty: Option<ty::t>,
-                       inputs: &[ty::t],
-                       output: ty::t) -> Type {
+pub fn type_of_rust_fn(cx: &CrateContext, has_env: bool,
+                       inputs: &[ty::t], output: ty::t) -> Type {
     let mut atys: ~[Type] = ~[];
 
     // Arg 0: Output pointer.
@@ -58,14 +51,13 @@ pub fn type_of_rust_fn(cx: &CrateContext,
     }
 
     // Arg 1: Environment
-    let env = match self_ty {
-        Some(t) => type_of_explicit_arg(cx, t),
-        None => Type::opaque_box(cx).ptr_to()
-    };
-    atys.push(env);
+    if has_env {
+        atys.push(Type::i8p());
+    }
 
     // ... then explicit args.
-    atys.push_all(type_of_explicit_args(cx, inputs));
+    let mut input_tys = inputs.iter().map(|&arg_ty| type_of_explicit_arg(cx, arg_ty));
+    atys.extend(&mut input_tys);
 
     // Use the output as the actual return value if it's immediate.
     if use_out_pointer || return_type_is_void(cx, output) {
@@ -76,14 +68,14 @@ pub fn type_of_rust_fn(cx: &CrateContext,
 }
 
 // Given a function type and a count of ty params, construct an llvm type
-pub fn type_of_fn_from_ty(cx: &CrateContext, self_ty: Option<ty::t>, fty: ty::t) -> Type {
-    return match ty::get(fty).sty {
+pub fn type_of_fn_from_ty(cx: &CrateContext, fty: ty::t) -> Type {
+    match ty::get(fty).sty {
         ty::ty_closure(ref f) => {
-            type_of_rust_fn(cx, None, f.sig.inputs, f.sig.output)
+            type_of_rust_fn(cx, true, f.sig.inputs, f.sig.output)
         }
         ty::ty_bare_fn(ref f) => {
             if f.abis.is_rust() || f.abis.is_intrinsic() {
-                type_of_rust_fn(cx, self_ty, f.sig.inputs, f.sig.output)
+                type_of_rust_fn(cx, false, f.sig.inputs, f.sig.output)
             } else {
                 foreign::lltype_for_foreign_fn(cx, fty)
             }
@@ -91,7 +83,7 @@ pub fn type_of_fn_from_ty(cx: &CrateContext, self_ty: Option<ty::t>, fty: ty::t)
         _ => {
             cx.sess.bug("type_of_fn_from_ty given non-closure, non-bare-fn")
         }
-    };
+    }
 }
 
 // A "sizing type" is an LLVM type, the size and alignment of which are
@@ -130,8 +122,7 @@ pub fn sizing_type_of(cx: &CrateContext, t: ty::t) -> Type {
         ty::ty_uniq(..) |
         ty::ty_ptr(..) |
         ty::ty_rptr(..) |
-        ty::ty_type |
-        ty::ty_opaque_closure_ptr(..) => Type::i8p(),
+        ty::ty_type => Type::i8p(),
 
         ty::ty_str(ty::vstore_slice(..)) |
         ty::ty_vec(_, ty::vstore_slice(..)) => {
@@ -231,18 +222,14 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
         adt::incomplete_type_of(cx, repr, name)
       }
       ty::ty_str(ty::vstore_box) => {
-        Type::smart_ptr(cx,
-                        &Type::vec(cx.sess.targ_cfg.arch,
-                                   &Type::i8())).ptr_to()
+          Type::at_box(cx, Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to()
       }
       ty::ty_vec(ref mt, ty::vstore_box) => {
           let e_ty = type_of(cx, mt.ty);
-          let v_ty = Type::vec(cx.sess.targ_cfg.arch, &e_ty);
-          Type::smart_ptr(cx, &v_ty).ptr_to()
+          Type::at_box(cx, Type::vec(cx.sess.targ_cfg.arch, &e_ty)).ptr_to()
       }
       ty::ty_box(typ) => {
-          let ty = type_of(cx, typ);
-          Type::smart_ptr(cx, &ty).ptr_to()
+          Type::at_box(cx, type_of(cx, typ)).ptr_to()
       }
       ty::ty_uniq(typ) => {
           type_of(cx, typ).ptr_to()
@@ -278,11 +265,11 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
       }
 
       ty::ty_bare_fn(_) => {
-          type_of_fn_from_ty(cx, None, t).ptr_to()
+          type_of_fn_from_ty(cx, t).ptr_to()
       }
       ty::ty_closure(_) => {
-          let ty = type_of_fn_from_ty(cx, None, t);
-          Type::func_pair(cx, &ty)
+          let fn_ty = type_of_fn_from_ty(cx, t).ptr_to();
+          Type::struct_([fn_ty, Type::i8p()], false)
       }
       ty::ty_trait(_, _, store, _, _) => Type::opaque_trait(cx, store),
       ty::ty_type => cx.tydesc_type.ptr_to(),
@@ -290,7 +277,6 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type {
           let repr = adt::represent_type(cx, t);
           adt::type_of(cx, repr)
       }
-      ty::ty_opaque_closure_ptr(_) => Type::opaque_box(cx).ptr_to(),
       ty::ty_struct(did, ref substs) => {
           if ty::type_is_simd(cx.tcx, t) {
               let et = ty::simd_type(cx.tcx, t);
index 5b038d3c9444dbaef0175834f0159dcc9d73cfc3..a31b8413550a789a985cdc9d0cb49425d5f54276 100644 (file)
@@ -73,7 +73,6 @@ pub enum MethodContainer {
 pub struct Method {
     ident: ast::Ident,
     generics: ty::Generics,
-    transformed_self_ty: Option<ty::t>,
     fty: BareFnTy,
     explicit_self: ast::ExplicitSelf_,
     vis: ast::Visibility,
@@ -87,7 +86,6 @@ pub struct Method {
 impl Method {
     pub fn new(ident: ast::Ident,
                generics: ty::Generics,
-               transformed_self_ty: Option<ty::t>,
                fty: BareFnTy,
                explicit_self: ast::ExplicitSelf_,
                vis: ast::Visibility,
@@ -95,17 +93,9 @@ pub fn new(ident: ast::Ident,
                container: MethodContainer,
                provided_source: Option<ast::DefId>)
                -> Method {
-        // Check the invariants.
-        if explicit_self == ast::SelfStatic {
-            assert!(transformed_self_ty.is_none());
-        } else {
-            assert!(transformed_self_ty.is_some());
-        }
-
        Method {
             ident: ident,
             generics: generics,
-            transformed_self_ty: transformed_self_ty,
             fty: fty,
             explicit_self: explicit_self,
             vis: vis,
@@ -650,7 +640,6 @@ pub enum sty {
 
     // "Fake" types, used for trans purposes
     ty_type, // type_desc*
-    ty_opaque_closure_ptr(Sigil), // ptr to env for || and proc
     ty_unboxed_vec(mt),
 }
 
@@ -1068,7 +1057,7 @@ fn sflags(substs: &substs) -> uint {
         flags |= get(mt.ty).flags;
       }
       &ty_nil | &ty_bool | &ty_char | &ty_int(_) | &ty_float(_) | &ty_uint(_) |
-      &ty_str(_) | &ty_type | &ty_opaque_closure_ptr(_) => {}
+      &ty_str(_) | &ty_type => {}
       // You might think that we could just return ty_err for
       // any type containing ty_err as a component, and get
       // rid of the has_ty_err flag -- likewise for ty_bot (with
@@ -1333,10 +1322,6 @@ pub fn mk_param(cx: ctxt, n: uint, k: DefId) -> t {
 
 pub fn mk_type(cx: ctxt) -> t { mk_t(cx, ty_type) }
 
-pub fn mk_opaque_closure_ptr(cx: ctxt, sigil: ast::Sigil) -> t {
-    mk_t(cx, ty_opaque_closure_ptr(sigil))
-}
-
 pub fn walk_ty(ty: t, f: |t|) {
     maybe_walk_ty(ty, |t| { f(t); true });
 }
@@ -1346,27 +1331,27 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
         return;
     }
     match get(ty).sty {
-      ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
-      ty_str(_) | ty_type | ty_self(_) |
-      ty_opaque_closure_ptr(_) | ty_infer(_) | ty_param(_) | ty_err => {}
-      ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
-      ty_vec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) |
-      ty_rptr(_, ref tm) => {
-        maybe_walk_ty(tm.ty, f);
-      }
-      ty_enum(_, ref substs) | ty_struct(_, ref substs) |
-      ty_trait(_, ref substs, _, _, _) => {
-        for subty in (*substs).tps.iter() { maybe_walk_ty(*subty, |x| f(x)); }
-      }
-      ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } }
-      ty_bare_fn(ref ft) => {
-        for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
-        maybe_walk_ty(ft.sig.output, f);
-      }
-      ty_closure(ref ft) => {
-        for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
-        maybe_walk_ty(ft.sig.output, f);
-      }
+        ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
+        ty_str(_) | ty_type | ty_self(_) |
+        ty_infer(_) | ty_param(_) | ty_err => {}
+        ty_box(ty) | ty_uniq(ty) => maybe_walk_ty(ty, f),
+        ty_vec(ref tm, _) | ty_unboxed_vec(ref tm) | ty_ptr(ref tm) |
+        ty_rptr(_, ref tm) => {
+            maybe_walk_ty(tm.ty, f);
+        }
+        ty_enum(_, ref substs) | ty_struct(_, ref substs) |
+        ty_trait(_, ref substs, _, _, _) => {
+            for subty in (*substs).tps.iter() { maybe_walk_ty(*subty, |x| f(x)); }
+        }
+        ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } }
+        ty_bare_fn(ref ft) => {
+            for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
+            maybe_walk_ty(ft.sig.output, f);
+        }
+        ty_closure(ref ft) => {
+            for a in ft.sig.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
+            maybe_walk_ty(ft.sig.output, f);
+        }
     }
 }
 
@@ -1608,11 +1593,8 @@ pub fn type_is_vec(ty: t) -> bool {
 
 pub fn type_is_unique(ty: t) -> bool {
     match get(ty).sty {
-        ty_uniq(_) |
-        ty_vec(_, vstore_uniq) |
-        ty_str(vstore_uniq) |
-        ty_opaque_closure_ptr(ast::OwnedSigil) => true,
-        _ => return false
+        ty_uniq(_) | ty_vec(_, vstore_uniq) | ty_str(vstore_uniq) => true,
+        _ => false
     }
 }
 
@@ -2118,13 +2100,6 @@ fn tc_ty(cx: ctxt,
                 TC::All
             }
             ty_unboxed_vec(mt) => TC::InteriorUnsized | tc_mt(cx, mt, cache),
-            ty_opaque_closure_ptr(sigil) => {
-                match sigil {
-                    ast::BorrowedSigil => TC::ReachesBorrowed,
-                    ast::ManagedSigil => TC::Managed,
-                    ast::OwnedSigil => TC::OwnsOwned,
-                }
-            }
 
             ty_type => TC::None,
 
@@ -2308,7 +2283,6 @@ fn subtypes_require(cx: ctxt, seen: &mut ~[DefId],
             ty_param(_) |
             ty_self(_) |
             ty_type |
-            ty_opaque_closure_ptr(_) |
             ty_vec(_, _) |
             ty_unboxed_vec(_) => {
                 false
@@ -2511,7 +2485,6 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
         result = type_is_pod(cx, mt.ty);
       }
       ty_param(_) => result = false,
-      ty_opaque_closure_ptr(_) => result = true,
       ty_struct(did, ref substs) => {
         let fields = lookup_struct_fields(cx, did);
         result = fields.iter().all(|f| {
@@ -3139,22 +3112,37 @@ pub fn expr_kind(tcx: ctxt,
     }
 
     match expr.node {
-        ast::ExprPath(..) | ast::ExprSelf => {
+        ast::ExprPath(..) => {
             match resolve_expr(tcx, expr) {
-                ast::DefVariant(..) | ast::DefStruct(..) => RvalueDpsExpr,
+                ast::DefVariant(tid, vid, _) => {
+                    let variant_info = enum_variant_with_id(tcx, tid, vid);
+                    if variant_info.args.len() > 0u {
+                        // N-ary variant.
+                        RvalueDatumExpr
+                    } else {
+                        // Nullary variant.
+                        RvalueDpsExpr
+                    }
+                }
+
+                ast::DefStruct(_) => {
+                    match get(expr_ty(tcx, expr)).sty {
+                        ty_bare_fn(..) => RvalueDatumExpr,
+                        _ => RvalueDpsExpr
+                    }
+                }
 
                 // Fn pointers are just scalar values.
                 ast::DefFn(..) | ast::DefStaticMethod(..) => RvalueDatumExpr,
 
                 // Note: there is actually a good case to be made that
-                // def_args, particularly those of immediate type, ought to
+                // DefArg's, particularly those of immediate type, ought to
                 // considered rvalues.
                 ast::DefStatic(..) |
                 ast::DefBinding(..) |
                 ast::DefUpvar(..) |
                 ast::DefArg(..) |
-                ast::DefLocal(..) |
-                ast::DefSelf(..) => LvalueExpr,
+                ast::DefLocal(..) => LvalueExpr,
 
                 def => {
                     tcx.sess.span_bug(expr.span, format!(
@@ -3343,30 +3331,29 @@ fn vars_in_type(ty: t) -> ~[TyVid] {
 
 pub fn ty_sort_str(cx: ctxt, t: t) -> ~str {
     match get(t).sty {
-      ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
-      ty_uint(_) | ty_float(_) | ty_str(_) |
-      ty_type | ty_opaque_closure_ptr(_) => {
-        ::util::ppaux::ty_to_str(cx, t)
-      }
-
-      ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
-      ty_box(_) => ~"@-ptr",
-      ty_uniq(_) => ~"~-ptr",
-      ty_vec(_, _) => ~"vector",
-      ty_unboxed_vec(_) => ~"unboxed vector",
-      ty_ptr(_) => ~"*-ptr",
-      ty_rptr(_, _) => ~"&-ptr",
-      ty_bare_fn(_) => ~"extern fn",
-      ty_closure(_) => ~"fn",
-      ty_trait(id, _, _, _, _) => format!("trait {}", item_path_str(cx, id)),
-      ty_struct(id, _) => format!("struct {}", item_path_str(cx, id)),
-      ty_tup(_) => ~"tuple",
-      ty_infer(TyVar(_)) => ~"inferred type",
-      ty_infer(IntVar(_)) => ~"integral variable",
-      ty_infer(FloatVar(_)) => ~"floating-point variable",
-      ty_param(_) => ~"type parameter",
-      ty_self(_) => ~"self",
-      ty_err => ~"type error"
+        ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
+        ty_uint(_) | ty_float(_) | ty_str(_) | ty_type => {
+            ::util::ppaux::ty_to_str(cx, t)
+        }
+
+        ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
+        ty_box(_) => ~"@-ptr",
+        ty_uniq(_) => ~"~-ptr",
+        ty_vec(_, _) => ~"vector",
+        ty_unboxed_vec(_) => ~"unboxed vector",
+        ty_ptr(_) => ~"*-ptr",
+        ty_rptr(_, _) => ~"&-ptr",
+        ty_bare_fn(_) => ~"extern fn",
+        ty_closure(_) => ~"fn",
+        ty_trait(id, _, _, _, _) => format!("trait {}", item_path_str(cx, id)),
+        ty_struct(id, _) => format!("struct {}", item_path_str(cx, id)),
+        ty_tup(_) => ~"tuple",
+        ty_infer(TyVar(_)) => ~"inferred type",
+        ty_infer(IntVar(_)) => ~"integral variable",
+        ty_infer(FloatVar(_)) => ~"floating-point variable",
+        ty_param(_) => ~"type parameter",
+        ty_self(_) => ~"self",
+        ty_err => ~"type error"
     }
 }
 
@@ -4912,12 +4899,8 @@ fn iter<T: IterBytes>(hash: &mut SipState, t: &T) {
             ty_infer(_) => unreachable!(),
             ty_err => hash.input([23]),
             ty_type => hash.input([24]),
-            ty_opaque_closure_ptr(s) => {
-                hash.input([25]);
-                iter(&mut hash, &s);
-            }
             ty_unboxed_vec(m) => {
-                hash.input([26]);
+                hash.input([25]);
                 mt(&mut hash, m);
             }
         }
index 28ba566c0a4ab5063594303b8a2a03ea3d69e8e3..e322792c996802f273f72a8c6a76338e9b3a043f 100644 (file)
@@ -189,7 +189,6 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
         ty::ty_nil | ty::ty_bot | ty::ty_bool | ty::ty_char |
         ty::ty_int(_) | ty::ty_uint(_) |
         ty::ty_float(_) | ty::ty_type |
-        ty::ty_opaque_closure_ptr(_) |
         ty::ty_err | ty::ty_infer(_) |
         ty::ty_param(..) | ty::ty_self(_) => {
             (*sty).clone()
index 2e25ac941a66dda43031b72dc07eb7c6864b7a67..f1e1f379b0c5e0d691bce69b431aa2b2f628913f 100644 (file)
@@ -589,13 +589,8 @@ fn check_path_args(tcx: ty::ctxt,
     return typ;
 }
 
-pub fn ty_of_arg<AC:AstConv,
-                 RS:RegionScope>(
-                 this: &AC,
-                 rscope: &RS,
-                 a: &ast::Arg,
-                 expected_ty: Option<ty::t>)
-                 -> ty::t {
+pub fn ty_of_arg<AC: AstConv, RS: RegionScope>(this: &AC, rscope: &RS, a: &ast::Arg,
+                                               expected_ty: Option<ty::t>) -> ty::t {
     match a.ty.node {
         ast::TyInfer if expected_ty.is_some() => expected_ty.unwrap(),
         ast::TyInfer => this.ty_infer(a.ty.span),
@@ -614,77 +609,38 @@ pub fn ty_of_method<AC:AstConv>(
     purity: ast::Purity,
     untransformed_self_ty: ty::t,
     explicit_self: ast::ExplicitSelf,
-    decl: &ast::FnDecl) -> (Option<ty::t>, ty::BareFnTy)
-{
-    let self_info = SelfInfo {
+    decl: &ast::FnDecl) -> ty::BareFnTy {
+    ty_of_method_or_bare_fn(this, id, purity, AbiSet::Rust(), Some(SelfInfo {
         untransformed_self_ty: untransformed_self_ty,
         explicit_self: explicit_self
-    };
-    let (a, b) = ty_of_method_or_bare_fn(
-        this, id, purity, AbiSet::Rust(), Some(&self_info), decl);
-    (a.unwrap(), b)
+    }), decl)
 }
 
-pub fn ty_of_bare_fn<AC:AstConv>(
-    this: &AC,
-    id: ast::NodeId,
-    purity: ast::Purity,
-    abi: AbiSet,
-    decl: &ast::FnDecl) -> ty::BareFnTy
-{
-    let (_, b) = ty_of_method_or_bare_fn(this, id, purity,
-                                         abi, None, decl);
-    b
+pub fn ty_of_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
+                                 purity: ast::Purity, abi: AbiSet,
+                                 decl: &ast::FnDecl) -> ty::BareFnTy {
+    ty_of_method_or_bare_fn(this, id, purity, abi, None, decl)
 }
 
-fn ty_of_method_or_bare_fn<AC:AstConv>(
-    this: &AC,
-    id: ast::NodeId,
-    purity: ast::Purity,
-    abi: AbiSet,
-    opt_self_info: Option<&SelfInfo>,
-    decl: &ast::FnDecl) -> (Option<Option<ty::t>>, ty::BareFnTy)
-{
+fn ty_of_method_or_bare_fn<AC:AstConv>(this: &AC, id: ast::NodeId,
+                                       purity: ast::Purity, abi: AbiSet,
+                                       opt_self_info: Option<SelfInfo>,
+                                       decl: &ast::FnDecl) -> ty::BareFnTy {
     debug!("ty_of_method_or_bare_fn");
 
     // new region names that appear inside of the fn decl are bound to
     // that function type
     let rb = rscope::BindingRscope::new(id);
 
-    let opt_transformed_self_ty = opt_self_info.map(|self_info| {
-        transform_self_ty(this, &rb, self_info)
-    });
-
-    let input_tys = decl.inputs.map(|a| ty_of_arg(this, &rb, a, None));
-
-    let output_ty = match decl.output.node {
-        ast::TyInfer => this.ty_infer(decl.output.span),
-        _ => ast_ty_to_ty(this, &rb, decl.output)
-    };
-
-    return (opt_transformed_self_ty,
-            ty::BareFnTy {
-                purity: purity,
-                abis: abi,
-                sig: ty::FnSig {binder_id: id,
-                                inputs: input_tys,
-                                output: output_ty,
-                                variadic: decl.variadic}
-            });
-
-    fn transform_self_ty<AC:AstConv,RS:RegionScope>(
-        this: &AC,
-        rscope: &RS,
-        self_info: &SelfInfo) -> Option<ty::t>
-    {
+    let self_ty = opt_self_info.and_then(|self_info| {
         match self_info.explicit_self.node {
             ast::SelfStatic => None,
-            ast::SelfValue(_) => {
+            ast::SelfValue => {
                 Some(self_info.untransformed_self_ty)
             }
             ast::SelfRegion(ref lifetime, mutability) => {
                 let region =
-                    opt_ast_region_to_region(this, rscope,
+                    opt_ast_region_to_region(this, &rb,
                                              self_info.explicit_self.span,
                                              lifetime);
                 Some(ty::mk_rptr(this.tcx(), region,
@@ -694,11 +650,37 @@ fn transform_self_ty<AC:AstConv,RS:RegionScope>(
             ast::SelfBox => {
                 Some(ty::mk_box(this.tcx(), self_info.untransformed_self_ty))
             }
-            ast::SelfUniq(_) => {
+            ast::SelfUniq => {
                 Some(ty::mk_uniq(this.tcx(), self_info.untransformed_self_ty))
             }
         }
-    }
+    });
+
+    // HACK(eddyb) replace the fake self type in the AST with the actual type.
+    let input_tys = if self_ty.is_some() {
+        decl.inputs.slice_from(1)
+    } else {
+        decl.inputs.as_slice()
+    };
+    let input_tys = input_tys.iter().map(|a| ty_of_arg(this, &rb, a, None));
+
+    let self_and_input_tys = self_ty.move_iter().chain(input_tys).collect();
+
+    let output_ty = match decl.output.node {
+        ast::TyInfer => this.ty_infer(decl.output.span),
+        _ => ast_ty_to_ty(this, &rb, decl.output)
+    };
+
+    return ty::BareFnTy {
+        purity: purity,
+        abis: abi,
+        sig: ty::FnSig {
+            binder_id: id,
+            inputs: self_and_input_tys,
+            output: output_ty,
+            variadic: decl.variadic
+        }
+    };
 }
 
 pub fn ty_of_closure<AC:AstConv,RS:RegionScope>(
index 002dd0c002aa4f8301b6845098b17b5adb63a2b9..398b4cca015b4e0bbb9f6ecb4a2505475edf23ae 100644 (file)
@@ -80,6 +80,7 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
 */
 
 
+use middle::subst::Subst;
 use middle::resolve;
 use middle::ty::*;
 use middle::ty;
@@ -422,19 +423,16 @@ fn push_inherent_candidates_from_object(&self,
             |new_trait_ref, m, method_num, _bound_num| {
             let vtable_index =
                 self.get_method_index(new_trait_ref, trait_ref, method_num);
+            let mut m = (*m).clone();
             // We need to fix up the transformed self type.
-            let transformed_self_ty =
+            m.fty.sig.inputs[0] =
                 self.construct_transformed_self_ty_for_object(
-                    did, &rcvr_substs, m);
-            let m = @Method {
-                transformed_self_ty: Some(transformed_self_ty),
-                .. (*m).clone()
-            };
+                    did, &rcvr_substs, &m);
 
             Candidate {
                 rcvr_match_condition: RcvrMatchesIfObject(did),
                 rcvr_substs: new_trait_ref.substs.clone(),
-                method_ty: m,
+                method_ty: @m,
                 origin: method_object(method_object {
                         trait_id: new_trait_ref.def_id,
                         object_trait_id: did,
@@ -790,8 +788,7 @@ fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
 
             ty_err => None,
 
-            ty_opaque_closure_ptr(_) | ty_unboxed_vec(_) |
-            ty_type | ty_infer(TyVar(_)) => {
+            ty_unboxed_vec(_) | ty_type | ty_infer(TyVar(_)) => {
                 self.bug(format!("Unexpected type: {}",
                               self.ty_to_str(self_ty)));
             }
@@ -932,32 +929,25 @@ fn merge_candidates(&self, candidates: &[Candidate]) -> ~[Candidate] {
 
     fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
                              -> method_map_entry {
+        // This method performs two sets of substitutions, one after the other:
+        // 1. Substitute values for any type/lifetime parameters from the impl and
+        //    method declaration into the method type. This is the function type
+        //    before it is called; it may still include late bound region variables.
+        // 2. Instantiate any late bound lifetime parameters in the method itself
+        //    with fresh region variables.
+
         let tcx = self.tcx();
-        let fty = ty::mk_bare_fn(tcx, candidate.method_ty.fty.clone());
 
-        debug!("confirm_candidate(expr={}, candidate={}, fty={})",
+        debug!("confirm_candidate(expr={}, candidate={})",
                self.expr.repr(tcx),
-               self.cand_to_str(candidate),
-               self.ty_to_str(fty));
+               self.cand_to_str(candidate));
 
-        self.enforce_object_limitations(fty, candidate);
+        self.enforce_object_limitations(candidate);
         self.enforce_drop_trait_limitations(candidate);
 
         // static methods should never have gotten this far:
         assert!(candidate.method_ty.explicit_self != SelfStatic);
 
-        let transformed_self_ty = match candidate.origin {
-            method_object(..) => {
-                // For annoying reasons, we've already handled the
-                // substitution for object calls.
-                candidate.method_ty.transformed_self_ty.unwrap()
-            }
-            _ => {
-                ty::subst(tcx, &candidate.rcvr_substs,
-                          candidate.method_ty.transformed_self_ty.unwrap())
-            }
-        };
-
         // Determine the values for the type parameters of the method.
         // If they were not explicitly supplied, just construct fresh
         // type variables.
@@ -990,29 +980,41 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
             self_ty: candidate.rcvr_substs.self_ty,
         };
 
+        let ref bare_fn_ty = candidate.method_ty.fty;
+
         // Compute the method type with type parameters substituted
         debug!("fty={} all_substs={}",
-               self.ty_to_str(fty),
+               bare_fn_ty.repr(tcx),
                ty::substs_to_str(tcx, &all_substs));
-        let fty = ty::subst(tcx, &all_substs, fty);
-        debug!("after subst, fty={}", self.ty_to_str(fty));
 
-        // Replace any bound regions that appear in the function
-        // signature with region variables
-        let bare_fn_ty = match ty::get(fty).sty {
-            ty::ty_bare_fn(ref f) => f,
-            ref s => {
-                tcx.sess.span_bug(
-                    self.expr.span,
-                    format!("Invoking method with non-bare-fn ty: {:?}", s));
+        let fn_sig = &bare_fn_ty.sig;
+        let inputs = match candidate.origin {
+            method_object(..) => {
+                // For annoying reasons, we've already handled the
+                // substitution of self for object calls.
+                let args = fn_sig.inputs.slice_from(1).iter().map(|t| {
+                    t.subst(tcx, &all_substs)
+                });
+                Some(fn_sig.inputs[0]).move_iter().chain(args).collect()
             }
+            _ => fn_sig.inputs.subst(tcx, &all_substs)
         };
-        let (_, opt_transformed_self_ty, fn_sig) =
-            replace_bound_regions_in_fn_sig(
-                tcx, Some(transformed_self_ty), &bare_fn_ty.sig,
-                |br| self.fcx.infcx().next_region_var(
-                    infer::BoundRegionInFnCall(self.expr.span, br)));
-        let transformed_self_ty = opt_transformed_self_ty.unwrap();
+        let fn_sig = ty::FnSig {
+            binder_id: fn_sig.binder_id,
+            inputs: inputs,
+            output: fn_sig.output.subst(tcx, &all_substs),
+            variadic: fn_sig.variadic
+        };
+
+        debug!("after subst, fty={}", fn_sig.repr(tcx));
+
+        // Replace any bound regions that appear in the function
+        // signature with region variables
+        let (_, fn_sig) = replace_bound_regions_in_fn_sig( tcx, &fn_sig, |br| {
+            self.fcx.infcx().next_region_var(
+                infer::BoundRegionInFnCall(self.expr.span, br))
+        });
+        let transformed_self_ty = fn_sig.inputs[0];
         let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
             sig: fn_sig,
             purity: bare_fn_ty.purity,
@@ -1027,7 +1029,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         // should never fail.
         match self.fcx.mk_subty(false, infer::Misc(self.self_expr.span),
                                 rcvr_ty, transformed_self_ty) {
-            result::Ok(_) => (),
+            result::Ok(_) => {}
             result::Err(_) => {
                 self.bug(format!("{} was a subtype of {} but now is not?",
                               self.ty_to_str(rcvr_ty),
@@ -1038,9 +1040,7 @@ fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
         self.fcx.write_ty(self.callee_id, fty);
         self.fcx.write_substs(self.callee_id, all_substs);
         method_map_entry {
-            self_ty: transformed_self_ty,
-            explicit_self: candidate.method_ty.explicit_self,
-            origin: candidate.origin,
+            origin: candidate.origin
         }
     }
 
@@ -1064,7 +1064,7 @@ fn construct_transformed_self_ty_for_object(
          * result to be `&'a Foo`. Assuming that `u_method` is being
          * called, we want the result to be `~Foo`. Of course,
          * this transformation has already been done as part of
-         * `method_ty.transformed_self_ty`, but there the type
+         * `method_ty.fty.sig.inputs[0]`, but there the type
          * is expressed in terms of `Self` (i.e., `&'a Self`, `~Self`).
          * Because objects are not standalone types, we can't just substitute
          * `s/Self/Foo/`, so we must instead perform this kind of hokey
@@ -1078,12 +1078,11 @@ fn construct_transformed_self_ty_for_object(
             ast::SelfStatic => {
                 self.bug(~"static method for object type receiver");
             }
-            ast::SelfValue(_) => {
+            ast::SelfValue => {
                 ty::mk_err() // error reported in `enforce_object_limitations()`
             }
-            ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq(..) => {
-                let transformed_self_ty =
-                    method_ty.transformed_self_ty.clone().unwrap();
+            ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq => {
+                let transformed_self_ty = method_ty.fty.sig.inputs[0];
                 match ty::get(transformed_self_ty).sty {
                     ty::ty_rptr(r, mt) => { // must be SelfRegion
                         ty::mk_trait(self.tcx(), trait_def_id,
@@ -1110,10 +1109,7 @@ fn construct_transformed_self_ty_for_object(
         }
     }
 
-    fn enforce_object_limitations(&self,
-                                  method_fty: ty::t,
-                                  candidate: &Candidate)
-    {
+    fn enforce_object_limitations(&self, candidate: &Candidate) {
         /*!
          * There are some limitations to calling functions through an
          * object, because (a) the self type is not known
@@ -1137,21 +1133,38 @@ fn enforce_object_limitations(&self,
                      through an object");
             }
 
-            ast::SelfValue(_) => { // reason (a) above
+            ast::SelfValue => { // reason (a) above
                 self.tcx().sess.span_err(
                     self.expr.span,
                     "cannot call a method with a by-value receiver \
                      through an object");
             }
 
-            ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq(..) => {}
+            ast::SelfRegion(..) | ast::SelfBox | ast::SelfUniq => {}
         }
 
-        if ty::type_has_self(method_fty) { // reason (a) above
-            self.tcx().sess.span_err(
-                self.expr.span,
-                "cannot call a method whose type contains a \
-                 self-type through an object");
+        // reason (a) above
+        let check_for_self_ty = |ty| {
+            if ty::type_has_self(ty) {
+                self.tcx().sess.span_err(
+                    self.expr.span,
+                    "cannot call a method whose type contains a \
+                     self-type through an object");
+                true
+            } else {
+                false
+            }
+        };
+        let ref sig = candidate.method_ty.fty.sig;
+        let mut found_self_ty = false;
+        for &input_ty in sig.inputs.iter() {
+            if check_for_self_ty(input_ty) {
+                found_self_ty = true;
+                break;
+            }
+        }
+        if !found_self_ty {
+            check_for_self_ty(sig.output);
         }
 
         if candidate.method_ty.generics.has_type_params() { // reason (b) above
@@ -1198,7 +1211,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 false
             }
 
-            SelfValue(_) => {
+            SelfValue => {
                 rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
             }
 
@@ -1234,7 +1247,7 @@ fn is_relevant(&self, rcvr_ty: ty::t, candidate: &Candidate) -> bool {
                 }
             }
 
-            SelfUniq(_) => {
+            SelfUniq => {
                 debug!("(is relevant?) explicit self is a unique pointer");
                 match ty::get(rcvr_ty).sty {
                     ty::ty_uniq(typ) => {
index 5f221994787b8c0c8d0d574940b1738c9368e078..a0b50f65f202c07982a25254fca5ccbb17626982 100644 (file)
 pub mod demand;
 pub mod method;
 
-pub struct SelfInfo {
-    self_ty: ty::t,
-    self_id: ast::NodeId,
-    span: Span
-}
-
 /// Fields that are part of a `FnCtxt` which are inherited by
 /// closures defined within the function.  For example:
 ///
@@ -320,23 +314,21 @@ pub fn check_item_types(ccx: @CrateCtxt, crate: &ast::Crate) {
     visit::walk_crate(&mut visit, crate, ());
 }
 
-pub fn check_bare_fn(ccx: @CrateCtxt,
-                     decl: &ast::FnDecl,
-                     body: &ast::Block,
-                     id: ast::NodeId,
-                     self_info: Option<SelfInfo>,
-                     fty: ty::t,
-                     param_env: ty::ParameterEnvironment) {
+fn check_bare_fn(ccx: @CrateCtxt,
+                 decl: &ast::FnDecl,
+                 body: &ast::Block,
+                 id: ast::NodeId,
+                 fty: ty::t,
+                 param_env: ty::ParameterEnvironment) {
     match ty::get(fty).sty {
         ty::ty_bare_fn(ref fn_ty) => {
             let fcx =
-                check_fn(ccx, self_info, fn_ty.purity,
-                         &fn_ty.sig, decl, id, body, Vanilla,
-                         @Inherited::new(ccx.tcx, param_env));
+                check_fn(ccx, fn_ty.purity, &fn_ty.sig, decl, id, body,
+                         Vanilla, @Inherited::new(ccx.tcx, param_env));
 
             vtable::resolve_in_block(fcx, body);
             regionck::regionck_fn(fcx, body);
-            writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info);
+            writeback::resolve_type_vars_in_fn(fcx, decl, body);
         }
         _ => ccx.tcx.sess.impossible_case(body.span,
                                  "check_bare_fn: function type expected")
@@ -419,15 +411,14 @@ fn visit_item(&mut self, _: &ast::Item, _: ()) { }
 
 }
 
-pub fn check_fn(ccx: @CrateCtxt,
-                opt_self_info: Option<SelfInfo>,
-                purity: ast::Purity,
-                fn_sig: &ty::FnSig,
-                decl: &ast::FnDecl,
-                id: ast::NodeId,
-                body: &ast::Block,
-                fn_kind: FnKind,
-                inherited: @Inherited) -> @FnCtxt
+fn check_fn(ccx: @CrateCtxt,
+            purity: ast::Purity,
+            fn_sig: &ty::FnSig,
+            decl: &ast::FnDecl,
+            id: ast::NodeId,
+            body: &ast::Block,
+            fn_kind: FnKind,
+            inherited: @Inherited) -> @FnCtxt
 {
     /*!
      * Helper used by check_bare_fn and check_expr_fn.  Does the
@@ -442,99 +433,44 @@ pub fn check_fn(ccx: @CrateCtxt,
     let tcx = ccx.tcx;
     let err_count_on_creation = tcx.sess.err_count();
 
-    // First, we have to replace any bound regions in the fn and self
-    // types with free ones.  The free region references will be bound
-    // the node_id of the body block.
-    let (opt_self_info, fn_sig) = {
-        let opt_self_ty = opt_self_info.map(|i| i.self_ty);
-        let (_, opt_self_ty, fn_sig) =
-            replace_bound_regions_in_fn_sig(
-                tcx, opt_self_ty, fn_sig,
-                |br| ty::ReFree(ty::FreeRegion {scope_id: body.id,
-                                                 bound_region: br}));
-        let opt_self_info =
-            opt_self_info.map(
-                |si| SelfInfo {self_ty: opt_self_ty.unwrap(), .. si});
-        (opt_self_info, fn_sig)
-    };
+    // First, we have to replace any bound regions in the fn type with free ones.
+    // The free region references will be bound the node_id of the body block.
+    let (_, fn_sig) = replace_bound_regions_in_fn_sig(tcx, fn_sig, |br| {
+        ty::ReFree(ty::FreeRegion {scope_id: body.id, bound_region: br})
+    });
 
-    relate_free_regions(tcx, opt_self_info.map(|s| s.self_ty), &fn_sig);
+    relate_free_regions(tcx, &fn_sig);
 
-    let arg_tys = fn_sig.inputs.map(|a| *a);
+    let arg_tys = fn_sig.inputs.as_slice();
     let ret_ty = fn_sig.output;
 
-    debug!("check_fn(arg_tys={:?}, ret_ty={:?}, opt_self_ty={:?})",
+    debug!("check_fn(arg_tys={:?}, ret_ty={:?})",
            arg_tys.map(|&a| ppaux::ty_to_str(tcx, a)),
-           ppaux::ty_to_str(tcx, ret_ty),
-           opt_self_info.map(|si| ppaux::ty_to_str(tcx, si.self_ty)));
+           ppaux::ty_to_str(tcx, ret_ty));
 
     // Create the function context.  This is either derived from scratch or,
     // in the case of function expressions, based on the outer context.
-    let fcx: @FnCtxt = {
-        @FnCtxt {
-            err_count_on_creation: err_count_on_creation,
-            ret_ty: ret_ty,
-            ps: RefCell::new(PurityState::function(purity, id)),
-            region_lb: Cell::new(body.id),
-            fn_kind: fn_kind,
-            inh: inherited,
-            ccx: ccx
-        }
+    let fcx = @FnCtxt {
+        err_count_on_creation: err_count_on_creation,
+        ret_ty: ret_ty,
+        ps: RefCell::new(PurityState::function(purity, id)),
+        region_lb: Cell::new(body.id),
+        fn_kind: fn_kind,
+        inh: inherited,
+        ccx: ccx
     };
 
-    gather_locals(fcx, decl, body, arg_tys, opt_self_info);
-    check_block_with_expected(fcx, body, Some(ret_ty));
-
-    // We unify the tail expr's type with the
-    // function result type, if there is a tail expr.
-    match body.expr {
-      Some(tail_expr) => {
-        let tail_expr_ty = fcx.expr_ty(tail_expr);
-        // Special case: we print a special error if there appears
-        // to be do-block/for-loop confusion
-        demand::suptype_with_fn(fcx, tail_expr.span, false,
-            fcx.ret_ty, tail_expr_ty,
-            |sp, e, a, s| {
-                fcx.report_mismatched_return_types(sp, e, a, s) });
-      }
-      None => ()
-    }
-
-    for self_info in opt_self_info.iter() {
-        fcx.write_ty(self_info.self_id, self_info.self_ty);
-    }
-    for (input, arg) in decl.inputs.iter().zip(arg_tys.iter()) {
-        fcx.write_ty(input.id, *arg);
-    }
-
-    return fcx;
-
-    fn gather_locals(fcx: @FnCtxt,
-                     decl: &ast::FnDecl,
-                     body: &ast::Block,
-                     arg_tys: &[ty::t],
-                     opt_self_info: Option<SelfInfo>) {
-        let tcx = fcx.ccx.tcx;
+    {
 
         let mut visit = GatherLocalsVisitor { fcx: fcx, tcx: tcx, };
-
-        // Add the self parameter
-        for self_info in opt_self_info.iter() {
-            visit.assign(self_info.self_id, Some(self_info.self_ty));
-            let locals = fcx.inh.locals.borrow();
-            debug!("self is assigned to {}",
-                   fcx.infcx().ty_to_str(
-                       locals.get().get_copy(&self_info.self_id)));
-        }
-
         // Add formal parameters.
         for (arg_ty, input) in arg_tys.iter().zip(decl.inputs.iter()) {
             // Create type variables for each argument.
             pat_util::pat_bindings(tcx.def_map,
                                    input.pat,
                                    |_bm, pat_id, _sp, _path| {
-                visit.assign(pat_id, None);
-            });
+                                       visit.assign(pat_id, None);
+                                   });
 
             // Check the pattern.
             let pcx = pat_ctxt {
@@ -546,6 +482,29 @@ fn gather_locals(fcx: @FnCtxt,
 
         visit.visit_block(body, ());
     }
+
+    check_block_with_expected(fcx, body, Some(ret_ty));
+
+    // We unify the tail expr's type with the
+    // function result type, if there is a tail expr.
+    match body.expr {
+        Some(tail_expr) => {
+            // Special case: we print a special error if there appears
+            // to be do-block/for-loop confusion
+            demand::suptype_with_fn(fcx, tail_expr.span, false,
+                fcx.ret_ty, fcx.expr_ty(tail_expr),
+                |sp, e, a, s| {
+                    fcx.report_mismatched_return_types(sp, e, a, s);
+                });
+        }
+        None => {}
+    }
+
+    for (input, arg) in decl.inputs.iter().zip(arg_tys.iter()) {
+        fcx.write_ty(input.id, *arg);
+    }
+
+    fcx
 }
 
 pub fn check_no_duplicate_fields(tcx: ty::ctxt,
@@ -606,7 +565,7 @@ pub fn check_item(ccx: @CrateCtxt, it: &ast::Item) {
                 [],
                 body.id);
 
-        check_bare_fn(ccx, decl, body, it.id, None, fn_tpt.ty, param_env);
+        check_bare_fn(ccx, decl, body, it.id, fn_tpt.ty, param_env);
       }
       ast::ItemImpl(_, ref opt_trait_ref, _, ref ms) => {
         debug!("ItemImpl {} with id {}", ccx.tcx.sess.str_of(it.ident), it.id);
@@ -716,23 +675,11 @@ fn check_method_body(ccx: @CrateCtxt,
             item_generics.region_param_defs,
             method.body.id);
 
-    // Compute the self type and fty from point of view of inside fn
-    let opt_self_info = method_ty.transformed_self_ty.map(|ty| {
-        SelfInfo {self_ty: ty.subst(ccx.tcx, &param_env.free_substs),
-                  self_id: method.self_id,
-                  span: method.explicit_self.span}
-    });
+    // Compute the fty from point of view of inside fn
     let fty = ty::node_id_to_type(ccx.tcx, method.id);
     let fty = fty.subst(ccx.tcx, &param_env.free_substs);
 
-    check_bare_fn(
-        ccx,
-        method.decl,
-        method.body,
-        method.id,
-        opt_self_info,
-        fty,
-        param_env);
+    check_bare_fn(ccx, method.decl, method.body, method.id, fty, param_env);
 }
 
 fn check_impl_methods_against_trait(ccx: @CrateCtxt,
@@ -815,13 +762,13 @@ fn check_impl_methods_against_trait(ccx: @CrateCtxt,
  * - trait_m: the method in the trait
  * - trait_substs: the substitutions used on the type of the trait
  */
-pub fn compare_impl_method(tcx: ty::ctxt,
-                           impl_generics: &ty::Generics,
-                           impl_m: @ty::Method,
-                           impl_m_span: Span,
-                           impl_m_body_id: ast::NodeId,
-                           trait_m: &ty::Method,
-                           trait_substs: &ty::substs) {
+fn compare_impl_method(tcx: ty::ctxt,
+                       impl_generics: &ty::Generics,
+                       impl_m: @ty::Method,
+                       impl_m_span: Span,
+                       impl_m_body_id: ast::NodeId,
+                       trait_m: &ty::Method,
+                       trait_substs: &ty::substs) {
     debug!("compare_impl_method()");
     let infcx = infer::new_infer_ctxt(tcx);
 
@@ -953,52 +900,10 @@ pub fn compare_impl_method(tcx: ty::ctxt,
         regions: ty::NonerasedRegions(dummy_impl_regions),
         self_ty: None };
 
-    // We are going to create a synthetic fn type that includes
-    // both the method's self argument and its normal arguments.
-    // So a method like `fn(&self, a: uint)` would be converted
-    // into a function `fn(self: &T, a: uint)`.
-    let mut trait_fn_args = ~[];
-    let mut impl_fn_args = ~[];
-
-    // For both the trait and the impl, create an argument to
-    // represent the self argument (unless this is a static method).
-    // This argument will have the *transformed* self type.
-    for &t in trait_m.transformed_self_ty.iter() {
-        trait_fn_args.push(t);
-    }
-    for &t in impl_m.transformed_self_ty.iter() {
-        impl_fn_args.push(t);
-    }
-
-    // Add in the normal arguments.
-    trait_fn_args.push_all(trait_m.fty.sig.inputs);
-    impl_fn_args.push_all(impl_m.fty.sig.inputs);
-
-    // Create a bare fn type for trait/impl that includes self argument
-    let trait_fty =
-        ty::mk_bare_fn(tcx,
-                       ty::BareFnTy {
-                            purity: trait_m.fty.purity,
-                            abis: trait_m.fty.abis,
-                            sig: ty::FnSig {
-                                binder_id: trait_m.fty.sig.binder_id,
-                                inputs: trait_fn_args,
-                                output: trait_m.fty.sig.output,
-                                variadic: false
-                            }
-                        });
-    let impl_fty =
-        ty::mk_bare_fn(tcx,
-                       ty::BareFnTy {
-                            purity: impl_m.fty.purity,
-                            abis: impl_m.fty.abis,
-                            sig: ty::FnSig {
-                                binder_id: impl_m.fty.sig.binder_id,
-                                inputs: impl_fn_args,
-                                output: impl_m.fty.sig.output,
-                                variadic: false
-                            }
-                        });
+    // Create a bare fn type for trait/impl
+    // It'd be nice to refactor so as to provide the bare fn types instead.
+    let trait_fty = ty::mk_bare_fn(tcx, trait_m.fty.clone());
+    let impl_fty = ty::mk_bare_fn(tcx, impl_m.fty.clone());
 
     // Perform substitutions so that the trait/impl methods are expressed
     // in terms of the same set of type/region parameters:
@@ -1669,6 +1574,8 @@ fn check_method_argument_types(
         sugar: ast::CallSugar,
         deref_args: DerefArgs) -> ty::t
     {
+        // HACK(eddyb) ignore provided self (it has special typeck rules).
+        let args = args.slice_from(1);
         if ty::type_is_error(method_fn_ty) {
             let err_inputs = err_args(args.len());
             check_argument_types(fcx, sp, err_inputs, callee_expr,
@@ -1677,8 +1584,10 @@ fn check_method_argument_types(
         } else {
             match ty::get(method_fn_ty).sty {
                 ty::ty_bare_fn(ref fty) => {
-                    check_argument_types(fcx, sp, fty.sig.inputs, callee_expr,
-                                         args, sugar, deref_args, fty.sig.variadic);
+                    // HACK(eddyb) ignore self in the definition (see above).
+                    check_argument_types(fcx, sp, fty.sig.inputs.slice_from(1),
+                                         callee_expr, args, sugar, deref_args,
+                                         fty.sig.variadic);
                     fty.sig.output
                 }
                 _ => {
@@ -1923,13 +1832,10 @@ fn check_call(fcx: @FnCtxt,
 
         // Replace any bound regions that appear in the function
         // signature with region variables
-        let (_, _, fn_sig) =
-            replace_bound_regions_in_fn_sig(fcx.tcx(),
-                                            None,
-                                            fn_sig,
-                                            |br| fcx.infcx()
-                                                    .next_region_var(
-                    infer::BoundRegionInFnCall(call_expr.span, br)));
+        let (_, fn_sig) = replace_bound_regions_in_fn_sig(fcx.tcx(), fn_sig, |br| {
+            fcx.infcx()
+               .next_region_var(infer::BoundRegionInFnCall(call_expr.span, br))
+        });
 
         // Call the generic checker.
         check_argument_types(fcx, call_expr.span, fn_sig.inputs, f,
@@ -1942,11 +1848,11 @@ fn check_call(fcx: @FnCtxt,
     fn check_method_call(fcx: @FnCtxt,
                          callee_id: ast::NodeId,
                          expr: &ast::Expr,
-                         rcvr: &ast::Expr,
                          method_name: ast::Ident,
                          args: &[@ast::Expr],
                          tps: &[ast::P<ast::Ty>],
                          sugar: ast::CallSugar) {
+        let rcvr = args[0];
         check_expr(fcx, rcvr);
 
         // no need to check for bot/err -- callee does that
@@ -2042,7 +1948,6 @@ fn check_then_else(fcx: @FnCtxt,
     fn lookup_op_method(fcx: @FnCtxt,
                         callee_id: ast::NodeId,
                         op_ex: &ast::Expr,
-                        self_ex: &ast::Expr,
                         self_t: ty::t,
                         opname: ast::Name,
                         args: &[@ast::Expr],
@@ -2052,7 +1957,7 @@ fn lookup_op_method(fcx: @FnCtxt,
                         _expected_result: Option<ty::t>
                        )
                      -> ty::t {
-        match method::lookup(fcx, op_ex, self_ex,
+        match method::lookup(fcx, op_ex, args[0],
                              callee_id, opname, self_t, [],
                              deref_args, CheckTraitsOnly, autoderef_receiver) {
             Some(ref origin) => {
@@ -2084,7 +1989,7 @@ fn check_binop(fcx: @FnCtxt,
                    callee_id: ast::NodeId,
                    expr: &ast::Expr,
                    op: ast::BinOp,
-                   lhs: &ast::Expr,
+                   lhs: @ast::Expr,
                    rhs: @ast::Expr,
                    // Used only in the error case
                    expected_result: Option<ty::t>,
@@ -2172,7 +2077,7 @@ fn check_binop(fcx: @FnCtxt,
     fn check_user_binop(fcx: @FnCtxt,
                         callee_id: ast::NodeId,
                         ex: &ast::Expr,
-                        lhs_expr: &ast::Expr,
+                        lhs_expr: @ast::Expr,
                         lhs_resolved_t: ty::t,
                         op: ast::BinOp,
                         rhs: @ast::Expr,
@@ -2187,10 +2092,10 @@ fn check_user_binop(fcx: @FnCtxt,
                              ast_util::binop_to_str(op), actual)},
                             lhs_resolved_t, None)
                 };
-                return lookup_op_method(fcx, callee_id, ex, lhs_expr, lhs_resolved_t,
-                                       token::intern(*name),
-                                       &[rhs], DoDerefArgs, DontAutoderefReceiver, if_op_unbound,
-                                       expected_result);
+                return lookup_op_method(fcx, callee_id, ex, lhs_resolved_t,
+                                        token::intern(*name), [lhs_expr, rhs],
+                                        DoDerefArgs,DontAutoderefReceiver,
+                                        if_op_unbound, expected_result);
             }
             None => ()
         };
@@ -2216,14 +2121,13 @@ fn check_user_unop(fcx: @FnCtxt,
                        op_str: &str,
                        mname: &str,
                        ex: &ast::Expr,
-                       rhs_expr: &ast::Expr,
+                       rhs_expr: @ast::Expr,
                        rhs_t: ty::t,
                        expected_t: Option<ty::t>)
                     -> ty::t {
        lookup_op_method(
-            fcx, callee_id, ex, rhs_expr, rhs_t,
-            token::intern(mname), &[],
-            DoDerefArgs, DontAutoderefReceiver,
+            fcx, callee_id, ex, rhs_t, token::intern(mname),
+            [rhs_expr], DoDerefArgs, DontAutoderefReceiver,
             || {
                 fcx.type_error_message(ex.span, |actual| {
                     format!("cannot apply unary operator `{}` to type `{}`",
@@ -2280,9 +2184,9 @@ fn check_expr_fn(fcx: @FnCtxt,
              expected_bounds) = {
             match expected_sty {
                 Some(ty::ty_closure(ref cenv)) => {
-                    let (_, _, sig) =
+                    let (_, sig) =
                         replace_bound_regions_in_fn_sig(
-                            tcx, None, &cenv.sig,
+                            tcx, &cenv.sig,
                             |_| fcx.inh.infcx.fresh_bound_region(expr.id));
                     (Some(sig), cenv.purity, cenv.sigil,
                      cenv.onceness, cenv.bounds)
@@ -2352,7 +2256,7 @@ fn check_expr_fn(fcx: @FnCtxt,
                                            (purity, expr.id),
                                            sigil);
 
-        check_fn(fcx.ccx, None, inherited_purity, &fty_sig,
+        check_fn(fcx.ccx, inherited_purity, &fty_sig,
                  decl, id, body, fn_kind, fcx.inh);
     }
 
@@ -2916,12 +2820,6 @@ fn check_struct_enum_variant(fcx: @FnCtxt,
         let tpt = ty_param_bounds_and_ty_for_def(fcx, expr.span, defn);
         instantiate_path(fcx, pth, tpt, defn, expr.span, expr.id);
       }
-      ast::ExprSelf => {
-        let definition = lookup_def(fcx, expr.span, id);
-        let ty_param_bounds_and_ty =
-            ty_param_bounds_and_ty_for_def(fcx, expr.span, definition);
-        fcx.write_ty(id, ty_param_bounds_and_ty.ty);
-      }
       ast::ExprInlineAsm(ref ia) => {
           for &(_, input) in ia.inputs.iter() {
               check_expr(fcx, input);
@@ -3088,18 +2986,16 @@ fn check_struct_enum_variant(fcx: @FnCtxt,
               fcx.write_bot(id);
           }
       }
-      ast::ExprMethodCall(callee_id, rcvr, ident, ref tps, ref args, sugar) => {
-        check_method_call(fcx, callee_id, expr, rcvr, ident, *args, *tps, sugar);
-        let f_ty = fcx.expr_ty(rcvr);
+      ast::ExprMethodCall(callee_id, ident, ref tps, ref args, sugar) => {
+        check_method_call(fcx, callee_id, expr, ident, *args, *tps, sugar);
         let arg_tys = args.map(|a| fcx.expr_ty(*a));
         let (args_bot, args_err) = arg_tys.iter().fold((false, false),
              |(rest_bot, rest_err), a| {
               (rest_bot || ty::type_is_bot(*a),
                rest_err || ty::type_is_error(*a))});
-        if ty::type_is_error(f_ty) || args_err {
+        if args_err {
             fcx.write_error(id);
-        }
-        else if ty::type_is_bot(f_ty) || args_bot {
+        } else if args_bot {
             fcx.write_bot(id);
         }
       }
@@ -3327,10 +3223,9 @@ fn types_compatible(fcx: @FnCtxt, sp: Span,
                       let ret_ty = lookup_op_method(fcx,
                                                     callee_id,
                                                     expr,
-                                                    base,
                                                     resolved,
                                                     index_ident.name,
-                                                    &[idx],
+                                                    [base, idx],
                                                     DoDerefArgs,
                                                     AutoderefReceiver,
                                                     error_message,
@@ -3760,7 +3655,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @FnCtxt,
                                       defn: ast::Def)
                                    -> ty_param_bounds_and_ty {
     match defn {
-      ast::DefArg(nid, _) | ast::DefLocal(nid, _) | ast::DefSelf(nid, _) |
+      ast::DefArg(nid, _) | ast::DefLocal(nid, _) |
       ast::DefBinding(nid, _) => {
           let typ = fcx.local_ty(sp, nid);
           return no_params(typ);
index b21f2c7463055b35da9ae09a30b668b4b451a467..1653429e457c601f9e2046ffb8c3763b50e65dda 100644 (file)
@@ -41,7 +41,7 @@
 use util::ppaux::{ty_to_str, region_to_str, Repr};
 
 use syntax::ast::{ManagedSigil, OwnedSigil, BorrowedSigil};
-use syntax::ast::{DefArg, DefBinding, DefLocal, DefSelf, DefUpvar};
+use syntax::ast::{DefArg, DefBinding, DefLocal, DefUpvar};
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::visit;
@@ -64,7 +64,7 @@ fn region_of_def(fcx: @FnCtxt, def: ast::Def) -> ty::Region {
     let tcx = fcx.tcx();
     match def {
         DefLocal(node_id, _) | DefArg(node_id, _) |
-        DefSelf(node_id, _) | DefBinding(node_id, _) => {
+        DefBinding(node_id, _) => {
             tcx.region_maps.var_region(node_id)
         }
         DefUpvar(_, subdef, closure_id, body_id) => {
@@ -316,8 +316,9 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             visit::walk_expr(rcx, expr, ());
         }
 
-        ast::ExprMethodCall(callee_id, arg0, _, _, ref args, _) => {
-            constrain_call(rcx, callee_id, expr, Some(arg0), *args, false);
+        ast::ExprMethodCall(callee_id, _, _, ref args, _) => {
+            constrain_call(rcx, callee_id, expr, Some(args[0]),
+                           args.slice_from(1), false);
 
             visit::walk_expr(rcx, expr, ());
         }
@@ -1012,12 +1013,10 @@ fn guarantor(rcx: &mut Rcx, expr: &ast::Expr) -> Option<ty::Region> {
                 guarantor(rcx, e)
             }
 
-            ast::ExprPath(..) | ast::ExprSelf => {
-                // Either a variable or constant and hence resides
-                // in constant memory or on the stack frame.  Either way,
-                // not guaranteed by a region pointer.
-                None
-            }
+            // Either a variable or constant and hence resides
+            // in constant memory or on the stack frame.  Either way,
+            // not guaranteed by a region pointer.
+            ast::ExprPath(..) => None,
 
             // All of these expressions are rvalues and hence their
             // value is not guaranteed by a region pointer.
index daf5bdd9ea3158c5a3468edaadd6282b4c5bcd62..0b04db882340a9c80858d33d4b609eb23ce0802b 100644 (file)
 
 pub fn replace_bound_regions_in_fn_sig(
         tcx: ty::ctxt,
-        opt_self_ty: Option<ty::t>,
         fn_sig: &ty::FnSig,
         mapf: |ty::BoundRegion| -> ty::Region)
-        -> (HashMap<ty::BoundRegion,ty::Region>, Option<ty::t>, ty::FnSig) {
-    debug!("replace_bound_regions_in_fn_sig(self_ty={}, fn_sig={})",
-            opt_self_ty.repr(tcx),
-            fn_sig.repr(tcx));
+        -> (HashMap<ty::BoundRegion,ty::Region>, ty::FnSig) {
+    debug!("replace_bound_regions_in_fn_sig({})", fn_sig.repr(tcx));
 
     let mut map = HashMap::new();
-    let (fn_sig, opt_self_ty) = {
+    let fn_sig = {
         let mut f = ty_fold::RegionFolder::regions(tcx, |r| {
-                debug!("region r={}", r.to_str());
-                match r {
+            debug!("region r={}", r.to_str());
+            match r {
                 ty::ReLateBound(s, br) if s == fn_sig.binder_id => {
                     *map.find_or_insert_with(br, |_| mapf(br))
                 }
                 _ => r
-            }});
-        (ty_fold::super_fold_sig(&mut f, fn_sig),
-         ty_fold::fold_opt_ty(&mut f, opt_self_ty))
+            }
+        });
+        ty_fold::super_fold_sig(&mut f, fn_sig)
     };
     debug!("resulting map: {}", map.to_str());
-    (map, opt_self_ty, fn_sig)
+    (map, fn_sig)
 }
 
 pub fn relate_nested_regions(tcx: ty::ctxt,
@@ -135,11 +132,7 @@ fn relate(&mut self, r_sub: ty::Region) {
     }
 }
 
-pub fn relate_free_regions(
-    tcx: ty::ctxt,
-    self_ty: Option<ty::t>,
-    fn_sig: &ty::FnSig)
-{
+pub fn relate_free_regions(tcx: ty::ctxt, fn_sig: &ty::FnSig) {
     /*!
      * This function populates the region map's `free_region_map`.
      * It walks over the transformed self type and argument types
@@ -158,9 +151,6 @@ pub fn relate_free_regions(
     for arg in fn_sig.inputs.iter() {
         all_tys.push(*arg);
     }
-    for &t in self_ty.iter() {
-        all_tys.push(t);
-    }
 
     for &t in all_tys.iter() {
         debug!("relate_free_regions(t={})", ppaux::ty_to_str(tcx, t));
index 43af40363cd36547ee57967088024f2f1677b85d..0a231be5d459b60343a4bd3e11f8b5d12ec18e2e 100644 (file)
@@ -712,7 +712,7 @@ fn mutability_allowed(a_mutbl: ast::Mutability,
       ast::ExprUnary(callee_id, _, _) |
       ast::ExprAssignOp(callee_id, _, _, _) |
       ast::ExprIndex(callee_id, _, _) |
-      ast::ExprMethodCall(callee_id, _, _, _, _, _) => {
+      ast::ExprMethodCall(callee_id, _, _, _, _) => {
         match ty::method_call_type_param_defs(cx.tcx, fcx.inh.method_map, ex.id) {
           Some(type_param_defs) => {
             debug!("vtable resolution on parameter bounds for method call {}",
index 2237c2f43e1934790ebc150901b755ccc7d8344b..48b1acd3f9b37546725c0d4a7850cbfd204cc6c6 100644 (file)
 use middle::pat_util;
 use middle::ty;
 use middle::typeck::astconv::AstConv;
-use middle::typeck::check::{FnCtxt, SelfInfo};
+use middle::typeck::check::FnCtxt;
 use middle::typeck::infer::{force_all, resolve_all, resolve_region};
 use middle::typeck::infer::resolve_type;
 use middle::typeck::infer;
 use middle::typeck::{vtable_res, vtable_origin};
 use middle::typeck::{vtable_static, vtable_param};
-use middle::typeck::method_map_entry;
 use middle::typeck::write_substs_to_tcx;
 use middle::typeck::write_ty_to_tcx;
 use util::ppaux;
@@ -62,7 +61,7 @@ fn resolve_type_vars_in_types(fcx: @FnCtxt, sp: Span, tys: &[ty::t])
     })
 }
 
-fn resolve_method_map_entry(fcx: @FnCtxt, sp: Span, id: ast::NodeId) {
+fn resolve_method_map_entry(fcx: @FnCtxt, id: ast::NodeId) {
     // Resolve any method map entry
     let method_map_entry_opt = {
         let method_map = fcx.inh.method_map.borrow();
@@ -71,18 +70,9 @@ fn resolve_method_map_entry(fcx: @FnCtxt, sp: Span, id: ast::NodeId) {
     match method_map_entry_opt {
         None => {}
         Some(mme) => {
-            {
-                let r = resolve_type_vars_in_type(fcx, sp, mme.self_ty);
-                for t in r.iter() {
-                    let method_map = fcx.ccx.method_map;
-                    let new_entry = method_map_entry { self_ty: *t, ..mme };
-                    debug!("writeback::resolve_method_map_entry(id={:?}, \
-                            new_entry={:?})",
-                           id, new_entry);
-                    let mut method_map = method_map.borrow_mut();
-                    method_map.get().insert(id, new_entry);
-                }
-            }
+            debug!("writeback::resolve_method_map_entry(id={:?}, entry={:?})", id, mme);
+            let mut method_map = fcx.ccx.method_map.borrow_mut();
+            method_map.get().insert(id, mme);
         }
     }
 }
@@ -148,19 +138,33 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
                                          resolve_all | force_all) {
                         Err(e) => {
                             // This should not, I think, happen:
-                            fcx.ccx.tcx.sess.span_err(
+                            tcx.sess.span_err(
                                 sp,
                                 format!("cannot resolve bound for closure: \
                                          {}",
                                         infer::fixup_err_to_str(e)));
                         }
                         Ok(r1) => {
+                            // FIXME(eddyb) #2190 Allow only statically resolved
+                            // bare functions to coerce to a closure to avoid
+                            // constructing (slower) indirect call wrappers.
+                            {
+                                let def_map = tcx.def_map.borrow();
+                                match def_map.get().find(&id) {
+                                    Some(&ast::DefFn(..)) |
+                                    Some(&ast::DefStaticMethod(..)) |
+                                    Some(&ast::DefVariant(..)) |
+                                    Some(&ast::DefStruct(_)) => {}
+                                    _ => tcx.sess.span_err(sp,
+                                            "cannot coerce non-statically resolved bare fn")
+                                }
+                            }
+
                             let resolved_adj = @ty::AutoAddEnv(r1, s);
                             debug!("Adjustments for node {}: {:?}",
                                    id,
                                    resolved_adj);
-                            let mut adjustments = fcx.tcx()
-                                                     .adjustments
+                            let mut adjustments = tcx.adjustments
                                                      .borrow_mut();
                             adjustments.get().insert(id, resolved_adj);
                         }
@@ -175,7 +179,7 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
                             Ok(r1) => r1,
                             Err(e) => {
                                 // This should not, I think, happen.
-                                fcx.ccx.tcx.sess.span_err(
+                                tcx.sess.span_err(
                                     sp,
                                     format!("cannot resolve scope of borrow: \
                                              {}",
@@ -195,13 +199,13 @@ fn resolve_type_vars_for_node(wbcx: &mut WbCtxt, sp: Span, id: ast::NodeId)
                         autoref: resolved_autoref,
                     });
                     debug!("Adjustments for node {}: {:?}", id, resolved_adj);
-                    let mut adjustments = fcx.tcx().adjustments.borrow_mut();
+                    let mut adjustments = tcx.adjustments.borrow_mut();
                     adjustments.get().insert(id, resolved_adj);
                 }
 
                 ty::AutoObject(..) => {
                     debug!("Adjustments for node {}: {:?}", id, adjustment);
-                    let mut adjustments = fcx.tcx().adjustments.borrow_mut();
+                    let mut adjustments = tcx.adjustments.borrow_mut();
                     adjustments.get().insert(id, adjustment);
                 }
             }
@@ -273,11 +277,11 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
 
     resolve_type_vars_for_node(wbcx, e.span, e.id);
 
-    resolve_method_map_entry(wbcx.fcx, e.span, e.id);
+    resolve_method_map_entry(wbcx.fcx, e.id);
     {
         let r = e.get_callee_id();
         for callee_id in r.iter() {
-            resolve_method_map_entry(wbcx.fcx, e.span, *callee_id);
+            resolve_method_map_entry(wbcx.fcx, *callee_id);
         }
     }
 
@@ -303,7 +307,7 @@ fn visit_expr(e: &ast::Expr, wbcx: &mut WbCtxt) {
             maybe_resolve_type_vars_for_node(wbcx, e.span, callee_id);
         }
 
-        ast::ExprMethodCall(callee_id, _, _, _, _, _) => {
+        ast::ExprMethodCall(callee_id, _, _, _, _) => {
             // We must always have written in a callee ID type for these.
             resolve_type_vars_for_node(wbcx, e.span, callee_id);
         }
@@ -381,18 +385,11 @@ pub fn resolve_type_vars_in_expr(fcx: @FnCtxt, e: &ast::Expr) -> bool {
     return wbcx.success;
 }
 
-pub fn resolve_type_vars_in_fn(fcx: @FnCtxt,
-                               decl: &ast::FnDecl,
-                               blk: &ast::Block,
-                               self_info: Option<SelfInfo>) -> bool {
+pub fn resolve_type_vars_in_fn(fcx: @FnCtxt, decl: &ast::FnDecl,
+                               blk: &ast::Block) -> bool {
     let mut wbcx = WbCtxt { fcx: fcx, success: true };
     let wbcx = &mut wbcx;
     wbcx.visit_block(blk, ());
-    for self_info in self_info.iter() {
-        resolve_type_vars_for_node(wbcx,
-                                   self_info.span,
-                                   self_info.self_id);
-    }
     for arg in decl.inputs.iter() {
         wbcx.visit_pat(arg.pat, ());
         // Privacy needs the type for the whole pattern, not just each binding
index d533f9b0b13f96ec9bf8499eda2871a78dc5f343..0dcb3c7329ba5259af18a991f3b9406eb4aa0014 100644 (file)
@@ -24,8 +24,7 @@
 use middle::ty::{ty_param, ty_param_bounds_and_ty, ty_ptr};
 use middle::ty::{ty_rptr, ty_self, ty_struct, ty_trait, ty_tup};
 use middle::ty::{ty_type, ty_uint, ty_uniq, ty_bare_fn, ty_closure};
-use middle::ty::{ty_opaque_closure_ptr, ty_unboxed_vec};
-use middle::ty::{type_is_ty_var};
+use middle::ty::{ty_unboxed_vec, type_is_ty_var};
 use middle::subst::Subst;
 use middle::ty;
 use middle::ty::{Impl, Method};
@@ -84,7 +83,7 @@ pub fn get_base_type(inference_context: @InferCtxt,
         ty_nil | ty_bot | ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
         ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_closure(..) | ty_tup(..) |
         ty_infer(..) | ty_param(..) | ty_self(..) | ty_type |
-        ty_opaque_closure_ptr(..) | ty_unboxed_vec(..) | ty_err | ty_box(_) |
+        ty_unboxed_vec(..) | ty_err | ty_box(_) |
         ty_uniq(_) | ty_ptr(_) | ty_rptr(_, _) => {
             debug!("(getting base type) no base type; found {:?}",
                    get(original_type).sty);
@@ -820,9 +819,6 @@ fn subst_receiver_types_in_method_ty(tcx: ty::ctxt,
         // method types *can* appear in the generic bounds
         method.generics.subst(tcx, &combined_substs),
 
-        // method tps cannot appear in the self_ty, so use `substs` from trait ref
-        method.transformed_self_ty.subst(tcx, &trait_ref.substs),
-
         // method types *can* appear in the fty
         method.fty.subst(tcx, &combined_substs),
 
index 474335caa7bb80b67735ee052ba7fe785c674dd9..04d708f0638e9fd403ecda7b2af0bf6d518c2315 100644 (file)
@@ -380,15 +380,13 @@ fn ty_method_of_trait_method(this: &CrateCtxt,
                                  m_decl: &ast::FnDecl) -> ty::Method
     {
         let trait_self_ty = ty::mk_self(this.tcx, local_def(trait_id));
-        let (transformed_self_ty, fty) =
-            astconv::ty_of_method(this, *m_id, *m_purity,
-                                  trait_self_ty, *m_explicit_self, m_decl);
+        let fty = astconv::ty_of_method(this, *m_id, *m_purity, trait_self_ty,
+                                        *m_explicit_self, m_decl);
         let num_trait_type_params = trait_generics.type_param_defs.len();
         ty::Method::new(
             *m_ident,
             // FIXME(#5121) -- distinguish early vs late lifetime params
             ty_generics(this, m_generics, num_trait_type_params),
-            transformed_self_ty,
             fty,
             m_explicit_self.node,
             // assume public, because this is only invoked on trait methods
@@ -512,10 +510,9 @@ fn ty_of_method(ccx: &CrateCtxt,
                     rcvr_generics: &ast::Generics,
                     rcvr_visibility: ast::Visibility) -> ty::Method
     {
-        let (transformed_self_ty, fty) =
-            astconv::ty_of_method(ccx, m.id, m.purity,
-                                  untransformed_rcvr_ty,
-                                  m.explicit_self, m.decl);
+        let fty = astconv::ty_of_method(ccx, m.id, m.purity,
+                                        untransformed_rcvr_ty,
+                                        m.explicit_self, m.decl);
 
         // if the method specifies a visibility, use that, otherwise
         // inherit the visibility from the impl (so `foo` in `pub impl
@@ -528,7 +525,6 @@ fn ty_of_method(ccx: &CrateCtxt,
             m.ident,
             // FIXME(#5121) -- distinguish early vs late lifetime params
             ty_generics(ccx, &m.generics, num_rcvr_type_params),
-            transformed_self_ty,
             fty,
             m.explicit_self.node,
             method_vis,
index d3931d277dd8f073906b0bd484f7651917b943b1..6a4de959c2bb93bf113c29d7a58cf105af28c4b2 100644 (file)
@@ -385,48 +385,37 @@ pub fn coerce_borrowed_fn(&self,
         })))
     }
 
-    pub fn coerce_from_bare_fn(&self,
-                               a: ty::t,
-                               fn_ty_a: &ty::BareFnTy,
-                               b: ty::t)
-                               -> CoerceResult {
-        self.unpack_actual_value(b, |sty_b| {
-            self.coerce_from_bare_fn_post_unpack(a, fn_ty_a, b, sty_b)
-        })
-    }
-
-    pub fn coerce_from_bare_fn_post_unpack(&self,
-                                           a: ty::t,
-                                           fn_ty_a: &ty::BareFnTy,
-                                           b: ty::t,
-                                           sty_b: &ty::sty)
-                                           -> CoerceResult {
+    fn coerce_from_bare_fn(&self, a: ty::t, fn_ty_a: &ty::BareFnTy, b: ty::t)
+                           -> CoerceResult {
         /*!
          *
          * Attempts to coerce from a bare Rust function (`extern
-         * "rust" fn`) into a closure.
+         * "Rust" fn`) into a closure or a `proc`.
          */
 
-        debug!("coerce_from_bare_fn(a={}, b={})",
-               a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx));
+        self.unpack_actual_value(b, |sty_b| {
 
-        if !fn_ty_a.abis.is_rust() || fn_ty_a.purity != ast::ImpureFn {
-            return self.subtype(a, b);
-        }
+            debug!("coerce_from_bare_fn(a={}, b={})",
+                   a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx));
 
-        let fn_ty_b = match *sty_b {
-            ty::ty_closure(ref f) => (*f).clone(),
-            _ => return self.subtype(a, b),
-        };
+            if !fn_ty_a.abis.is_rust() || fn_ty_a.purity != ast::ImpureFn {
+                return self.subtype(a, b);
+            }
 
-        let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
-        let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
-                                       ty::ClosureTy {
-                                            sig: fn_ty_a.sig.clone(),
-                                            ..fn_ty_b
-                                       });
-        if_ok!(self.subtype(a_closure, b));
-        Ok(Some(adj))
+            let fn_ty_b = match *sty_b {
+                ty::ty_closure(ref f) => (*f).clone(),
+                _ => return self.subtype(a, b)
+            };
+
+            let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
+            let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
+                                           ty::ClosureTy {
+                                                sig: fn_ty_a.sig.clone(),
+                                                ..fn_ty_b
+                                           });
+            if_ok!(self.subtype(a_closure, b));
+            Ok(Some(adj))
+        })
     }
 
     pub fn coerce_unsafe_ptr(&self,
index 68fb4b1e579a6d5204398055fd8cd9d5dd8e5b49..812b7ffd97d60dccf9fbd106bed48792a6ce5945 100644 (file)
@@ -25,7 +25,7 @@
 use middle::ty;
 use middle::ty_fold;
 use middle::ty_fold::TypeFolder;
-use middle::typeck::check::regionmanip::{replace_bound_regions_in_fn_sig};
+use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
 use middle::typeck::infer::coercion::Coerce;
 use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys};
 use middle::typeck::infer::region_inference::{RegionVarBindings};
@@ -809,8 +809,8 @@ pub fn replace_bound_regions_with_fresh_regions(&self,
                                                     -> (ty::FnSig,
                                                         HashMap<ty::BoundRegion,
                                                                 ty::Region>) {
-        let (map, _, fn_sig) =
-            replace_bound_regions_in_fn_sig(self.tcx, None, fsig, |br| {
+        let (map, fn_sig) =
+            replace_bound_regions_in_fn_sig(self.tcx, fsig, |br| {
                 let rvar = self.next_region_var(
                     BoundRegionInFnType(trace.origin.span(), br));
                 debug!("Bound region {} maps to {:?}",
index 6e370a85096c20ac27812d56276be15618ff1e94..19abbecaa8a72929756416f7a5979d851a34c58b 100644 (file)
@@ -171,8 +171,8 @@ fn fn_sigs(&self, a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
 
         // Second, we instantiate each bound region in the supertype with a
         // fresh concrete region.
-        let (skol_map, _, b_sig) = {
-            replace_bound_regions_in_fn_sig(self.get_ref().infcx.tcx, None, b, |br| {
+        let (skol_map, b_sig) = {
+            replace_bound_regions_in_fn_sig(self.get_ref().infcx.tcx, b, |br| {
                 let skol = self.get_ref().infcx.region_vars.new_skolemized(br);
                 debug!("Bound region {} skolemized to {:?}",
                        bound_region_to_str(self.get_ref().infcx.tcx, "", false, br),
index da3a2eebfeb1beeaf428d54bdf85ee753fccac7e..8837a978f439ac35ac57a00a2f1d6b56a55e0d16 100644 (file)
@@ -144,13 +144,6 @@ pub struct method_object {
 
 #[deriving(Clone)]
 pub struct method_map_entry {
-    // the type of the self parameter, which is not reflected in the fn type
-    // (FIXME #3446)
-    self_ty: ty::t,
-
-    // the type of explicit self on the method
-    explicit_self: ast::ExplicitSelf_,
-
     // method details being invoked
     origin: method_origin,
 }
@@ -264,10 +257,10 @@ pub fn write_tpt_to_tcx(tcx: ty::ctxt,
 pub fn lookup_def_tcx(tcx: ty::ctxt, sp: Span, id: ast::NodeId) -> ast::Def {
     let def_map = tcx.def_map.borrow();
     match def_map.get().find(&id) {
-      Some(&x) => x,
-      _ => {
-        tcx.sess.span_fatal(sp, "internal error looking up a definition")
-      }
+        Some(&x) => x,
+        _ => {
+            tcx.sess.span_fatal(sp, "internal error looking up a definition")
+        }
     }
 }
 
index 7740645030d221681eba8e18cf0d925bf869e40d..c260896731335c349b117db009b94f0a820e0ade 100644 (file)
@@ -472,22 +472,6 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
             ast::ItemTrait(..) => {
                 let methods = ty::trait_methods(tcx, did);
                 for method in methods.iter() {
-                    match method.transformed_self_ty {
-                        Some(self_ty) => {
-                            // The implicit self parameter is basically
-                            // equivalent to a normal parameter declared
-                            // like:
-                            //
-                            //     self : self_ty
-                            //
-                            // where self_ty is `&Self` or `&mut Self`
-                            // or whatever.
-                            self.add_constraints_from_ty(
-                                self_ty, self.contravariant);
-                        }
-                        None => {}
-                    }
-
                     self.add_constraints_from_sig(
                         &method.fty.sig, self.covariant);
                 }
@@ -691,8 +675,8 @@ fn add_constraints_from_ty(&mut self,
                 self.add_constraints_from_sig(sig, variance);
             }
 
-            ty::ty_infer(..) | ty::ty_err | ty::ty_type |
-            ty::ty_opaque_closure_ptr(..) | ty::ty_unboxed_vec(..) => {
+            ty::ty_infer(..) | ty::ty_err |
+            ty::ty_type | ty::ty_unboxed_vec(..) => {
                 self.tcx().sess.bug(
                     format!("Unexpected type encountered in \
                             variance inference: {}",
index dc35ab7e885ee222c8466cacc33cbd7d320d8fb1..7199c945627468fbffa1e2d33a472af10bb2f8c0 100644 (file)
                  ReEmpty};
 use middle::ty::{ty_bool, ty_char, ty_bot, ty_box, ty_struct, ty_enum};
 use middle::ty::{ty_err, ty_str, ty_vec, ty_float, ty_bare_fn, ty_closure};
-use middle::ty::{ty_nil, ty_opaque_closure_ptr, ty_param};
-use middle::ty::{ty_ptr, ty_rptr, ty_self, ty_tup, ty_type, ty_uniq};
-use middle::ty::{ty_trait, ty_int};
-use middle::ty::{ty_uint, ty_unboxed_vec, ty_infer};
+use middle::ty::{ty_nil, ty_param, ty_ptr, ty_rptr, ty_self, ty_tup, ty_type};
+use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_unboxed_vec, ty_infer};
 use middle::ty;
 use middle::typeck;
 use syntax::abi::AbiSet;
@@ -501,10 +499,7 @@ fn push_sig_to_str(cx: ctxt,
       ty_vec(ref mt, vs) => {
         vstore_ty_to_str(cx, mt, vs)
       }
-      ty_str(vs) => format!("{}{}", vstore_to_str(cx, vs), "str"),
-      ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"&closure",
-      ty_opaque_closure_ptr(ast::ManagedSigil) => ~"@closure",
-      ty_opaque_closure_ptr(ast::OwnedSigil) => ~"~closure",
+      ty_str(vs) => format!("{}{}", vstore_to_str(cx, vs), "str")
     }
 }
 
@@ -800,11 +795,10 @@ fn repr(&self, _: ctxt) -> ~str {
 
 impl Repr for ty::Method {
     fn repr(&self, tcx: ctxt) -> ~str {
-        format!("method(ident: {}, generics: {}, transformed_self_ty: {}, \
-                fty: {}, explicit_self: {}, vis: {}, def_id: {})",
+        format!("method(ident: {}, generics: {}, fty: {}, \
+                explicit_self: {}, vis: {}, def_id: {})",
                 self.ident.repr(tcx),
                 self.generics.repr(tcx),
-                self.transformed_self_ty.repr(tcx),
                 self.fty.repr(tcx),
                 self.explicit_self.repr(tcx),
                 self.vis.repr(tcx),
@@ -847,12 +841,7 @@ fn repr(&self, tcx: ctxt) -> ~str {
 
 impl Repr for typeck::method_map_entry {
     fn repr(&self, tcx: ctxt) -> ~str {
-        format!("method_map_entry \\{self_arg: {}, \
-              explicit_self: {}, \
-              origin: {}\\}",
-             self.self_ty.repr(tcx),
-             self.explicit_self.repr(tcx),
-             self.origin.repr(tcx))
+        format!("method_map_entry \\{origin: {}\\}", self.origin.repr(tcx))
     }
 }
 
index e48c0800506f90bd9cf359efb03efb1dfdc4d290..e86122fb7d1e670fd5bfe0517aae14ddf38cd276 100644 (file)
@@ -330,6 +330,16 @@ pub struct Method {
 
 impl Clean<Item> for ast::Method {
     fn clean(&self) -> Item {
+        let inputs = match self.explicit_self.node {
+            ast::SelfStatic => self.decl.inputs.as_slice(),
+            _ => self.decl.inputs.slice_from(1)
+        };
+        let decl = FnDecl {
+            inputs: inputs.iter().map(|x| x.clean()).collect(),
+            output: (self.decl.output.clean()),
+            cf: self.decl.cf.clean(),
+            attrs: ~[]
+        };
         Item {
             name: Some(self.ident.clean()),
             attrs: self.attrs.clean(),
@@ -340,7 +350,7 @@ fn clean(&self) -> Item {
                 generics: self.generics.clean(),
                 self_: self.explicit_self.clean(),
                 purity: self.purity.clone(),
-                decl: self.decl.clean(),
+                decl: decl,
             }),
         }
     }
@@ -356,6 +366,16 @@ pub struct TyMethod {
 
 impl Clean<Item> for ast::TypeMethod {
     fn clean(&self) -> Item {
+        let inputs = match self.explicit_self.node {
+            ast::SelfStatic => self.decl.inputs.as_slice(),
+            _ => self.decl.inputs.slice_from(1)
+        };
+        let decl = FnDecl {
+            inputs: inputs.iter().map(|x| x.clean()).collect(),
+            output: (self.decl.output.clean()),
+            cf: self.decl.cf.clean(),
+            attrs: ~[]
+        };
         Item {
             name: Some(self.ident.clean()),
             attrs: self.attrs.clean(),
@@ -364,7 +384,7 @@ fn clean(&self) -> Item {
             visibility: None,
             inner: TyMethodItem(TyMethod {
                 purity: self.purity.clone(),
-                decl: self.decl.clean(),
+                decl: decl,
                 self_: self.explicit_self.clean(),
                 generics: self.generics.clean(),
             }),
@@ -385,8 +405,8 @@ impl Clean<SelfTy> for ast::ExplicitSelf {
     fn clean(&self) -> SelfTy {
         match self.node {
             ast::SelfStatic => SelfStatic,
-            ast::SelfValue(_) => SelfValue,
-            ast::SelfUniq(_) => SelfOwned,
+            ast::SelfValue => SelfValue,
+            ast::SelfUniq => SelfOwned,
             ast::SelfRegion(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
             ast::SelfBox => SelfManaged,
         }
@@ -1178,7 +1198,7 @@ fn resolve_type(path: Path, tpbs: Option<~[TyParamBound]>,
 
     let (def_id, kind) = match *d {
         ast::DefFn(i, _) => (i, TypeFunction),
-        ast::DefSelf(i, _) | ast::DefSelfTy(i) => return Self(i),
+        ast::DefSelfTy(i) => return Self(i),
         ast::DefTy(i) => (i, TypeEnum),
         ast::DefTrait(i) => {
             debug!("saw DefTrait in def_to_id");
index b0a56cb402b5ffe57a100c22333148f6c9217fae..90ed4a4c744c5ab7593ad72b9c0368307acd0ef9 100644 (file)
@@ -682,7 +682,7 @@ fn recurse<T>(&mut self, s: ~str, f: |&mut Context| -> T) -> T {
     ///
     /// This currently isn't parallelized, but it'd be pretty easy to add
     /// parallelization to this function.
-    fn crate(mut self, mut crate: clean::Crate, cache: Cache) {
+    fn crate(self, mut crate: clean::Crate, cache: Cache) {
         let mut item = match crate.module.take() {
             Some(i) => i,
             None => return
index 74489b70192783db497679ea137985e5aae8463b..012ab9ed1226bfc85b5eea33268929e4015ee874 100644 (file)
@@ -338,7 +338,7 @@ fn socket_name(&mut self) -> Result<ip::SocketAddr, IoError> {
 }
 
 impl rtio::RtioTcpListener for TcpListener {
-    fn listen(mut ~self) -> Result<~rtio::RtioTcpAcceptor, IoError> {
+    fn listen(~self) -> Result<~rtio::RtioTcpAcceptor, IoError> {
         // create the acceptor object from ourselves
         let mut acceptor = ~TcpAcceptor { listener: self };
 
index 0fed29631a65a7d1f87716d3593c230a2e2e4885..36a7a631943262afb8a8a845c2e03ac103c1c429 100644 (file)
@@ -174,7 +174,7 @@ pub fn bind(io: &mut UvIoFactory, name: &CString)
 }
 
 impl RtioUnixListener for PipeListener {
-    fn listen(mut ~self) -> Result<~RtioUnixAcceptor, IoError> {
+    fn listen(~self) -> Result<~RtioUnixAcceptor, IoError> {
         // create the acceptor object from ourselves
         let mut acceptor = ~PipeAcceptor { listener: self };
 
index 745273a1d74be3064559d44f578b0589a9ea86c7..64e42c5480f28bfdf86eaf50624a954d40c916bc 100644 (file)
@@ -230,7 +230,7 @@ pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
     /// Unwraps this buffer, returning the underlying writer.
     ///
     /// The internal buffer is flushed before returning the writer.
-    pub fn unwrap(mut self) -> W { self.inner.unwrap() }
+    pub fn unwrap(self) -> W { self.inner.unwrap() }
 }
 
 impl<W: Writer> Writer for LineBufferedWriter<W> {
index c0af649f26cfe7395843f473b120248e2c0825d6..87655f5911fe700927684768f67575d0c3989c70 100644 (file)
@@ -451,13 +451,8 @@ fn visit_type(&mut self) -> bool {
         true
     }
 
-    fn visit_opaque_box(&mut self) -> bool {
-        self.align_to::<@u8>();
-        if ! self.inner.visit_opaque_box() { return false; }
-        self.bump_past::<@u8>();
-        true
-    }
-
+    // NOTE remove after next snapshot
+    #[cfg(stage0)]
     fn visit_closure_ptr(&mut self, ck: uint) -> bool {
         self.align_to::<proc()>();
         if ! self.inner.visit_closure_ptr(ck) {
index e3b34147c010a33e33413fa8d1dab0b3fde898a3..1ecc31ec2f4e9a5571924d20b7ac22291e27792e 100644 (file)
@@ -580,14 +580,8 @@ fn visit_param(&mut self, _i: uint) -> bool { true }
     fn visit_self(&mut self) -> bool { true }
     fn visit_type(&mut self) -> bool { true }
 
-    fn visit_opaque_box(&mut self) -> bool {
-        self.writer.write(['@' as u8]);
-        self.get::<&raw::Box<()>>(|this, b| {
-            let p = ptr::to_unsafe_ptr(&b.data) as *u8;
-            this.visit_ptr_inner(p, b.type_desc);
-        })
-    }
-
+    // NOTE remove after next snapshot
+    #[cfg(stage0)]
     fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
 }
 
index 198df3090ee80fcc39bc2a2df19eaf5b58120e5a..1988993707fce39822707ff91094f8ff9e66dfbb 100644 (file)
@@ -164,7 +164,9 @@ fn visit_leave_fn(&mut self, purity: uint, proto: uint,
     fn visit_param(&mut self, i: uint) -> bool;
     fn visit_self(&mut self) -> bool;
     fn visit_type(&mut self) -> bool;
-    fn visit_opaque_box(&mut self) -> bool;
+
+    // NOTE remove after next snapshot
+    #[cfg(stage0)]
     fn visit_closure_ptr(&mut self, ck: uint) -> bool;
 }
 
index 03b7f1891a16c51f447b683e4e63124847dd0876..10b1aad81382ef90764af5074718602442a4dce8 100644 (file)
 
 // The Rust abstract syntax tree.
 
-use codemap::{Span, Spanned};
+use codemap::{Span, Spanned, DUMMY_SP};
 use abi::AbiSet;
+use ast_util;
 use opt_vec::OptVec;
-use parse::token::{interner_get, str_to_ident};
+use parse::token::{interner_get, str_to_ident, special_idents};
 
 use std::cell::RefCell;
 use std::hashmap::HashMap;
@@ -236,7 +237,6 @@ pub enum MethodProvenance {
 pub enum Def {
     DefFn(DefId, Purity),
     DefStaticMethod(/* method */ DefId, MethodProvenance, Purity),
-    DefSelf(NodeId, bool /* is_mutbl */),
     DefSelfTy(/* trait id */ NodeId),
     DefMod(DefId),
     DefForeignMod(DefId),
@@ -357,7 +357,7 @@ pub enum BindingMode {
 pub enum Pat_ {
     PatWild,
     PatWildMulti,
-    // A pat_ident may either be a new bound variable,
+    // A PatIdent may either be a new bound variable,
     // or a nullary enum (in which case the second field
     // is None).
     // In the nullary enum case, the parser can't determine
@@ -366,7 +366,7 @@ pub enum Pat_ {
     // set (of "pat_idents that refer to nullary enums")
     PatIdent(BindingMode, Path, Option<@Pat>),
     PatEnum(Path, Option<~[@Pat]>), /* "none" means a * pattern where
-                                       * we don't bind the fields to names */
+                                     * we don't bind the fields to names */
     PatStruct(Path, ~[FieldPat], bool),
     PatTup(~[@Pat]),
     PatUniq(@Pat),
@@ -374,7 +374,7 @@ pub enum Pat_ {
     PatLit(@Expr),
     PatRange(@Expr, @Expr),
     // [a, b, ..i, y, z] is represented as
-    // pat_vec(~[a, b], Some(i), ~[y, z])
+    // PatVec(~[a, b], Some(i), ~[y, z])
     PatVec(~[@Pat], Option<@Pat>, ~[@Pat])
 }
 
@@ -526,7 +526,7 @@ pub struct Expr {
 impl Expr {
     pub fn get_callee_id(&self) -> Option<NodeId> {
         match self.node {
-            ExprMethodCall(callee_id, _, _, _, _, _) |
+            ExprMethodCall(callee_id, _, _, _, _) |
             ExprIndex(callee_id, _, _) |
             ExprBinary(callee_id, _, _, _) |
             ExprAssignOp(callee_id, _, _, _) |
@@ -550,7 +550,7 @@ pub enum Expr_ {
     ExprBox(@Expr, @Expr),
     ExprVec(~[@Expr], Mutability),
     ExprCall(@Expr, ~[@Expr], CallSugar),
-    ExprMethodCall(NodeId, @Expr, Ident, ~[P<Ty>], ~[@Expr], CallSugar),
+    ExprMethodCall(NodeId, Ident, ~[P<Ty>], ~[@Expr], CallSugar),
     ExprTup(~[@Expr]),
     ExprBinary(NodeId, BinOp, @Expr, @Expr),
     ExprUnary(NodeId, UnOp, @Expr),
@@ -579,8 +579,6 @@ pub enum Expr_ {
     /// of a function call.
     ExprPath(Path),
 
-    /// The special identifier `self`.
-    ExprSelf,
     ExprAddrOf(Mutability, @Expr),
     ExprBreak(Option<Name>),
     ExprAgain(Option<Name>),
@@ -783,7 +781,7 @@ pub enum IntTy {
 
 impl ToStr for IntTy {
     fn to_str(&self) -> ~str {
-        ::ast_util::int_ty_to_str(*self)
+        ast_util::int_ty_to_str(*self)
     }
 }
 
@@ -798,7 +796,7 @@ pub enum UintTy {
 
 impl ToStr for UintTy {
     fn to_str(&self) -> ~str {
-        ::ast_util::uint_ty_to_str(*self)
+        ast_util::uint_ty_to_str(*self)
     }
 }
 
@@ -810,7 +808,7 @@ pub enum FloatTy {
 
 impl ToStr for FloatTy {
     fn to_str(&self) -> ~str {
-        ::ast_util::float_ty_to_str(*self)
+        ast_util::float_ty_to_str(*self)
     }
 }
 
@@ -886,7 +884,7 @@ pub enum Ty_ {
     TyTup(~[P<Ty>]),
     TyPath(Path, Option<OptVec<TyParamBound>>, NodeId), // for #7264; see above
     TyTypeof(@Expr),
-    // ty_infer means the type should be inferred instead of it having been
+    // TyInfer means the type should be inferred instead of it having been
     // specified. This should only appear at the "top level" of a type and not
     // nested in one.
     TyInfer,
@@ -917,6 +915,26 @@ pub struct Arg {
     id: NodeId,
 }
 
+impl Arg {
+    pub fn new_self(span: Span, mutability: Mutability) -> Arg {
+        let path = ast_util::ident_to_path(span, special_idents::self_);
+        Arg {
+            // HACK(eddyb) fake type for the self argument.
+            ty: P(Ty {
+                id: DUMMY_NODE_ID,
+                node: TyInfer,
+                span: DUMMY_SP,
+            }),
+            pat: @Pat {
+                id: DUMMY_NODE_ID,
+                node: PatIdent(BindByValue(mutability), path, None),
+                span: span
+            },
+            id: DUMMY_NODE_ID
+        }
+    }
+}
+
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub struct FnDecl {
     inputs: ~[Arg],
@@ -952,10 +970,10 @@ pub enum RetStyle {
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum ExplicitSelf_ {
     SelfStatic,                                // no self
-    SelfValue(Mutability),                     // `self`, `mut self`
+    SelfValue,                                 // `self`
     SelfRegion(Option<Lifetime>, Mutability),  // `&'lt self`, `&'lt mut self`
     SelfBox,                                   // `@self`
-    SelfUniq(Mutability)                       // `~self`, `mut ~self`
+    SelfUniq                                   // `~self`
 }
 
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
@@ -971,7 +989,6 @@ pub struct Method {
     body: P<Block>,
     id: NodeId,
     span: Span,
-    self_id: NodeId,
     vis: Visibility,
 }
 
index 49bea6a33a9d1bba8a056b8a5e1ec1ff5a91caab..bb66d620d2910392d5f6729264beb8672b3dd5ef 100644 (file)
@@ -17,7 +17,6 @@
 use fold::Folder;
 use fold;
 use parse::token::{get_ident_interner, IdentInterner};
-use parse::token::special_idents;
 use print::pprust;
 use util::small_vector::SmallVector;
 
@@ -163,10 +162,7 @@ pub enum Node {
     NodeExpr(@Expr),
     NodeStmt(@Stmt),
     NodeArg(@Pat),
-    // HACK(eddyb) should always be a pattern, but `self` is not, and thus it
-    // is identified only by an ident and no span is available. In all other
-    // cases, node_span will return the proper span (required by borrowck).
-    NodeLocal(Ident, Option<@Pat>),
+    NodeLocal(@Pat),
     NodeBlock(P<Block>),
 
     /// NodeStructCtor represents a tuple struct.
@@ -246,10 +242,6 @@ fn insert(&self, id: ast::NodeId, node: Node) {
         let mut map = self.map.map.borrow_mut();
         map.get().insert(id as uint, node);
     }
-
-    fn map_self(&self, m: @Method) {
-        self.insert(m.self_id, NodeLocal(special_idents::self_, None));
-    }
 }
 
 impl<F: FoldOps> Folder for Ctx<F> {
@@ -285,7 +277,6 @@ fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
                 let impl_did = ast_util::local_def(i.id);
                 for &m in ms.iter() {
                     self.insert(m.id, NodeMethod(m, impl_did, p));
-                    self.map_self(m);
                 }
 
             }
@@ -332,7 +323,6 @@ fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
                         }
                         Provided(m) => {
                             self.insert(m.id, NodeTraitMethod(@Provided(m), d_id, p));
-                            self.map_self(m);
                         }
                     }
                 }
@@ -348,9 +338,9 @@ fn fold_item(&mut self, i: @Item) -> SmallVector<@Item> {
     fn fold_pat(&mut self, pat: @Pat) -> @Pat {
         let pat = fold::noop_fold_pat(pat, self);
         match pat.node {
-            PatIdent(_, ref path, _) => {
+            PatIdent(..) => {
                 // Note: this is at least *potentially* a pattern...
-                self.insert(pat.id, NodeLocal(ast_util::path_to_ident(path), Some(pat)));
+                self.insert(pat.id, NodeLocal(pat));
             }
             _ => {}
         }
@@ -467,7 +457,6 @@ pub fn map_decoded_item<F: 'static + FoldOps>(diag: @SpanHandler,
                 NodeMethod(m, impl_did, @path)
             };
             cx.insert(m.id, entry);
-            cx.map_self(m);
         }
     }
 
@@ -525,8 +514,8 @@ pub fn node_id_to_str(map: Map, id: NodeId, itr: @IdentInterner) -> ~str {
       Some(NodeArg(pat)) => {
         format!("arg {} (id={})", pprust::pat_to_str(pat, itr), id)
       }
-      Some(NodeLocal(ident, _)) => {
-        format!("local (id={}, name={})", id, itr.get(ident.name))
+      Some(NodeLocal(pat)) => {
+        format!("local {} (id={})", pprust::pat_to_str(pat, itr), id)
       }
       Some(NodeBlock(block)) => {
         format!("block {} (id={})", pprust::block_to_str(block, itr), id)
@@ -559,11 +548,7 @@ pub fn node_span(items: Map, id: ast::NodeId) -> Span {
         Some(NodeVariant(variant, _, _)) => variant.span,
         Some(NodeExpr(expr)) => expr.span,
         Some(NodeStmt(stmt)) => stmt.span,
-        Some(NodeArg(pat)) => pat.span,
-        Some(NodeLocal(_, pat)) => match pat {
-            Some(pat) => pat.span,
-            None => fail!("node_span: cannot get span from NodeLocal (likely `self`)")
-        },
+        Some(NodeArg(pat)) | Some(NodeLocal(pat)) => pat.span,
         Some(NodeBlock(block)) => block.span,
         Some(NodeStructCtor(_, item, _)) => item.span,
         Some(NodeCalleeScope(expr)) => expr.span,
index d3504f8d204660fbc3f27dfd8de3bae7c7c03a92..405de5c5542d075dc334c536fd719f9d54a46eb9 100644 (file)
@@ -60,19 +60,19 @@ pub fn variant_def_ids(d: Def) -> Option<(DefId, DefId)> {
 
 pub fn def_id_of_def(d: Def) -> DefId {
     match d {
-      DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
-      DefForeignMod(id) | DefStatic(id, _) |
-      DefVariant(_, id, _) | DefTy(id) | DefTyParam(id, _) |
-      DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
-        id
-      }
-      DefArg(id, _) | DefLocal(id, _) | DefSelf(id, _) | DefSelfTy(id)
-      | DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id)
-      | DefTyParamBinder(id) | DefLabel(id) => {
-        local_def(id)
-      }
+        DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
+        DefForeignMod(id) | DefStatic(id, _) |
+        DefVariant(_, id, _) | DefTy(id) | DefTyParam(id, _) |
+        DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
+            id
+        }
+        DefArg(id, _) | DefLocal(id, _) | DefSelfTy(id)
+        | DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id)
+        | DefTyParamBinder(id) | DefLabel(id) => {
+            local_def(id)
+        }
 
-      DefPrimTy(_) => fail!()
+        DefPrimTy(_) => fail!()
     }
 }
 
@@ -292,16 +292,6 @@ pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
     }
 }
 
-/* True if d is either a def_self, or a chain of def_upvars
- referring to a def_self */
-pub fn is_self(d: ast::Def) -> bool {
-  match d {
-    DefSelf(..)           => true,
-    DefUpvar(_, d, _, _) => is_self(*d),
-    _                     => false
-  }
-}
-
 /// Maps a binary operator to its precedence
 pub fn operator_prec(op: ast::BinOp) -> uint {
   match op {
@@ -504,11 +494,8 @@ fn visit_fn(&mut self,
         self.operation.visit_id(node_id);
 
         match *function_kind {
-            visit::FkItemFn(_, generics, _, _) => {
-                self.visit_generics_helper(generics)
-            }
-            visit::FkMethod(_, generics, method) => {
-                self.operation.visit_id(method.self_id);
+            visit::FkItemFn(_, generics, _, _) |
+            visit::FkMethod(_, generics, _) => {
                 self.visit_generics_helper(generics)
             }
             visit::FkFnBlock => {}
index 3b2cc4ca6ede99c8348cb48b6b3cb180bead8f2c..3b43c96a184cdf656088fbb83dc07bddfbb55032 100644 (file)
@@ -18,6 +18,7 @@
 use fold::Folder;
 use opt_vec;
 use opt_vec::OptVec;
+use parse::token::special_idents;
 
 pub struct Field {
     ident: ast::Ident,
@@ -478,7 +479,7 @@ fn expr_ident(&self, span: Span, id: ast::Ident) -> @ast::Expr {
         self.expr_path(self.path_ident(span, id))
     }
     fn expr_self(&self, span: Span) -> @ast::Expr {
-        self.expr(span, ast::ExprSelf)
+        self.expr_ident(span, special_idents::self_)
     }
 
     fn expr_binary(&self, sp: Span, op: ast::BinOp,
@@ -523,9 +524,9 @@ fn expr_call_global(&self, sp: Span, fn_path: ~[ast::Ident],
     fn expr_method_call(&self, span: Span,
                         expr: @ast::Expr,
                         ident: ast::Ident,
-                        args: ~[@ast::Expr]) -> @ast::Expr {
-        self.expr(span,
-                  ast::ExprMethodCall(ast::DUMMY_NODE_ID, expr, ident, ~[], args, ast::NoSugar))
+                        mut args: ~[@ast::Expr]) -> @ast::Expr {
+        args.unshift(expr);
+        self.expr(span, ast::ExprMethodCall(ast::DUMMY_NODE_ID, ident, ~[], args, ast::NoSugar))
     }
     fn expr_block(&self, b: P<ast::Block>) -> @ast::Expr {
         self.expr(b.span, ast::ExprBlock(b))
index 1f778779fbd42a30f679681d41db6974ca3b71d7..e1fb80049e083a611bdcd37cee4726fa7cc35032 100644 (file)
@@ -551,9 +551,14 @@ fn create_method(&self, trait_: &TraitDef,
         // create the generics that aren't for Self
         let fn_generics = self.generics.to_generics(trait_.cx, trait_.span, type_ident, generics);
 
+        let self_arg = match explicit_self.node {
+            ast::SelfStatic => None,
+            _ => Some(ast::Arg::new_self(trait_.span, ast::MutImmutable))
+        };
         let args = arg_types.move_iter().map(|(name, ty)| {
             trait_.cx.arg(trait_.span, name, ty)
-        }).collect();
+        });
+        let args = self_arg.move_iter().chain(args).collect();
 
         let ret_type = self.get_ret_ty(trait_, generics, type_ident);
 
@@ -578,7 +583,6 @@ fn create_method(&self, trait_: &TraitDef,
             body: body_block,
             id: ast::DUMMY_NODE_ID,
             span: trait_.span,
-            self_id: ast::DUMMY_NODE_ID,
             vis: ast::Inherited,
         }
     }
index c2b32b45ce45b2f4d6a0d5216cf187816ed5a3a7..b22dcfe0da2c9a602e6132a36c426c701adad59e 100644 (file)
@@ -244,13 +244,13 @@ pub fn get_explicit_self(cx: &ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
     let self_path = cx.expr_self(span);
     match *self_ptr {
         None => {
-            (self_path, respan(span, ast::SelfValue(ast::MutImmutable)))
+            (self_path, respan(span, ast::SelfValue))
         }
         Some(ref ptr) => {
             let self_ty = respan(
                 span,
                 match *ptr {
-                    Send => ast::SelfUniq(ast::MutImmutable),
+                    Send => ast::SelfUniq,
                     Managed => ast::SelfBox,
                     Borrowed(ref lt, mutbl) => {
                         let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s)));
index 7a86dd6e4ce72d70548f2e940c6afcd261307ac4..c739fb911ba7fa0335ccaa9886b70780571cb88f 100644 (file)
@@ -306,9 +306,7 @@ fn fold_explicit_self(&mut self, es: &ExplicitSelf) -> ExplicitSelf {
 
     fn fold_explicit_self_(&mut self, es: &ExplicitSelf_) -> ExplicitSelf_ {
         match *es {
-            SelfStatic | SelfValue(_) | SelfUniq(_) | SelfBox => {
-                *es
-            }
+            SelfStatic | SelfValue | SelfUniq | SelfBox => *es,
             SelfRegion(ref lifetime, m) => {
                 SelfRegion(fold_opt_lifetime(lifetime, self), m)
             }
@@ -666,7 +664,6 @@ pub fn noop_fold_method<T: Folder>(m: &Method, folder: &mut T) -> @Method {
         body: folder.fold_block(m.body),
         id: folder.new_id(m.id),
         span: folder.new_span(m.span),
-        self_id: folder.new_id(m.self_id),
         vis: m.vis
     }
 }
@@ -737,10 +734,9 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
                      args.map(|&x| folder.fold_expr(x)),
                      blk)
         }
-        ExprMethodCall(callee_id, f, i, ref tps, ref args, blk) => {
+        ExprMethodCall(callee_id, i, ref tps, ref args, blk) => {
             ExprMethodCall(
                 folder.new_id(callee_id),
-                folder.fold_expr(f),
                 folder.fold_ident(i),
                 tps.map(|&x| folder.fold_ty(x)),
                 args.map(|&x| folder.fold_expr(x)),
@@ -811,7 +807,6 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
                       folder.fold_expr(er))
         }
         ExprPath(ref pth) => ExprPath(folder.fold_path(pth)),
-        ExprSelf => ExprSelf,
         ExprLogLevel => ExprLogLevel,
         ExprBreak(opt_ident) => ExprBreak(opt_ident),
         ExprAgain(opt_ident) => ExprAgain(opt_ident),
index 1204cbc2eeae7c578f1474e982b30d73faf4947c..61c80919b6e713113f74f3bcdb4275f6427f66e0 100644 (file)
@@ -31,8 +31,8 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::Expr) -> bool {
       | ast::ExprForLoop(..)
       | ast::ExprCall(_, _, ast::DoSugar)
       | ast::ExprCall(_, _, ast::ForSugar)
-      | ast::ExprMethodCall(_, _, _, _, _, ast::DoSugar)
-      | ast::ExprMethodCall(_, _, _, _, _, ast::ForSugar) => false,
+      | ast::ExprMethodCall(_, _, _, _, ast::DoSugar)
+      | ast::ExprMethodCall(_, _, _, _, ast::ForSugar) => false,
       _ => true
     }
 }
index e110ebae0930d3f5b63b878394992858bacd37dc..17590ccf52358320e1651c44c81c65c67c94087e 100644 (file)
@@ -27,8 +27,8 @@
 use ast::{ExprBreak, ExprCall, ExprCast, ExprDoBody};
 use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
 use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac};
-use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc, ExprRepeat};
-use ast::{ExprRet, ExprSelf, ExprStruct, ExprTup, ExprUnary};
+use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
+use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprVstore, ExprVstoreSlice, ExprVstoreBox};
 use ast::{ExprVstoreMutSlice, ExprWhile, ExprForLoop, ExternFn, Field, FnDecl};
 use ast::{ExprVstoreUniq, Onceness, Once, Many};
@@ -1093,7 +1093,6 @@ pub fn parse_trait_methods(&mut self) -> ~[TraitMethod] {
                     body: body,
                     id: ast::DUMMY_NODE_ID,
                     span: mk_sp(lo, hi),
-                    self_id: ast::DUMMY_NODE_ID,
                     vis: vis,
                 })
               }
@@ -1687,13 +1686,9 @@ pub fn mk_call(&mut self, f: @Expr, args: ~[@Expr], sugar: CallSugar) -> ast::Ex
         ExprCall(f, args, sugar)
     }
 
-    pub fn mk_method_call(&mut self,
-                      rcvr: @Expr,
-                      ident: Ident,
-                      tps: ~[P<Ty>],
-                      args: ~[@Expr],
+    fn mk_method_call(&mut self, ident: Ident, tps: ~[P<Ty>], args: ~[@Expr],
                       sugar: CallSugar) -> ast::Expr_ {
-        ExprMethodCall(ast::DUMMY_NODE_ID, rcvr, ident, tps, args, sugar)
+        ExprMethodCall(ast::DUMMY_NODE_ID, ident, tps, args, sugar)
     }
 
     pub fn mk_index(&mut self, expr: @Expr, idx: @Expr) -> ast::Expr_ {
@@ -1794,7 +1789,8 @@ pub fn parse_bottom_expr(&mut self) -> @Expr {
 
             return self.mk_expr(lo, body.span.hi, ExprProc(decl, fakeblock));
         } else if self.eat_keyword(keywords::Self) {
-            ex = ExprSelf;
+            let path = ast_util::ident_to_path(mk_sp(lo, hi), special_idents::self_);
+            ex = ExprPath(path);
             hi = self.span.hi;
         } else if self.eat_keyword(keywords::If) {
             return self.parse_if_expr();
@@ -1993,7 +1989,7 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr {
                     // expr.f() method call
                     match self.token {
                         token::LPAREN => {
-                            let es = self.parse_unspanned_seq(
+                            let mut es = self.parse_unspanned_seq(
                                 &token::LPAREN,
                                 &token::RPAREN,
                                 seq_sep_trailing_disallowed(token::COMMA),
@@ -2001,7 +1997,8 @@ pub fn parse_dot_or_call_expr_with(&mut self, e0: @Expr) -> @Expr {
                             );
                             hi = self.span.hi;
 
-                            let nd = self.mk_method_call(e, i, tys, es, NoSugar);
+                            es.unshift(e);
+                            let nd = self.mk_method_call(i, tys, es, NoSugar);
                             e = self.mk_expr(lo, hi, nd);
                         }
                         _ => {
@@ -2569,16 +2566,15 @@ pub fn parse_sugary_call_expr(&mut self,
                 let block = self.parse_lambda_block_expr();
                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
                                             ctor(block));
-                let args = vec::append((*args).clone(), [last_arg]);
+                let args = vec::append_one((*args).clone(), last_arg);
                 self.mk_expr(lo, block.span.hi, ExprCall(f, args, sugar))
             }
-            ExprMethodCall(_, f, i, ref tps, ref args, NoSugar) => {
+            ExprMethodCall(_, i, ref tps, ref args, NoSugar) => {
                 let block = self.parse_lambda_block_expr();
                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
                                             ctor(block));
-                let args = vec::append((*args).clone(), [last_arg]);
-                let method_call = self.mk_method_call(f,
-                                                      i,
+                let args = vec::append_one((*args).clone(), last_arg);
+                let method_call = self.mk_method_call(i,
                                                       (*tps).clone(),
                                                       args,
                                                       sugar);
@@ -2588,10 +2584,9 @@ pub fn parse_sugary_call_expr(&mut self,
                 let block = self.parse_lambda_block_expr();
                 let last_arg = self.mk_expr(block.span.lo, block.span.hi,
                                             ctor(block));
-                let method_call = self.mk_method_call(f,
-                                                      i,
+                let method_call = self.mk_method_call(i,
                                                       (*tps).clone(),
-                                                      ~[last_arg],
+                                                      ~[f, last_arg],
                                                       sugar);
                 self.mk_expr(lo, block.span.hi, method_call)
             }
@@ -3712,6 +3707,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
         // A bit of complexity and lookahead is needed here in order to be
         // backwards compatible.
         let lo = self.span.lo;
+        let mut mutbl_self = MutImmutable;
         let explicit_self = match self.token {
             token::BINOP(token::AND) => {
                 maybe_parse_borrowed_explicit_self(self)
@@ -3720,57 +3716,60 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                 maybe_parse_explicit_self(SelfBox, self)
             }
             token::TILDE => {
-                maybe_parse_explicit_self(SelfUniq(MutImmutable), self)
+                maybe_parse_explicit_self(SelfUniq, self)
             }
             token::IDENT(..) if self.is_self_ident() => {
                 self.bump();
-                SelfValue(MutImmutable)
+                SelfValue
             }
             token::BINOP(token::STAR) => {
                 // Possibly "*self" or "*mut self" -- not supported. Try to avoid
                 // emitting cryptic "unexpected token" errors.
                 self.bump();
-                let mutability = if Parser::token_is_mutability(&self.token) {
+                let _mutability = if Parser::token_is_mutability(&self.token) {
                     self.parse_mutability()
                 } else { MutImmutable };
                 if self.is_self_ident() {
                     self.span_err(self.span, "cannot pass self by unsafe pointer");
                     self.bump();
                 }
-                SelfValue(mutability)
+                SelfValue
             }
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
-                let mutability = self.parse_mutability();
+                mutbl_self = self.parse_mutability();
                 self.expect_self_ident();
-                SelfValue(mutability)
+                SelfValue
             }
             _ if Parser::token_is_mutability(&self.token) &&
                     self.look_ahead(1, |t| *t == token::TILDE) &&
                     self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
-                let mutability = self.parse_mutability();
+                mutbl_self = self.parse_mutability();
                 self.bump();
                 self.expect_self_ident();
-                SelfUniq(mutability)
+                SelfUniq
             }
             _ => SelfStatic
         };
 
+        let explicit_self_sp = mk_sp(lo, self.span.hi);
+
         // If we parsed a self type, expect a comma before the argument list.
-        let fn_inputs;
-        if explicit_self != SelfStatic {
+        let fn_inputs = if explicit_self != SelfStatic {
             match self.token {
                 token::COMMA => {
                     self.bump();
                     let sep = seq_sep_trailing_disallowed(token::COMMA);
-                    fn_inputs = self.parse_seq_to_before_end(
+                    let mut fn_inputs = self.parse_seq_to_before_end(
                         &token::RPAREN,
                         sep,
                         parse_arg_fn
                     );
+                    fn_inputs.unshift(Arg::new_self(explicit_self_sp, mutbl_self));
+                    fn_inputs
                 }
                 token::RPAREN => {
-                    fn_inputs = ~[];
+                    ~[Arg::new_self(explicit_self_sp, mutbl_self)]
                 }
                 _ => {
                     let token_str = self.this_token_to_str();
@@ -3780,10 +3779,8 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
             }
         } else {
             let sep = seq_sep_trailing_disallowed(token::COMMA);
-            fn_inputs = self.parse_seq_to_before_end(&token::RPAREN,
-                                                     sep,
-                                                     parse_arg_fn);
-        }
+            self.parse_seq_to_before_end(&token::RPAREN, sep, parse_arg_fn)
+        };
 
         self.expect(&token::RPAREN);
 
@@ -3918,7 +3915,6 @@ fn parse_method(&mut self, already_parsed_attrs: Option<~[Attribute]>) -> @Metho
             body: body,
             id: ast::DUMMY_NODE_ID,
             span: mk_sp(lo, hi),
-            self_id: ast::DUMMY_NODE_ID,
             vis: visa,
         }
     }
index 36a87658c111f139468cea445689b5a24b2c6e1e..d3c194b6af67a8852e920e3aaae09b35cfadd5b9 100644 (file)
@@ -1213,10 +1213,10 @@ fn print_field(s: &mut State, field: &ast::Field) {
         print_expr(s, func);
         print_call_post(s, sugar, &blk, &mut base_args);
       }
-      ast::ExprMethodCall(_, func, ident, ref tys, ref args, sugar) => {
-        let mut base_args = (*args).clone();
+      ast::ExprMethodCall(_, ident, ref tys, ref args, sugar) => {
+        let mut base_args = args.slice_from(1).to_owned();
         let blk = print_call_pre(s, sugar, &mut base_args);
-        print_expr(s, func);
+        print_expr(s, args[0]);
         word(&mut s.s, ".");
         print_ident(s, ident);
         if tys.len() > 0u {
@@ -1445,7 +1445,6 @@ fn print_field(s: &mut State, field: &ast::Field) {
         word(&mut s.s, "]");
       }
       ast::ExprPath(ref path) => print_path(s, path, true),
-      ast::ExprSelf => word(&mut s.s, "self"),
       ast::ExprBreak(opt_ident) => {
         word(&mut s.s, "break");
         space(&mut s.s);
@@ -1749,19 +1748,20 @@ fn print_field(s: &mut State, f: &ast::FieldPat) {
 }
 
 pub fn explicit_self_to_str(explicit_self: &ast::ExplicitSelf_, intr: @IdentInterner) -> ~str {
-    to_str(explicit_self, |a, &b| { print_explicit_self(a, b); () }, intr)
+    to_str(explicit_self, |a, &b| { print_explicit_self(a, b, ast::MutImmutable); () }, intr)
 }
 
 // Returns whether it printed anything
-pub fn print_explicit_self(s: &mut State, explicit_self: ast::ExplicitSelf_) -> bool {
+fn print_explicit_self(s: &mut State,
+                       explicit_self: ast::ExplicitSelf_,
+                       mutbl: ast::Mutability) -> bool {
+    print_mutability(s, mutbl);
     match explicit_self {
         ast::SelfStatic => { return false; }
-        ast::SelfValue(m) => {
-            print_mutability(s, m);
+        ast::SelfValue => {
             word(&mut s.s, "self");
         }
-        ast::SelfUniq(m) => {
-            print_mutability(s, m);
+        ast::SelfUniq => {
             word(&mut s.s, "~self");
         }
         ast::SelfRegion(ref lt, m) => {
@@ -1799,11 +1799,25 @@ pub fn print_fn_args(s: &mut State, decl: &ast::FnDecl,
     // self type and the args all in the same box.
     rbox(s, 0u, Inconsistent);
     let mut first = true;
-    for explicit_self in opt_explicit_self.iter() {
-        first = !print_explicit_self(s, *explicit_self);
+    for &explicit_self in opt_explicit_self.iter() {
+        let m = match explicit_self {
+            ast::SelfStatic => ast::MutImmutable,
+            _ => match decl.inputs[0].pat.node {
+                ast::PatIdent(ast::BindByValue(m), _, _) => m,
+                _ => ast::MutImmutable
+            }
+        };
+        first = !print_explicit_self(s, explicit_self, m);
     }
 
-    for arg in decl.inputs.iter() {
+    // HACK(eddyb) ignore the separately printed self argument.
+    let args = if first {
+        decl.inputs.as_slice()
+    } else {
+        decl.inputs.slice_from(1)
+    };
+
+    for arg in args.iter() {
         if first { first = false; } else { word_space(s, ","); }
         print_arg(s, arg);
     }
@@ -2090,18 +2104,7 @@ pub fn print_ty_fn(s: &mut State,
         popen(s);
     }
 
-    // It is unfortunate to duplicate the commasep logic, but we want the
-    // self type and the args all in the same box.
-    rbox(s, 0u, Inconsistent);
-    let mut first = true;
-    for explicit_self in opt_explicit_self.iter() {
-        first = !print_explicit_self(s, *explicit_self);
-    }
-    for arg in decl.inputs.iter() {
-        if first { first = false; } else { word_space(s, ","); }
-        print_arg(s, arg);
-    }
-    end(s);
+    print_fn_args(s, decl, opt_explicit_self);
 
     if opt_sigil == Some(ast::BorrowedSigil) {
         word(&mut s.s, "|");
index 484f8dce1f745c685d4124c258c1d04949c7b392..5e7ad3af526b2e8ec458e22f8c1fbb81a575a42e 100644 (file)
@@ -186,7 +186,7 @@ fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
                                                explicit_self: &ExplicitSelf,
                                                env: E) {
     match explicit_self.node {
-        SelfStatic | SelfValue(_) | SelfBox | SelfUniq(_) => {}
+        SelfStatic | SelfValue | SelfBox | SelfUniq => {}
         SelfRegion(ref lifetime, _) => {
             visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
         }
@@ -654,12 +654,11 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
             }
             visitor.visit_expr(callee_expression, env.clone())
         }
-        ExprMethodCall(_, callee, _, ref types, ref arguments, _) => {
+        ExprMethodCall(_, _, ref types, ref arguments, _) => {
             walk_exprs(visitor, *arguments, env.clone());
             for &typ in types.iter() {
                 visitor.visit_ty(typ, env.clone())
             }
-            visitor.visit_expr(callee, env.clone())
         }
         ExprBinary(_, _, left_expression, right_expression) => {
             visitor.visit_expr(left_expression, env.clone());
@@ -734,7 +733,7 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
         ExprPath(ref path) => {
             visitor.visit_path(path, expression.id, env.clone())
         }
-        ExprSelf | ExprBreak(_) | ExprAgain(_) => {}
+        ExprBreak(_) | ExprAgain(_) => {}
         ExprRet(optional_expression) => {
             walk_expr_opt(visitor, optional_expression, env.clone())
         }
diff --git a/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs b/src/test/compile-fail/coerce-bare-fn-to-closure-and-proc.rs
new file mode 100644 (file)
index 0000000..c165802
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn foo() {}
+
+fn main() {
+    let f = foo;
+    let f_closure: || = f;
+    //~^ ERROR: cannot coerce non-statically resolved bare fn
+    let f_proc: proc() = f;
+    //~^ ERROR: cannot coerce non-statically resolved bare fn
+}
index bffca995b8e3a7116cdddb6573855868eca23891..2c1809d4d4886f45c25a7f5ff87a679d10eeaa17 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
 struct A;
 impl A {
     fn m(&self) {
-          fn x() {
-              self.m()
-              //~^ ERROR can't capture dynamic environment in a fn item
-              //~^^ ERROR `self` is not allowed in this context
-          }
+        fn x() {
+            self.m() //~ ERROR can't capture dynamic environment in a fn item
+            //~^ ERROR unresolved name `self`
+        }
     }
 }
 fn main() {}
diff --git a/src/test/compile-fail/lint-unused-mut-self.rs b/src/test/compile-fail/lint-unused-mut-self.rs
new file mode 100644 (file)
index 0000000..ada534f
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[allow(dead_assignment)];
+#[allow(unused_variable)];
+#[allow(dead_code)];
+#[deny(unused_mut)];
+
+struct Foo;
+impl Foo {
+    fn foo(mut self) {} //~ ERROR: variable does not need to be mutable
+    fn bar(mut ~self) {} //~ ERROR: variable does not need to be mutable
+}
+
+fn main() {}
index f293644840a1cec7d911a68ba7cc33b36b185529..ea2062dd2720985aba0cdf0094a14db896a72c1c 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -13,7 +13,7 @@ trait foo {
 }
 impl foo for int {
     fn bar(&self) -> int {
-        //~^ ERROR method `bar` has 0 parameters but the declaration in trait `foo::bar` has 1
+        //~^ ERROR method `bar` has 1 parameter but the declaration in trait `foo::bar` has 2
         *self
     }
 }
diff --git a/src/test/run-pass/coerce-to-closure-and-proc.rs b/src/test/run-pass/coerce-to-closure-and-proc.rs
new file mode 100644 (file)
index 0000000..6f643ca
--- /dev/null
@@ -0,0 +1,47 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn id<T>(x: T) -> T {
+    x
+}
+
+#[deriving(Eq)]
+struct Foo<T>(T);
+
+#[deriving(Eq)]
+enum Bar<T> {
+    Bar(T)
+}
+
+pub fn main() {
+    let f: |int| -> int = id;
+    assert_eq!(f(5), 5);
+
+    let f: proc(int) -> int = id;
+    assert_eq!(f(5), 5);
+
+    let f: |int| -> Foo<int> = Foo;
+    assert_eq!(f(5), Foo(5));
+
+    let f: proc(int) -> Foo<int> = Foo;
+    assert_eq!(f(5), Foo(5));
+
+    let f: |int| -> Bar<int> = Bar;
+    assert_eq!(f(5), Bar(5));
+
+    let f: proc(int) -> Bar<int> = Bar;
+    assert_eq!(f(5), Bar(5));
+
+    let f: |int| -> Option<int> = Some;
+    assert_eq!(f(5), Some(5));
+
+    let f: proc(int) -> Option<int> = Some;
+    assert_eq!(f(5), Some(5));
+}
index e18509252235de514e832233a7a8d2943535ccfe..9ca41c56dc9602174be374f0a4961da5e2fde1e5 100644 (file)
@@ -13,7 +13,7 @@
 fn test_fn() {
     type t = 'static || -> int;
     fn ten() -> int { return 10; }
-    let rs: t = { ten };
+    let rs: t = ten;
     assert!((rs() == 10));
 }
 
index e244eace65be626078c4f95eb9ca47f138a4bbe6..6dec5fdaa1cbac0a7a498c600aadc4167042e292 100644 (file)
@@ -436,20 +436,6 @@ fn visit_type(&mut self) -> bool {
         if ! self.inner().visit_type() { return false; }
         true
     }
-
-    fn visit_opaque_box(&mut self) -> bool {
-        self.align_to::<@u8>();
-        if ! self.inner().visit_opaque_box() { return false; }
-        self.bump_past::<@u8>();
-        true
-    }
-
-    fn visit_closure_ptr(&mut self, ck: uint) -> bool {
-        self.align_to::<(uint,uint)>();
-        if ! self.inner().visit_closure_ptr(ck) { return false; }
-        self.bump_past::<(uint,uint)>();
-        true
-    }
 }
 
 struct my_visitor(@RefCell<Stuff>);
@@ -611,8 +597,6 @@ fn visit_trait(&mut self, _name: &str) -> bool { true }
     fn visit_param(&mut self, _i: uint) -> bool { true }
     fn visit_self(&mut self) -> bool { true }
     fn visit_type(&mut self) -> bool { true }
-    fn visit_opaque_box(&mut self) -> bool { true }
-    fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
 }
 
 fn get_tydesc_for<T>(_t: T) -> *TyDesc {
index f5871facd1da21666312e4ab2d2a56516e9d5d97..91e69028103a33536aa675b4f6d814f8926a9671 100644 (file)
@@ -137,8 +137,6 @@ fn visit_trait(&mut self, _name: &str) -> bool { true }
     fn visit_param(&mut self, _i: uint) -> bool { true }
     fn visit_self(&mut self) -> bool { true }
     fn visit_type(&mut self) -> bool { true }
-    fn visit_opaque_box(&mut self) -> bool { true }
-    fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
 }
 
 fn visit_ty<T>(v: &mut MyVisitor) {