rustc: Implement parsing and typechecking for "once fn"
This commit is contained in:
@@ -387,6 +387,14 @@ fn parse_purity(c: char) -> purity {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_onceness(c: char) -> ast::Onceness {
|
||||
match c {
|
||||
'o' => ast::Once,
|
||||
'm' => ast::Many,
|
||||
_ => fail ~"parse_onceness: bad onceness"
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
|
||||
{mode: parse_mode(st),
|
||||
ty: parse_ty(st, conv)}
|
||||
@@ -406,6 +414,7 @@ fn parse_mode(st: @pstate) -> ast::mode {
|
||||
fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy {
|
||||
let proto = parse_proto(st);
|
||||
let purity = parse_purity(next(st));
|
||||
let onceness = parse_onceness(next(st));
|
||||
let bounds = parse_bounds(st, conv);
|
||||
assert (next(st) == '[');
|
||||
let mut inputs: ~[ty::arg] = ~[];
|
||||
@@ -418,6 +427,7 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy {
|
||||
return FnTyBase {
|
||||
meta: FnMeta {purity: purity,
|
||||
proto: proto,
|
||||
onceness: onceness,
|
||||
bounds: bounds,
|
||||
ret_style: ret_style},
|
||||
sig: FnSig {inputs: inputs,
|
||||
|
||||
@@ -349,9 +349,17 @@ fn enc_purity(w: io::Writer, p: purity) {
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_onceness(w: io::Writer, o: Onceness) {
|
||||
match o {
|
||||
Once => w.write_char('o'),
|
||||
Many => w.write_char('m')
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_ty_fn(w: io::Writer, cx: @ctxt, ft: ty::FnTy) {
|
||||
enc_proto(w, cx, ft.meta.proto);
|
||||
enc_purity(w, ft.meta.purity);
|
||||
enc_onceness(w, ft.meta.onceness);
|
||||
enc_bounds(w, cx, ft.meta.bounds);
|
||||
w.write_char('[');
|
||||
for ft.sig.inputs.each |arg| {
|
||||
|
||||
@@ -841,7 +841,7 @@ fn check_fn_deprecated_modes(tcx: ty::ctxt, fn_ty: ty::t, decl: ast::fn_decl,
|
||||
let span = arg_ast.ty.span;
|
||||
// Recurse to check fn-type argument
|
||||
match arg_ast.ty.node {
|
||||
ast::ty_fn(_, _, _, decl) => {
|
||||
ast::ty_fn(_, _, _, _, decl) => {
|
||||
check_fn_deprecated_modes(tcx, arg_ty.ty,
|
||||
decl, span, id);
|
||||
}
|
||||
@@ -856,7 +856,7 @@ fn check_fn_deprecated_modes(tcx: ty::ctxt, fn_ty: ty::t, decl: ast::fn_decl,
|
||||
// Functions with preceding sigil are parsed
|
||||
// as pointers of functions
|
||||
match mt.ty.node {
|
||||
ast::ty_fn(_, _, _, decl) => {
|
||||
ast::ty_fn(_, _, _, _, decl) => {
|
||||
check_fn_deprecated_modes(
|
||||
tcx, arg_ty.ty,
|
||||
decl, span, id);
|
||||
@@ -889,7 +889,7 @@ fn check_item_deprecated_modes(tcx: ty::ctxt, it: @ast::item) {
|
||||
match it.node {
|
||||
ast::item_ty(ty, _) => {
|
||||
match ty.node {
|
||||
ast::ty_fn(_, _, _, decl) => {
|
||||
ast::ty_fn(_, _, _, _, decl) => {
|
||||
let fn_ty = ty::node_id_to_type(tcx, it.id);
|
||||
check_fn_deprecated_modes(
|
||||
tcx, fn_ty, decl, ty.span, it.id)
|
||||
|
||||
@@ -624,8 +624,8 @@ fn determine_rp_in_ty(ty: @ast::Ty,
|
||||
}
|
||||
}
|
||||
|
||||
ast::ty_fn(ast::proto_bare, _, _, _) |
|
||||
ast::ty_fn(ast::proto_block, _, _, _) if cx.anon_implies_rp => {
|
||||
ast::ty_fn(ast::proto_bare, _, _, _, _) |
|
||||
ast::ty_fn(ast::proto_block, _, _, _, _) if cx.anon_implies_rp => {
|
||||
debug!("referenced bare fn type with regions %s",
|
||||
pprust::ty_to_str(ty, cx.sess.intr()));
|
||||
cx.add_rp(cx.item_id, cx.add_variance(rv_contravariant));
|
||||
@@ -672,8 +672,8 @@ fn determine_rp_in_ty(ty: @ast::Ty,
|
||||
match ty.node {
|
||||
ast::ty_box(mt) | ast::ty_uniq(mt) => {
|
||||
match mt.ty.node {
|
||||
ast::ty_fn(ast::proto_bare, _, _, _) |
|
||||
ast::ty_fn(ast::proto_block, _, _, _) => {
|
||||
ast::ty_fn(ast::proto_bare, _, _, _, _) |
|
||||
ast::ty_fn(ast::proto_block, _, _, _, _) => {
|
||||
do cx.with(cx.item_id, false) {
|
||||
visit_mt(mt, cx, visitor);
|
||||
}
|
||||
@@ -706,7 +706,7 @@ fn determine_rp_in_ty(ty: @ast::Ty,
|
||||
}
|
||||
}
|
||||
|
||||
ast::ty_fn(_, _, bounds, decl) => {
|
||||
ast::ty_fn(_, _, _, bounds, decl) => {
|
||||
// fn() binds the & region, so do not consider &T types that
|
||||
// appear *inside* a fn() type to affect the enclosing item:
|
||||
do cx.with(cx.item_id, false) {
|
||||
|
||||
@@ -1000,6 +1000,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
||||
proto:
|
||||
ty::proto_vstore(ty::vstore_slice(
|
||||
ty::re_bound(ty::br_anon(0)))),
|
||||
onceness: ast::Many,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
|
||||
|
||||
@@ -250,6 +250,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> Option<ty::t> {
|
||||
tcx,
|
||||
FnTyBase {meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: fty.meta.proto,
|
||||
onceness: ast::Many,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: ~[],
|
||||
@@ -261,6 +262,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> Option<ty::t> {
|
||||
tcx,
|
||||
FnTyBase {meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: box_proto,
|
||||
onceness: ast::Many,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: ~[],
|
||||
|
||||
@@ -126,6 +126,7 @@ export kind_is_owned;
|
||||
export meta_kind, kind_lteq, type_kind;
|
||||
export operators;
|
||||
export type_err, terr_vstore_kind;
|
||||
export terr_onceness_mismatch;
|
||||
export type_err_to_str, note_and_explain_type_err;
|
||||
export expected_found;
|
||||
export type_needs_drop;
|
||||
@@ -186,6 +187,7 @@ export terr_proto_mismatch;
|
||||
export terr_ret_style_mismatch;
|
||||
export terr_fn, terr_trait;
|
||||
export purity_to_str;
|
||||
export onceness_to_str;
|
||||
export param_tys_in_type;
|
||||
export eval_repeat_count;
|
||||
export fn_proto, proto_bare, proto_vstore;
|
||||
@@ -504,11 +506,14 @@ impl fn_proto : cmp::Eq {
|
||||
*
|
||||
* - `purity` is the function's effect (pure, impure, unsafe).
|
||||
* - `proto` is the protocol (fn@, fn~, etc).
|
||||
* - `onceness` indicates whether the function can be called one time or many
|
||||
* times.
|
||||
* - `bounds` is the parameter bounds on the function's upvars.
|
||||
* - `ret_style` indicates whether the function returns a value or fails. */
|
||||
struct FnMeta {
|
||||
purity: ast::purity,
|
||||
proto: fn_proto,
|
||||
onceness: ast::Onceness,
|
||||
bounds: @~[param_bound],
|
||||
ret_style: ret_style
|
||||
}
|
||||
@@ -679,6 +684,7 @@ enum type_err {
|
||||
terr_mismatch,
|
||||
terr_ret_style_mismatch(expected_found<ast::ret_style>),
|
||||
terr_purity_mismatch(expected_found<purity>),
|
||||
terr_onceness_mismatch(expected_found<Onceness>),
|
||||
terr_mutability,
|
||||
terr_proto_mismatch(expected_found<ty::fn_proto>),
|
||||
terr_box_mutability,
|
||||
@@ -3326,6 +3332,11 @@ fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str {
|
||||
purity_to_str(values.expected),
|
||||
purity_to_str(values.found))
|
||||
}
|
||||
terr_onceness_mismatch(values) => {
|
||||
fmt!("expected %s fn but found %s fn",
|
||||
onceness_to_str(values.expected),
|
||||
onceness_to_str(values.found))
|
||||
}
|
||||
terr_proto_mismatch(values) => {
|
||||
fmt!("expected %s closure, found %s closure",
|
||||
proto_ty_to_str(cx, values.expected),
|
||||
|
||||
@@ -208,7 +208,8 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope Copy Owned>(
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
ast::ty_fn(ast::proto_block, purity, ast_bounds, ast_fn_decl) => {
|
||||
ast::ty_fn(ast::proto_block, purity, onceness, ast_bounds,
|
||||
ast_fn_decl) => {
|
||||
let new_proto;
|
||||
match vst {
|
||||
ty::vstore_fixed(_) => {
|
||||
@@ -223,9 +224,15 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope Copy Owned>(
|
||||
|
||||
// Run through the normal function type conversion process.
|
||||
let bounds = collect::compute_bounds(self.ccx(), ast_bounds);
|
||||
let fn_decl = ty_of_fn_decl(self, rscope, new_proto, purity,
|
||||
let fn_decl = ty_of_fn_decl(self,
|
||||
rscope,
|
||||
new_proto,
|
||||
purity,
|
||||
onceness,
|
||||
bounds,
|
||||
ast_fn_decl, None, span);
|
||||
ast_fn_decl,
|
||||
None,
|
||||
span);
|
||||
return ty::mk_fn(tcx, fn_decl);
|
||||
}
|
||||
_ => ()
|
||||
@@ -309,10 +316,10 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope Copy Owned>(
|
||||
};
|
||||
ty::mk_rec(tcx, flds)
|
||||
}
|
||||
ast::ty_fn(proto, purity, ast_bounds, decl) => {
|
||||
ast::ty_fn(proto, purity, onceness, ast_bounds, decl) => {
|
||||
let bounds = collect::compute_bounds(self.ccx(), ast_bounds);
|
||||
let fn_decl = ty_of_fn_decl(self, rscope, proto, purity,
|
||||
bounds, decl, None,
|
||||
onceness, bounds, decl, None,
|
||||
ast_ty.span);
|
||||
ty::mk_fn(tcx, fn_decl)
|
||||
}
|
||||
@@ -476,6 +483,7 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope Copy Owned>(
|
||||
self: AC, rscope: RS,
|
||||
ast_proto: ast::proto,
|
||||
purity: ast::purity,
|
||||
onceness: ast::Onceness,
|
||||
bounds: @~[ty::param_bound],
|
||||
decl: ast::fn_decl,
|
||||
expected_tys: expected_tys,
|
||||
@@ -508,6 +516,7 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope Copy Owned>(
|
||||
FnTyBase {
|
||||
meta: FnMeta {purity: purity,
|
||||
proto: proto,
|
||||
onceness: onceness,
|
||||
bounds: bounds,
|
||||
ret_style: decl.cf},
|
||||
sig: FnSig {inputs: input_tys,
|
||||
|
||||
@@ -1310,7 +1310,10 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
// block syntax lambdas; that is, lambdas without explicit
|
||||
// protos.
|
||||
let expected_sty = unpack_expected(fcx, expected, |x| Some(x));
|
||||
let (expected_tys, expected_purity, expected_proto) =
|
||||
let (expected_tys,
|
||||
expected_purity,
|
||||
expected_proto,
|
||||
expected_onceness) =
|
||||
match expected_sty {
|
||||
Some(ty::ty_fn(ref fn_ty)) => {
|
||||
let {fn_ty, _} =
|
||||
@@ -1320,10 +1323,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
(Some({inputs: fn_ty.sig.inputs,
|
||||
output: fn_ty.sig.output}),
|
||||
fn_ty.meta.purity,
|
||||
fn_ty.meta.proto)
|
||||
fn_ty.meta.proto,
|
||||
fn_ty.meta.onceness)
|
||||
}
|
||||
_ => {
|
||||
(None, ast::impure_fn, ty::proto_vstore(ty::vstore_box))
|
||||
(None,
|
||||
ast::impure_fn,
|
||||
ty::proto_vstore(ty::vstore_box),
|
||||
ast::Many)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1334,17 +1341,25 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
// XXX: This is a hack.
|
||||
let ast_proto = ast_proto_opt.get_default(ast::proto_box);
|
||||
let ast_purity = ast::impure_fn;
|
||||
let ast_onceness = ast::Many;
|
||||
|
||||
// construct the function type
|
||||
let mut fn_ty = astconv::ty_of_fn_decl(fcx, fcx,
|
||||
ast_proto, ast_purity, @~[],
|
||||
decl, expected_tys, expr.span);
|
||||
let mut fn_ty = astconv::ty_of_fn_decl(fcx,
|
||||
fcx,
|
||||
ast_proto,
|
||||
ast_purity,
|
||||
ast_onceness,
|
||||
@~[],
|
||||
decl,
|
||||
expected_tys,
|
||||
expr.span);
|
||||
|
||||
// Patch up the function declaration, if necessary.
|
||||
match ast_proto_opt {
|
||||
None => {
|
||||
fn_ty.meta.purity = expected_purity;
|
||||
fn_ty.meta.proto = expected_proto;
|
||||
fn_ty.meta.onceness = expected_onceness;
|
||||
}
|
||||
Some(_) => { }
|
||||
}
|
||||
@@ -2802,6 +2817,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
||||
meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: ty::proto_vstore(ty::vstore_slice(
|
||||
ty::re_bound(ty::br_anon(0)))),
|
||||
onceness: ast::Many,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
|
||||
@@ -2825,6 +2841,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
||||
let fty = ty::mk_fn(tcx, FnTyBase {
|
||||
meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: ty::proto_bare,
|
||||
onceness: ast::Many,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: inputs,
|
||||
|
||||
@@ -134,6 +134,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
|
||||
result_ty = Some(ty::mk_fn(tcx, FnTyBase {
|
||||
meta: FnMeta {purity: ast::pure_fn,
|
||||
proto: ty::proto_vstore(ty::vstore_box),
|
||||
onceness: ast::Many,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: args,
|
||||
@@ -604,7 +605,7 @@ fn convert_struct(ccx: @crate_ctxt,
|
||||
let t_dtor = ty::mk_fn(
|
||||
tcx,
|
||||
ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_bare,
|
||||
ast::impure_fn, @~[],
|
||||
ast::impure_fn, ast::Many, @~[],
|
||||
ast_util::dtor_dec(), None, dtor.span));
|
||||
write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
|
||||
tcx.tcache.insert(local_def(dtor.node.id),
|
||||
@@ -643,6 +644,7 @@ fn convert_struct(ccx: @crate_ctxt,
|
||||
meta: FnMeta {
|
||||
purity: ast::pure_fn,
|
||||
proto: ty::proto_bare,
|
||||
onceness: ast::Many,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val,
|
||||
},
|
||||
@@ -682,9 +684,15 @@ fn ty_of_method(ccx: @crate_ctxt,
|
||||
rp: Option<ty::region_variance>) -> ty::method {
|
||||
{ident: m.ident,
|
||||
tps: ty_param_bounds(ccx, m.tps),
|
||||
fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_bare,
|
||||
m.purity, @~[],
|
||||
m.decl, None, m.span),
|
||||
fty: ty_of_fn_decl(ccx,
|
||||
type_rscope(rp),
|
||||
ast::proto_bare,
|
||||
m.purity,
|
||||
ast::Many,
|
||||
@~[],
|
||||
m.decl,
|
||||
None,
|
||||
m.span),
|
||||
self_ty: m.self_ty.node,
|
||||
vis: m.vis,
|
||||
def_id: local_def(m.id)}
|
||||
@@ -696,8 +704,15 @@ fn ty_of_ty_method(self: @crate_ctxt,
|
||||
id: ast::def_id) -> ty::method {
|
||||
{ident: m.ident,
|
||||
tps: ty_param_bounds(self, m.tps),
|
||||
fty: ty_of_fn_decl(self, type_rscope(rp), ast::proto_bare, m.purity,
|
||||
@~[], m.decl, None, m.span),
|
||||
fty: ty_of_fn_decl(self,
|
||||
type_rscope(rp),
|
||||
ast::proto_bare,
|
||||
m.purity,
|
||||
ast::Many,
|
||||
@~[],
|
||||
m.decl,
|
||||
None,
|
||||
m.span),
|
||||
// assume public, because this is only invoked on trait methods
|
||||
self_ty: m.self_ty.node,
|
||||
vis: ast::public,
|
||||
@@ -752,9 +767,15 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
|
||||
}
|
||||
ast::item_fn(decl, purity, tps, _) => {
|
||||
let bounds = ty_param_bounds(ccx, tps);
|
||||
let tofd = ty_of_fn_decl(ccx, empty_rscope,
|
||||
ast::proto_bare, purity, @~[],
|
||||
decl, None, it.span);
|
||||
let tofd = ty_of_fn_decl(ccx,
|
||||
empty_rscope,
|
||||
ast::proto_bare,
|
||||
purity,
|
||||
ast::Many,
|
||||
@~[],
|
||||
decl,
|
||||
None,
|
||||
it.span);
|
||||
let tpt = {bounds: bounds,
|
||||
region_param: None,
|
||||
ty: ty::mk_fn(ccx.tcx, tofd)};
|
||||
@@ -910,6 +931,7 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
|
||||
let t_fn = ty::mk_fn(ccx.tcx, FnTyBase {
|
||||
meta: FnMeta {purity: purity,
|
||||
proto: ty::proto_bare,
|
||||
onceness: ast::Many,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: input_tys,
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
use to_str::ToStr;
|
||||
use ty::{FnTyBase, FnMeta, FnSig};
|
||||
use syntax::ast::Onceness;
|
||||
|
||||
trait combine {
|
||||
fn infcx() -> infer_ctxt;
|
||||
@@ -72,6 +73,7 @@ trait combine {
|
||||
fn protos(p1: ty::fn_proto, p2: ty::fn_proto) -> cres<ty::fn_proto>;
|
||||
fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style>;
|
||||
fn purities(a: purity, b: purity) -> cres<purity>;
|
||||
fn oncenesses(a: Onceness, b: Onceness) -> cres<Onceness>;
|
||||
fn contraregions(a: ty::Region, b: ty::Region) -> cres<ty::Region>;
|
||||
fn regions(a: ty::Region, b: ty::Region) -> cres<ty::Region>;
|
||||
fn vstores(vk: ty::terr_vstore_kind,
|
||||
@@ -311,10 +313,14 @@ fn super_fn_metas<C:combine>(
|
||||
do self.protos(a_f.proto, b_f.proto).chain |p| {
|
||||
do self.ret_styles(a_f.ret_style, b_f.ret_style).chain |rs| {
|
||||
do self.purities(a_f.purity, b_f.purity).chain |purity| {
|
||||
Ok(FnMeta {purity: purity,
|
||||
proto: p,
|
||||
bounds: a_f.bounds, // XXX: This is wrong!
|
||||
ret_style: rs})
|
||||
do self.oncenesses(a_f.onceness, b_f.onceness).chain
|
||||
|onceness| {
|
||||
Ok(FnMeta {purity: purity,
|
||||
proto: p,
|
||||
onceness: onceness,
|
||||
bounds: a_f.bounds, // XXX: This is wrong!
|
||||
ret_style: rs})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use combine::*;
|
||||
use lattice::*;
|
||||
use to_str::ToStr;
|
||||
use syntax::ast::{Many, Once};
|
||||
|
||||
enum Glb = combine_fields; // "greatest lower bound" (common subtype)
|
||||
|
||||
@@ -97,6 +98,13 @@ impl Glb: combine {
|
||||
}
|
||||
}
|
||||
|
||||
fn oncenesses(a: Onceness, b: Onceness) -> cres<Onceness> {
|
||||
match (a, b) {
|
||||
(Many, _) | (_, Many) => Ok(Many),
|
||||
(Once, Once) => Ok(Once)
|
||||
}
|
||||
}
|
||||
|
||||
fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
|
||||
match (r1, r2) {
|
||||
(ast::return_val, ast::return_val) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use combine::*;
|
||||
use lattice::*;
|
||||
use to_str::ToStr;
|
||||
use syntax::ast::{Many, Once};
|
||||
|
||||
enum Lub = combine_fields; // "subtype", "subregion" etc
|
||||
|
||||
@@ -80,6 +81,13 @@ impl Lub: combine {
|
||||
}
|
||||
}
|
||||
|
||||
fn oncenesses(a: Onceness, b: Onceness) -> cres<Onceness> {
|
||||
match (a, b) {
|
||||
(Once, _) | (_, Once) => Ok(Once),
|
||||
(Many, Many) => Ok(Many)
|
||||
}
|
||||
}
|
||||
|
||||
fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
|
||||
match (r1, r2) {
|
||||
(ast::return_val, _) |
|
||||
|
||||
@@ -93,6 +93,12 @@ impl Sub: combine {
|
||||
})
|
||||
}
|
||||
|
||||
fn oncenesses(a: Onceness, b: Onceness) -> cres<Onceness> {
|
||||
self.lub().oncenesses(a, b).compare(b, || {
|
||||
ty::terr_onceness_mismatch(expected_found(&self, a, b))
|
||||
})
|
||||
}
|
||||
|
||||
fn ret_styles(a: ret_style, b: ret_style) -> cres<ret_style> {
|
||||
self.lub().ret_styles(a, b).compare(b, || {
|
||||
ty::terr_ret_style_mismatch(expected_found(&self, a, b))
|
||||
|
||||
@@ -19,7 +19,8 @@ use syntax::codemap;
|
||||
use syntax::codemap::span;
|
||||
use syntax::print::pprust;
|
||||
use syntax::print::pprust::{path_to_str, proto_to_str,
|
||||
mode_to_str, purity_to_str};
|
||||
mode_to_str, purity_to_str,
|
||||
onceness_to_str};
|
||||
use syntax::{ast, ast_util};
|
||||
use syntax::ast_map;
|
||||
|
||||
@@ -266,14 +267,24 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
|
||||
};
|
||||
modestr + ty_to_str(cx, ty)
|
||||
}
|
||||
fn fn_to_str(cx: ctxt, purity: ast::purity, proto: ty::fn_proto,
|
||||
fn fn_to_str(cx: ctxt,
|
||||
purity: ast::purity,
|
||||
proto: ty::fn_proto,
|
||||
onceness: ast::Onceness,
|
||||
ident: Option<ast::ident>,
|
||||
inputs: ~[arg], output: t, cf: ast::ret_style) -> ~str {
|
||||
inputs: ~[arg],
|
||||
output: t,
|
||||
cf: ast::ret_style) -> ~str {
|
||||
let mut s;
|
||||
|
||||
s = match purity {
|
||||
ast::impure_fn => ~"",
|
||||
_ => purity_to_str(purity) + ~" "
|
||||
ast::impure_fn => ~"",
|
||||
_ => purity_to_str(purity) + ~" "
|
||||
};
|
||||
|
||||
s += match onceness {
|
||||
ast::Many => ~"",
|
||||
ast::Once => onceness_to_str(onceness) + ~" "
|
||||
};
|
||||
|
||||
s += ~"fn";
|
||||
@@ -298,8 +309,13 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
|
||||
}
|
||||
fn method_to_str(cx: ctxt, m: method) -> ~str {
|
||||
return fn_to_str(
|
||||
cx, m.fty.meta.purity, m.fty.meta.proto, Some(m.ident),
|
||||
m.fty.sig.inputs, m.fty.sig.output,
|
||||
cx,
|
||||
m.fty.meta.purity,
|
||||
m.fty.meta.proto,
|
||||
m.fty.meta.onceness,
|
||||
Some(m.ident),
|
||||
m.fty.sig.inputs,
|
||||
m.fty.sig.output,
|
||||
m.fty.meta.ret_style) + ~";";
|
||||
}
|
||||
fn field_to_str(cx: ctxt, f: field) -> ~str {
|
||||
@@ -347,8 +363,14 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
|
||||
~"(" + str::connect(strs, ~",") + ~")"
|
||||
}
|
||||
ty_fn(ref f) => {
|
||||
fn_to_str(cx, f.meta.purity, f.meta.proto, None, f.sig.inputs,
|
||||
f.sig.output, f.meta.ret_style)
|
||||
fn_to_str(cx,
|
||||
f.meta.purity,
|
||||
f.meta.proto,
|
||||
f.meta.onceness,
|
||||
None,
|
||||
f.sig.inputs,
|
||||
f.sig.output,
|
||||
f.meta.ret_style)
|
||||
}
|
||||
ty_infer(infer_ty) => infer_ty.to_str(),
|
||||
ty_param({idx: id, _}) => {
|
||||
|
||||
Reference in New Issue
Block a user