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:
parent
c1c083cd66
commit
51dae63c44
4 changed files with 34 additions and 31 deletions
|
@ -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
|
||||
|
|
|
@ -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"; }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue