Require the parameter that will be referenced to be noted

Issue #918
This commit is contained in:
Marijn Haverbeke 2011-09-15 16:15:17 +02:00
parent 75eee8b194
commit 3abe3671bd
9 changed files with 74 additions and 38 deletions

View file

@ -285,7 +285,7 @@ fn parse_ty_fn(proto: ast::proto, p: parser) -> ast::ty_ {
// FIXME: there's no syntax for this right now anyway
// auto constrs = parse_constrs(~[], p);
let constrs: [@ast::constr] = [];
let (ret_style, ret_ty) = parse_ret_ty(p);
let (ret_style, ret_ty) = parse_ret_ty(p, vec::len(inputs.node));
ret ast::ty_fn(proto, inputs.node, ret_ty, ret_style, constrs);
}
@ -437,7 +437,7 @@ fn parse_ty_postfix(orig_t: ast::ty_, p: parser, colons_before_params: bool)
}
}
fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) {
fn parse_ret_ty(p: parser, n_args: uint) -> (ast::ret_style, @ast::ty) {
ret if eat(p, token::RARROW) {
let lo = p.get_lo_pos();
if eat(p, token::NOT) {
@ -445,7 +445,20 @@ fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) {
} else {
let style = ast::return_val;
if eat(p, token::BINOP(token::AND)) {
style = ast::return_ref(eat(p, token::NOT));
if n_args == 0u {
p.fatal("can not return reference from argument-less fn");
}
let mut_root = eat(p, token::NOT), arg = 0u;
alt p.peek() {
token::LIT_INT(val) { p.bump(); arg = val as uint; }
_ { if n_args > 1u {
p.fatal("must specify referenced parameter");
} }
}
if arg >= n_args {
p.fatal("referenced argument does not exist");
}
style = ast::return_ref(mut_root, arg);
};
(style, parse_ty(p, false))
}
@ -1734,7 +1747,7 @@ fn parse_fn_decl(p: parser, purity: ast::purity, il: ast::inlineness) ->
p.bump();
constrs = parse_constrs(bind parse_ty_constr(inputs.node, _), p);
}
let (ret_style, ret_ty) = parse_ret_ty(p);
let (ret_style, ret_ty) = parse_ret_ty(p, vec::len(inputs.node));
ret {inputs: inputs.node,
output: ret_ty,
purity: purity,