diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-09-15 16:15:17 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-09-15 16:15:17 +0200 |
| commit | 3abe3671bd39a359de3421b062b98d3adaa1942d (patch) | |
| tree | a6a95df9c3ab53b55cc902cf736b0a282be98da0 /src/comp/syntax/parse | |
| parent | 75eee8b194231c2fe808242a9828253125b854c8 (diff) | |
| download | rust-3abe3671bd39a359de3421b062b98d3adaa1942d.tar.gz rust-3abe3671bd39a359de3421b062b98d3adaa1942d.zip | |
Require the parameter that will be referenced to be noted
Issue #918
Diffstat (limited to 'src/comp/syntax/parse')
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 4a449c25a97..b2da68b0cd9 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -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, |
