Skip to content

Commit

Permalink
Fix pretty-printer test failure by carrying the bound lifetime names …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
nikomatsakis committed Mar 27, 2013
1 parent b93393e commit 772293a
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 100 deletions.
5 changes: 4 additions & 1 deletion src/librustc/metadata/tydecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/trans/foreign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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())}
});
Expand Down
7 changes: 5 additions & 2 deletions src/librustc/middle/trans/monomorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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)}})
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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}})
}

Expand Down Expand Up @@ -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)
}
Expand Down
103 changes: 59 additions & 44 deletions src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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}
}
}

Expand All @@ -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();

Expand All @@ -599,19 +613,19 @@ 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}
};
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),
Expand All @@ -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}
}
}
9 changes: 6 additions & 3 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) = {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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));
Expand Down
Loading

5 comments on commit 772293a

@bors
Copy link
Contributor

@bors bors commented on 772293a Mar 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from nikomatsakis
at nikomatsakis@772293a

@bors
Copy link
Contributor

@bors bors commented on 772293a Mar 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging nikomatsakis/rust/issue-4846-carry-bound-lifetime-names-in-fn-types = 772293a into auto

@bors
Copy link
Contributor

@bors bors commented on 772293a Mar 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nikomatsakis/rust/issue-4846-carry-bound-lifetime-names-in-fn-types = 772293a merged ok, testing candidate = 3ff8e01

@bors
Copy link
Contributor

@bors bors commented on 772293a Mar 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 772293a Mar 28, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding incoming to auto = 3ff8e01

Please sign in to comment.