1
Fork 0

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.
This commit is contained in:
Niko Matsakis 2013-03-27 12:55:18 -04:00 committed by Graydon Hoare
parent 83aa70d7e3
commit 2a74fda316
14 changed files with 130 additions and 100 deletions

View file

@ -24,6 +24,7 @@ use core::vec;
use syntax::ast; use syntax::ast;
use syntax::ast::*; use syntax::ast::*;
use syntax::codemap::{respan, dummy_sp}; use syntax::codemap::{respan, dummy_sp};
use syntax::opt_vec;
// Compact string representation for ty::t values. API ty_str & // Compact string representation for ty::t values. API ty_str &
// parse_from_str. Extra parameters are for converting to/from def_ids in the // 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 ']' st.pos += 1u; // eat the ']'
let ret_ty = parse_ty(st, conv); 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 // Rust metadata parsing

View file

@ -40,6 +40,7 @@ use util::ppaux::ty_to_str;
use syntax::codemap::span; use syntax::codemap::span;
use syntax::{ast, ast_util}; use syntax::{ast, ast_util};
use syntax::{attr, ast_map}; use syntax::{attr, ast_map};
use syntax::opt_vec;
use syntax::parse::token::special_idents; use syntax::parse::token::special_idents;
fn abi_info(arch: session::arch) -> @cabi::ABIInfo { fn abi_info(arch: session::arch) -> @cabi::ABIInfo {
@ -615,7 +616,8 @@ pub fn trans_intrinsic(ccx: @CrateContext,
sigil: ast::BorrowedSigil, sigil: ast::BorrowedSigil,
onceness: ast::Many, onceness: ast::Many,
region: ty::re_bound(ty::br_anon(0)), 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}], ty: star_u8}],
output: ty::mk_nil(bcx.tcx())} output: ty::mk_nil(bcx.tcx())}
}); });

View file

@ -37,6 +37,7 @@ use syntax::ast;
use syntax::ast_map; use syntax::ast_map;
use syntax::ast_map::{path, path_mod, path_name}; use syntax::ast_map::{path, path_mod, path_name};
use syntax::ast_util::local_def; use syntax::ast_util::local_def;
use syntax::opt_vec;
use syntax::parse::token::special_idents; use syntax::parse::token::special_idents;
pub fn monomorphic_fn(ccx: @CrateContext, pub fn monomorphic_fn(ccx: @CrateContext,
@ -282,7 +283,8 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
ty::BareFnTy { ty::BareFnTy {
purity: ast::impure_fn, purity: ast::impure_fn,
abi: ast::RustAbi, abi: ast::RustAbi,
sig: FnSig {inputs: ~[], sig: FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: ~[],
output: ty::mk_nil(tcx)}})) output: ty::mk_nil(tcx)}}))
} }
ty::ty_closure(ref fty) => { ty::ty_closure(ref fty) => {
@ -316,7 +318,8 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
sigil: sigil, sigil: sigil,
onceness: ast::Many, onceness: ast::Many,
region: ty::re_static, region: ty::re_static,
sig: ty::FnSig {inputs: ~[], sig: ty::FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: ~[],
output: ty::mk_nil(tcx)}}) output: ty::mk_nil(tcx)}})
} }
} }

View file

@ -45,6 +45,8 @@ use syntax::codemap::span;
use syntax::codemap; use syntax::codemap;
use syntax::print::pprust; use syntax::print::pprust;
use syntax::{ast, ast_map}; use syntax::{ast, ast_map};
use syntax::opt_vec::OptVec;
use syntax::opt_vec;
use syntax; use syntax;
// Data types // Data types
@ -376,10 +378,12 @@ pub struct ClosureTy {
* Signature of a function type, which I have arbitrarily * Signature of a function type, which I have arbitrarily
* decided to use to refer to the input/output types. * 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. * - `inputs` is the list of arguments and their modes.
* - `output` is the return type. */ * - `output` is the return type. */
#[deriving(Eq)] #[deriving(Eq)]
pub struct FnSig { pub struct FnSig {
bound_lifetime_names: OptVec<ast::ident>,
inputs: ~[arg], inputs: ~[arg],
output: t output: t
} }
@ -1062,7 +1066,8 @@ pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t {
BareFnTy { BareFnTy {
purity: ast::pure_fn, purity: ast::pure_fn,
abi: ast::RustAbi, abi: ast::RustAbi,
sig: FnSig {inputs: input_args, sig: FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: input_args,
output: output}}) output: output}})
} }
@ -1203,6 +1208,7 @@ pub fn fold_sig(sig: &FnSig, fldop: &fn(t) -> t) -> FnSig {
}; };
FnSig { FnSig {
bound_lifetime_names: copy sig.bound_lifetime_names,
inputs: args, inputs: args,
output: fldop(sig.output) output: fldop(sig.output)
} }

