Refactor data structures representing constraints (again...)
I added a "resolved" version of the ast::constr type -- ty::constr_def -- that has a def_id field instead of an ann_field. This is more consistent with other types and eliminates some checking. Incidentally, I removed the def_map argument to the top-level function in middle::alias, since the ty::ctxt already has a def_map field.
This commit is contained in:
parent
52d4f48144
commit
a5bca7df88
@ -81,10 +81,10 @@ fn compile_input(session::session sess, eval::env env, str input,
|
||||
auto crate =
|
||||
time(time_passes, "parsing", bind parse_input(sess, p, input));
|
||||
if (sess.get_opts().output_type == link::output_type_none) { ret; }
|
||||
auto def_map =
|
||||
auto d =
|
||||
time(time_passes, "resolution",
|
||||
bind resolve::resolve_crate(sess, crate));
|
||||
auto ty_cx = ty::mk_ctxt(sess, def_map);
|
||||
auto ty_cx = ty::mk_ctxt(sess, d._0, d._1);
|
||||
time[()](time_passes, "typechecking",
|
||||
bind typeck::check_crate(ty_cx, crate));
|
||||
if (sess.get_opts().run_typestate) {
|
||||
@ -92,7 +92,7 @@ fn compile_input(session::session sess, eval::env env, str input,
|
||||
bind middle::tstate::ck::check_crate(ty_cx, crate));
|
||||
}
|
||||
time(time_passes, "alias checking",
|
||||
bind middle::alias::check_crate(@ty_cx, def_map, crate));
|
||||
bind middle::alias::check_crate(@ty_cx, crate));
|
||||
auto llmod =
|
||||
time[llvm::llvm::ModuleRef](time_passes, "translation",
|
||||
bind trans::trans_crate(sess, crate,
|
||||
@ -109,8 +109,8 @@ fn pretty_print_input(session::session sess, eval::env env, str input,
|
||||
auto mode;
|
||||
alt (ppm) {
|
||||
case (ppm_typed) {
|
||||
auto def_map = resolve::resolve_crate(sess, crate);
|
||||
auto ty_cx = ty::mk_ctxt(sess, def_map);
|
||||
auto d = resolve::resolve_crate(sess, crate);
|
||||
auto ty_cx = ty::mk_ctxt(sess, d._0, d._1);
|
||||
typeck::check_crate(ty_cx, crate);
|
||||
mode = ppaux::mo_typed(ty_cx);
|
||||
}
|
||||
|
@ -359,19 +359,17 @@ tag constr_arg_general_[T] { carg_base; carg_ident(T); carg_lit(@lit); }
|
||||
|
||||
type constr_arg = constr_arg_general[uint];
|
||||
|
||||
type constr_arg_use = constr_arg_general[ident];
|
||||
|
||||
type constr_arg_general[T] = spanned[constr_arg_general_[T]];
|
||||
|
||||
type constr_ = rec(path path,
|
||||
vec[@constr_arg_general[uint]] args,
|
||||
ann ann);
|
||||
|
||||
// The ann field is there so that using the def_map in the type
|
||||
// context, we can get the def_id for the path.
|
||||
type constr_general[T] =
|
||||
rec(path path, vec[@constr_arg_general[T]] args, ann ann);
|
||||
type constr = spanned[constr_];
|
||||
|
||||
type constr = spanned[constr_general[uint]];
|
||||
|
||||
type constr_use = spanned[constr_general[ident]];
|
||||
/* The parser generates ast::constrs; resolve generates
|
||||
a mapping from each function to a list of ty::constr_defs,
|
||||
corresponding to these. */
|
||||
|
||||
type arg = rec(mode mode, @ty ty, ident ident, def_id id);
|
||||
|
||||
|
@ -78,8 +78,8 @@ fn parse_ty_or_bang(@pstate st, str_def sd) -> ty_or_bang {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_constrs(@pstate st, str_def sd) -> vec[@ast::constr] {
|
||||
let vec[@ast::constr] res = [];
|
||||
fn parse_constrs(@pstate st, str_def sd) -> vec[@ty::constr_def] {
|
||||
let vec[@ty::constr_def] res = [];
|
||||
alt (peek(st) as char) {
|
||||
case (':') {
|
||||
do {
|
||||
@ -92,7 +92,7 @@ fn parse_constrs(@pstate st, str_def sd) -> vec[@ast::constr] {
|
||||
ret res;
|
||||
}
|
||||
|
||||
fn parse_constr(@pstate st, str_def sd) -> @ast::constr {
|
||||
fn parse_constr(@pstate st, str_def sd) -> @ty::constr_def {
|
||||
st.tcx.sess.unimpl("Reading constraints " + " isn't implemented");
|
||||
/*
|
||||
let vec[@ast::constr_arg] args = [];
|
||||
@ -318,7 +318,7 @@ fn parse_hex(@pstate st) -> uint {
|
||||
}
|
||||
|
||||
fn parse_ty_fn(@pstate st, str_def sd) ->
|
||||
tup(vec[ty::arg], ty::t, ast::controlflow, vec[@ast::constr]) {
|
||||
tup(vec[ty::arg], ty::t, ast::controlflow, vec[@ty::constr_def]) {
|
||||
assert (next(st) as char == '[');
|
||||
let vec[ty::arg] inputs = [];
|
||||
while (peek(st) as char != ']') {
|
||||
|
@ -35,14 +35,11 @@ tag local_info { arg(ast::mode); objfield(ast::mutability); }
|
||||
|
||||
type ctx =
|
||||
rec(@ty::ctxt tcx,
|
||||
resolve::def_map dm,
|
||||
std::map::hashmap[def_num, local_info] local_map);
|
||||
|
||||
fn check_crate(@ty::ctxt tcx, resolve::def_map dm, &@ast::crate crate) {
|
||||
fn check_crate(@ty::ctxt tcx, &@ast::crate crate) {
|
||||
auto cx =
|
||||
@rec(tcx=tcx,
|
||||
dm=dm,
|
||||
|
||||
// Stores information about object fields and function
|
||||
// arguments that's otherwise not easily available.
|
||||
local_map=util::common::new_int_hash());
|
||||
@ -173,7 +170,7 @@ fn check_call(&ctx cx, &@ast::expr f, &vec[@ast::expr] args, &scope sc) ->
|
||||
if (vec::len(unsafe_ts) > 0u) {
|
||||
alt (f.node) {
|
||||
case (ast::expr_path(_, ?ann)) {
|
||||
if (def_is_local(cx.dm.get(ann.id), true)) {
|
||||
if (def_is_local(cx.tcx.def_map.get(ann.id), true)) {
|
||||
cx.tcx.sess.span_err
|
||||
(f.span, #fmt("function may alias with argument \
|
||||
%u, which is not immutably rooted",
|
||||
@ -231,7 +228,7 @@ fn check_tail_call(&ctx cx, &@ast::expr call) {
|
||||
auto ok = true;
|
||||
alt (args.(i).node) {
|
||||
case (ast::expr_path(_, ?ann)) {
|
||||
auto def = cx.dm.get(ann.id);
|
||||
auto def = cx.tcx.def_map.get(ann.id);
|
||||
auto dnum = ast::def_id_of_def(def)._1;
|
||||
alt (cx.local_map.find(dnum)) {
|
||||
case (some(arg(ast::alias(?mut)))) {
|
||||
@ -353,7 +350,7 @@ fn check_for(&ctx cx, &@ast::local local, &@ast::expr seq, &ast::block block,
|
||||
|
||||
fn check_var(&ctx cx, &@ast::expr ex, &ast::path p, ast::ann ann, bool assign,
|
||||
&scope sc) {
|
||||
auto def = cx.dm.get(ann.id);
|
||||
auto def = cx.tcx.def_map.get(ann.id);
|
||||
if (!def_is_local(def, true)) { ret; }
|
||||
auto my_defnum = ast::def_id_of_def(def)._1;
|
||||
auto var_t = ty::expr_ty(*cx.tcx, ex);
|
||||
@ -379,7 +376,7 @@ fn check_assign(&@ctx cx, &@ast::expr dest, &@ast::expr src, &scope sc,
|
||||
visit_expr(cx, src, sc, v);
|
||||
alt (dest.node) {
|
||||
case (ast::expr_path(?p, ?ann)) {
|
||||
auto dnum = ast::def_id_of_def(cx.dm.get(ann.id))._1;
|
||||
auto dnum = ast::def_id_of_def(cx.tcx.def_map.get(ann.id))._1;
|
||||
if (is_immutable_alias(cx, sc, dnum)) {
|
||||
cx.tcx.sess.span_err(dest.span,
|
||||
"assigning to immutable alias");
|
||||
@ -566,7 +563,7 @@ fn inner_mut(&vec[deref] ds) -> option::t[ty::t] {
|
||||
fn path_def_id(&ctx cx, &@ast::expr ex) -> option::t[ast::def_id] {
|
||||
alt (ex.node) {
|
||||
case (ast::expr_path(_, ?ann)) {
|
||||
ret some(ast::def_id_of_def(cx.dm.get(ann.id)));
|
||||
ret some(ast::def_id_of_def(cx.tcx.def_map.get(ann.id)));
|
||||
}
|
||||
case (_) { ret none; }
|
||||
}
|
||||
|
@ -221,8 +221,7 @@ mod Encode {
|
||||
case (ast::native_abi_cdecl) { w.write_char('c'); }
|
||||
case (ast::native_abi_llvm) { w.write_char('l'); }
|
||||
}
|
||||
let vec[@constr] res_constrs = [];
|
||||
enc_ty_fn(w, cx, args, out, ast::return, res_constrs);
|
||||
enc_ty_fn(w, cx, args, out, ast::return, []);
|
||||
}
|
||||
case (ty::ty_obj(?methods)) {
|
||||
w.write_str("O[");
|
||||
@ -253,7 +252,7 @@ mod Encode {
|
||||
}
|
||||
}
|
||||
fn enc_ty_fn(&io::writer w, &@ctxt cx, &vec[ty::arg] args, &ty::t out,
|
||||
&ast::controlflow cf, &vec[@ast::constr] constrs) {
|
||||
&ast::controlflow cf, &vec[@ty::constr_def] constrs) {
|
||||
w.write_char('[');
|
||||
for (ty::arg arg in args) {
|
||||
alt (arg.mode) {
|
||||
@ -271,7 +270,7 @@ mod Encode {
|
||||
case (_) { enc_ty(w, cx, out); }
|
||||
}
|
||||
auto colon = true;
|
||||
for (@ast::constr c in constrs) {
|
||||
for (@ty::constr_def c in constrs) {
|
||||
if (colon) {
|
||||
w.write_char(':');
|
||||
colon = false;
|
||||
@ -279,7 +278,7 @@ mod Encode {
|
||||
enc_constr(w, cx, c);
|
||||
}
|
||||
}
|
||||
fn enc_constr(&io::writer w, &@ctxt cx, &@ast::constr c) {
|
||||
fn enc_constr(&io::writer w, &@ctxt cx, &@ty::constr_def c) {
|
||||
w.write_str(path_to_str(c.node.path));
|
||||
w.write_char('(');
|
||||
// FIXME
|
||||
|
@ -11,7 +11,8 @@ import util::common::new_int_hash;
|
||||
import util::common::new_uint_hash;
|
||||
import util::common::new_str_hash;
|
||||
import util::common::span;
|
||||
import middle::tstate::ann::ts_ann;
|
||||
import util::common::respan;
|
||||
import middle::ty::constr_table;
|
||||
import visit::vt;
|
||||
import std::map::hashmap;
|
||||
import std::list;
|
||||
@ -111,6 +112,7 @@ type def_map = hashmap[uint, def];
|
||||
type env =
|
||||
rec(crate_map crate_map,
|
||||
def_map def_map,
|
||||
constr_table fn_constrs,
|
||||
hashmap[def_id, @ast::item] ast_map,
|
||||
hashmap[ast::def_num, import_state] imports,
|
||||
hashmap[ast::def_num, @indexed_mod] mod_map,
|
||||
@ -118,17 +120,18 @@ type env =
|
||||
ext_hash ext_cache,
|
||||
session sess);
|
||||
|
||||
|
||||
// Used to distinguish between lookups from outside and from inside modules,
|
||||
// since export restrictions should only be applied for the former.
|
||||
tag dir { inside; outside; }
|
||||
|
||||
tag namespace { ns_value; ns_type; ns_module; }
|
||||
|
||||
fn resolve_crate(session sess, @ast::crate crate) -> def_map {
|
||||
fn resolve_crate(session sess, @ast::crate crate)
|
||||
-> tup(def_map, constr_table) {
|
||||
auto e =
|
||||
@rec(crate_map=new_uint_hash[ast::crate_num](),
|
||||
def_map=new_uint_hash[def](),
|
||||
fn_constrs = new_def_hash[vec[ty::constr_def]](),
|
||||
ast_map=new_def_hash[@ast::item](),
|
||||
imports=new_int_hash[import_state](),
|
||||
mod_map=new_int_hash[@indexed_mod](),
|
||||
@ -140,7 +143,7 @@ fn resolve_crate(session sess, @ast::crate crate) -> def_map {
|
||||
resolve_imports(*e);
|
||||
check_for_collisions(e, *crate);
|
||||
resolve_names(e, crate);
|
||||
ret e.def_map;
|
||||
ret tup(e.def_map, e.fn_constrs);
|
||||
}
|
||||
|
||||
|
||||
@ -266,8 +269,9 @@ fn resolve_names(&@env e, &@ast::crate c) {
|
||||
visit_arm=bind walk_arm(e, _, _, _),
|
||||
visit_expr=bind walk_expr(e, _, _, _),
|
||||
visit_ty=bind walk_ty(e, _, _, _),
|
||||
visit_fn=visit_fn_with_scope,
|
||||
visit_constr=bind walk_constr(e, _, _, _)
|
||||
visit_constr = bind walk_constr(e, _, _, _),
|
||||
visit_fn=bind visit_fn_with_scope
|
||||
(e, _, _, _, _, _, _, _, _)
|
||||
with *visit::default_visitor());
|
||||
visit::visit_crate(*c, cons(scope_crate(c), @nil), visit::vtor(v));
|
||||
fn walk_expr(@env e, &@ast::expr exp, &scopes sc, &vt[scopes] v) {
|
||||
@ -282,12 +286,7 @@ fn resolve_names(&@env e, &@ast::crate c) {
|
||||
case (_) { }
|
||||
}
|
||||
}
|
||||
fn walk_constr(@env e, &@ast::constr c, &scopes sc, &vt[scopes] v) {
|
||||
auto new_def =
|
||||
lookup_path_strict(*e, sc, c.span, c.node.path.node.idents,
|
||||
ns_value);
|
||||
e.def_map.insert(c.node.ann.id, new_def);
|
||||
}
|
||||
|
||||
fn walk_ty(@env e, &@ast::ty t, &scopes sc, &vt[scopes] v) {
|
||||
visit::visit_ty(t, sc, v);
|
||||
alt (t.node) {
|
||||
@ -300,6 +299,13 @@ fn resolve_names(&@env e, &@ast::crate c) {
|
||||
case (_) { }
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_constr(@env e, &@ast::constr c, &scopes sc, &vt[scopes] v) {
|
||||
auto new_def = lookup_path_strict(*e, sc, c.span,
|
||||
c.node.path.node.idents, ns_value);
|
||||
e.def_map.insert(c.node.ann.id, new_def);
|
||||
}
|
||||
|
||||
fn walk_arm(@env e, &ast::arm a, &scopes sc, &vt[scopes] v) {
|
||||
walk_pat(*e, sc, a.pat);
|
||||
visit_arm_with_scope(a, sc, v);
|
||||
@ -338,11 +344,16 @@ fn visit_native_item_with_scope(&@ast::native_item ni, &scopes sc,
|
||||
visit::visit_native_item(ni, cons(scope_native_item(ni), @sc), v);
|
||||
}
|
||||
|
||||
fn visit_fn_with_scope(&ast::_fn f, &vec[ast::ty_param] tp, &span sp,
|
||||
fn visit_fn_with_scope(&@env e, &ast::_fn f, &vec[ast::ty_param] tp, &span sp,
|
||||
&ident name, &def_id d_id, &ann a, &scopes sc,
|
||||
&vt[scopes] v) {
|
||||
visit::visit_fn(f, tp, sp, name, d_id, a, cons(scope_fn(f.decl, tp), @sc),
|
||||
v);
|
||||
// here's where we need to set up the mapping
|
||||
// for f's constrs in the table.
|
||||
for (@ast::constr c in f.decl.constraints) {
|
||||
resolve_constr(e, d_id, c, sc, v);
|
||||
}
|
||||
visit::visit_fn(f, tp, sp, name, d_id, a,
|
||||
cons(scope_fn(f.decl, tp), @sc), v);
|
||||
}
|
||||
|
||||
fn visit_block_with_scope(&ast::block b, &scopes sc, &vt[scopes] v) {
|
||||
@ -389,6 +400,37 @@ fn follow_import(&env e, &scopes sc, vec[ident] path, &span sp) -> def {
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_constr(@env e, &def_id d_id, &@ast::constr c, &scopes sc,
|
||||
&vt[scopes] v) {
|
||||
let def new_def = lookup_path_strict(*e, sc, c.span,
|
||||
c.node.path.node.idents,
|
||||
ns_value);
|
||||
alt (new_def) {
|
||||
case (ast::def_fn(?pred_id)) {
|
||||
let ty::constr_general[uint] c_ = rec(path=c.node.path,
|
||||
args=c.node.args,
|
||||
id=pred_id);
|
||||
let ty::constr_def new_constr = respan(c.span, c_);
|
||||
add_constr(e, d_id, new_constr);
|
||||
}
|
||||
case (_) {
|
||||
e.sess.span_err(c.span, "Non-predicate in constraint: "
|
||||
+ ty::path_to_str(c.node.path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_constr(&@env e, &def_id d_id, &ty::constr_def c) {
|
||||
e.fn_constrs.insert(d_id,
|
||||
alt (e.fn_constrs.find(d_id)) {
|
||||
case (none) {
|
||||
[c]
|
||||
}
|
||||
case (some(?cs)) {
|
||||
cs + [c]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Import resolution
|
||||
fn resolve_import(&env e, &@ast::view_item it, &scopes sc) {
|
||||
|
@ -198,8 +198,9 @@ to represent predicate *arguments* however. This type
|
||||
Both types store an ident and span, for error-logging purposes.
|
||||
*/
|
||||
type pred_desc_ = rec(vec[@constr_arg_use] args, uint bit_num);
|
||||
|
||||
type pred_desc = spanned[pred_desc_];
|
||||
type constr_arg_use = constr_arg_general[ident];
|
||||
|
||||
|
||||
tag constraint {
|
||||
cinit(uint, span, ident);
|
||||
@ -456,7 +457,7 @@ fn controlflow_expr(&crate_ctxt ccx, @expr e) -> controlflow {
|
||||
}
|
||||
}
|
||||
|
||||
fn constraints_expr(&ty::ctxt cx, @expr e) -> vec[@ast::constr] {
|
||||
fn constraints_expr(&ty::ctxt cx, @expr e) -> vec[@ty::constr_def] {
|
||||
alt (ty::struct(cx, ty::ann_to_type(cx, expr_ann(e)))) {
|
||||
case (ty::ty_fn(_, _, _, _, ?cs)) { ret cs; }
|
||||
case (_) { ret []; }
|
||||
@ -511,9 +512,11 @@ fn constraints(&fn_ctxt fcx) -> vec[norm_constraint] {
|
||||
// FIXME:
|
||||
// this probably doesn't handle name shadowing well (or at all)
|
||||
// variables should really always be id'd by def_id and not ident
|
||||
|
||||
fn match_args(&fn_ctxt fcx, vec[pred_desc] occs, vec[@constr_arg_use] occ) ->
|
||||
uint {
|
||||
log "match_args: looking at " + pretty::ppaux::constr_args_to_str_1(occ);
|
||||
log ("match_args: looking at " +
|
||||
pretty::ppaux::constr_args_to_str(std::util::id[str], occ));
|
||||
for (pred_desc pd in occs) {
|
||||
log "match_args: candidate " + pred_desc_to_str(pd);
|
||||
if (ty::args_eq(str::eq, pd.node.args, occ)) { ret pd.node.bit_num; }
|
||||
@ -586,11 +589,13 @@ fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr {
|
||||
|
||||
fn pred_desc_to_str(&pred_desc p) -> str {
|
||||
ret "<" + uistr(p.node.bit_num) + ", " +
|
||||
pretty::ppaux::constr_args_to_str_1(p.node.args) + ">";
|
||||
pretty::ppaux::constr_args_to_str(std::util::id[str], p.node.args)
|
||||
+ ">";
|
||||
}
|
||||
|
||||
fn substitute_constr_args(&ty::ctxt cx, &vec[@expr] actuals, &@ast::constr c)
|
||||
-> constr__ {
|
||||
fn substitute_constr_args(&ty::ctxt cx,
|
||||
&vec[@expr] actuals, &@ty::constr_def c)
|
||||
-> constr__ {
|
||||
let vec[@constr_arg_use] res = [];
|
||||
for (@constr_arg a in c.node.args) {
|
||||
res += [substitute_arg(cx, actuals, a)];
|
||||
|
@ -37,30 +37,16 @@ fn collect_pred(&ctxt cx, &@expr e) {
|
||||
case (expr_check(?e, _)) {
|
||||
vec::push(*cx.cs, expr_to_constr(cx.tcx, e));
|
||||
}
|
||||
case (
|
||||
// If it's a call, generate appropriate instances of the
|
||||
// call's constraints.
|
||||
expr_call(?operator, ?operands, ?a)) {
|
||||
for (@ast::constr c in constraints_expr(cx.tcx, operator)) {
|
||||
auto d_id = ann_to_def_strict(cx.tcx, c.node.ann);
|
||||
alt (d_id) {
|
||||
case (def_fn(?an_id)) {
|
||||
let aux::constr ct =
|
||||
respan(c.span,
|
||||
rec(id=an_id,
|
||||
c=aux::substitute_constr_args(cx.tcx,
|
||||
operands,
|
||||
c)));
|
||||
vec::push(*cx.cs, ct);
|
||||
}
|
||||
case (_) {
|
||||
cx.tcx.sess.span_err(c.span,
|
||||
"Non-pred in constraint");
|
||||
}
|
||||
}
|
||||
// If it's a call, generate appropriate instances of the
|
||||
// call's constraints.
|
||||
case (expr_call(?operator, ?operands, ?a)) {
|
||||
for (@ty::constr_def c in constraints_expr(cx.tcx, operator)) {
|
||||
let aux::constr ct = respan(c.span,
|
||||
rec(id=c.node.id,
|
||||
c=aux::substitute_constr_args(cx.tcx,
|
||||
operands, c)));
|
||||
vec::push(*cx.cs, ct);
|
||||
}
|
||||
// FIXME: constraints on result type
|
||||
|
||||
}
|
||||
case (_) { }
|
||||
}
|
||||
|
@ -208,38 +208,16 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
|
||||
auto args = vec::clone[@expr](operands);
|
||||
vec::push[@expr](args, operator);
|
||||
find_pre_post_exprs(fcx, args, a);
|
||||
/* should test higher-order constrained functions */
|
||||
|
||||
/* FIXME */
|
||||
|
||||
/* see if the call has any constraints on its in type */
|
||||
|
||||
log "a function: ";
|
||||
/* see if the call has any constraints on its type */
|
||||
log("a function: " );
|
||||
log_expr(*operator);
|
||||
auto pp = expr_pp(fcx.ccx, e);
|
||||
for (@constr c in constraints_expr(fcx.ccx.tcx, operator)) {
|
||||
auto id = ann_to_def(fcx.ccx, c.node.ann);
|
||||
alt (id) {
|
||||
case (some(def_fn(?d_id))) {
|
||||
auto i =
|
||||
bit_num(fcx,
|
||||
rec(id=d_id,
|
||||
c=substitute_constr_args(fcx.ccx.tcx,
|
||||
operands,
|
||||
c)));
|
||||
require(i, pp);
|
||||
}
|
||||
case (_) {
|
||||
fcx.ccx.tcx.sess.span_err(c.span,
|
||||
"Unbound pred " +
|
||||
" or pred that's not \
|
||||
bound to a function");
|
||||
}
|
||||
}
|
||||
for (@ty::constr_def c in
|
||||
constraints_expr(fcx.ccx.tcx, operator)) {
|
||||
auto i = bit_num(fcx, rec(id=c.node.id,
|
||||
c=substitute_constr_args(fcx.ccx.tcx, operands, c)));
|
||||
require(i, pp);
|
||||
}
|
||||
|
||||
// FIXME: constraints on result type
|
||||
|
||||
/* if this is a failing call, its postcondition sets everything */
|
||||
alt (controlflow_expr(fcx.ccx, operator)) {
|
||||
case (noreturn) { set_postcond_false(fcx.ccx, a); }
|
||||
|
@ -13,23 +13,14 @@ import std::option::some;
|
||||
import std::smallintmap;
|
||||
import driver::session;
|
||||
import front::ast;
|
||||
import front::ast::def_id;
|
||||
import front::ast::constr_arg_general;
|
||||
import front::ast::mutability;
|
||||
import front::ast::controlflow;
|
||||
import front::creader;
|
||||
import middle::metadata;
|
||||
import util::common;
|
||||
import util::common::ty_u8;
|
||||
import util::common::ty_u16;
|
||||
import util::common::ty_u32;
|
||||
import util::common::ty_u64;
|
||||
import util::common::ty_i8;
|
||||
import util::common::ty_i16;
|
||||
import util::common::ty_i32;
|
||||
import util::common::ty_i64;
|
||||
import util::common::ty_f32;
|
||||
import util::common::ty_f64;
|
||||
import util::common::new_def_hash;
|
||||
import util::common::span;
|
||||
import util::common::*;
|
||||
|
||||
import util::data::interner;
|
||||
|
||||
|
||||
@ -46,7 +37,7 @@ type method =
|
||||
vec[arg] inputs,
|
||||
t output,
|
||||
controlflow cf,
|
||||
vec[@ast::constr] constrs);
|
||||
vec[@constr_def] constrs);
|
||||
|
||||
tag any_item {
|
||||
any_item_rust(@ast::item);
|
||||
@ -54,12 +45,14 @@ tag any_item {
|
||||
}
|
||||
|
||||
type item_table = hashmap[ast::def_id, any_item];
|
||||
type constr_table = hashmap[ast::def_id, vec[constr_def]];
|
||||
|
||||
type mt = rec(t ty, ast::mutability mut);
|
||||
|
||||
|
||||
// Contains information needed to resolve types and (in the future) look up
|
||||
// the types of AST nodes.
|
||||
|
||||
type creader_cache = hashmap[tup(int, uint, uint), ty::t];
|
||||
|
||||
type ctxt =
|
||||
@ -68,7 +61,7 @@ type ctxt =
|
||||
resolve::def_map def_map,
|
||||
node_type_table node_types,
|
||||
item_table items, // Only contains type items
|
||||
|
||||
constr_table fn_constrs,
|
||||
type_cache tcache,
|
||||
creader_cache rcache,
|
||||
hashmap[t, str] short_names_cache,
|
||||
@ -83,7 +76,6 @@ type ty_ctxt = ctxt;
|
||||
ret mk_fn(cx, m.proto, m.inputs, m.output, m.cf, m.constrs);
|
||||
}
|
||||
|
||||
|
||||
// Never construct these manually. These are interned.
|
||||
//
|
||||
// TODO: It'd be really nice to be able to hide this definition from the
|
||||
@ -107,11 +99,11 @@ tag sty {
|
||||
ty_int;
|
||||
ty_float;
|
||||
ty_uint;
|
||||
ty_machine(util::common::ty_mach);
|
||||
ty_machine(ty_mach);
|
||||
ty_char;
|
||||
ty_str;
|
||||
ty_istr;
|
||||
ty_tag(ast::def_id, vec[t]);
|
||||
ty_tag(def_id, vec[t]);
|
||||
ty_box(mt);
|
||||
ty_vec(mt);
|
||||
ty_ivec(mt);
|
||||
@ -121,7 +113,7 @@ tag sty {
|
||||
ty_task;
|
||||
ty_tup(vec[mt]);
|
||||
ty_rec(vec[field]);
|
||||
ty_fn(ast::proto, vec[arg], t, controlflow, vec[@ast::constr]);
|
||||
ty_fn(ast::proto, vec[arg], t, controlflow, vec[@constr_def]);
|
||||
ty_native_fn(ast::native_abi, vec[arg], t);
|
||||
ty_obj(vec[method]);
|
||||
ty_var(int); // type variable
|
||||
@ -134,6 +126,10 @@ tag sty {
|
||||
|
||||
}
|
||||
|
||||
type constr_def = spanned[constr_general[uint]];
|
||||
type constr_general[T] = rec(path path,
|
||||
vec[@constr_arg_general[T]] args,
|
||||
def_id id);
|
||||
|
||||
// Data structures used in type unification
|
||||
tag type_err {
|
||||
@ -247,12 +243,13 @@ fn mk_rcache() -> creader_cache {
|
||||
ret map::mk_hashmap[tup(int, uint, uint), t](h, e);
|
||||
}
|
||||
|
||||
fn mk_ctxt(session::session s, resolve::def_map dm) -> ctxt {
|
||||
fn mk_ctxt(session::session s, resolve::def_map dm, constr_table cs) -> ctxt {
|
||||
|
||||
let vec[mutable option::t[ty::ty_param_substs_opt_and_ty]] ntt_sub =
|
||||
[mutable ];
|
||||
let node_type_table ntt = @mutable ntt_sub;
|
||||
auto tcache = common::new_def_hash[ty::ty_param_count_and_ty]();
|
||||
auto items = common::new_def_hash[any_item]();
|
||||
auto tcache = new_def_hash[ty::ty_param_count_and_ty]();
|
||||
auto items = new_def_hash[any_item]();
|
||||
auto ts = @interner::mk[raw_t](hash_raw_ty, eq_raw_ty);
|
||||
auto cx =
|
||||
rec(ts=ts,
|
||||
@ -260,6 +257,7 @@ fn mk_ctxt(session::session s, resolve::def_map dm) -> ctxt {
|
||||
def_map=dm,
|
||||
node_types=ntt,
|
||||
items=items,
|
||||
fn_constrs = cs,
|
||||
tcache=tcache,
|
||||
rcache=mk_rcache(),
|
||||
short_names_cache=map::mk_hashmap[ty::t,
|
||||
@ -379,7 +377,7 @@ fn mk_float(&ctxt cx) -> t { ret idx_float; }
|
||||
|
||||
fn mk_uint(&ctxt cx) -> t { ret idx_uint; }
|
||||
|
||||
fn mk_mach(&ctxt cx, &util::common::ty_mach tm) -> t {
|
||||
fn mk_mach(&ctxt cx, &ty_mach tm) -> t {
|
||||
alt (tm) {
|
||||
case (ty_u8) { ret idx_u8; }
|
||||
case (ty_u16) { ret idx_u16; }
|
||||
@ -439,7 +437,7 @@ fn mk_imm_tup(&ctxt cx, &vec[t] tys) -> t {
|
||||
fn mk_rec(&ctxt cx, &vec[field] fs) -> t { ret gen_ty(cx, ty_rec(fs)); }
|
||||
|
||||
fn mk_fn(&ctxt cx, &ast::proto proto, &vec[arg] args, &t ty, &controlflow cf,
|
||||
&vec[@ast::constr] constrs) -> t {
|
||||
&vec[@constr_def] constrs) -> t {
|
||||
ret gen_ty(cx, ty_fn(proto, args, ty, cf, constrs));
|
||||
}
|
||||
|
||||
@ -759,8 +757,8 @@ fn sequence_is_interior(&ctxt cx, &t ty) -> bool {
|
||||
|
||||
fn sequence_element_type(&ctxt cx, &t ty) -> t {
|
||||
alt (struct(cx, ty)) {
|
||||
case (ty_str) { ret mk_mach(cx, common::ty_u8); }
|
||||
case (ty_istr) { ret mk_mach(cx, common::ty_u8); }
|
||||
case (ty_str) { ret mk_mach(cx, ty_u8); }
|
||||
case (ty_istr) { ret mk_mach(cx, ty_u8); }
|
||||
case (ty_vec(?mt)) { ret mt.ty; }
|
||||
case (ty_ivec(?mt)) { ret mt.ty; }
|
||||
case (_) {
|
||||
@ -915,14 +913,14 @@ fn type_is_integral(&ctxt cx, &t ty) -> bool {
|
||||
case (ty_uint) { ret true; }
|
||||
case (ty_machine(?m)) {
|
||||
alt (m) {
|
||||
case (common::ty_i8) { ret true; }
|
||||
case (common::ty_i16) { ret true; }
|
||||
case (common::ty_i32) { ret true; }
|
||||
case (common::ty_i64) { ret true; }
|
||||
case (common::ty_u8) { ret true; }
|
||||
case (common::ty_u16) { ret true; }
|
||||
case (common::ty_u32) { ret true; }
|
||||
case (common::ty_u64) { ret true; }
|
||||
case (ty_i8) { ret true; }
|
||||
case (ty_i16) { ret true; }
|
||||
case (ty_i32) { ret true; }
|
||||
case (ty_i64) { ret true; }
|
||||
case (ty_u8) { ret true; }
|
||||
case (ty_u16) { ret true; }
|
||||
case (ty_u32) { ret true; }
|
||||
case (ty_u64) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
}
|
||||
@ -935,8 +933,8 @@ fn type_is_fp(&ctxt cx, &t ty) -> bool {
|
||||
alt (struct(cx, ty)) {
|
||||
case (ty_machine(?tm)) {
|
||||
alt (tm) {
|
||||
case (common::ty_f32) { ret true; }
|
||||
case (common::ty_f64) { ret true; }
|
||||
case (ty_f32) { ret true; }
|
||||
case (ty_f64) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
}
|
||||
@ -950,10 +948,10 @@ fn type_is_signed(&ctxt cx, &t ty) -> bool {
|
||||
case (ty_int) { ret true; }
|
||||
case (ty_machine(?tm)) {
|
||||
alt (tm) {
|
||||
case (common::ty_i8) { ret true; }
|
||||
case (common::ty_i16) { ret true; }
|
||||
case (common::ty_i32) { ret true; }
|
||||
case (common::ty_i64) { ret true; }
|
||||
case (ty_i8) { ret true; }
|
||||
case (ty_i16) { ret true; }
|
||||
case (ty_i32) { ret true; }
|
||||
case (ty_i64) { ret true; }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
}
|
||||
@ -1005,16 +1003,16 @@ fn hash_type_structure(&sty st) -> uint {
|
||||
case (ty_uint) { ret 4u; }
|
||||
case (ty_machine(?tm)) {
|
||||
alt (tm) {
|
||||
case (common::ty_i8) { ret 5u; }
|
||||
case (common::ty_i16) { ret 6u; }
|
||||
case (common::ty_i32) { ret 7u; }
|
||||
case (common::ty_i64) { ret 8u; }
|
||||
case (common::ty_u8) { ret 9u; }
|
||||
case (common::ty_u16) { ret 10u; }
|
||||
case (common::ty_u32) { ret 11u; }
|
||||
case (common::ty_u64) { ret 12u; }
|
||||
case (common::ty_f32) { ret 13u; }
|
||||
case (common::ty_f64) { ret 14u; }
|
||||
case (ty_i8) { ret 5u; }
|
||||
case (ty_i16) { ret 6u; }
|
||||
case (ty_i32) { ret 7u; }
|
||||
case (ty_i64) { ret 8u; }
|
||||
case (ty_u8) { ret 9u; }
|
||||
case (ty_u16) { ret 10u; }
|
||||
case (ty_u32) { ret 11u; }
|
||||
case (ty_u64) { ret 12u; }
|
||||
case (ty_f32) { ret 13u; }
|
||||
case (ty_f64) { ret 14u; }
|
||||
}
|
||||
}
|
||||
case (ty_char) { ret 15u; }
|
||||
@ -1096,7 +1094,7 @@ fn arg_eq[T](&fn(&T, &T) -> bool eq, @ast::constr_arg_general[T] a,
|
||||
}
|
||||
case (ast::carg_lit(?l)) {
|
||||
alt (b.node) {
|
||||
case (ast::carg_lit(?m)) { ret util::common::lit_eq(l, m); }
|
||||
case (ast::carg_lit(?m)) { ret lit_eq(l, m); }
|
||||
case (_) { ret false; }
|
||||
}
|
||||
}
|
||||
@ -1113,18 +1111,18 @@ fn args_eq[T](fn(&T, &T) -> bool eq, vec[@ast::constr_arg_general[T]] a,
|
||||
ret true;
|
||||
}
|
||||
|
||||
fn constr_eq(&@ast::constr c, &@ast::constr d) -> bool {
|
||||
fn constr_eq(&@constr_def c, &@constr_def d) -> bool {
|
||||
ret path_to_str(c.node.path) == path_to_str(d.node.path) &&
|
||||
// FIXME: hack
|
||||
args_eq(eq_int, c.node.args, d.node.args);
|
||||
}
|
||||
|
||||
fn constrs_eq(&vec[@ast::constr] cs, &vec[@ast::constr] ds) -> bool {
|
||||
fn constrs_eq(&vec[@constr_def] cs, &vec[@constr_def] ds) -> bool {
|
||||
if (vec::len(cs) != vec::len(ds)) { ret false; }
|
||||
auto i = 0;
|
||||
for (@ast::constr c in cs) {
|
||||
auto i = 0u;
|
||||
for (@constr_def c in cs) {
|
||||
if (!constr_eq(c, ds.(i))) { ret false; }
|
||||
i += 1;
|
||||
i += 1u;
|
||||
}
|
||||
ret true;
|
||||
}
|
||||
@ -1829,8 +1827,8 @@ mod unify {
|
||||
&t expected, &t actual, &vec[arg] expected_inputs,
|
||||
&t expected_output, &vec[arg] actual_inputs, &t actual_output,
|
||||
&controlflow expected_cf, &controlflow actual_cf,
|
||||
&vec[@ast::constr] expected_constrs,
|
||||
&vec[@ast::constr] actual_constrs) -> result {
|
||||
&vec[@constr_def] expected_constrs,
|
||||
&vec[@constr_def] actual_constrs) -> result {
|
||||
if (e_proto != a_proto) { ret ures_err(terr_mismatch); }
|
||||
alt (expected_cf) {
|
||||
case (ast::return) { }
|
||||
@ -2473,7 +2471,7 @@ fn tag_variant_with_id(&ctxt cx, &ast::def_id tag_id, &ast::def_id variant_id)
|
||||
auto i = 0u;
|
||||
while (i < vec::len[variant_info](variants)) {
|
||||
auto variant = variants.(i);
|
||||
if (common::def_eq(variant.id, variant_id)) { ret variant; }
|
||||
if (def_eq(variant.id, variant_id)) { ret variant; }
|
||||
i += 1u;
|
||||
}
|
||||
cx.sess.bug("tag_variant_with_id(): no variant exists with that ID");
|
||||
|
@ -6,6 +6,7 @@ import front::creader;
|
||||
import driver::session;
|
||||
import util::common;
|
||||
import util::common::span;
|
||||
import util::common::respan;
|
||||
import util::common::new_def_hash;
|
||||
import util::common::log_expr_err;
|
||||
import middle::ty;
|
||||
@ -312,7 +313,10 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
|
||||
auto f = bind ast_arg_to_arg(tcx, getter, _);
|
||||
auto i = vec::map[ast::ty_arg, arg](f, inputs);
|
||||
auto out_ty = ast_ty_to_ty(tcx, getter, output);
|
||||
typ = ty::mk_fn(tcx, proto, i, out_ty, cf, constrs);
|
||||
let fn(&@ast::constr) -> @ty::constr_def g =
|
||||
bind ast_constr_to_constr(tcx, _);
|
||||
let vec[@ty::constr_def] out_constrs = vec::map(g, constrs);
|
||||
typ = ty::mk_fn(tcx, proto, i, out_ty, cf, out_constrs);
|
||||
}
|
||||
case (ast::ty_path(?path, ?ann)) {
|
||||
alt (tcx.def_map.get(ann.id)) {
|
||||
@ -341,13 +345,17 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
|
||||
for (ast::ty_method m in meths) {
|
||||
auto ins = vec::map[ast::ty_arg, arg](f, m.node.inputs);
|
||||
auto out = ast_ty_to_ty(tcx, getter, m.node.output);
|
||||
let fn(&@ast::constr) -> @ty::constr_def g =
|
||||
bind ast_constr_to_constr(tcx, _);
|
||||
let vec[@ty::constr_def] out_constrs =
|
||||
vec::map(g, m.node.constrs);
|
||||
let ty::method new_m =
|
||||
rec(proto=m.node.proto,
|
||||
ident=m.node.ident,
|
||||
inputs=ins,
|
||||
output=out,
|
||||
cf=m.node.cf,
|
||||
constrs=m.node.constrs);
|
||||
constrs=out_constrs);
|
||||
vec::push[ty::method](tmeths, new_m);
|
||||
}
|
||||
typ = ty::mk_obj(tcx, ty::sort_methods(tmeths));
|
||||
@ -449,9 +457,12 @@ mod collect {
|
||||
ty::ty_param_count_and_ty {
|
||||
auto input_tys = vec::map[ast::arg, arg](ty_of_arg, decl.inputs);
|
||||
auto output_ty = convert(decl.output);
|
||||
let fn(&@ast::constr) -> @ty::constr_def g =
|
||||
bind ast_constr_to_constr(cx.tcx, _);
|
||||
let vec[@ty::constr_def] out_constrs = vec::map(g, decl.constraints);
|
||||
auto t_fn =
|
||||
ty::mk_fn(cx.tcx, proto, input_tys, output_ty, decl.cf,
|
||||
decl.constraints);
|
||||
out_constrs);
|
||||
auto ty_param_count = vec::len[ast::ty_param](ty_params);
|
||||
auto tpt = tup(ty_param_count, t_fn);
|
||||
alt (def_id) {
|
||||
@ -512,12 +523,13 @@ mod collect {
|
||||
auto f = bind ty_of_arg(cx, _);
|
||||
auto inputs = vec::map[ast::arg, arg](f, m.node.meth.decl.inputs);
|
||||
auto output = convert(m.node.meth.decl.output);
|
||||
ret rec(proto=m.node.meth.proto,
|
||||
ident=m.node.ident,
|
||||
inputs=inputs,
|
||||
output=output,
|
||||
cf=m.node.meth.decl.cf,
|
||||
constrs=m.node.meth.decl.constraints);
|
||||
let fn(&@ast::constr) -> @ty::constr_def g =
|
||||
bind ast_constr_to_constr(cx.tcx, _);
|
||||
let vec[@ty::constr_def] out_constrs =
|
||||
vec::map(g, m.node.meth.decl.constraints);
|
||||
ret rec(proto=m.node.meth.proto, ident=m.node.ident,
|
||||
inputs=inputs, output=output, cf=m.node.meth.decl.cf,
|
||||
constrs=out_constrs);
|
||||
}
|
||||
fn ty_of_obj(@ctxt cx, &ast::ident id, &ast::_obj obj_info,
|
||||
&vec[ast::ty_param] ty_params) -> ty::ty_param_count_and_ty {
|
||||
@ -537,10 +549,8 @@ mod collect {
|
||||
auto t_field = ast_ty_to_ty(cx.tcx, g, f.ty);
|
||||
vec::push(t_inputs, rec(mode=ty::mo_alias(false), ty=t_field));
|
||||
}
|
||||
let vec[@ast::constr] constrs = [];
|
||||
auto t_fn =
|
||||
ty::mk_fn(cx.tcx, ast::proto_fn, t_inputs, t_obj._1, ast::return,
|
||||
constrs);
|
||||
auto t_fn = ty::mk_fn(cx.tcx, ast::proto_fn, t_inputs, t_obj._1,
|
||||
ast::return, []);
|
||||
auto tpt = tup(t_obj._0, t_fn);
|
||||
cx.tcx.tcache.insert(ctor_id, tpt);
|
||||
ret tpt;
|
||||
@ -652,11 +662,8 @@ mod collect {
|
||||
}
|
||||
auto tag_t = ty::mk_tag(cx.tcx, tag_id, ty_param_tys);
|
||||
// FIXME: this will be different for constrained types
|
||||
|
||||
let vec[@ast::constr] res_constrs = [];
|
||||
result_ty =
|
||||
ty::mk_fn(cx.tcx, ast::proto_fn, args, tag_t, ast::return,
|
||||
res_constrs);
|
||||
result_ty = ty::mk_fn(cx.tcx, ast::proto_fn, args, tag_t,
|
||||
ast::return, []);
|
||||
}
|
||||
auto tpt = tup(ty_param_count, result_ty);
|
||||
cx.tcx.tcache.insert(variant.node.id, tpt);
|
||||
@ -752,12 +759,8 @@ mod collect {
|
||||
alt (object.dtor) {
|
||||
case (none) {/* nothing to do */ }
|
||||
case (some(?m)) {
|
||||
let vec[@ast::constr] constrs = [];
|
||||
let vec[arg] res_inputs = [];
|
||||
auto t =
|
||||
ty::mk_fn(cx.tcx, ast::proto_fn, res_inputs,
|
||||
ty::mk_nil(cx.tcx), ast::return,
|
||||
constrs);
|
||||
auto t = ty::mk_fn(cx.tcx, ast::proto_fn, [],
|
||||
ty::mk_nil(cx.tcx), ast::return, []);
|
||||
write::ty_only(cx.tcx, m.node.ann.id, t);
|
||||
}
|
||||
}
|
||||
@ -2123,12 +2126,13 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
|
||||
auto inputs =
|
||||
vec::map[ast::arg, arg](f, m.node.meth.decl.inputs);
|
||||
auto output = convert(m.node.meth.decl.output);
|
||||
ret rec(proto=m.node.meth.proto,
|
||||
ident=m.node.ident,
|
||||
inputs=inputs,
|
||||
output=output,
|
||||
cf=m.node.meth.decl.cf,
|
||||
constrs=m.node.meth.decl.constraints);
|
||||
let fn(&@ast::constr) -> @ty::constr_def g =
|
||||
bind ast_constr_to_constr(ccx.tcx, _);
|
||||
let vec[@ty::constr_def] out_constrs =
|
||||
vec::map(g, m.node.meth.decl.constraints);
|
||||
ret rec(proto=m.node.meth.proto, ident=m.node.ident,
|
||||
inputs=inputs, output=output, cf=m.node.meth.decl.cf,
|
||||
constrs=out_constrs);
|
||||
}
|
||||
fn get_anon_obj_method_types(@crate_ctxt ccx,
|
||||
&ast::anon_obj anon_obj) ->
|
||||
@ -2180,6 +2184,21 @@ fn get_obj_info(&@crate_ctxt ccx) -> option::t[obj_info] {
|
||||
ret vec::last[obj_info](ccx.obj_infos);
|
||||
}
|
||||
|
||||
fn ast_constr_to_constr(ty::ctxt tcx, &@ast::constr c)
|
||||
-> @ty::constr_def {
|
||||
alt (tcx.def_map.find(c.node.ann.id)) {
|
||||
case (some(ast::def_fn(?pred_id))) {
|
||||
ret @respan(c.span, rec(path=c.node.path, args=c.node.args,
|
||||
id=pred_id));
|
||||
}
|
||||
case (_) {
|
||||
tcx.sess.span_err(c.span, "Predicate "
|
||||
+ path_to_str(c.node.path)
|
||||
+ " is unbound or bound to a non-function");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_decl_initializer(&@fn_ctxt fcx, &ast::def_id lid,
|
||||
&ast::initializer init) {
|
||||
check_expr(fcx, init.expr);
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
import std::io;
|
||||
import middle::ty::*;
|
||||
import front::ast::constr_arg;
|
||||
import front::lexer;
|
||||
import pp::word;
|
||||
import pp::eof;
|
||||
@ -21,9 +20,10 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
|
||||
};
|
||||
ret s + ty_to_str(cx, input.ty);
|
||||
}
|
||||
|
||||
fn fn_to_str(&ctxt cx, ast::proto proto, option::t[ast::ident] ident,
|
||||
vec[arg] inputs, t output, ast::controlflow cf,
|
||||
&vec[@ast::constr] constrs) -> str {
|
||||
&vec[@constr_def] constrs) -> str {
|
||||
auto f = bind fn_input_to_str(cx, _);
|
||||
auto s;
|
||||
alt (proto) {
|
||||
@ -69,7 +69,7 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
|
||||
case (ty_int) { s += "int"; }
|
||||
case (ty_float) { s += "float"; }
|
||||
case (ty_uint) { s += "uint"; }
|
||||
case (ty_machine(?tm)) { s += common::ty_mach_to_str(tm); }
|
||||
case (ty_machine(?tm)) { s += ty_mach_to_str(tm); }
|
||||
case (ty_char) { s += "char"; }
|
||||
case (ty_str) { s += "str"; }
|
||||
case (ty_istr) { s += "istr"; }
|
||||
@ -92,10 +92,8 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
|
||||
}
|
||||
case (ty_tag(?id, ?tps)) {
|
||||
// The user should never see this if the cname is set properly!
|
||||
|
||||
s +=
|
||||
"<tag#" + util::common::istr(id._0) + ":" +
|
||||
util::common::istr(id._1) + ">";
|
||||
"<tag#" + istr(id._0) + ":" + istr(id._1) + ">";
|
||||
if (vec::len[t](tps) > 0u) {
|
||||
auto f = bind ty_to_str(cx, _);
|
||||
auto strs = vec::map[t, str](f, tps);
|
||||
@ -104,21 +102,20 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
|
||||
}
|
||||
case (ty_fn(?proto, ?inputs, ?output, ?cf, ?constrs)) {
|
||||
s +=
|
||||
fn_to_str(cx, proto, none[ast::ident], inputs, output, cf,
|
||||
fn_to_str(cx, proto, none, inputs, output, cf,
|
||||
constrs);
|
||||
}
|
||||
case (ty_native_fn(_, ?inputs, ?output)) {
|
||||
let vec[@ast::constr] constrs = [];
|
||||
s +=
|
||||
fn_to_str(cx, ast::proto_fn, none[ast::ident], inputs, output,
|
||||
ast::return, constrs);
|
||||
fn_to_str(cx, ast::proto_fn, none, inputs, output,
|
||||
ast::return, []);
|
||||
}
|
||||
case (ty_obj(?meths)) {
|
||||
auto f = bind method_to_str(cx, _);
|
||||
auto m = vec::map[method, str](f, meths);
|
||||
s += "obj {\n\t" + str::connect(m, "\n\t") + "\n}";
|
||||
}
|
||||
case (ty_var(?v)) { s += "<T" + util::common::istr(v) + ">"; }
|
||||
case (ty_var(?v)) { s += "<T" + istr(v) + ">"; }
|
||||
case (ty_param(?id)) {
|
||||
s += "'" + str::unsafe_from_bytes([('a' as u8) + (id as u8)]);
|
||||
}
|
||||
@ -144,7 +141,7 @@ fn constr_arg_to_str[T](fn(&T) -> str f, &ast::constr_arg_general_[T] c) ->
|
||||
}
|
||||
}
|
||||
|
||||
fn constr_arg_to_str_1(&ast::constr_arg_general_[str] c) -> str {
|
||||
fn constr_arg_to_str_1(&front::ast::constr_arg_general_[str] c) -> str {
|
||||
alt (c) {
|
||||
case (ast::carg_base) { ret "*"; }
|
||||
case (ast::carg_ident(?i)) { ret i; }
|
||||
@ -164,18 +161,7 @@ fn constr_args_to_str[T](fn(&T) -> str f,
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn constr_args_to_str_1(&vec[@ast::constr_arg_use] args) -> str {
|
||||
auto comma = false;
|
||||
auto s = "(";
|
||||
for (@ast::constr_arg_use a in args) {
|
||||
if (comma) { s += ", "; } else { comma = true; }
|
||||
s += constr_arg_to_str_1(a.node);
|
||||
}
|
||||
s += ")";
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn print_literal(&ps s, &@ast::lit lit) {
|
||||
fn print_literal(&ps s, &@front::ast::lit lit) {
|
||||
maybe_print_comment(s, lit.span.lo);
|
||||
alt (next_lit(s)) {
|
||||
case (some(?lt)) {
|
||||
@ -196,18 +182,18 @@ fn print_literal(&ps s, &@ast::lit lit) {
|
||||
word(s.s,
|
||||
"'" + escape_str(str::from_bytes([ch as u8]), '\'') + "'");
|
||||
}
|
||||
case (ast::lit_int(?val)) { word(s.s, common::istr(val)); }
|
||||
case (ast::lit_uint(?val)) { word(s.s, common::uistr(val) + "u"); }
|
||||
case (ast::lit_int(?val)) { word(s.s, istr(val)); }
|
||||
case (ast::lit_uint(?val)) { word(s.s, uistr(val) + "u"); }
|
||||
case (ast::lit_float(?fstr)) { word(s.s, fstr); }
|
||||
case (ast::lit_mach_int(?mach, ?val)) {
|
||||
word(s.s, common::istr(val as int));
|
||||
word(s.s, common::ty_mach_to_str(mach));
|
||||
word(s.s, istr(val as int));
|
||||
word(s.s, ty_mach_to_str(mach));
|
||||
}
|
||||
case (ast::lit_mach_float(?mach, ?val)) {
|
||||
// val is already a str
|
||||
|
||||
word(s.s, val);
|
||||
word(s.s, common::ty_mach_to_str(mach));
|
||||
word(s.s, ty_mach_to_str(mach));
|
||||
}
|
||||
case (ast::lit_nil) { word(s.s, "()"); }
|
||||
case (ast::lit_bool(?val)) {
|
||||
@ -216,7 +202,7 @@ fn print_literal(&ps s, &@ast::lit lit) {
|
||||
}
|
||||
}
|
||||
|
||||
fn lit_to_str(&@ast::lit l) -> str { be to_str(l, print_literal); }
|
||||
fn lit_to_str(&@front::ast::lit l) -> str { be to_str(l, print_literal); }
|
||||
|
||||
fn next_lit(&ps s) -> option::t[lexer::lit] {
|
||||
alt (s.literals) {
|
||||
@ -360,22 +346,46 @@ const uint default_columns = 78u;
|
||||
// needed b/c constr_args_to_str needs
|
||||
// something that takes an alias
|
||||
// (argh)
|
||||
fn uint_to_str(&uint i) -> str { ret util::common::uistr(i); }
|
||||
|
||||
fn constr_to_str(&@ast::constr c) -> str {
|
||||
ret path_to_str(c.node.path) +
|
||||
constr_args_to_str(uint_to_str, c.node.args);
|
||||
fn uint_to_str(&uint i) -> str { ret uistr(i); }
|
||||
|
||||
fn constr_to_str(&@constr_def c) -> str {
|
||||
ret path_to_str(c.node.path)
|
||||
+ constr_args_to_str(uint_to_str, c.node.args);
|
||||
}
|
||||
|
||||
fn constrs_str(&vec[@ast::constr] constrs) -> str {
|
||||
|
||||
fn ast_constr_to_str(&@front::ast::constr c) -> str {
|
||||
ret path_to_str(c.node.path)
|
||||
+ constr_args_to_str(uint_to_str, c.node.args);
|
||||
}
|
||||
|
||||
fn constrs_str(&vec[@constr_def] constrs) -> str {
|
||||
auto s = "";
|
||||
auto colon = true;
|
||||
for (@ast::constr c in constrs) {
|
||||
for (@constr_def c in constrs) {
|
||||
if (colon) { s += " : "; colon = false; } else { s += ", "; }
|
||||
s += constr_to_str(c);
|
||||
}
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn ast_constrs_str(&vec[@ast::constr] constrs) -> str {
|
||||
auto s = "";
|
||||
auto colon = true;
|
||||
for (@ast::constr c in constrs) {
|
||||
if (colon) {
|
||||
s += " : ";
|
||||
colon = false;
|
||||
}
|
||||
else {
|
||||
s += ", ";
|
||||
}
|
||||
s += ast_constr_to_str(c);
|
||||
}
|
||||
ret s;
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
@ -1094,7 +1094,7 @@ fn print_ty_fn(&ps s, &ast::proto proto, &option::t[str] id,
|
||||
}
|
||||
end(s);
|
||||
}
|
||||
word_space(s, constrs_str(constrs));
|
||||
word_space(s, ast_constrs_str(constrs));
|
||||
end(s);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// -*- rust -*-
|
||||
|
||||
// error-pattern: mismatched types
|
||||
// xfail-stage0
|
||||
// error-pattern: Non-predicate in constraint: lt
|
||||
|
||||
fn f(int a, int b) : lt(a,b) {
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user