about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2013-03-27 12:55:18 -0400
committerGraydon Hoare <graydon@mozilla.com>2013-03-27 11:35:04 -0700
commit2a74fda316f5c4b31d3582fd1cf7b6c04c178557 (patch)
treee38ca82517d13ab78f7a8306a87506d85175031b
parent83aa70d7e3dba557d1812fe436082098cdf90c9a (diff)
downloadrust-2a74fda316f5c4b31d3582fd1cf7b6c04c178557.tar.gz
rust-2a74fda316f5c4b31d3582fd1cf7b6c04c178557.zip
Fix pretty-printer test failure by carrying the bound lifetime names through
the types.  Initially I thought it would be necessary to thread this data
through not only the AST but the types themselves, but then I remembered that
the pretty printer only cares about the AST.  Regardless, I have elected to
leave the changes to the types intact since they will eventually be needed.  I
left a few FIXMEs where it didn't seem worth finishing up since the code wasn't
crucial yet.
-rw-r--r--src/librustc/metadata/tydecode.rs5
-rw-r--r--src/librustc/middle/trans/foreign.rs4
-rw-r--r--src/librustc/middle/trans/monomorphize.rs7
-rw-r--r--src/librustc/middle/ty.rs8
-rw-r--r--src/librustc/middle/typeck/astconv.rs103
-rw-r--r--src/librustc/middle/typeck/check/mod.rs9
-rw-r--r--src/librustc/middle/typeck/collect.rs53
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs5
-rw-r--r--src/librustc/middle/typeck/rscope.rs17
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs3
-rw-r--r--src/libsyntax/print/pprust.rs12
-rw-r--r--src/test/run-pass/regions-fn-subtyping.rs2
14 files changed, 130 insertions, 100 deletions
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 8b88b39a84c..e37b3a963c4 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -24,6 +24,7 @@ use core::vec;
 use syntax::ast;
 use syntax::ast::*;
 use syntax::codemap::{respan, dummy_sp};
+use syntax::opt_vec;
 
 // Compact string representation for ty::t values. API ty_str &
 // parse_from_str. Extra parameters are for converting to/from def_ids in the
@@ -479,7 +480,9 @@ fn parse_sig(st: @mut PState, conv: conv_did) -> ty::FnSig {
     }
     st.pos += 1u; // eat the ']'
     let ret_ty = parse_ty(st, conv);
-    ty::FnSig {inputs: inputs, output: ret_ty}
+    ty::FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
+               inputs: inputs,
+               output: ret_ty}
 }
 
 // Rust metadata parsing
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 08f86bfb2df..92d231a96aa 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -40,6 +40,7 @@ use util::ppaux::ty_to_str;
 use syntax::codemap::span;
 use syntax::{ast, ast_util};
 use syntax::{attr, ast_map};
+use syntax::opt_vec;
 use syntax::parse::token::special_idents;
 
 fn abi_info(arch: session::arch) -> @cabi::ABIInfo {
@@ -615,7 +616,8 @@ pub fn trans_intrinsic(ccx: @CrateContext,
                 sigil: ast::BorrowedSigil,
                 onceness: ast::Many,
                 region: ty::re_bound(ty::br_anon(0)),
-                sig: FnSig {inputs: ~[arg {mode: ast::expl(ast::by_copy),
+                sig: FnSig {bound_lifetime_names: opt_vec::Empty,
+                            inputs: ~[arg {mode: ast::expl(ast::by_copy),
                                            ty: star_u8}],
                             output: ty::mk_nil(bcx.tcx())}
             });
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index e8c6cf78a18..0a7024b161e 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -37,6 +37,7 @@ use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_map::{path, path_mod, path_name};
 use syntax::ast_util::local_def;
+use syntax::opt_vec;
 use syntax::parse::token::special_idents;
 
 pub fn monomorphic_fn(ccx: @CrateContext,
@@ -282,7 +283,8 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
                 ty::BareFnTy {
                     purity: ast::impure_fn,
                     abi: ast::RustAbi,
-                    sig: FnSig {inputs: ~[],
+                    sig: FnSig {bound_lifetime_names: opt_vec::Empty,
+                                inputs: ~[],
                                 output: ty::mk_nil(tcx)}}))
         }
         ty::ty_closure(ref fty) => {
@@ -316,7 +318,8 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
                 sigil: sigil,
                 onceness: ast::Many,
                 region: ty::re_static,
-                sig: ty::FnSig {inputs: ~[],
+                sig: ty::FnSig {bound_lifetime_names: opt_vec::Empty,
+                                inputs: ~[],
                                 output: ty::mk_nil(tcx)}})
     }
 }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index edf76ee7c36..0d36453c757 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -45,6 +45,8 @@ use syntax::codemap::span;
 use syntax::codemap;
 use syntax::print::pprust;
 use syntax::{ast, ast_map};
+use syntax::opt_vec::OptVec;
+use syntax::opt_vec;
 use syntax;
 
 // Data types
@@ -376,10 +378,12 @@ pub struct ClosureTy {
  * Signature of a function type, which I have arbitrarily
  * decided to use to refer to the input/output types.
  *
+ * - `lifetimes` is the list of region names bound in this fn.
  * - `inputs` is the list of arguments and their modes.
  * - `output` is the return type. */
 #[deriving(Eq)]
 pub struct FnSig {
+    bound_lifetime_names: OptVec<ast::ident>,
     inputs: ~[arg],
     output: t
 }
@@ -1062,7 +1066,8 @@ pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t {
                BareFnTy {
                    purity: ast::pure_fn,
                    abi: ast::RustAbi,
-                   sig: FnSig {inputs: input_args,
+                   sig: FnSig {bound_lifetime_names: opt_vec::Empty,
+                               inputs: input_args,
                                output: output}})
 }
 
@@ -1203,6 +1208,7 @@ pub fn fold_sig(sig: &FnSig, fldop: &fn(t) -> t) -> FnSig {
     };
 
     FnSig {
+        bound_lifetime_names: copy sig.bound_lifetime_names,
         inputs: args,
         output: fldop(sig.output)
     }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index dad660e8c70..b167f0c0d75 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -58,7 +58,7 @@ use middle::const_eval;
 use middle::ty::{arg, field, substs};
 use middle::ty::{ty_param_substs_and_ty};
 use middle::ty;
-use middle::typeck::rscope::{in_binding_rscope, in_binding_rscope_ext};
+use middle::typeck::rscope::{in_binding_rscope};
 use middle::typeck::rscope::{region_scope, type_rscope, RegionError};
 use middle::typeck::rscope::{RegionParamNames};
 
@@ -67,6 +67,7 @@ use core::vec;
 use syntax::{ast, ast_util};
 use syntax::codemap::span;
 use syntax::opt_vec::OptVec;
+use syntax::opt_vec;
 use syntax::print::pprust::{lifetime_to_str, path_to_str};
 use syntax::parse::token::special_idents;
 use util::common::indenter;
@@ -347,7 +348,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
       }
       ast::ty_bare_fn(ref bf) => {
           ty::mk_bare_fn(tcx, ty_of_bare_fn(self, rscope, bf.purity,
-                                            bf.abi, &bf.decl))
+                                            bf.abi, &bf.lifetimes, &bf.decl))
       }
       ast::ty_closure(ref f) => {
           let fn_decl = ty_of_closure(self,
@@ -508,45 +509,50 @@ pub fn ty_of_arg<AC:AstConv,RS:region_scope + Copy + Durable>(
     arg {mode: mode, ty: ty}
 }
 
-pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
-        self: &AC,
-        rscope: &RS,
-        purity: ast::purity,
-        abi: ast::Abi,
-        decl: &ast::fn_decl)
-     -> ty::BareFnTy {
-    debug!("ty_of_bare_fn");
-
-    // new region names that appear inside of the fn decl are bound to
-    // that function type
-    let rb = in_binding_rscope(rscope);
-
-    let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
-    let output_ty = match decl.output.node {
-        ast::ty_infer => self.ty_infer(decl.output.span),
-        _ => ast_ty_to_ty(self, &rb, decl.output)
-    };
-
-    ty::BareFnTy {
-        purity: purity,
-        abi: abi,
-        sig: ty::FnSig {inputs: input_tys, output: output_ty}
-    }
+pub fn bound_lifetimes<AC:AstConv>(
+    self: &AC,
+    ast_lifetimes: &OptVec<ast::Lifetime>) -> OptVec<ast::ident>
+{
+    /*!
+     *
+     * Converts a list of lifetimes into a list of bound identifier
+     * names.  Does not permit special names like 'static or 'self to
+     * be bound.  Note that this function is for use in closures,
+     * methods, and fn definitions.  It is legal to bind 'self in a
+     * type.  Eventually this distinction should go away and the same
+     * rules should apply everywhere ('self would not be a special name
+     * at that point).
+     */
+
+    let special_idents = [special_idents::static, special_idents::self_];
+    let mut bound_lifetime_names = opt_vec::Empty;
+    ast_lifetimes.map_to_vec(|ast_lifetime| {
+        if special_idents.any(|&i| i == ast_lifetime.ident) {
+            self.tcx().sess.span_err(
+                ast_lifetime.span,
+                fmt!("illegal lifetime parameter name: `%s`",
+                     lifetime_to_str(ast_lifetime, self.tcx().sess.intr())));
+        } else {
+            bound_lifetime_names.push(ast_lifetime.ident);
+        }
+    });
+    bound_lifetime_names
 }
 
-pub fn ty_of_bare_fn_ext<AC:AstConv,RS:region_scope + Copy + Durable>(
-        self: &AC,
-        rscope: &RS,
-        purity: ast::purity,
-        abi: ast::Abi,
-        decl: &ast::fn_decl,
-        +region_param_names: RegionParamNames)
-     -> ty::BareFnTy {
-    debug!("ty_of_bare_fn_ext");
+pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
+    self: &AC,
+    rscope: &RS,
+    purity: ast::purity,
+    abi: ast::Abi,
+    lifetimes: &OptVec<ast::Lifetime>,
+    decl: &ast::fn_decl) -> ty::BareFnTy
+{
+    debug!("ty_of_bare_fn");
 
     // new region names that appear inside of the fn decl are bound to
     // that function type
-    let rb = in_binding_rscope_ext(rscope, region_param_names);
+    let bound_lifetime_names = bound_lifetimes(self, lifetimes);
+    let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
 
     let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
     let output_ty = match decl.output.node {
@@ -557,7 +563,9 @@ pub fn ty_of_bare_fn_ext<AC:AstConv,RS:region_scope + Copy + Durable>(
     ty::BareFnTy {
         purity: purity,
         abi: abi,
-        sig: ty::FnSig {inputs: input_tys, output: output_ty}
+        sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
+                        inputs: input_tys,
+                        output: output_ty}
     }
 }
 
@@ -569,10 +577,16 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
         onceness: ast::Onceness,
         opt_lifetime: Option<@ast::Lifetime>,
         decl: &ast::fn_decl,
-        expected_tys: Option<ty::FnSig>,
+        expected_sig: Option<ty::FnSig>,
         lifetimes: &OptVec<ast::Lifetime>,
         span: span)
-     -> ty::ClosureTy {
+     -> ty::ClosureTy
+{
+    // The caller should not both provide explicit bound lifetime
+    // names and expected types.  Either we infer the bound lifetime
+    // names or they are provided, but not both.
+    fail_unless!(lifetimes.is_empty() || expected_sig.is_none());
+
     debug!("ty_of_fn_decl");
     let _i = indenter();
 
@@ -599,11 +613,11 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
 
     // new region names that appear inside of the fn decl are bound to
     // that function type
-    let region_param_names = RegionParamNames::from_lifetimes(lifetimes);
-    let rb = in_binding_rscope_ext(rscope, region_param_names);
+    let bound_lifetime_names = bound_lifetimes(self, lifetimes);
+    let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
 
     let input_tys = do decl.inputs.mapi |i, a| {
-        let expected_arg_ty = do expected_tys.chain_ref |e| {
+        let expected_arg_ty = do expected_sig.chain_ref |e| {
             // no guarantee that the correct number of expected args
             // were supplied
             if i < e.inputs.len() {Some(e.inputs[i])} else {None}
@@ -611,7 +625,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
         ty_of_arg(self, &rb, *a, expected_arg_ty)
     };
 
-    let expected_ret_ty = expected_tys.map(|e| e.output);
+    let expected_ret_ty = expected_sig.map(|e| e.output);
     let output_ty = match decl.output.node {
         ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(),
         ast::ty_infer => self.ty_infer(decl.output.span),
@@ -623,7 +637,8 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
         sigil: sigil,
         onceness: onceness,
         region: bound_region,
-        sig: ty::FnSig {inputs: input_tys,
+        sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
+                        inputs: input_tys,
                         output: output_ty}
     }
 }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 75c6bfd5d64..90e6b6c88a5 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1633,7 +1633,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
         // sigils.
         let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
         let mut error_happened = false;
-        let (expected_tys,
+        let (expected_sig,
              expected_purity,
              expected_sigil,
              expected_onceness) = {
@@ -1668,13 +1668,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
                                                expected_onceness,
                                                None,
                                                decl,
-                                               expected_tys,
+                                               expected_sig,
                                                &opt_vec::Empty,
                                                expr.span);
 
         let mut fty_sig;
         let fty = if error_happened {
             fty_sig = FnSig {
+                bound_lifetime_names: opt_vec::Empty,
                 inputs: fn_ty.sig.inputs.map(|an_arg| {
                     arg { mode: an_arg.mode,
                          ty: ty::mk_err(tcx)
@@ -3492,6 +3493,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
             onceness: ast::Once,
             region: ty::re_bound(ty::br_anon(0)),
             sig: ty::FnSig {
+                bound_lifetime_names: opt_vec::Empty,
                 inputs: ~[arg {mode: ast::expl(ast::by_copy),
                                ty: ty::mk_imm_ptr(
                                    ccx.tcx,
@@ -3723,7 +3725,8 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
     let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
         purity: ast::unsafe_fn,
         abi: ast::RustAbi,
-        sig: FnSig {inputs: inputs,
+        sig: FnSig {bound_lifetime_names: opt_vec::Empty,
+                    inputs: inputs,
                     output: output}
     });
     let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 6d304247c5d..573285c357e 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -59,6 +59,7 @@ use syntax::codemap;
 use syntax::print::pprust::path_to_str;
 use syntax::visit;
 use syntax::opt_vec::OptVec;
+use syntax::opt_vec;
 
 pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) {
 
@@ -716,6 +717,7 @@ pub fn convert_struct(ccx: &CrateCtxt,
                 &type_rscope(region_parameterization),
                 ast::impure_fn,
                 ast::RustAbi,
+                &opt_vec::Empty,
                 &ast_util::dtor_dec()));
         write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
         tcx.tcache.insert(local_def(dtor.node.id),
@@ -776,17 +778,16 @@ pub fn ty_of_method(ccx: &CrateCtxt,
                  -> ty::method {
     let rscope = MethodRscope::new(m.self_ty.node,
                                    rp,
-                                   rcvr_generics,
-                                   method_generics);
+                                   rcvr_generics);
     ty::method {
         ident: m.ident,
         tps: ty_param_bounds(ccx, &m.generics),
-        fty: astconv::ty_of_bare_fn_ext(ccx,
-                                        &rscope,
-                                        m.purity,
-                                        ast::RustAbi,
-                                        &m.decl,
-                                        rscope.region_param_names()),
+        fty: astconv::ty_of_bare_fn(ccx,
+                                    &rscope,
+                                    m.purity,
+                                    ast::RustAbi,
+                                    &method_generics.lifetimes,
+                                    &m.decl),
         self_ty: m.self_ty.node,
         vis: m.vis,
         def_id: local_def(m.id)
@@ -799,16 +800,16 @@ pub fn ty_of_ty_method(self: &CrateCtxt,
                        id: ast::def_id,
                        generics: &ast::Generics)
                     -> ty::method {
-    let rscope = MethodRscope::new(m.self_ty.node, rp, generics, &m.generics);
+    let rscope = MethodRscope::new(m.self_ty.node, rp, generics);
     ty::method {
         ident: m.ident,
         tps: ty_param_bounds(self, &m.generics),
-        fty: astconv::ty_of_bare_fn_ext(self,
-                                        &rscope,
-                                        m.purity,
-                                        ast::RustAbi,
-                                        &m.decl,
-                                        rscope.region_param_names()),
+        fty: astconv::ty_of_bare_fn(self,
+                                    &rscope,
+                                    m.purity,
+                                    ast::RustAbi,
+                                    &m.generics.lifetimes,
+                                    &m.decl),
         // assume public, because this is only invoked on trait methods
         self_ty: m.self_ty.node,
         vis: ast::public,
@@ -869,13 +870,12 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item)
       }
       ast::item_fn(ref decl, purity, ref generics, _) => {
         let bounds = ty_param_bounds(ccx, generics);
-        let region_param_names = RegionParamNames::from_generics(generics);
-        let tofd = astconv::ty_of_bare_fn_ext(ccx,
-                                              &empty_rscope,
-                                              purity,
-                                              ast::RustAbi,
-                                              decl,
-                                              region_param_names);
+        let tofd = astconv::ty_of_bare_fn(ccx,
+                                          &empty_rscope,
+                                          purity,
+                                          ast::RustAbi,
+                                          &generics.lifetimes,
+                                          decl);
         let tpt = ty_param_bounds_and_ty {
             bounds: bounds,
             region_param: None,
@@ -971,11 +971,10 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt, it: @ast::foreign_item)
                                   generics)
         }
         ast::foreign_item_const(t) => {
-            let rb = in_binding_rscope(&empty_rscope);
             ty::ty_param_bounds_and_ty {
                 bounds: @~[],
                 region_param: None,
-                ty: ast_ty_to_ty(ccx, &rb, t)
+                ty: ast_ty_to_ty(ccx, &empty_rscope, t)
             }
         }
     }
@@ -1043,7 +1042,7 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
                           -> ty::ty_param_bounds_and_ty {
     let bounds = ty_param_bounds(ccx, generics);
     let region_param_names = RegionParamNames::from_generics(generics);
-    let rb = in_binding_rscope_ext(&empty_rscope, region_param_names);
+    let rb = in_binding_rscope(&empty_rscope, region_param_names);
     let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, &rb, *a, None) );
     let output_ty = ast_ty_to_ty(ccx, &rb, decl.output);
 
@@ -1052,7 +1051,9 @@ pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
         ty::BareFnTy {
             abi: ast::RustAbi,
             purity: ast::unsafe_fn,
-            sig: ty::FnSig {inputs: input_tys, output: output_ty}
+            sig: ty::FnSig {bound_lifetime_names: opt_vec::Empty,
+                            inputs: input_tys,
+                            output: output_ty}
         });
     let tpt = ty_param_bounds_and_ty {
         bounds: bounds,
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index 8b128dbc5c5..2c053e2bbe0 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -70,6 +70,7 @@ use core::result::{iter_vec2, map_vec2};
 use core::vec;
 use syntax::ast::{Onceness, purity, ret_style};
 use syntax::ast;
+use syntax::opt_vec;
 use syntax::codemap::span;
 
 pub trait Combine {
@@ -432,7 +433,9 @@ pub fn super_fn_sigs<C:Combine>(
     do argvecs(self, a_f.inputs, b_f.inputs)
             .chain |inputs| {
         do self.tys(a_f.output, b_f.output).chain |output| {
-            Ok(FnSig {inputs: /*bad*/copy inputs, output: output})
+            Ok(FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
+                      inputs: /*bad*/copy inputs,
+                      output: output})
         }
     }
 }
diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs
index 135993e18a2..7082c154d2f 100644
--- a/src/librustc/middle/typeck/rscope.rs
+++ b/src/librustc/middle/typeck/rscope.rs
@@ -156,12 +156,10 @@ impl MethodRscope {
     // trait).
     pub fn new(self_ty: ast::self_ty_,
                variance: Option<ty::region_variance>,
-               rcvr_generics: &ast::Generics,
-               method_generics: &ast::Generics)
+               rcvr_generics: &ast::Generics)
             -> MethodRscope {
         let mut region_param_names =
             RegionParamNames::from_generics(rcvr_generics);
-        region_param_names.add_generics(method_generics);
         MethodRscope {
             self_ty: self_ty,
             variance: variance,
@@ -273,18 +271,7 @@ pub struct binding_rscope {
     region_param_names: RegionParamNames,
 }
 
-pub fn in_binding_rscope<RS:region_scope + Copy + Durable>(self: &RS)
-    -> binding_rscope {
-    let base = @copy *self;
-    let base = base as @region_scope;
-    binding_rscope {
-        base: base,
-        anon_bindings: @mut 0,
-        region_param_names: RegionParamNames::new()
-    }
-}
-
-pub fn in_binding_rscope_ext<RS:region_scope + Copy + Durable>(
+pub fn in_binding_rscope<RS:region_scope + Copy + Durable>(
         self: &RS,
         +region_param_names: RegionParamNames)
      -> binding_rscope {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 6071cc643a3..9112e92df7e 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -904,6 +904,7 @@ pub struct TyClosure {
 pub struct TyBareFn {
     purity: purity,
     abi: Abi,
+    lifetimes: OptVec<Lifetime>,
     decl: fn_decl
 }
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 017e95ab4c1..9d4cf4e8939 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -615,6 +615,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
         }
         ty_bare_fn(ref f) => {
             ty_bare_fn(@TyBareFn {
+                lifetimes: f.lifetimes,
                 purity: f.purity,
                 abi: f.abi,
                 decl: fold_fn_decl(&f.decl, fld)
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 53d618e3340..c82151bb4a9 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -363,10 +363,11 @@ pub impl Parser {
 
         let purity = self.parse_purity();
         self.expect_keyword(&~"fn");
-        let (decl, _) = self.parse_ty_fn_decl();
+        let (decl, lifetimes) = self.parse_ty_fn_decl();
         return ty_bare_fn(@TyBareFn {
             abi: RustAbi,
             purity: purity,
+            lifetimes: lifetimes,
             decl: decl
         });
     }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 9a9834c488b..a6064b467b1 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -14,6 +14,7 @@ use ast::{RegionTyParamBound, TraitTyParamBound, required, provided};
 use ast;
 use ast_util;
 use opt_vec::OptVec;
+use opt_vec;
 use attr;
 use codemap::{CodeMap, BytePos};
 use codemap;
@@ -402,14 +403,18 @@ pub fn print_type(s: @ps, &&ty: @ast::Ty) {
         pclose(s);
       }
       ast::ty_bare_fn(f) => {
+          let generics = ast::Generics {lifetimes: copy f.lifetimes,
+                                        ty_params: opt_vec::Empty};
           print_ty_fn(s, Some(f.abi), None, None,
                       f.purity, ast::Many, &f.decl, None,
-                      None, None);
+                      Some(&generics), None);
       }
       ast::ty_closure(f) => {
+          let generics = ast::Generics {lifetimes: copy f.lifetimes,
+                                        ty_params: opt_vec::Empty};
           print_ty_fn(s, None, Some(f.sigil), f.region,
                       f.purity, f.onceness, &f.decl, None,
-                      None, None);
+                      Some(&generics), None);
       }
       ast::ty_path(path, _) => print_path(s, path, false),
       ast::ty_fixed_length_vec(ref mt, v) => {
@@ -1923,7 +1928,8 @@ pub fn print_ty_fn(s: @ps,
                    opt_region: Option<@ast::Lifetime>,
                    purity: ast::purity,
                    onceness: ast::Onceness,
-                   decl: &ast::fn_decl, id: Option<ast::ident>,
+                   decl: &ast::fn_decl,
+                   id: Option<ast::ident>,
                    generics: Option<&ast::Generics>,
                    opt_self_ty: Option<ast::self_ty_>) {
     ibox(s, indent_unit);
diff --git a/src/test/run-pass/regions-fn-subtyping.rs b/src/test/run-pass/regions-fn-subtyping.rs
index 3233e900e58..652a7a33396 100644
--- a/src/test/run-pass/regions-fn-subtyping.rs
+++ b/src/test/run-pass/regions-fn-subtyping.rs
@@ -1,5 +1,3 @@
-// xfail-pretty
-
 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.