rustc: Alias fix part 1 -- Separate out AST modes from typechecker modes, and introduce an "either value or alias" mode
This commit is contained in:
parent
bc879a4e1e
commit
662e949540
@ -249,9 +249,9 @@ fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], ty.t) {
|
||||
assert (next(st) as char == '[');
|
||||
let vec[ty.arg] inputs = vec();
|
||||
while (peek(st) as char != ']') {
|
||||
auto mode = ast.val;
|
||||
auto mode = ty.mo_val;
|
||||
if (peek(st) as char == '&') {
|
||||
mode = ast.alias;
|
||||
mode = ty.mo_alias;
|
||||
st.pos = st.pos + 1u;
|
||||
}
|
||||
inputs += vec(rec(mode=mode, ty=parse_ty(st, sd)));
|
||||
|
@ -241,7 +241,7 @@ mod Encode {
|
||||
fn enc_ty_fn(IO.writer w, @ctxt cx, vec[ty.arg] args, ty.t out) {
|
||||
w.write_char('[');
|
||||
for (ty.arg arg in args) {
|
||||
if (arg.mode == ast.alias) { w.write_char('&'); }
|
||||
if (arg.mode == ty.mo_alias) { w.write_char('&'); }
|
||||
enc_ty(w, cx, arg.ty);
|
||||
}
|
||||
w.write_char(']');
|
||||
|
@ -605,12 +605,12 @@ fn type_of_explicit_args(@crate_ctxt cx, vec[ty.arg] inputs) -> vec[TypeRef] {
|
||||
let vec[TypeRef] atys = vec();
|
||||
for (ty.arg arg in inputs) {
|
||||
if (ty.type_has_dynamic_size(cx.tcx, arg.ty)) {
|
||||
assert (arg.mode == ast.alias);
|
||||
assert (arg.mode == ty.mo_alias);
|
||||
atys += vec(T_typaram_ptr(cx.tn));
|
||||
} else {
|
||||
let TypeRef t;
|
||||
alt (arg.mode) {
|
||||
case (ast.alias) {
|
||||
case (ty.mo_alias) {
|
||||
t = T_ptr(type_of_inner(cx, arg.ty));
|
||||
}
|
||||
case (_) {
|
||||
@ -675,7 +675,8 @@ fn type_of_fn_full(@crate_ctxt cx,
|
||||
atys +=
|
||||
vec(T_fn_pair(cx.tn,
|
||||
type_of_fn_full(cx, ast.proto_fn, none[TypeRef],
|
||||
vec(rec(mode=ast.alias, ty=output)),
|
||||
vec(rec(mode=ty.mo_alias,
|
||||
ty=output)),
|
||||
ty.mk_nil(cx.tcx), 0u)));
|
||||
}
|
||||
|
||||
@ -829,7 +830,7 @@ fn type_of_inner(@crate_ctxt cx, ty.t t) -> TypeRef {
|
||||
fn type_of_arg(@local_ctxt cx, &ty.arg arg) -> TypeRef {
|
||||
alt (ty.struct(cx.ccx.tcx, arg.ty)) {
|
||||
case (ty.ty_param(_)) {
|
||||
if (arg.mode == ast.alias) {
|
||||
if (arg.mode == ty.mo_alias) {
|
||||
ret T_typaram_ptr(cx.ccx.tn);
|
||||
}
|
||||
}
|
||||
@ -839,7 +840,7 @@ fn type_of_arg(@local_ctxt cx, &ty.arg arg) -> TypeRef {
|
||||
}
|
||||
|
||||
auto typ;
|
||||
if (arg.mode == ast.alias) {
|
||||
if (arg.mode == ty.mo_alias) {
|
||||
typ = T_ptr(type_of_inner(cx.ccx, arg.ty));
|
||||
} else {
|
||||
typ = type_of_inner(cx.ccx, arg.ty);
|
||||
@ -3712,7 +3713,7 @@ fn trans_for_each(@block_ctxt cx,
|
||||
auto iter_body_llty =
|
||||
type_of_fn_full(lcx.ccx, ast.proto_fn,
|
||||
none[TypeRef],
|
||||
vec(rec(mode=ast.alias, ty=decl_ty)),
|
||||
vec(rec(mode=ty.mo_alias, ty=decl_ty)),
|
||||
ty.mk_nil(lcx.ccx.tcx), 0u);
|
||||
|
||||
let ValueRef lliterbody = decl_internal_fastcall_fn(lcx.ccx.llmod,
|
||||
@ -4482,7 +4483,7 @@ fn trans_bind_thunk(@local_ctxt cx,
|
||||
bcx = bound_arg.bcx;
|
||||
auto val = bound_arg.val;
|
||||
|
||||
if (out_arg.mode == ast.val) {
|
||||
if (out_arg.mode == ty.mo_val) {
|
||||
if (type_is_immediate(cx.ccx, e_ty)) {
|
||||
val = bcx.build.Load(val);
|
||||
bcx = take_ty(bcx, val, e_ty).bcx;
|
||||
@ -4492,7 +4493,7 @@ fn trans_bind_thunk(@local_ctxt cx,
|
||||
}
|
||||
} else if (ty.type_contains_params(cx.ccx.tcx,
|
||||
out_arg.ty)) {
|
||||
assert (out_arg.mode == ast.alias);
|
||||
assert (out_arg.mode == ty.mo_alias);
|
||||
val = bcx.build.PointerCast(val, llout_arg_ty);
|
||||
}
|
||||
|
||||
@ -4505,7 +4506,7 @@ fn trans_bind_thunk(@local_ctxt cx,
|
||||
let ValueRef passed_arg = llvm.LLVMGetParam(llthunk, a);
|
||||
|
||||
if (ty.type_contains_params(cx.ccx.tcx, out_arg.ty)) {
|
||||
assert (out_arg.mode == ast.alias);
|
||||
assert (out_arg.mode == ty.mo_alias);
|
||||
passed_arg = bcx.build.PointerCast(passed_arg,
|
||||
llout_arg_ty);
|
||||
}
|
||||
@ -4745,7 +4746,7 @@ fn trans_arg_expr(@block_ctxt cx,
|
||||
auto re = trans_expr(bcx, e);
|
||||
val = re.val;
|
||||
bcx = re.bcx;
|
||||
} else if (arg.mode == ast.alias) {
|
||||
} else if (arg.mode == ty.mo_alias) {
|
||||
let lval_result lv;
|
||||
if (ty.is_lval(e)) {
|
||||
lv = trans_lval(bcx, e);
|
||||
@ -4772,13 +4773,13 @@ fn trans_arg_expr(@block_ctxt cx,
|
||||
bcx = re.bcx;
|
||||
}
|
||||
|
||||
if (arg.mode != ast.alias) {
|
||||
if (arg.mode != ty.mo_alias) {
|
||||
bcx = take_ty(bcx, val, e_ty).bcx;
|
||||
}
|
||||
|
||||
if (ty.type_contains_params(cx.fcx.lcx.ccx.tcx, arg.ty)) {
|
||||
auto lldestty = lldestty0;
|
||||
if (arg.mode == ast.val) {
|
||||
if (arg.mode == ty.mo_val) {
|
||||
// FIXME: we'd prefer to use &&, but rustboot doesn't like it
|
||||
if (ty.type_is_structural(cx.fcx.lcx.ccx.tcx, e_ty)) {
|
||||
lldestty = T_ptr(lldestty);
|
||||
@ -4787,7 +4788,7 @@ fn trans_arg_expr(@block_ctxt cx,
|
||||
val = bcx.build.PointerCast(val, lldestty);
|
||||
}
|
||||
|
||||
if (arg.mode == ast.val) {
|
||||
if (arg.mode == ty.mo_val) {
|
||||
// FIXME: we'd prefer to use &&, but rustboot doesn't like it
|
||||
if (ty.type_is_structural(cx.fcx.lcx.ccx.tcx, e_ty)) {
|
||||
// Until here we've been treating structures by pointer;
|
||||
@ -5496,7 +5497,7 @@ fn trans_put(@block_ctxt cx, &Option.t[@ast.expr] e) -> result {
|
||||
case (none[@ast.expr]) { }
|
||||
case (some[@ast.expr](?x)) {
|
||||
auto e_ty = ty.expr_ty(cx.fcx.lcx.ccx.tcx, x);
|
||||
auto arg = rec(mode=ast.alias, ty=e_ty);
|
||||
auto arg = rec(mode=ty.mo_alias, ty=e_ty);
|
||||
auto arg_tys = type_of_explicit_args(cx.fcx.lcx.ccx, vec(arg));
|
||||
auto r = trans_arg_expr(bcx, arg, arg_tys.(0), x);
|
||||
bcx = r.bcx;
|
||||
@ -6362,10 +6363,7 @@ fn trans_obj(@local_ctxt cx, &ast._obj ob, ast.def_id oid,
|
||||
// Translate obj ctor args to function arguments.
|
||||
let vec[ast.arg] fn_args = vec();
|
||||
for (ast.obj_field f in ob.fields) {
|
||||
fn_args += vec(rec(mode=ast.alias,
|
||||
ty=f.ty,
|
||||
ident=f.ident,
|
||||
id=f.id));
|
||||
fn_args += vec(rec(mode=ast.alias, ty=f.ty, ident=f.ident, id=f.id));
|
||||
}
|
||||
|
||||
auto fcx = new_fn_ctxt(cx, llctor_decl);
|
||||
@ -6814,8 +6812,8 @@ fn decl_native_fn_and_pair(@crate_ctxt ccx,
|
||||
fn convert_arg_to_i32(@block_ctxt cx,
|
||||
ValueRef v,
|
||||
ty.t t,
|
||||
ast.mode mode) -> ValueRef {
|
||||
if (mode == ast.val) {
|
||||
ty.mode mode) -> ValueRef {
|
||||
if (mode == ty.mo_val) {
|
||||
if (ty.type_is_integral(cx.fcx.lcx.ccx.tcx, t)) {
|
||||
auto lldsttype = T_int();
|
||||
auto llsrctype = type_of(cx.fcx.lcx.ccx, t);
|
||||
@ -6875,7 +6873,7 @@ fn decl_native_fn_and_pair(@crate_ctxt ccx,
|
||||
call_args += vec(llarg);
|
||||
}
|
||||
|
||||
if (arg.mode == ast.val) {
|
||||
if (arg.mode == ty.mo_val) {
|
||||
drop_args += vec(tup(llarg, arg.ty));
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,13 @@ import util.typestate_ann.ts_ann;
|
||||
|
||||
// Data types
|
||||
|
||||
type arg = rec(ast.mode mode, t ty);
|
||||
tag mode {
|
||||
mo_val;
|
||||
mo_alias;
|
||||
mo_either;
|
||||
}
|
||||
|
||||
type arg = rec(mode mode, t ty);
|
||||
type field = rec(ast.ident ident, mt mt);
|
||||
type method = rec(ast.proto proto,
|
||||
ast.ident ident,
|
||||
@ -500,12 +506,12 @@ fn path_to_str(&ast.path pth) -> str {
|
||||
|
||||
fn ty_to_str(ctxt cx, &t typ) -> str {
|
||||
|
||||
fn fn_input_to_str(ctxt cx, &rec(ast.mode mode, t ty) input) -> str {
|
||||
fn fn_input_to_str(ctxt cx, &rec(mode mode, t ty) input) -> str {
|
||||
auto s;
|
||||
if (mode_is_alias(input.mode)) {
|
||||
s = "&";
|
||||
} else {
|
||||
s = "";
|
||||
alt (input.mode) {
|
||||
case (mo_val) { s = ""; }
|
||||
case (mo_alias) { s = "&"; }
|
||||
case (mo_either) { s = "?"; }
|
||||
}
|
||||
|
||||
ret s + ty_to_str(cx, input.ty);
|
||||
@ -827,15 +833,6 @@ fn copy_cname(ctxt cx, t struct_ty, t cname_ty) -> t {
|
||||
ret gen_ty_full(cx, struct(cx, struct_ty), cname_ty.cname);
|
||||
}
|
||||
|
||||
// FIXME: remove me when == works on these tags.
|
||||
fn mode_is_alias(ast.mode m) -> bool {
|
||||
alt (m) {
|
||||
case (ast.val) { ret false; }
|
||||
case (ast.alias) { ret true; }
|
||||
}
|
||||
fail;
|
||||
}
|
||||
|
||||
fn type_is_nil(ctxt cx, t ty) -> bool {
|
||||
alt (struct(cx, ty)) {
|
||||
case (ty_nil) { ret true; }
|
||||
@ -1272,23 +1269,6 @@ fn equal_type_structures(&sty a, &sty b) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn equal_mode(ast.mode a, ast.mode b) -> bool {
|
||||
alt (a) {
|
||||
case (ast.val) {
|
||||
alt (b) {
|
||||
case (ast.val) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
}
|
||||
case (ast.alias) {
|
||||
alt (b) {
|
||||
case (ast.alias) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn equal_mt(&mt a, &mt b) -> bool {
|
||||
ret equal_mut(a.mut, b.mut) && eq_ty(a.ty, b.ty);
|
||||
}
|
||||
@ -1303,7 +1283,7 @@ fn equal_type_structures(&sty a, &sty b) -> bool {
|
||||
auto i = 0u;
|
||||
while (i < len) {
|
||||
auto arg_a = args_a.(i); auto arg_b = args_b.(i);
|
||||
if (!equal_mode(arg_a.mode, arg_b.mode)) { ret false; }
|
||||
if (arg_a.mode != arg_b.mode) { ret false; }
|
||||
if (!eq_ty(arg_a.ty, arg_b.ty)) { ret false; }
|
||||
i += 1u;
|
||||
}
|
||||
@ -2117,12 +2097,13 @@ mod Unify {
|
||||
auto actual_input = actual_inputs.(i);
|
||||
|
||||
// This should be safe, I think?
|
||||
// FIXME: It's not. At all.
|
||||
auto result_mode;
|
||||
if (mode_is_alias(expected_input.mode) ||
|
||||
mode_is_alias(actual_input.mode)) {
|
||||
result_mode = ast.alias;
|
||||
if (expected_input.mode == mo_alias ||
|
||||
actual_input.mode == mo_alias) {
|
||||
result_mode = mo_alias;
|
||||
} else {
|
||||
result_mode = ast.val;
|
||||
result_mode = mo_val;
|
||||
}
|
||||
|
||||
auto result = unify_step(cx, actual_input.ty, expected_input.ty);
|
||||
|
@ -19,7 +19,9 @@ import middle.ty.block_ty;
|
||||
import middle.ty.expr_ty;
|
||||
import middle.ty.field;
|
||||
import middle.ty.method;
|
||||
import middle.ty.mode_is_alias;
|
||||
import middle.ty.mo_val;
|
||||
import middle.ty.mo_alias;
|
||||
import middle.ty.mo_either;
|
||||
import middle.ty.pat_ty;
|
||||
import middle.ty.path_to_str;
|
||||
import middle.ty.struct;
|
||||
@ -210,6 +212,15 @@ fn instantiate_path(@fn_ctxt fcx, &ast.path pth, &ty_param_count_and_ty tpt,
|
||||
ret ast.ann_type(t, ty_substs_opt, none[@ts_ann]);
|
||||
}
|
||||
|
||||
fn ast_mode_to_mode(ast.mode mode) -> ty.mode {
|
||||
auto ty_mode;
|
||||
alt (mode) {
|
||||
case (ast.val) { ty_mode = mo_val; }
|
||||
case (ast.alias) { ty_mode = mo_alias; }
|
||||
}
|
||||
ret ty_mode;
|
||||
}
|
||||
|
||||
// Parses the programmer's textual representation of a type into our internal
|
||||
// notion of a type. `getter` is a function that returns the type
|
||||
// corresponding to a definition ID.
|
||||
@ -217,8 +228,9 @@ fn ast_ty_to_ty(ty.ctxt tcx, ty_getter getter, &@ast.ty ast_ty) -> ty.t {
|
||||
fn ast_arg_to_arg(ty.ctxt tcx,
|
||||
ty_getter getter,
|
||||
&rec(ast.mode mode, @ast.ty ty) arg)
|
||||
-> rec(ast.mode mode, ty.t ty) {
|
||||
ret rec(mode=arg.mode, ty=ast_ty_to_ty(tcx, getter, arg.ty));
|
||||
-> rec(ty.mode mode, ty.t ty) {
|
||||
auto ty_mode = ast_mode_to_mode(arg.mode);
|
||||
ret rec(mode=ty_mode, ty=ast_ty_to_ty(tcx, getter, arg.ty));
|
||||
}
|
||||
|
||||
fn ast_mt_to_mt(ty.ctxt tcx,
|
||||
@ -430,8 +442,9 @@ mod Collect {
|
||||
}
|
||||
|
||||
fn ty_of_arg(@ctxt cx, &ast.arg a) -> arg {
|
||||
auto ty_mode = ast_mode_to_mode(a.mode);
|
||||
auto f = bind getter(cx, _);
|
||||
ret rec(mode=a.mode, ty=ast_ty_to_ty(cx.tcx, f, a.ty));
|
||||
ret rec(mode=ty_mode, ty=ast_ty_to_ty(cx.tcx, f, a.ty));
|
||||
}
|
||||
|
||||
fn ty_of_method(@ctxt cx, &@ast.method m) -> method {
|
||||
@ -468,7 +481,7 @@ mod Collect {
|
||||
for (ast.obj_field f in obj_info.fields) {
|
||||
auto g = bind getter(cx, _);
|
||||
auto t_field = ast_ty_to_ty(cx.tcx, g, f.ty);
|
||||
Vec.push[arg](t_inputs, rec(mode=ast.alias, ty=t_field));
|
||||
Vec.push[arg](t_inputs, rec(mode=ty.mo_alias, ty=t_field));
|
||||
}
|
||||
|
||||
cx.type_cache.insert(obj_ty_id, t_obj);
|
||||
@ -601,7 +614,7 @@ mod Collect {
|
||||
let vec[arg] args = vec();
|
||||
for (ast.variant_arg va in variant.node.args) {
|
||||
auto arg_ty = ast_ty_to_ty(cx.tcx, f, va.ty);
|
||||
args += vec(rec(mode=ast.alias, ty=arg_ty));
|
||||
args += vec(rec(mode=ty.mo_alias, ty=arg_ty));
|
||||
}
|
||||
auto tag_t = ty.mk_tag(cx.tcx, tag_id, ty_param_tys);
|
||||
result_ty = ty.mk_fn(cx.tcx, ast.proto_fn, args, tag_t);
|
||||
@ -1754,7 +1767,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
||||
args_0 += vec(some[@ast.expr](a_0));
|
||||
|
||||
// FIXME: this breaks aliases. We need a ty_fn_arg.
|
||||
auto arg_ty = rec(mode=ast.val,
|
||||
auto arg_ty = rec(mode=mo_val,
|
||||
ty=expr_ty(fcx.ccx.tcx, a_0));
|
||||
Vec.push[arg](arg_tys_0, arg_ty);
|
||||
}
|
||||
@ -1763,7 +1776,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
||||
|
||||
// FIXME: breaks aliases too?
|
||||
auto typ = next_ty_var(fcx.ccx);
|
||||
Vec.push[arg](arg_tys_0, rec(mode=ast.val, ty=typ));
|
||||
Vec.push[arg](arg_tys_0, rec(mode=mo_val, ty=typ));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2869,7 +2882,7 @@ fn check_item_fn(&@crate_ctxt ccx, &span sp, ast.ident ident, &ast._fn f,
|
||||
let vec[arg] inputs = vec();
|
||||
for (ast.arg arg in f.decl.inputs) {
|
||||
auto input_ty = ast_ty_to_ty_crate(ccx, arg.ty);
|
||||
inputs += vec(rec(mode=arg.mode, ty=input_ty));
|
||||
inputs += vec(rec(mode=ast_mode_to_mode(arg.mode), ty=input_ty));
|
||||
}
|
||||
|
||||
auto output_ty = ast_ty_to_ty_crate(ccx, f.decl.output);
|
||||
|
@ -939,7 +939,7 @@ fn print_ty_fn(ps s, ast.proto proto, Option.t[str] id,
|
||||
}
|
||||
popen_h(s);
|
||||
fn print_arg(ps s, &ast.ty_arg input) {
|
||||
if (middle.ty.mode_is_alias(input.mode)) {wrd(s.s, "&");}
|
||||
if (input.mode == ast.alias) {wrd(s.s, "&");}
|
||||
print_type(s, input.ty);
|
||||
}
|
||||
auto f = print_arg;
|
||||
|
Loading…
x
Reference in New Issue
Block a user