View file

@ -58,7 +58,7 @@ use middle::const_eval;
use middle::ty::{arg, field, substs}; use middle::ty::{arg, field, substs};
use middle::ty::{ty_param_substs_and_ty}; use middle::ty::{ty_param_substs_and_ty};
use middle::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::{region_scope, type_rscope, RegionError};
use middle::typeck::rscope::{RegionParamNames}; use middle::typeck::rscope::{RegionParamNames};
@ -67,6 +67,7 @@ use core::vec;
use syntax::{ast, ast_util}; use syntax::{ast, ast_util};
use syntax::codemap::span; use syntax::codemap::span;
use syntax::opt_vec::OptVec; use syntax::opt_vec::OptVec;
use syntax::opt_vec;
use syntax::print::pprust::{lifetime_to_str, path_to_str}; use syntax::print::pprust::{lifetime_to_str, path_to_str};
use syntax::parse::token::special_idents; use syntax::parse::token::special_idents;
use util::common::indenter; 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) => { ast::ty_bare_fn(ref bf) => {
ty::mk_bare_fn(tcx, ty_of_bare_fn(self, rscope, bf.purity, 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) => { ast::ty_closure(ref f) => {
let fn_decl = ty_of_closure(self, let fn_decl = ty_of_closure(self,
@ -508,18 +509,50 @@ pub fn ty_of_arg<AC:AstConv,RS:region_scope + Copy + Durable>(
arg {mode: mode, ty: ty} arg {mode: mode, ty: 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<AC:AstConv,RS:region_scope + Copy + Durable>( pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
self: &AC, self: &AC,
rscope: &RS, rscope: &RS,
purity: ast::purity, purity: ast::purity,
abi: ast::Abi, abi: ast::Abi,
decl: &ast::fn_decl) lifetimes: &OptVec<ast::Lifetime>,
-> ty::BareFnTy { decl: &ast::fn_decl) -> ty::BareFnTy
{
debug!("ty_of_bare_fn"); debug!("ty_of_bare_fn");
// new region names that appear inside of the fn decl are bound to // new region names that appear inside of the fn decl are bound to
// that function type // that function type
let rb = in_binding_rscope(rscope); 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 input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
let output_ty = match decl.output.node { let output_ty = match decl.output.node {
@ -530,34 +563,9 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
ty::BareFnTy { ty::BareFnTy {
purity: purity, purity: purity,
abi: abi, 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}
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");
// 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 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}
} }
} }
@ -569,10 +577,16 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
onceness: ast::Onceness, onceness: ast::Onceness,
opt_lifetime: Option<@ast::Lifetime>, opt_lifetime: Option<@ast::Lifetime>,
decl: &ast::fn_decl, decl: &ast::fn_decl,
expected_tys: Option<ty::FnSig>, expected_sig: Option<ty::FnSig>,
lifetimes: &OptVec<ast::Lifetime>, lifetimes: &OptVec<ast::Lifetime>,
span: span) 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"); debug!("ty_of_fn_decl");
let _i = indenter(); 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 // new region names that appear inside of the fn decl are bound to
// that function type // that function type
let region_param_names = RegionParamNames::from_lifetimes(lifetimes); let bound_lifetime_names = bound_lifetimes(self, lifetimes);
let rb = in_binding_rscope_ext(rscope, region_param_names); let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
let input_tys = do decl.inputs.mapi |i, a| { 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 // no guarantee that the correct number of expected args
// were supplied // were supplied
if i < e.inputs.len() {Some(e.inputs[i])} else {None} 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) 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 { let output_ty = match decl.output.node {
ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(), ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(),
ast::ty_infer => self.ty_infer(decl.output.span), 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, sigil: sigil,
onceness: onceness, onceness: onceness,
region: bound_region, region: bound_region,
sig: ty::FnSig {inputs: input_tys, sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
inputs: input_tys,
output: output_ty} output: output_ty}
} }
} }

View file

@ -1633,7 +1633,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
// sigils. // sigils.
let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x)); let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
let mut error_happened = false; let mut error_happened = false;
let (expected_tys, let (expected_sig,
expected_purity, expected_purity,
expected_sigil, expected_sigil,
expected_onceness) = { expected_onceness) = {
@ -1668,13 +1668,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
expected_onceness, expected_onceness,
None, None,
decl, decl,
expected_tys, expected_sig,
&opt_vec::Empty, &opt_vec::Empty,
expr.span); expr.span);
let mut fty_sig; let mut fty_sig;
let fty = if error_happened { let fty = if error_happened {
fty_sig = FnSig { fty_sig = FnSig {
bound_lifetime_names: opt_vec::Empty,
inputs: fn_ty.sig.inputs.map(|an_arg| { inputs: fn_ty.sig.inputs.map(|an_arg| {
arg { mode: an_arg.mode, arg { mode: an_arg.mode,
ty: ty::mk_err(tcx) ty: ty::mk_err(tcx)
@ -3492,6 +3493,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
onceness: ast::Once, onceness: ast::Once,
region: ty::re_bound(ty::br_anon(0)), region: ty::re_bound(ty::br_anon(0)),
sig: ty::FnSig { sig: ty::FnSig {
bound_lifetime_names: opt_vec::Empty,
inputs: ~[arg {mode: ast::expl(ast::by_copy), inputs: ~[arg {mode: ast::expl(ast::by_copy),
ty: ty::mk_imm_ptr( ty: ty::mk_imm_ptr(
ccx.tcx, 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 { let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
purity: ast::unsafe_fn, purity: ast::unsafe_fn,
abi: ast::RustAbi, abi: ast::RustAbi,
sig: FnSig {inputs: inputs, sig: FnSig {bound_lifetime_names: opt_vec::Empty,
inputs: inputs,
output: output} output: output}
}); });
let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id)); let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));

View file

@ -59,6 +59,7 @@ use syntax::codemap;
use syntax::print::pprust::path_to_str; use syntax::print::pprust::path_to_str;
use syntax::visit; use syntax::visit;
use syntax::opt_vec::OptVec; use syntax::opt_vec::OptVec;
use syntax::opt_vec;
pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) { 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), &type_rscope(region_parameterization),
ast::impure_fn, ast::impure_fn,
ast::RustAbi, ast::RustAbi,
&opt_vec::Empty,
&ast_util::dtor_dec())); &ast_util::dtor_dec()));
write_ty_to_tcx(tcx, dtor.node.id, t_dtor); write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
tcx.tcache.insert(local_def(dtor.node.id), tcx.tcache.insert(local_def(dtor.node.id),
@ -776,17 +778,16 @@ pub fn ty_of_method(ccx: &CrateCtxt,
-> ty::method { -> ty::method {
let rscope = MethodRscope::new(m.self_ty.node, let rscope = MethodRscope::new(m.self_ty.node,
rp, rp,
rcvr_generics, rcvr_generics);
method_generics);
ty::method { ty::method {
ident: m.ident, ident: m.ident,
tps: ty_param_bounds(ccx, &m.generics), tps: ty_param_bounds(ccx, &m.generics),
fty: astconv::ty_of_bare_fn_ext(ccx, fty: astconv::ty_of_bare_fn(ccx,
&rscope, &rscope,
m.purity, m.purity,
ast::RustAbi, ast::RustAbi,
&m.decl, &method_generics.lifetimes,
rscope.region_param_names()), &m.decl),
self_ty: m.self_ty.node, self_ty: m.self_ty.node,
vis: m.vis, vis: m.vis,
def_id: local_def(m.id) def_id: local_def(m.id)
@ -799,16 +800,16 @@ pub fn ty_of_ty_method(self: &CrateCtxt,
id: ast::def_id, id: ast::def_id,
generics: &ast::Generics) generics: &ast::Generics)
-> ty::method { -> 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 { ty::method {
ident: m.ident, ident: m.ident,
tps: ty_param_bounds(self, &m.generics), tps: ty_param_bounds(self, &m.generics),
fty: astconv::ty_of_bare_fn_ext(self, fty: astconv::ty_of_bare_fn(self,
&rscope, &rscope,
m.purity, m.purity,
ast::RustAbi, ast::RustAbi,
&m.decl, &m.generics.lifetimes,
rscope.region_param_names()), &m.decl),
// assume public, because this is only invoked on trait methods // assume public, because this is only invoked on trait methods
self_ty: m.self_ty.node, self_ty: m.self_ty.node,
vis: ast::public, 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, _) => { ast::item_fn(ref decl, purity, ref generics, _) => {
let bounds = ty_param_bounds(ccx, generics); let bounds = ty_param_bounds(ccx, generics);
let region_param_names = RegionParamNames::from_generics(generics); let tofd = astconv::ty_of_bare_fn(ccx,
let tofd = astconv::ty_of_bare_fn_ext(ccx,
&empty_rscope, &empty_rscope,
purity, purity,
ast::RustAbi, ast::RustAbi,
decl, &generics.lifetimes,
region_param_names); decl);
let tpt = ty_param_bounds_and_ty { let tpt = ty_param_bounds_and_ty {
bounds: bounds, bounds: bounds,
region_param: None, region_param: None,
@ -971,11 +971,10 @@ pub fn ty_of_foreign_item(ccx: &CrateCtxt, it: @ast::foreign_item)
generics) generics)
} }
ast::foreign_item_const(t) => { ast::foreign_item_const(t) => {
let rb = in_binding_rscope(&empty_rscope);
ty::ty_param_bounds_and_ty { ty::ty_param_bounds_and_ty {
bounds: @~[], bounds: @~[],
region_param: None, 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 { -> ty::ty_param_bounds_and_ty {
let bounds = ty_param_bounds(ccx, generics); let bounds = ty_param_bounds(ccx, generics);
let region_param_names = RegionParamNames::from_generics(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 input_tys = decl.inputs.map(|a| ty_of_arg(ccx, &rb, *a, None) );
let output_ty = ast_ty_to_ty(ccx, &rb, decl.output); 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 { ty::BareFnTy {
abi: ast::RustAbi, abi: ast::RustAbi,
purity: ast::unsafe_fn, 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 { let tpt = ty_param_bounds_and_ty {
bounds: bounds, bounds: bounds,

View file

@ -70,6 +70,7 @@ use core::result::{iter_vec2, map_vec2};
use core::vec; use core::vec;
use syntax::ast::{Onceness, purity, ret_style}; use syntax::ast::{Onceness, purity, ret_style};
use syntax::ast; use syntax::ast;
use syntax::opt_vec;
use syntax::codemap::span; use syntax::codemap::span;
pub trait Combine { pub trait Combine {
@ -432,7 +433,9 @@ pub fn super_fn_sigs<C:Combine>(
do argvecs(self, a_f.inputs, b_f.inputs) do argvecs(self, a_f.inputs, b_f.inputs)
.chain |inputs| { .chain |inputs| {
do self.tys(a_f.output, b_f.output).chain |output| { 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})
} }
} }
} }

View file

@ -156,12 +156,10 @@ impl MethodRscope {
// trait). // trait).
pub fn new(self_ty: ast::self_ty_, pub fn new(self_ty: ast::self_ty_,
variance: Option<ty::region_variance>, variance: Option<ty::region_variance>,
rcvr_generics: &ast::Generics, rcvr_generics: &ast::Generics)
method_generics: &ast::Generics)
-> MethodRscope { -> MethodRscope {
let mut region_param_names = let mut region_param_names =
RegionParamNames::from_generics(rcvr_generics); RegionParamNames::from_generics(rcvr_generics);
region_param_names.add_generics(method_generics);
MethodRscope { MethodRscope {
self_ty: self_ty, self_ty: self_ty,
variance: variance, variance: variance,
@ -273,18 +271,7 @@ pub struct binding_rscope {
region_param_names: RegionParamNames, region_param_names: RegionParamNames,
} }
pub fn in_binding_rscope<RS:region_scope + Copy + Durable>(self: &RS) pub fn in_binding_rscope<RS:region_scope + Copy + Durable>(
-> 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>(
self: &RS, self: &RS,
+region_param_names: RegionParamNames) +region_param_names: RegionParamNames)
-> binding_rscope { -> binding_rscope {

View file

@ -904,6 +904,7 @@ pub struct TyClosure {
pub struct TyBareFn { pub struct TyBareFn {
purity: purity, purity: purity,
abi: Abi, abi: Abi,
lifetimes: OptVec<Lifetime>,
decl: fn_decl decl: fn_decl
} }

View file

@ -615,6 +615,7 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
} }
ty_bare_fn(ref f) => { ty_bare_fn(ref f) => {
ty_bare_fn(@TyBareFn { ty_bare_fn(@TyBareFn {
lifetimes: f.lifetimes,
purity: f.purity, purity: f.purity,
abi: f.abi, abi: f.abi,
decl: fold_fn_decl(&f.decl, fld) decl: fold_fn_decl(&f.decl, fld)

View file

@ -363,10 +363,11 @@ pub impl Parser {
let purity = self.parse_purity(); let purity = self.parse_purity();
self.expect_keyword(&~"fn"); self.expect_keyword(&~"fn");
let (decl, _) = self.parse_ty_fn_decl(); let (decl, lifetimes) = self.parse_ty_fn_decl();
return ty_bare_fn(@TyBareFn { return ty_bare_fn(@TyBareFn {
abi: RustAbi, abi: RustAbi,
purity: purity, purity: purity,
lifetimes: lifetimes,
decl: decl decl: decl
}); });
} }

View file

@ -14,6 +14,7 @@ use ast::{RegionTyParamBound, TraitTyParamBound, required, provided};
use ast; use ast;
use ast_util; use ast_util;
use opt_vec::OptVec; use opt_vec::OptVec;
use opt_vec;
use attr; use attr;
use codemap::{CodeMap, BytePos}; use codemap::{CodeMap, BytePos};
use codemap; use codemap;
@ -402,14 +403,18 @@ pub fn print_type(s: @ps, &&ty: @ast::Ty) {
pclose(s); pclose(s);
} }
ast::ty_bare_fn(f) => { 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, print_ty_fn(s, Some(f.abi), None, None,
f.purity, ast::Many, &f.decl, None, f.purity, ast::Many, &f.decl, None,
None, None); Some(&generics), None);
} }
ast::ty_closure(f) => { 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, print_ty_fn(s, None, Some(f.sigil), f.region,
f.purity, f.onceness, &f.decl, None, f.purity, f.onceness, &f.decl, None,
None, None); Some(&generics), None);
} }
ast::ty_path(path, _) => print_path(s, path, false), ast::ty_path(path, _) => print_path(s, path, false),
ast::ty_fixed_length_vec(ref mt, v) => { ast::ty_fixed_length_vec(ref mt, v) => {
@ -1923,7 +1928,8 @@ pub fn print_ty_fn(s: @ps,
opt_region: Option<@ast::Lifetime>, opt_region: Option<@ast::Lifetime>,
purity: ast::purity, purity: ast::purity,
onceness: ast::Onceness, onceness: ast::Onceness,
decl: &ast::fn_decl, id: Option<ast::ident>, decl: &ast::fn_decl,
id: Option<ast::ident>,
generics: Option<&ast::Generics>, generics: Option<&ast::Generics>,
opt_self_ty: Option<ast::self_ty_>) { opt_self_ty: Option<ast::self_ty_>) {
ibox(s, indent_unit); ibox(s, indent_unit);

View file

@ -1,5 +1,3 @@
// xfail-pretty
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at // file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT. // http://rust-lang.org/COPYRIGHT.