1
Fork 0

Make most of the compiler aware of return-by-reference

tyencode/tydecode still don't know about it. return_ref will be extended to take
arguments anyway.
This commit is contained in:
Marijn Haverbeke 2011-09-14 11:01:42 +02:00
parent c1c083cd66
commit 51dae63c44
4 changed files with 34 additions and 31 deletions

View file

@ -218,7 +218,10 @@ fn enc_ty_fn(w: io::writer, cx: @ctxt, args: [ty::arg], out: ty::t,
} else { w.write_char(';'); }
enc_constr(w, cx, c);
}
alt cf { noreturn. { w.write_char('!'); } _ { enc_ty(w, cx, out); } }
alt cf {
noreturn. { w.write_char('!'); }
_ { enc_ty(w, cx, out); }
}
}
// FIXME less copy-and-paste

View file

@ -279,7 +279,7 @@ type constr = constr_general<uint>;
// Data structures used in type unification
tag type_err {
terr_mismatch;
terr_controlflow_mismatch;
terr_ret_style_mismatch(ast::ret_style, ast::ret_style);
terr_box_mutability;
terr_vec_mutability;
terr_tuple_size(uint, uint);
@ -1952,26 +1952,13 @@ mod unify {
_expected_constrs: [@constr], actual_constrs: [@constr]) ->
result {
if e_proto != a_proto { ret ures_err(terr_mismatch); }
alt expected_cf {
ast::return_val. { }
// ok
ast::noreturn. {
alt actual_cf {
ast::noreturn. {
// ok
}
_ {
/* even though typestate checking is mostly
responsible for checking control flow annotations,
this check is necessary to ensure that the
annotation in an object method matches the
declared object type */
ret ures_err(terr_controlflow_mismatch);
}
}
}
if actual_cf != ast::noreturn && actual_cf != expected_cf {
/* even though typestate checking is mostly
responsible for checking control flow annotations,
this check is necessary to ensure that the
annotation in an object method matches the
declared object type */
ret ures_err(terr_ret_style_mismatch(expected_cf, actual_cf));
}
let t =
unify_fn_common(cx, expected, actual, expected_inputs,
@ -2470,9 +2457,16 @@ mod unify {
fn type_err_to_str(err: ty::type_err) -> str {
alt err {
terr_mismatch. { ret "types differ"; }
terr_controlflow_mismatch. {
ret "returning function used where non-returning function" +
" was expected";
terr_ret_style_mismatch(expect, actual) {
fn to_str(s: ast::ret_style) -> str {
alt s {
ast::noreturn. { "non-returning" }
ast::return_val. { "return-by-value" }
ast::return_ref. { "return-by-reference" }
}
}
ret to_str(actual) + " function found where " + to_str(expect) +
" function was expected";
}
terr_box_mutability. { ret "boxed values differ in mutability"; }
terr_vec_mutability. { ret "vectors differ in mutability"; }

View file

@ -1224,6 +1224,7 @@ fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl, constrs: [@ast::constr]) {
if decl.output.node != ast::ty_nil {
space_if_not_bol(s);
word_space(s, "->");
if decl.cf == ast::return_ref { word(s.s, "&"); }
print_type(s, decl.output);
}
}
@ -1419,9 +1420,11 @@ fn print_ty_fn(s: ps, proto: ast::proto, id: option::t<ast::ident>,
space_if_not_bol(s);
ibox(s, indent_unit);
word_space(s, "->");
alt cf {
ast::return_val. { print_type(s, output); }
ast::noreturn. { word_nbsp(s, "!"); }
if cf == ast::noreturn {
word_nbsp(s, "!")
} else {
if cf == ast::return_ref { word(s.s, "&"); }
print_type(s, output);
}
end(s);
}

View file

@ -58,9 +58,12 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
s += str::connect(strs, ", ");
s += ")";
if struct(cx, output) != ty_nil {
alt cf {
ast::noreturn. { s += " -> !"; }
ast::return_val. { s += " -> " + ty_to_str(cx, output); }
s += " -> ";
if cf == ast::noreturn {
s += "!";
} else {
if cf == ast::return_ref { s += "&"; }
s += ty_to_str(cx, output);
}
}
s += constrs_str(constrs);