Skip to content

Commit 772293a

Browse files
committed
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.
1 parent b93393e commit 772293a

File tree

14 files changed

+130
-100
lines changed

14 files changed

+130
-100
lines changed

src/librustc/metadata/tydecode.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use core::vec;
2424
use syntax::ast;
2525
use syntax::ast::*;
2626
use syntax::codemap::{respan, dummy_sp};
27+
use syntax::opt_vec;
2728

2829
// Compact string representation for ty::t values. API ty_str &
2930
// 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 {
479480
}
480481
st.pos += 1u; // eat the ']'
481482
let ret_ty = parse_ty(st, conv);
482-
ty::FnSig {inputs: inputs, output: ret_ty}
483+
ty::FnSig {bound_lifetime_names: opt_vec::Empty, // FIXME(#4846)
484+
inputs: inputs,
485+
output: ret_ty}
483486
}
484487
485488
// Rust metadata parsing

src/librustc/middle/trans/foreign.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use util::ppaux::ty_to_str;
4040
use syntax::codemap::span;
4141
use syntax::{ast, ast_util};
4242
use syntax::{attr, ast_map};
43+
use syntax::opt_vec;
4344
use syntax::parse::token::special_idents;
4445

4546
fn abi_info(arch: session::arch) -> @cabi::ABIInfo {
@@ -615,7 +616,8 @@ pub fn trans_intrinsic(ccx: @CrateContext,
615616
sigil: ast::BorrowedSigil,
616617
onceness: ast::Many,
617618
region: ty::re_bound(ty::br_anon(0)),
618-
sig: FnSig {inputs: ~[arg {mode: ast::expl(ast::by_copy),
619+
sig: FnSig {bound_lifetime_names: opt_vec::Empty,
620+
inputs: ~[arg {mode: ast::expl(ast::by_copy),
619621
ty: star_u8}],
620622
output: ty::mk_nil(bcx.tcx())}
621623
});

src/librustc/middle/trans/monomorphize.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use syntax::ast;
3737
use syntax::ast_map;
3838
use syntax::ast_map::{path, path_mod, path_name};
3939
use syntax::ast_util::local_def;
40+
use syntax::opt_vec;
4041
use syntax::parse::token::special_idents;
4142

4243
pub fn monomorphic_fn(ccx: @CrateContext,
@@ -282,7 +283,8 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
282283
ty::BareFnTy {
283284
purity: ast::impure_fn,
284285
abi: ast::RustAbi,
285-
sig: FnSig {inputs: ~[],
286+
sig: FnSig {bound_lifetime_names: opt_vec::Empty,
287+
inputs: ~[],
286288
output: ty::mk_nil(tcx)}}))
287289
}
288290
ty::ty_closure(ref fty) => {
@@ -316,7 +318,8 @@ pub fn normalize_for_monomorphization(tcx: ty::ctxt,
316318
sigil: sigil,
317319
onceness: ast::Many,
318320
region: ty::re_static,
319-
sig: ty::FnSig {inputs: ~[],
321+
sig: ty::FnSig {bound_lifetime_names: opt_vec::Empty,
322+
inputs: ~[],
320323
output: ty::mk_nil(tcx)}})
321324
}
322325
}

src/librustc/middle/ty.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ use syntax::codemap::span;
4545
use syntax::codemap;
4646
use syntax::print::pprust;
4747
use syntax::{ast, ast_map};
48+
use syntax::opt_vec::OptVec;
49+
use syntax::opt_vec;
4850
use syntax;
4951

5052
// Data types
@@ -376,10 +378,12 @@ pub struct ClosureTy {
376378
* Signature of a function type, which I have arbitrarily
377379
* decided to use to refer to the input/output types.
378380
*
381+
* - `lifetimes` is the list of region names bound in this fn.
379382
* - `inputs` is the list of arguments and their modes.
380383
* - `output` is the return type. */
381384
#[deriving(Eq)]
382385
pub struct FnSig {
386+
bound_lifetime_names: OptVec<ast::ident>,
383387
inputs: ~[arg],
384388
output: t
385389
}
@@ -1062,7 +1066,8 @@ pub fn mk_ctor_fn(cx: ctxt, input_tys: &[ty::t], output: ty::t) -> t {
10621066
BareFnTy {
10631067
purity: ast::pure_fn,
10641068
abi: ast::RustAbi,
1065-
sig: FnSig {inputs: input_args,
1069+
sig: FnSig {bound_lifetime_names: opt_vec::Empty,
1070+
inputs: input_args,
10661071
output: output}})
10671072
}
10681073

@@ -1203,6 +1208,7 @@ pub fn fold_sig(sig: &FnSig, fldop: &fn(t) -> t) -> FnSig {
12031208
};
12041209

12051210
FnSig {
1211+
bound_lifetime_names: copy sig.bound_lifetime_names,
12061212
inputs: args,
12071213
output: fldop(sig.output)
12081214
}

src/librustc/middle/typeck/astconv.rs

+59-44
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ use middle::const_eval;
5858
use middle::ty::{arg, field, substs};
5959
use middle::ty::{ty_param_substs_and_ty};
6060
use middle::ty;
61-
use middle::typeck::rscope::{in_binding_rscope, in_binding_rscope_ext};
61+
use middle::typeck::rscope::{in_binding_rscope};
6262
use middle::typeck::rscope::{region_scope, type_rscope, RegionError};
6363
use middle::typeck::rscope::{RegionParamNames};
6464

@@ -67,6 +67,7 @@ use core::vec;
6767
use syntax::{ast, ast_util};
6868
use syntax::codemap::span;
6969
use syntax::opt_vec::OptVec;
70+
use syntax::opt_vec;
7071
use syntax::print::pprust::{lifetime_to_str, path_to_str};
7172
use syntax::parse::token::special_idents;
7273
use util::common::indenter;
@@ -347,7 +348,7 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
347348
}
348349
ast::ty_bare_fn(ref bf) => {
349350
ty::mk_bare_fn(tcx, ty_of_bare_fn(self, rscope, bf.purity,
350-
bf.abi, &bf.decl))
351+
bf.abi, &bf.lifetimes, &bf.decl))
351352
}
352353
ast::ty_closure(ref f) => {
353354
let fn_decl = ty_of_closure(self,
@@ -508,45 +509,50 @@ pub fn ty_of_arg<AC:AstConv,RS:region_scope + Copy + Durable>(
508509
arg {mode: mode, ty: ty}
509510
}
510511

511-
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
512-
self: &AC,
513-
rscope: &RS,
514-
purity: ast::purity,
515-
abi: ast::Abi,
516-
decl: &ast::fn_decl)
517-
-> ty::BareFnTy {
518-
debug!("ty_of_bare_fn");
519-
520-
// new region names that appear inside of the fn decl are bound to
521-
// that function type
522-
let rb = in_binding_rscope(rscope);
523-
524-
let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
525-
let output_ty = match decl.output.node {
526-
ast::ty_infer => self.ty_infer(decl.output.span),
527-
_ => ast_ty_to_ty(self, &rb, decl.output)
528-
};
529-
530-
ty::BareFnTy {
531-
purity: purity,
532-
abi: abi,
533-
sig: ty::FnSig {inputs: input_tys, output: output_ty}
534-
}
512+
pub fn bound_lifetimes<AC:AstConv>(
513+
self: &AC,
514+
ast_lifetimes: &OptVec<ast::Lifetime>) -> OptVec<ast::ident>
515+
{
516+
/*!
517+
*
518+
* Converts a list of lifetimes into a list of bound identifier
519+
* names. Does not permit special names like 'static or 'self to
520+
* be bound. Note that this function is for use in closures,
521+
* methods, and fn definitions. It is legal to bind 'self in a
522+
* type. Eventually this distinction should go away and the same
523+
* rules should apply everywhere ('self would not be a special name
524+
* at that point).
525+
*/
526+
527+
let special_idents = [special_idents::static, special_idents::self_];
528+
let mut bound_lifetime_names = opt_vec::Empty;
529+
ast_lifetimes.map_to_vec(|ast_lifetime| {
530+
if special_idents.any(|&i| i == ast_lifetime.ident) {
531+
self.tcx().sess.span_err(
532+
ast_lifetime.span,
533+
fmt!("illegal lifetime parameter name: `%s`",
534+
lifetime_to_str(ast_lifetime, self.tcx().sess.intr())));
535+
} else {
536+
bound_lifetime_names.push(ast_lifetime.ident);
537+
}
538+
});
539+
bound_lifetime_names
535540
}
536541

537-
pub fn ty_of_bare_fn_ext<AC:AstConv,RS:region_scope + Copy + Durable>(
538-
self: &AC,
539-
rscope: &RS,
540-
purity: ast::purity,
541-
abi: ast::Abi,
542-
decl: &ast::fn_decl,
543-
+region_param_names: RegionParamNames)
544-
-> ty::BareFnTy {
545-
debug!("ty_of_bare_fn_ext");
542+
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
543+
self: &AC,
544+
rscope: &RS,
545+
purity: ast::purity,
546+
abi: ast::Abi,
547+
lifetimes: &OptVec<ast::Lifetime>,
548+
decl: &ast::fn_decl) -> ty::BareFnTy
549+
{
550+
debug!("ty_of_bare_fn");
546551

547552
// new region names that appear inside of the fn decl are bound to
548553
// that function type
549-
let rb = in_binding_rscope_ext(rscope, region_param_names);
554+
let bound_lifetime_names = bound_lifetimes(self, lifetimes);
555+
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
550556

551557
let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
552558
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>(
557563
ty::BareFnTy {
558564
purity: purity,
559565
abi: abi,
560-
sig: ty::FnSig {inputs: input_tys, output: output_ty}
566+
sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
567+
inputs: input_tys,
568+
output: output_ty}
561569
}
562570
}
563571

@@ -569,10 +577,16 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
569577
onceness: ast::Onceness,
570578
opt_lifetime: Option<@ast::Lifetime>,
571579
decl: &ast::fn_decl,
572-
expected_tys: Option<ty::FnSig>,
580+
expected_sig: Option<ty::FnSig>,
573581
lifetimes: &OptVec<ast::Lifetime>,
574582
span: span)
575-
-> ty::ClosureTy {
583+
-> ty::ClosureTy
584+
{
585+
// The caller should not both provide explicit bound lifetime
586+
// names and expected types. Either we infer the bound lifetime
587+
// names or they are provided, but not both.
588+
fail_unless!(lifetimes.is_empty() || expected_sig.is_none());
589+
576590
debug!("ty_of_fn_decl");
577591
let _i = indenter();
578592

@@ -599,19 +613,19 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
599613

600614
// new region names that appear inside of the fn decl are bound to
601615
// that function type
602-
let region_param_names = RegionParamNames::from_lifetimes(lifetimes);
603-
let rb = in_binding_rscope_ext(rscope, region_param_names);
616+
let bound_lifetime_names = bound_lifetimes(self, lifetimes);
617+
let rb = in_binding_rscope(rscope, RegionParamNames(copy bound_lifetime_names));
604618

605619
let input_tys = do decl.inputs.mapi |i, a| {
606-
let expected_arg_ty = do expected_tys.chain_ref |e| {
620+
let expected_arg_ty = do expected_sig.chain_ref |e| {
607621
// no guarantee that the correct number of expected args
608622
// were supplied
609623
if i < e.inputs.len() {Some(e.inputs[i])} else {None}
610624
};
611625
ty_of_arg(self, &rb, *a, expected_arg_ty)
612626
};
613627

614-
let expected_ret_ty = expected_tys.map(|e| e.output);
628+
let expected_ret_ty = expected_sig.map(|e| e.output);
615629
let output_ty = match decl.output.node {
616630
ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(),
617631
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>(
623637
sigil: sigil,
624638
onceness: onceness,
625639
region: bound_region,
626-
sig: ty::FnSig {inputs: input_tys,
640+
sig: ty::FnSig {bound_lifetime_names: bound_lifetime_names,
641+
inputs: input_tys,
627642
output: output_ty}
628643
}
629644
}

src/librustc/middle/typeck/check/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1633,7 +1633,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
16331633
// sigils.
16341634
let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
16351635
let mut error_happened = false;
1636-
let (expected_tys,
1636+
let (expected_sig,
16371637
expected_purity,
16381638
expected_sigil,
16391639
expected_onceness) = {
@@ -1668,13 +1668,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
16681668
expected_onceness,
16691669
None,
16701670
decl,
1671-
expected_tys,
1671+
expected_sig,
16721672
&opt_vec::Empty,
16731673
expr.span);
16741674

16751675
let mut fty_sig;
16761676
let fty = if error_happened {
16771677
fty_sig = FnSig {
1678+
bound_lifetime_names: opt_vec::Empty,
16781679
inputs: fn_ty.sig.inputs.map(|an_arg| {
16791680
arg { mode: an_arg.mode,
16801681
ty: ty::mk_err(tcx)
@@ -3492,6 +3493,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
34923493
onceness: ast::Once,
34933494
region: ty::re_bound(ty::br_anon(0)),
34943495
sig: ty::FnSig {
3496+
bound_lifetime_names: opt_vec::Empty,
34953497
inputs: ~[arg {mode: ast::expl(ast::by_copy),
34963498
ty: ty::mk_imm_ptr(
34973499
ccx.tcx,
@@ -3723,7 +3725,8 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
37233725
let fty = ty::mk_bare_fn(tcx, ty::BareFnTy {
37243726
purity: ast::unsafe_fn,
37253727
abi: ast::RustAbi,
3726-
sig: FnSig {inputs: inputs,
3728+
sig: FnSig {bound_lifetime_names: opt_vec::Empty,
3729+
inputs: inputs,
37273730
output: output}
37283731
});
37293732
let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));

0 commit comments

Comments
 (0)