Reformat. Issue #855
This commit is contained in:
parent
b5f9053423
commit
5c49e4f4e9
194 changed files with 5106 additions and 5789 deletions
|
@ -88,13 +88,13 @@ const worst_case_glue_call_args: int = 7;
|
|||
|
||||
const abi_version: uint = 1u;
|
||||
|
||||
fn memcpy_glue_name() -> istr { ret ~"rust_memcpy_glue"; }
|
||||
fn memcpy_glue_name() -> str { ret "rust_memcpy_glue"; }
|
||||
|
||||
fn bzero_glue_name() -> istr { ret ~"rust_bzero_glue"; }
|
||||
fn bzero_glue_name() -> str { ret "rust_bzero_glue"; }
|
||||
|
||||
fn yield_glue_name() -> istr { ret ~"rust_yield_glue"; }
|
||||
fn yield_glue_name() -> str { ret "rust_yield_glue"; }
|
||||
|
||||
fn no_op_type_glue_name() -> istr { ret ~"rust_no_op_type_glue"; }
|
||||
fn no_op_type_glue_name() -> str { ret "rust_no_op_type_glue"; }
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
|
|
@ -31,37 +31,35 @@ tag output_type {
|
|||
output_type_exe;
|
||||
}
|
||||
|
||||
fn llvm_err(sess: session::session, msg: &istr) {
|
||||
fn llvm_err(sess: session::session, msg: &str) {
|
||||
let buf = llvm::LLVMRustGetLastError();
|
||||
if buf == std::ptr::null() {
|
||||
sess.fatal(msg);
|
||||
} else {
|
||||
sess.fatal(
|
||||
msg + ~": " + str::str_from_cstr(buf));
|
||||
}
|
||||
} else { sess.fatal(msg + ": " + str::str_from_cstr(buf)); }
|
||||
}
|
||||
|
||||
fn link_intrinsics(sess: session::session, llmod: ModuleRef) {
|
||||
let path =
|
||||
fs::connect(sess.get_opts().sysroot,
|
||||
~"lib/intrinsics.bc");
|
||||
let membuf = str::as_buf(path, { |buf|
|
||||
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
|
||||
});
|
||||
let path = fs::connect(sess.get_opts().sysroot, "lib/intrinsics.bc");
|
||||
let membuf =
|
||||
str::as_buf(
|
||||
path,
|
||||
{|buf|
|
||||
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
|
||||
});
|
||||
if membuf as uint == 0u {
|
||||
llvm_err(sess, ~"installation problem: couldn't open " + path);
|
||||
llvm_err(sess, "installation problem: couldn't open " + path);
|
||||
fail;
|
||||
}
|
||||
let llintrinsicsmod = llvm::LLVMRustParseBitcode(membuf);
|
||||
llvm::LLVMDisposeMemoryBuffer(membuf);
|
||||
if llintrinsicsmod as uint == 0u {
|
||||
llvm_err(sess, ~"installation problem: couldn't parse intrinsics.bc");
|
||||
llvm_err(sess, "installation problem: couldn't parse intrinsics.bc");
|
||||
fail;
|
||||
}
|
||||
let linkres = llvm::LLVMLinkModules(llmod, llintrinsicsmod);
|
||||
llvm::LLVMDisposeModule(llintrinsicsmod);
|
||||
if linkres == False {
|
||||
llvm_err(sess, ~"couldn't link the module with the intrinsics");
|
||||
llvm_err(sess, "couldn't link the module with the intrinsics");
|
||||
fail;
|
||||
}
|
||||
}
|
||||
|
@ -77,15 +75,15 @@ mod write {
|
|||
|
||||
// Decides what to call an intermediate file, given the name of the output
|
||||
// and the extension to use.
|
||||
fn mk_intermediate_name(output_path: &istr, extension: &istr) -> istr {
|
||||
fn mk_intermediate_name(output_path: &str, extension: &str) -> str {
|
||||
let dot_pos = str::index(output_path, '.' as u8);
|
||||
let stem;
|
||||
if dot_pos < 0 {
|
||||
stem = output_path;
|
||||
} else { stem = str::substr(output_path, 0u, dot_pos as uint); }
|
||||
ret stem + ~"." + extension;
|
||||
ret stem + "." + extension;
|
||||
}
|
||||
fn run_passes(sess: session::session, llmod: ModuleRef, output: &istr) {
|
||||
fn run_passes(sess: session::session, llmod: ModuleRef, output: &str) {
|
||||
let opts = sess.get_opts();
|
||||
if opts.time_llvm_passes { llvm::LLVMRustEnableTimePasses(); }
|
||||
link_intrinsics(sess, llmod);
|
||||
|
@ -102,17 +100,19 @@ mod write {
|
|||
alt opts.output_type {
|
||||
output_type_bitcode. {
|
||||
if opts.optimize != 0u {
|
||||
let filename = mk_intermediate_name(output, ~"no-opt.bc");
|
||||
str::as_buf(filename, { |buf|
|
||||
llvm::LLVMWriteBitcodeToFile(llmod, buf)
|
||||
});
|
||||
let filename = mk_intermediate_name(output, "no-opt.bc");
|
||||
str::as_buf(filename,
|
||||
{|buf|
|
||||
llvm::LLVMWriteBitcodeToFile(llmod, buf)
|
||||
});
|
||||
}
|
||||
}
|
||||
_ {
|
||||
let filename = mk_intermediate_name(output, ~"bc");
|
||||
str::as_buf(filename, { |buf|
|
||||
llvm::LLVMWriteBitcodeToFile(llmod, buf)
|
||||
});
|
||||
let filename = mk_intermediate_name(output, "bc");
|
||||
str::as_buf(filename,
|
||||
{|buf|
|
||||
llvm::LLVMWriteBitcodeToFile(llmod, buf)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -183,25 +183,28 @@ mod write {
|
|||
if opts.save_temps {
|
||||
// Always output the bitcode file with --save-temps
|
||||
|
||||
let filename = mk_intermediate_name(output, ~"opt.bc");
|
||||
let filename = mk_intermediate_name(output, "opt.bc");
|
||||
llvm::LLVMRunPassManager(pm.llpm, llmod);
|
||||
str::as_buf(filename, { |buf|
|
||||
llvm::LLVMWriteBitcodeToFile(llmod, buf)
|
||||
});
|
||||
str::as_buf(filename,
|
||||
{|buf|
|
||||
llvm::LLVMWriteBitcodeToFile(llmod, buf)
|
||||
});
|
||||
pm = mk_pass_manager();
|
||||
// Save the assembly file if -S is used
|
||||
|
||||
if opts.output_type == output_type_assembly {
|
||||
let _: () =
|
||||
str::as_buf(x86::get_target_triple(), { |buf_t|
|
||||
str::as_buf(output, { |buf_o|
|
||||
str::as_buf(x86::get_target_triple(), {|buf_t|
|
||||
str::as_buf(output, {|buf_o|
|
||||
llvm::LLVMRustWriteOutputFile(
|
||||
pm.llpm, llmod,
|
||||
pm.llpm,
|
||||
llmod,
|
||||
buf_t,
|
||||
buf_o,
|
||||
LLVMAssemblyFile,
|
||||
CodeGenOptLevel)
|
||||
})});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,28 +213,32 @@ mod write {
|
|||
if opts.output_type == output_type_object ||
|
||||
opts.output_type == output_type_exe {
|
||||
let _: () =
|
||||
str::as_buf(x86::get_target_triple(), { |buf_t|
|
||||
str::as_buf(output, { |buf_o|
|
||||
llvm::LLVMRustWriteOutputFile(
|
||||
pm.llpm, llmod,
|
||||
buf_t,
|
||||
buf_o,
|
||||
LLVMObjectFile,
|
||||
CodeGenOptLevel)
|
||||
})});
|
||||
str::as_buf(x86::get_target_triple(), {|buf_t|
|
||||
str::as_buf(output, {|buf_o|
|
||||
llvm::LLVMRustWriteOutputFile(pm.llpm,
|
||||
llmod,
|
||||
buf_t,
|
||||
buf_o,
|
||||
LLVMObjectFile,
|
||||
CodeGenOptLevel)
|
||||
})
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// If we aren't saving temps then just output the file
|
||||
// type corresponding to the '-c' or '-S' flag used
|
||||
|
||||
let _: () = str::as_buf(x86::get_target_triple(), { |buf_t|
|
||||
str::as_buf(output, { |buf_o|
|
||||
llvm::LLVMRustWriteOutputFile(pm.llpm, llmod,
|
||||
buf_t,
|
||||
buf_o,
|
||||
FileType,
|
||||
CodeGenOptLevel)
|
||||
})});
|
||||
let _: () =
|
||||
str::as_buf(x86::get_target_triple(), {|buf_t|
|
||||
str::as_buf(output, {|buf_o|
|
||||
llvm::LLVMRustWriteOutputFile(pm.llpm,
|
||||
llmod,
|
||||
buf_t,
|
||||
buf_o,
|
||||
FileType,
|
||||
CodeGenOptLevel)
|
||||
})
|
||||
});
|
||||
}
|
||||
// Clean up and return
|
||||
|
||||
|
@ -243,9 +250,8 @@ mod write {
|
|||
// flag, then output it here
|
||||
|
||||
llvm::LLVMRunPassManager(pm.llpm, llmod);
|
||||
str::as_buf(output, { |buf|
|
||||
llvm::LLVMWriteBitcodeToFile(llmod, buf)
|
||||
});
|
||||
str::as_buf(output,
|
||||
{|buf| llvm::LLVMWriteBitcodeToFile(llmod, buf) });
|
||||
llvm::LLVMDisposeModule(llmod);
|
||||
if opts.time_llvm_passes { llvm::LLVMRustPrintPassTimings(); }
|
||||
}
|
||||
|
@ -303,30 +309,30 @@ mod write {
|
|||
*
|
||||
*/
|
||||
|
||||
type link_meta = {name: istr, vers: istr, extras_hash: istr};
|
||||
type link_meta = {name: str, vers: str, extras_hash: str};
|
||||
|
||||
fn build_link_meta(sess: &session::session, c: &ast::crate, output: &istr,
|
||||
fn build_link_meta(sess: &session::session, c: &ast::crate, output: &str,
|
||||
sha: sha1) -> link_meta {
|
||||
|
||||
type provided_metas =
|
||||
{name: option::t<istr>,
|
||||
vers: option::t<istr>,
|
||||
{name: option::t<str>,
|
||||
vers: option::t<str>,
|
||||
cmh_items: [@ast::meta_item]};
|
||||
|
||||
fn provided_link_metas(sess: &session::session, c: &ast::crate) ->
|
||||
provided_metas {
|
||||
let name: option::t<istr> = none;
|
||||
let vers: option::t<istr> = none;
|
||||
let name: option::t<str> = none;
|
||||
let vers: option::t<str> = none;
|
||||
let cmh_items: [@ast::meta_item] = [];
|
||||
let linkage_metas = attr::find_linkage_metas(c.node.attrs);
|
||||
attr::require_unique_names(sess, linkage_metas);
|
||||
for meta: @ast::meta_item in linkage_metas {
|
||||
if attr::get_meta_item_name(meta) == ~"name" {
|
||||
if attr::get_meta_item_name(meta) == "name" {
|
||||
alt attr::get_meta_item_value_str(meta) {
|
||||
some(v) { name = some(v); }
|
||||
none. { cmh_items += [meta]; }
|
||||
}
|
||||
} else if attr::get_meta_item_name(meta) == ~"vers" {
|
||||
} else if attr::get_meta_item_name(meta) == "vers" {
|
||||
alt attr::get_meta_item_value_str(meta) {
|
||||
some(v) { vers = some(v); }
|
||||
none. { cmh_items += [meta]; }
|
||||
|
@ -338,12 +344,12 @@ fn build_link_meta(sess: &session::session, c: &ast::crate, output: &istr,
|
|||
|
||||
// This calculates CMH as defined above
|
||||
fn crate_meta_extras_hash(sha: sha1, _crate: &ast::crate,
|
||||
metas: &provided_metas) -> istr {
|
||||
fn len_and_str(s: &istr) -> istr {
|
||||
metas: &provided_metas) -> str {
|
||||
fn len_and_str(s: &str) -> str {
|
||||
ret #fmt["%u_%s", str::byte_len(s), s];
|
||||
}
|
||||
|
||||
fn len_and_str_lit(l: &ast::lit) -> istr {
|
||||
fn len_and_str_lit(l: &ast::lit) -> str {
|
||||
ret len_and_str(pprust::lit_to_str(@l));
|
||||
}
|
||||
|
||||
|
@ -357,9 +363,7 @@ fn build_link_meta(sess: &session::session, c: &ast::crate, output: &istr,
|
|||
sha.input_str(len_and_str(key));
|
||||
sha.input_str(len_and_str_lit(value));
|
||||
}
|
||||
ast::meta_word(name) {
|
||||
sha.input_str(len_and_str(name));
|
||||
}
|
||||
ast::meta_word(name) { sha.input_str(len_and_str(name)); }
|
||||
ast::meta_list(_, _) {
|
||||
// FIXME (#607): Implement this
|
||||
fail "unimplemented meta_item variant";
|
||||
|
@ -369,40 +373,37 @@ fn build_link_meta(sess: &session::session, c: &ast::crate, output: &istr,
|
|||
ret truncated_sha1_result(sha);
|
||||
}
|
||||
|
||||
fn warn_missing(sess: &session::session, name: &istr, default: &istr) {
|
||||
fn warn_missing(sess: &session::session, name: &str, default: &str) {
|
||||
if !sess.get_opts().library { ret; }
|
||||
sess.warn(
|
||||
#fmt["missing crate link meta '%s', using '%s' as default",
|
||||
sess.warn(#fmt["missing crate link meta '%s', using '%s' as default",
|
||||
name, default]);
|
||||
}
|
||||
|
||||
fn crate_meta_name(sess: &session::session, _crate: &ast::crate,
|
||||
output: &istr, metas: &provided_metas) -> istr {
|
||||
output: &str, metas: &provided_metas) -> str {
|
||||
ret alt metas.name {
|
||||
some(v) { v }
|
||||
none. {
|
||||
let name =
|
||||
{
|
||||
let os = str::split(
|
||||
fs::basename(output),
|
||||
'.' as u8);
|
||||
let os = str::split(fs::basename(output), '.' as u8);
|
||||
assert (vec::len(os) >= 2u);
|
||||
vec::pop(os);
|
||||
str::connect(os, ~".")
|
||||
str::connect(os, ".")
|
||||
};
|
||||
warn_missing(sess, ~"name", name);
|
||||
warn_missing(sess, "name", name);
|
||||
name
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn crate_meta_vers(sess: &session::session, _crate: &ast::crate,
|
||||
metas: &provided_metas) -> istr {
|
||||
metas: &provided_metas) -> str {
|
||||
ret alt metas.vers {
|
||||
some(v) { v }
|
||||
none. {
|
||||
let vers = ~"0.0";
|
||||
warn_missing(sess, ~"vers", vers);
|
||||
let vers = "0.0";
|
||||
warn_missing(sess, "vers", vers);
|
||||
vers
|
||||
}
|
||||
};
|
||||
|
@ -416,32 +417,32 @@ fn build_link_meta(sess: &session::session, c: &ast::crate, output: &istr,
|
|||
ret {name: name, vers: vers, extras_hash: extras_hash};
|
||||
}
|
||||
|
||||
fn truncated_sha1_result(sha: sha1) -> istr {
|
||||
fn truncated_sha1_result(sha: sha1) -> str {
|
||||
ret str::substr(sha.result_str(), 0u, 16u);
|
||||
}
|
||||
|
||||
|
||||
// This calculates STH for a symbol, as defined above
|
||||
fn symbol_hash(tcx: ty::ctxt, sha: sha1, t: ty::t, link_meta: &link_meta) ->
|
||||
istr {
|
||||
str {
|
||||
// NB: do *not* use abbrevs here as we want the symbol names
|
||||
// to be independent of one another in the crate.
|
||||
|
||||
sha.reset();
|
||||
sha.input_str(link_meta.name);
|
||||
sha.input_str(~"-");
|
||||
sha.input_str("-");
|
||||
// FIXME: This wants to be link_meta.meta_hash
|
||||
sha.input_str(link_meta.name);
|
||||
sha.input_str(~"-");
|
||||
sha.input_str("-");
|
||||
sha.input_str(encoder::encoded_ty(tcx, t));
|
||||
let hash = truncated_sha1_result(sha);
|
||||
// Prefix with _ so that it never blends into adjacent digits
|
||||
|
||||
ret ~"_" + hash;
|
||||
ret "_" + hash;
|
||||
}
|
||||
|
||||
fn get_symbol_hash(ccx: &@crate_ctxt, t: ty::t) -> istr {
|
||||
let hash = ~"";
|
||||
fn get_symbol_hash(ccx: &@crate_ctxt, t: ty::t) -> str {
|
||||
let hash = "";
|
||||
alt ccx.type_sha1s.find(t) {
|
||||
some(h) { hash = h; }
|
||||
none. {
|
||||
|
@ -452,48 +453,46 @@ fn get_symbol_hash(ccx: &@crate_ctxt, t: ty::t) -> istr {
|
|||
ret hash;
|
||||
}
|
||||
|
||||
fn mangle(ss: &[istr]) -> istr {
|
||||
fn mangle(ss: &[str]) -> str {
|
||||
// Follow C++ namespace-mangling style
|
||||
|
||||
let n = ~"_ZN"; // Begin name-sequence.
|
||||
let n = "_ZN"; // Begin name-sequence.
|
||||
|
||||
for s: istr in ss {
|
||||
n += #fmt["%u%s", str::byte_len(s), s];
|
||||
}
|
||||
n += ~"E"; // End name-sequence.
|
||||
for s: str in ss { n += #fmt["%u%s", str::byte_len(s), s]; }
|
||||
n += "E"; // End name-sequence.
|
||||
|
||||
ret n;
|
||||
}
|
||||
|
||||
fn exported_name(path: &[istr], hash: &istr, _vers: &istr) -> istr {
|
||||
fn exported_name(path: &[str], hash: &str, _vers: &str) -> str {
|
||||
// FIXME: versioning isn't working yet
|
||||
|
||||
ret mangle(path + [hash]); // + "@" + vers;
|
||||
|
||||
}
|
||||
|
||||
fn mangle_exported_name(ccx: &@crate_ctxt, path: &[istr], t: ty::t) -> istr {
|
||||
fn mangle_exported_name(ccx: &@crate_ctxt, path: &[str], t: ty::t) -> str {
|
||||
let hash = get_symbol_hash(ccx, t);
|
||||
ret exported_name(path, hash, ccx.link_meta.vers);
|
||||
}
|
||||
|
||||
fn mangle_internal_name_by_type_only(ccx: &@crate_ctxt, t: ty::t, name: &istr)
|
||||
-> istr {
|
||||
fn mangle_internal_name_by_type_only(ccx: &@crate_ctxt, t: ty::t, name: &str)
|
||||
-> str {
|
||||
let s = util::ppaux::ty_to_short_str(ccx.tcx, t);
|
||||
let hash = get_symbol_hash(ccx, t);
|
||||
ret mangle([name, s, hash]);
|
||||
}
|
||||
|
||||
fn mangle_internal_name_by_path_and_seq(ccx: &@crate_ctxt, path: &[istr],
|
||||
flav: &istr) -> istr {
|
||||
fn mangle_internal_name_by_path_and_seq(ccx: &@crate_ctxt, path: &[str],
|
||||
flav: &str) -> str {
|
||||
ret mangle(path + [ccx.names.next(flav)]);
|
||||
}
|
||||
|
||||
fn mangle_internal_name_by_path(_ccx: &@crate_ctxt, path: &[istr]) -> istr {
|
||||
fn mangle_internal_name_by_path(_ccx: &@crate_ctxt, path: &[str]) -> str {
|
||||
ret mangle(path);
|
||||
}
|
||||
|
||||
fn mangle_internal_name_by_seq(ccx: &@crate_ctxt, flav: &istr) -> istr {
|
||||
fn mangle_internal_name_by_seq(ccx: &@crate_ctxt, flav: &str) -> str {
|
||||
ret ccx.names.next(flav);
|
||||
}
|
||||
//
|
||||
|
|
|
@ -46,16 +46,14 @@ type upcalls =
|
|||
|
||||
fn declare_upcalls(_tn: type_names, tydesc_type: TypeRef,
|
||||
taskptr_type: TypeRef, llmod: ModuleRef) -> @upcalls {
|
||||
fn decl(llmod: ModuleRef, name: &istr, tys: [TypeRef], rv: TypeRef) ->
|
||||
fn decl(llmod: ModuleRef, name: &str, tys: [TypeRef], rv: TypeRef) ->
|
||||
ValueRef {
|
||||
let arg_tys: [TypeRef] = [];
|
||||
for t: TypeRef in tys { arg_tys += [t]; }
|
||||
let fn_ty = T_fn(arg_tys, rv);
|
||||
ret trans::decl_cdecl_fn(llmod,
|
||||
~"upcall_" + name, fn_ty);
|
||||
ret trans::decl_cdecl_fn(llmod, "upcall_" + name, fn_ty);
|
||||
}
|
||||
fn decl_with_taskptr(taskptr_type: TypeRef, llmod: ModuleRef,
|
||||
name: &istr,
|
||||
fn decl_with_taskptr(taskptr_type: TypeRef, llmod: ModuleRef, name: &str,
|
||||
tys: [TypeRef], rv: TypeRef) -> ValueRef {
|
||||
ret decl(llmod, name, [taskptr_type] + tys, rv);
|
||||
}
|
||||
|
@ -64,44 +62,45 @@ fn declare_upcalls(_tn: type_names, tydesc_type: TypeRef,
|
|||
let dr = bind decl(llmod, _, _, _);
|
||||
|
||||
let empty_vec: [TypeRef] = [];
|
||||
ret @{grow_task: dv(~"grow_task", [T_size_t()]),
|
||||
_yield: dv(~"yield", empty_vec),
|
||||
sleep: dv(~"sleep", [T_size_t()]),
|
||||
_fail: dv(~"fail", [T_ptr(T_i8()), T_ptr(T_i8()), T_size_t()]),
|
||||
kill: dv(~"kill", [taskptr_type]),
|
||||
exit: dv(~"exit", empty_vec),
|
||||
ret @{grow_task: dv("grow_task", [T_size_t()]),
|
||||
_yield: dv("yield", empty_vec),
|
||||
sleep: dv("sleep", [T_size_t()]),
|
||||
_fail: dv("fail", [T_ptr(T_i8()), T_ptr(T_i8()), T_size_t()]),
|
||||
kill: dv("kill", [taskptr_type]),
|
||||
exit: dv("exit", empty_vec),
|
||||
malloc:
|
||||
d(~"malloc", [T_size_t(), T_ptr(tydesc_type)], T_ptr(T_i8())),
|
||||
free: dv(~"free", [T_ptr(T_i8()), T_int()]),
|
||||
d("malloc", [T_size_t(), T_ptr(tydesc_type)], T_ptr(T_i8())),
|
||||
free: dv("free", [T_ptr(T_i8()), T_int()]),
|
||||
shared_malloc:
|
||||
d(~"shared_malloc", [T_size_t(), T_ptr(tydesc_type)],
|
||||
d("shared_malloc", [T_size_t(), T_ptr(tydesc_type)],
|
||||
T_ptr(T_i8())),
|
||||
shared_free: dv(~"shared_free", [T_ptr(T_i8())]),
|
||||
mark: d(~"mark", [T_ptr(T_i8())], T_int()),
|
||||
shared_free: dv("shared_free", [T_ptr(T_i8())]),
|
||||
mark: d("mark", [T_ptr(T_i8())], T_int()),
|
||||
get_type_desc:
|
||||
d(~"get_type_desc",
|
||||
d("get_type_desc",
|
||||
[T_ptr(T_nil()), T_size_t(), T_size_t(), T_size_t(),
|
||||
T_ptr(T_ptr(tydesc_type)), T_int()], T_ptr(tydesc_type)),
|
||||
vec_grow:
|
||||
d(~"vec_grow", [T_ptr(T_ptr(T_opaque_vec())), T_int()],
|
||||
d("vec_grow", [T_ptr(T_ptr(T_opaque_vec())), T_int()],
|
||||
T_void()),
|
||||
vec_push:
|
||||
d(~"vec_push",
|
||||
d("vec_push",
|
||||
[T_ptr(T_ptr(T_opaque_vec())), T_ptr(tydesc_type),
|
||||
T_ptr(T_i8())], T_void()),
|
||||
cmp_type:
|
||||
dr(~"cmp_type",
|
||||
dr("cmp_type",
|
||||
[T_ptr(T_i1()), taskptr_type, T_ptr(tydesc_type),
|
||||
T_ptr(T_ptr(tydesc_type)), T_ptr(T_i8()), T_ptr(T_i8()),
|
||||
T_i8()], T_void()),
|
||||
log_type:
|
||||
dr(~"log_type",
|
||||
dr("log_type",
|
||||
[taskptr_type, T_ptr(tydesc_type), T_ptr(T_i8()), T_i32()],
|
||||
T_void()),
|
||||
dynastack_mark: d(~"dynastack_mark", [], T_ptr(T_i8())),
|
||||
dynastack_alloc: d(~"dynastack_alloc_2",
|
||||
[T_size_t(), T_ptr(tydesc_type)], T_ptr(T_i8())),
|
||||
dynastack_free: d(~"dynastack_free", [T_ptr(T_i8())], T_void())};
|
||||
dynastack_mark: d("dynastack_mark", [], T_ptr(T_i8())),
|
||||
dynastack_alloc:
|
||||
d("dynastack_alloc_2", [T_size_t(), T_ptr(tydesc_type)],
|
||||
T_ptr(T_i8())),
|
||||
dynastack_free: d("dynastack_free", [T_ptr(T_i8())], T_void())};
|
||||
}
|
||||
//
|
||||
// Local Variables:
|
||||
|
|
|
@ -4,32 +4,30 @@ import lib::llvm::llvm::ModuleRef;
|
|||
import std::str;
|
||||
import std::os::target_os;
|
||||
|
||||
fn get_module_asm() -> istr { ret ~""; }
|
||||
fn get_module_asm() -> str { ret ""; }
|
||||
|
||||
fn get_meta_sect_name() -> istr {
|
||||
if str::eq(target_os(), ~"macos") { ret ~"__DATA,__note.rustc"; }
|
||||
if str::eq(target_os(), ~"win32") { ret ~".note.rustc"; }
|
||||
ret ~".note.rustc";
|
||||
fn get_meta_sect_name() -> str {
|
||||
if str::eq(target_os(), "macos") { ret "__DATA,__note.rustc"; }
|
||||
if str::eq(target_os(), "win32") { ret ".note.rustc"; }
|
||||
ret ".note.rustc";
|
||||
}
|
||||
|
||||
fn get_data_layout() -> istr {
|
||||
if str::eq(target_os(), ~"macos") {
|
||||
ret ~"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16" +
|
||||
~"-i32:32:32-i64:32:64" +
|
||||
~"-f32:32:32-f64:32:64-v64:64:64" +
|
||||
~"-v128:128:128-a0:0:64-f80:128:128" +
|
||||
~"-n8:16:32";
|
||||
fn get_data_layout() -> str {
|
||||
if str::eq(target_os(), "macos") {
|
||||
ret "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16" + "-i32:32:32-i64:32:64" +
|
||||
"-f32:32:32-f64:32:64-v64:64:64" +
|
||||
"-v128:128:128-a0:0:64-f80:128:128" + "-n8:16:32";
|
||||
}
|
||||
if str::eq(target_os(), ~"win32") {
|
||||
ret ~"e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32";
|
||||
if str::eq(target_os(), "win32") {
|
||||
ret "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32";
|
||||
}
|
||||
ret ~"e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32";
|
||||
ret "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32";
|
||||
}
|
||||
|
||||
fn get_target_triple() -> istr {
|
||||
if str::eq(target_os(), ~"macos") { ret ~"i686-apple-darwin"; }
|
||||
if str::eq(target_os(), ~"win32") { ret ~"i686-pc-mingw32"; }
|
||||
ret ~"i686-unknown-linux-gnu";
|
||||
fn get_target_triple() -> str {
|
||||
if str::eq(target_os(), "macos") { ret "i686-apple-darwin"; }
|
||||
if str::eq(target_os(), "win32") { ret "i686-pc-mingw32"; }
|
||||
ret "i686-unknown-linux-gnu";
|
||||
}
|
||||
//
|
||||
// Local Variables:
|
||||
|
|
|
@ -41,29 +41,26 @@ import back::link::output_type;
|
|||
|
||||
tag pp_mode { ppm_normal; ppm_expanded; ppm_typed; ppm_identified; }
|
||||
|
||||
fn default_configuration(sess: session::session,
|
||||
argv0: &istr, input: &istr) ->
|
||||
fn default_configuration(sess: session::session, argv0: &str, input: &str) ->
|
||||
ast::crate_cfg {
|
||||
let libc =
|
||||
alt sess.get_targ_cfg().os {
|
||||
session::os_win32. { ~"msvcrt.dll" }
|
||||
session::os_macos. { ~"libc.dylib" }
|
||||
session::os_linux. { ~"libc.so.6" }
|
||||
_ { ~"libc.so" }
|
||||
session::os_win32. { "msvcrt.dll" }
|
||||
session::os_macos. { "libc.dylib" }
|
||||
session::os_linux. { "libc.so.6" }
|
||||
_ { "libc.so" }
|
||||
};
|
||||
|
||||
let mk = attr::mk_name_value_item_str;
|
||||
|
||||
ret [ // Target bindings.
|
||||
mk(~"target_os", std::os::target_os()),
|
||||
mk(~"target_arch", ~"x86"),
|
||||
mk(~"target_libc", libc),
|
||||
mk("target_os", std::os::target_os()), mk("target_arch", "x86"),
|
||||
mk("target_libc", libc),
|
||||
// Build bindings.
|
||||
mk(~"build_compiler", argv0),
|
||||
mk(~"build_input", input)];
|
||||
mk("build_compiler", argv0), mk("build_input", input)];
|
||||
}
|
||||
|
||||
fn build_configuration(sess: session::session, argv0: &istr, input: &istr) ->
|
||||
fn build_configuration(sess: session::session, argv0: &str, input: &str) ->
|
||||
ast::crate_cfg {
|
||||
// Combine the configuration requested by the session (command line) with
|
||||
// some default and generated configuration items
|
||||
|
@ -72,51 +69,46 @@ fn build_configuration(sess: session::session, argv0: &istr, input: &istr) ->
|
|||
// If the user wants a test runner, then add the test cfg
|
||||
let gen_cfg =
|
||||
{
|
||||
if sess.get_opts().test
|
||||
&& !attr::contains_name(user_cfg, ~"test") {
|
||||
[attr::mk_word_item(~"test")]
|
||||
if sess.get_opts().test && !attr::contains_name(user_cfg, "test")
|
||||
{
|
||||
[attr::mk_word_item("test")]
|
||||
} else { [] }
|
||||
};
|
||||
ret user_cfg + gen_cfg + default_cfg;
|
||||
}
|
||||
|
||||
// Convert strings provided as --cfg [cfgspec] into a crate_cfg
|
||||
fn parse_cfgspecs(cfgspecs: &[istr]) -> ast::crate_cfg {
|
||||
fn parse_cfgspecs(cfgspecs: &[str]) -> ast::crate_cfg {
|
||||
// FIXME: It would be nice to use the parser to parse all varieties of
|
||||
// meta_item here. At the moment we just support the meta_word variant.
|
||||
let words = [];
|
||||
for s: istr in cfgspecs {
|
||||
words += [attr::mk_word_item(s)];
|
||||
}
|
||||
for s: str in cfgspecs { words += [attr::mk_word_item(s)]; }
|
||||
ret words;
|
||||
}
|
||||
|
||||
fn input_is_stdin(filename: &istr) -> bool { filename == ~"-" }
|
||||
fn input_is_stdin(filename: &str) -> bool { filename == "-" }
|
||||
|
||||
fn parse_input(sess: session::session, cfg: &ast::crate_cfg,
|
||||
input: &istr) -> @ast::crate {
|
||||
fn parse_input(sess: session::session, cfg: &ast::crate_cfg, input: &str) ->
|
||||
@ast::crate {
|
||||
if !input_is_stdin(input) {
|
||||
parser::parse_crate_from_file(
|
||||
input, cfg, sess.get_parse_sess())
|
||||
parser::parse_crate_from_file(input, cfg, sess.get_parse_sess())
|
||||
} else { parse_input_src(sess, cfg, input).crate }
|
||||
}
|
||||
|
||||
fn parse_input_src(sess: session::session, cfg: &ast::crate_cfg,
|
||||
infile: &istr) -> {crate: @ast::crate, src: istr} {
|
||||
fn parse_input_src(sess: session::session, cfg: &ast::crate_cfg, infile: &str)
|
||||
-> {crate: @ast::crate, src: str} {
|
||||
let srcbytes =
|
||||
if infile != ~"-" {
|
||||
if infile != "-" {
|
||||
io::file_reader(infile)
|
||||
} else { io::stdin() }.read_whole_stream();
|
||||
let src = str::unsafe_from_bytes(srcbytes);
|
||||
let crate =
|
||||
parser::parse_crate_from_source_str(
|
||||
infile,
|
||||
src, cfg,
|
||||
sess.get_parse_sess());
|
||||
parser::parse_crate_from_source_str(infile, src, cfg,
|
||||
sess.get_parse_sess());
|
||||
ret {crate: crate, src: src};
|
||||
}
|
||||
|
||||
fn time<@T>(do_it: bool, what: &istr, thunk: fn() -> T) -> T {
|
||||
fn time<@T>(do_it: bool, what: &str, thunk: fn() -> T) -> T {
|
||||
if !do_it { ret thunk(); }
|
||||
let start = std::time::precise_time_s();
|
||||
let rv = thunk();
|
||||
|
@ -126,61 +118,60 @@ fn time<@T>(do_it: bool, what: &istr, thunk: fn() -> T) -> T {
|
|||
ret rv;
|
||||
}
|
||||
|
||||
fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: &istr,
|
||||
output: &istr) {
|
||||
fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: &str,
|
||||
output: &str) {
|
||||
let time_passes = sess.get_opts().time_passes;
|
||||
let crate =
|
||||
time(time_passes, ~"parsing", bind parse_input(sess, cfg, input));
|
||||
time(time_passes, "parsing", bind parse_input(sess, cfg, input));
|
||||
if sess.get_opts().parse_only { ret; }
|
||||
crate =
|
||||
time(time_passes, ~"configuration",
|
||||
time(time_passes, "configuration",
|
||||
bind front::config::strip_unconfigured_items(crate));
|
||||
if sess.get_opts().test {
|
||||
crate =
|
||||
time(time_passes, ~"building test harness",
|
||||
time(time_passes, "building test harness",
|
||||
bind front::test::modify_for_testing(crate));
|
||||
}
|
||||
crate =
|
||||
time(time_passes, ~"expansion",
|
||||
time(time_passes, "expansion",
|
||||
bind syntax::ext::expand::expand_crate(sess, crate));
|
||||
|
||||
let ast_map =
|
||||
time(time_passes, ~"ast indexing",
|
||||
time(time_passes, "ast indexing",
|
||||
bind middle::ast_map::map_crate(*crate));
|
||||
time(time_passes, ~"external crate/lib resolution",
|
||||
time(time_passes, "external crate/lib resolution",
|
||||
bind creader::read_crates(sess, *crate));
|
||||
let {def_map: def_map, ext_map: ext_map} =
|
||||
time(time_passes, ~"resolution",
|
||||
time(time_passes, "resolution",
|
||||
bind resolve::resolve_crate(sess, ast_map, crate));
|
||||
let freevars =
|
||||
time(time_passes, ~"freevar finding",
|
||||
time(time_passes, "freevar finding",
|
||||
bind freevars::annotate_freevars(def_map, crate));
|
||||
let ty_cx = ty::mk_ctxt(sess, def_map, ext_map, ast_map, freevars);
|
||||
time(time_passes, ~"typechecking",
|
||||
bind typeck::check_crate(ty_cx, crate));
|
||||
time(time_passes, ~"alt checking",
|
||||
time(time_passes, "typechecking", bind typeck::check_crate(ty_cx, crate));
|
||||
time(time_passes, "alt checking",
|
||||
bind middle::check_alt::check_crate(ty_cx, crate));
|
||||
if sess.get_opts().run_typestate {
|
||||
time(time_passes, ~"typestate checking",
|
||||
time(time_passes, "typestate checking",
|
||||
bind middle::tstate::ck::check_crate(ty_cx, crate));
|
||||
}
|
||||
let mut_map = time(time_passes, ~"mutability checking",
|
||||
bind middle::mut::check_crate(ty_cx, crate));
|
||||
time(time_passes, ~"alias checking",
|
||||
let mut_map =
|
||||
time(time_passes, "mutability checking",
|
||||
bind middle::mut::check_crate(ty_cx, crate));
|
||||
time(time_passes, "alias checking",
|
||||
bind middle::alias::check_crate(ty_cx, crate));
|
||||
time(time_passes, ~"kind checking",
|
||||
bind kind::check_crate(ty_cx, crate));
|
||||
time(time_passes, "kind checking", bind kind::check_crate(ty_cx, crate));
|
||||
if sess.get_opts().no_trans { ret; }
|
||||
let llmod = time(time_passes, ~"translation",
|
||||
bind trans::trans_crate(sess, crate, ty_cx,
|
||||
output,
|
||||
ast_map, mut_map));
|
||||
time(time_passes, ~"LLVM passes",
|
||||
let llmod =
|
||||
time(time_passes, "translation",
|
||||
bind trans::trans_crate(sess, crate, ty_cx, output, ast_map,
|
||||
mut_map));
|
||||
time(time_passes, "LLVM passes",
|
||||
bind link::write::run_passes(sess, llmod, output));
|
||||
}
|
||||
|
||||
fn pretty_print_input(sess: session::session, cfg: ast::crate_cfg,
|
||||
input: &istr, ppm: pp_mode) {
|
||||
input: &str, ppm: pp_mode) {
|
||||
fn ann_paren_for_expr(node: &pprust::ann_node) {
|
||||
alt node { pprust::node_expr(s, expr) { pprust::popen(s); } _ { } }
|
||||
}
|
||||
|
@ -188,11 +179,9 @@ fn pretty_print_input(sess: session::session, cfg: ast::crate_cfg,
|
|||
alt node {
|
||||
pprust::node_expr(s, expr) {
|
||||
pp::space(s.s);
|
||||
pp::word(s.s, ~"as");
|
||||
pp::word(s.s, "as");
|
||||
pp::space(s.s);
|
||||
pp::word(
|
||||
s.s,
|
||||
ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr)));
|
||||
pp::word(s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr)));
|
||||
pprust::pclose(s);
|
||||
}
|
||||
_ { }
|
||||
|
@ -202,18 +191,16 @@ fn pretty_print_input(sess: session::session, cfg: ast::crate_cfg,
|
|||
alt node {
|
||||
pprust::node_item(s, item) {
|
||||
pp::space(s.s);
|
||||
pprust::synth_comment(
|
||||
s, int::to_str(item.id, 10u));
|
||||
pprust::synth_comment(s, int::to_str(item.id, 10u));
|
||||
}
|
||||
pprust::node_block(s, blk) {
|
||||
pp::space(s.s);
|
||||
pprust::synth_comment(
|
||||
s, ~"block " + int::to_str(blk.node.id, 10u));
|
||||
pprust::synth_comment(s,
|
||||
"block " + int::to_str(blk.node.id, 10u));
|
||||
}
|
||||
pprust::node_expr(s, expr) {
|
||||
pp::space(s.s);
|
||||
pprust::synth_comment(
|
||||
s, int::to_str(expr.id, 10u));
|
||||
pprust::synth_comment(s, int::to_str(expr.id, 10u));
|
||||
pprust::pclose(s);
|
||||
}
|
||||
_ { }
|
||||
|
@ -249,26 +236,20 @@ fn pretty_print_input(sess: session::session, cfg: ast::crate_cfg,
|
|||
}
|
||||
ppm_normal. { ann = pprust::no_ann(); }
|
||||
}
|
||||
pprust::print_crate(sess.get_codemap(), crate,
|
||||
input,
|
||||
io::string_reader(src),
|
||||
io::stdout(), ann);
|
||||
pprust::print_crate(sess.get_codemap(), crate, input,
|
||||
io::string_reader(src), io::stdout(), ann);
|
||||
}
|
||||
|
||||
fn version(argv0: &istr) {
|
||||
let vers = ~"unknown version";
|
||||
fn version(argv0: &str) {
|
||||
let vers = "unknown version";
|
||||
let env_vers = #env["CFG_VERSION"];
|
||||
if str::byte_len(env_vers) != 0u { vers = env_vers; }
|
||||
io::stdout().write_str(
|
||||
#fmt["%s %s\n",
|
||||
argv0,
|
||||
vers]);
|
||||
io::stdout().write_str(#fmt["%s %s\n", argv0, vers]);
|
||||
}
|
||||
|
||||
fn usage(argv0: &istr) {
|
||||
io::stdout().write_str(
|
||||
#fmt["usage: %s [options] <input>\n", argv0] +
|
||||
~"
|
||||
fn usage(argv0: &str) {
|
||||
io::stdout().write_str(#fmt["usage: %s [options] <input>\n", argv0] +
|
||||
"
|
||||
options:
|
||||
|
||||
-h --help display this message
|
||||
|
@ -304,41 +285,39 @@ options:
|
|||
");
|
||||
}
|
||||
|
||||
fn get_os(triple: &istr) -> session::os {
|
||||
ret if str::find(triple, ~"win32") >= 0 ||
|
||||
str::find(triple, ~"mingw32") >= 0 {
|
||||
fn get_os(triple: &str) -> session::os {
|
||||
ret if str::find(triple, "win32") >= 0 ||
|
||||
str::find(triple, "mingw32") >= 0 {
|
||||
session::os_win32
|
||||
} else if str::find(triple, ~"darwin") >= 0 {
|
||||
} else if str::find(triple, "darwin") >= 0 {
|
||||
session::os_macos
|
||||
} else if str::find(triple, ~"linux") >= 0 {
|
||||
} else if str::find(triple, "linux") >= 0 {
|
||||
session::os_linux
|
||||
} else { log_err ~"Unknown operating system!"; fail };
|
||||
} else { log_err "Unknown operating system!"; fail };
|
||||
}
|
||||
|
||||
fn get_arch(triple: &istr) -> session::arch {
|
||||
ret if str::find(triple, ~"i386") >= 0 ||
|
||||
str::find(triple, ~"i486") >= 0 ||
|
||||
str::find(triple, ~"i586") >= 0 ||
|
||||
str::find(triple, ~"i686") >= 0 ||
|
||||
str::find(triple, ~"i786") >= 0 {
|
||||
fn get_arch(triple: &str) -> session::arch {
|
||||
ret if str::find(triple, "i386") >= 0 || str::find(triple, "i486") >= 0 ||
|
||||
str::find(triple, "i586") >= 0 ||
|
||||
str::find(triple, "i686") >= 0 ||
|
||||
str::find(triple, "i786") >= 0 {
|
||||
session::arch_x86
|
||||
} else if str::find(triple, ~"x86_64") >= 0 {
|
||||
} else if str::find(triple, "x86_64") >= 0 {
|
||||
session::arch_x64
|
||||
} else if str::find(triple, ~"arm") >= 0 ||
|
||||
str::find(triple, ~"xscale") >= 0 {
|
||||
} else if str::find(triple, "arm") >= 0 ||
|
||||
str::find(triple, "xscale") >= 0 {
|
||||
session::arch_arm
|
||||
} else { log_err ~"Unknown architecture! " + triple; fail };
|
||||
} else { log_err "Unknown architecture! " + triple; fail };
|
||||
}
|
||||
|
||||
fn get_default_sysroot(binary: &istr) -> istr {
|
||||
fn get_default_sysroot(binary: &str) -> str {
|
||||
let dirname = fs::dirname(binary);
|
||||
if str::eq(dirname, binary) { ret ~"."; }
|
||||
if str::eq(dirname, binary) { ret "."; }
|
||||
ret dirname;
|
||||
}
|
||||
|
||||
fn build_target_config() -> @session::config {
|
||||
let triple: istr =
|
||||
str::str_from_cstr(llvm::llvm::LLVMRustGetHostTriple());
|
||||
let triple: str = str::str_from_cstr(llvm::llvm::LLVMRustGetHostTriple());
|
||||
let target_cfg: @session::config =
|
||||
@{os: get_os(triple),
|
||||
arch: get_arch(triple),
|
||||
|
@ -348,51 +327,49 @@ fn build_target_config() -> @session::config {
|
|||
ret target_cfg;
|
||||
}
|
||||
|
||||
fn build_session_options(binary: &istr, match: &getopts::match,
|
||||
binary_dir: &istr) -> @session::options {
|
||||
let library = opt_present(match, ~"lib");
|
||||
let static = opt_present(match, ~"static");
|
||||
fn build_session_options(binary: &str, match: &getopts::match,
|
||||
binary_dir: &str) -> @session::options {
|
||||
let library = opt_present(match, "lib");
|
||||
let static = opt_present(match, "static");
|
||||
|
||||
let library_search_paths = [binary_dir + ~"/lib"];
|
||||
let lsp_vec = getopts::opt_strs(match, ~"L");
|
||||
for lsp: istr in lsp_vec {
|
||||
library_search_paths += [lsp];
|
||||
}
|
||||
let library_search_paths = [binary_dir + "/lib"];
|
||||
let lsp_vec = getopts::opt_strs(match, "L");
|
||||
for lsp: str in lsp_vec { library_search_paths += [lsp]; }
|
||||
|
||||
let parse_only = opt_present(match, ~"parse-only");
|
||||
let no_trans = opt_present(match, ~"no-trans");
|
||||
let parse_only = opt_present(match, "parse-only");
|
||||
let no_trans = opt_present(match, "no-trans");
|
||||
|
||||
let output_type =
|
||||
if parse_only || no_trans {
|
||||
link::output_type_none
|
||||
} else if opt_present(match, ~"S") {
|
||||
} else if opt_present(match, "S") {
|
||||
link::output_type_assembly
|
||||
} else if opt_present(match, ~"c") {
|
||||
} else if opt_present(match, "c") {
|
||||
link::output_type_object
|
||||
} else if opt_present(match, ~"emit-llvm") {
|
||||
} else if opt_present(match, "emit-llvm") {
|
||||
link::output_type_bitcode
|
||||
} else { link::output_type_exe };
|
||||
let verify = !opt_present(match, ~"noverify");
|
||||
let save_temps = opt_present(match, ~"save-temps");
|
||||
let debuginfo = opt_present(match, ~"g");
|
||||
let stats = opt_present(match, ~"stats");
|
||||
let time_passes = opt_present(match, ~"time-passes");
|
||||
let time_llvm_passes = opt_present(match, ~"time-llvm-passes");
|
||||
let run_typestate = !opt_present(match, ~"no-typestate");
|
||||
let sysroot_opt = getopts::opt_maybe_str(match, ~"sysroot");
|
||||
let verify = !opt_present(match, "noverify");
|
||||
let save_temps = opt_present(match, "save-temps");
|
||||
let debuginfo = opt_present(match, "g");
|
||||
let stats = opt_present(match, "stats");
|
||||
let time_passes = opt_present(match, "time-passes");
|
||||
let time_llvm_passes = opt_present(match, "time-llvm-passes");
|
||||
let run_typestate = !opt_present(match, "no-typestate");
|
||||
let sysroot_opt = getopts::opt_maybe_str(match, "sysroot");
|
||||
let opt_level: uint =
|
||||
if opt_present(match, ~"O") {
|
||||
if opt_present(match, ~"OptLevel") {
|
||||
if opt_present(match, "O") {
|
||||
if opt_present(match, "OptLevel") {
|
||||
log_err "error: -O and --OptLevel both provided";
|
||||
fail;
|
||||
}
|
||||
2u
|
||||
} else if opt_present(match, ~"OptLevel") {
|
||||
alt getopts::opt_str(match, ~"OptLevel") {
|
||||
~"0" { 0u }
|
||||
~"1" { 1u }
|
||||
~"2" { 2u }
|
||||
~"3" { 3u }
|
||||
} else if opt_present(match, "OptLevel") {
|
||||
alt getopts::opt_str(match, "OptLevel") {
|
||||
"0" { 0u }
|
||||
"1" { 1u }
|
||||
"2" { 2u }
|
||||
"3" { 3u }
|
||||
_ {
|
||||
log_err "error: optimization level needs " +
|
||||
"to be between 0-3";
|
||||
|
@ -405,10 +382,9 @@ fn build_session_options(binary: &istr, match: &getopts::match,
|
|||
none. { get_default_sysroot(binary) }
|
||||
some(s) { s }
|
||||
};
|
||||
let cfg = parse_cfgspecs(
|
||||
getopts::opt_strs(match, ~"cfg"));
|
||||
let test = opt_present(match, ~"test");
|
||||
let do_gc = opt_present(match, ~"gc");
|
||||
let cfg = parse_cfgspecs(getopts::opt_strs(match, "cfg"));
|
||||
let test = opt_present(match, "test");
|
||||
let do_gc = opt_present(match, "gc");
|
||||
let sopts: @session::options =
|
||||
@{library: library,
|
||||
static: static,
|
||||
|
@ -439,32 +415,31 @@ fn build_session(sopts: @session::options) -> session::session {
|
|||
none, 0u);
|
||||
}
|
||||
|
||||
fn parse_pretty(sess: session::session, name: &istr) -> pp_mode {
|
||||
if str::eq(name, ~"normal") {
|
||||
fn parse_pretty(sess: session::session, name: &str) -> pp_mode {
|
||||
if str::eq(name, "normal") {
|
||||
ret ppm_normal;
|
||||
} else if str::eq(name, ~"expanded") {
|
||||
} else if str::eq(name, "expanded") {
|
||||
ret ppm_expanded;
|
||||
} else if str::eq(name, ~"typed") {
|
||||
} else if str::eq(name, "typed") {
|
||||
ret ppm_typed;
|
||||
} else if str::eq(name, ~"identified") { ret ppm_identified; }
|
||||
sess.fatal(~"argument to `pretty` must be one of `normal`, `typed`, or "
|
||||
+ ~"`identified`");
|
||||
} else if str::eq(name, "identified") { ret ppm_identified; }
|
||||
sess.fatal("argument to `pretty` must be one of `normal`, `typed`, or " +
|
||||
"`identified`");
|
||||
}
|
||||
|
||||
fn opts() -> [getopts::opt] {
|
||||
ret [optflag(~"h"), optflag(~"help"), optflag(~"v"), optflag(~"version"),
|
||||
optflag(~"glue"), optflag(~"emit-llvm"), optflagopt(~"pretty"),
|
||||
optflag(~"ls"), optflag(~"parse-only"), optflag(~"no-trans"),
|
||||
optflag(~"O"), optopt(~"OptLevel"), optmulti(~"L"),
|
||||
optflag(~"S"), optflag(~"c"), optopt(~"o"), optflag(~"g"),
|
||||
optflag(~"save-temps"), optopt(~"sysroot"), optflag(~"stats"),
|
||||
optflag(~"time-passes"), optflag(~"time-llvm-passes"),
|
||||
optflag(~"no-typestate"), optflag(~"noverify"), optmulti(~"cfg"),
|
||||
optflag(~"test"), optflag(~"lib"), optflag(~"static"),
|
||||
optflag(~"gc")];
|
||||
ret [optflag("h"), optflag("help"), optflag("v"), optflag("version"),
|
||||
optflag("glue"), optflag("emit-llvm"), optflagopt("pretty"),
|
||||
optflag("ls"), optflag("parse-only"), optflag("no-trans"),
|
||||
optflag("O"), optopt("OptLevel"), optmulti("L"), optflag("S"),
|
||||
optflag("c"), optopt("o"), optflag("g"), optflag("save-temps"),
|
||||
optopt("sysroot"), optflag("stats"), optflag("time-passes"),
|
||||
optflag("time-llvm-passes"), optflag("no-typestate"),
|
||||
optflag("noverify"), optmulti("cfg"), optflag("test"),
|
||||
optflag("lib"), optflag("static"), optflag("gc")];
|
||||
}
|
||||
|
||||
fn main(args: [istr]) {
|
||||
fn main(args: [str]) {
|
||||
let binary = vec::shift(args);
|
||||
let binary_dir = fs::dirname(binary);
|
||||
let match =
|
||||
|
@ -475,49 +450,45 @@ fn main(args: [istr]) {
|
|||
fail
|
||||
}
|
||||
};
|
||||
if opt_present(match, ~"h") || opt_present(match, ~"help") {
|
||||
if opt_present(match, "h") || opt_present(match, "help") {
|
||||
usage(binary);
|
||||
ret;
|
||||
}
|
||||
if opt_present(match, ~"v") || opt_present(match, ~"version") {
|
||||
if opt_present(match, "v") || opt_present(match, "version") {
|
||||
version(binary);
|
||||
ret;
|
||||
}
|
||||
let sopts = build_session_options(binary, match, binary_dir);
|
||||
let sess = build_session(sopts);
|
||||
let n_inputs = vec::len::<istr>(match.free);
|
||||
let output_file = getopts::opt_maybe_str(match, ~"o");
|
||||
let glue = opt_present(match, ~"glue");
|
||||
let n_inputs = vec::len::<str>(match.free);
|
||||
let output_file = getopts::opt_maybe_str(match, "o");
|
||||
let glue = opt_present(match, "glue");
|
||||
if glue {
|
||||
if n_inputs > 0u {
|
||||
sess.fatal(~"No input files allowed with --glue.");
|
||||
sess.fatal("No input files allowed with --glue.");
|
||||
}
|
||||
let out = option::from_maybe::<istr>(~"glue.bc", output_file);
|
||||
let out = option::from_maybe::<str>("glue.bc", output_file);
|
||||
middle::trans::make_common_glue(sess, out);
|
||||
ret;
|
||||
}
|
||||
if n_inputs == 0u {
|
||||
sess.fatal(~"No input filename given.");
|
||||
sess.fatal("No input filename given.");
|
||||
} else if n_inputs > 1u {
|
||||
sess.fatal(~"Multiple input filenames provided.");
|
||||
sess.fatal("Multiple input filenames provided.");
|
||||
}
|
||||
let ifile = match.free[0];
|
||||
let saved_out_filename: istr = ~"";
|
||||
let cfg = build_configuration(sess, binary,
|
||||
ifile);
|
||||
let saved_out_filename: str = "";
|
||||
let cfg = build_configuration(sess, binary, ifile);
|
||||
let pretty =
|
||||
option::map::<istr,
|
||||
option::map::<str,
|
||||
pp_mode>(bind parse_pretty(sess, _),
|
||||
getopts::opt_default(match, ~"pretty",
|
||||
~"normal"));
|
||||
getopts::opt_default(match, "pretty",
|
||||
"normal"));
|
||||
alt pretty {
|
||||
some::<pp_mode>(ppm) {
|
||||
pretty_print_input(sess, cfg, ifile, ppm);
|
||||
ret;
|
||||
}
|
||||
some::<pp_mode>(ppm) { pretty_print_input(sess, cfg, ifile, ppm); ret; }
|
||||
none::<pp_mode>. {/* continue */ }
|
||||
}
|
||||
let ls = opt_present(match, ~"ls");
|
||||
let ls = opt_present(match, "ls");
|
||||
if ls { metadata::creader::list_file_metadata(ifile, io::stdout()); ret; }
|
||||
|
||||
let stop_after_codegen =
|
||||
|
@ -532,21 +503,22 @@ fn main(args: [istr]) {
|
|||
let parts =
|
||||
if !input_is_stdin(ifile) {
|
||||
str::split(ifile, '.' as u8)
|
||||
} else { [~"default", ~"rs"] };
|
||||
} else { ["default", "rs"] };
|
||||
vec::pop(parts);
|
||||
saved_out_filename = str::connect(parts, ~".");
|
||||
saved_out_filename = str::connect(parts, ".");
|
||||
let suffix =
|
||||
alt sopts.output_type {
|
||||
link::output_type_none. { ~"none" }
|
||||
link::output_type_bitcode. { ~"bc" }
|
||||
link::output_type_assembly. { ~"s" }
|
||||
link::output_type_none. { "none" }
|
||||
link::output_type_bitcode. { "bc" }
|
||||
link::output_type_assembly. { "s" }
|
||||
|
||||
|
||||
// Object and exe output both use the '.o' extension here
|
||||
link::output_type_object. | link::output_type_exe. {
|
||||
~"o"
|
||||
"o"
|
||||
}
|
||||
};
|
||||
let ofile = saved_out_filename + ~"." + suffix;
|
||||
let ofile = saved_out_filename + "." + suffix;
|
||||
compile_input(sess, cfg, ifile, ofile);
|
||||
}
|
||||
some(ofile) {
|
||||
|
@ -554,7 +526,7 @@ fn main(args: [istr]) {
|
|||
// FIXME: what about windows? This will create a foo.exe.o.
|
||||
saved_out_filename = ofile;
|
||||
let temp_filename =
|
||||
if !stop_after_codegen { ofile + ~".o" } else { ofile };
|
||||
if !stop_after_codegen { ofile + ".o" } else { ofile };
|
||||
compile_input(sess, cfg, ifile, temp_filename);
|
||||
}
|
||||
}
|
||||
|
@ -565,39 +537,37 @@ fn main(args: [istr]) {
|
|||
// TODO: Factor this out of main.
|
||||
if stop_after_codegen { ret; }
|
||||
|
||||
let glu: istr = binary_dir + ~"/lib/glue.o";
|
||||
let main: istr = binary_dir + ~"/lib/main.o";
|
||||
let stage: istr = ~"-L" + binary_dir + ~"/lib";
|
||||
let prog: istr = ~"gcc";
|
||||
let glu: str = binary_dir + "/lib/glue.o";
|
||||
let main: str = binary_dir + "/lib/main.o";
|
||||
let stage: str = "-L" + binary_dir + "/lib";
|
||||
let prog: str = "gcc";
|
||||
// The invocations of gcc share some flags across platforms
|
||||
|
||||
let gcc_args =
|
||||
[stage,
|
||||
~"-Lrt", ~"-lrustrt", glu,
|
||||
~"-m32", ~"-o", saved_out_filename,
|
||||
saved_out_filename + ~".o"];
|
||||
[stage, "-Lrt", "-lrustrt", glu, "-m32", "-o", saved_out_filename,
|
||||
saved_out_filename + ".o"];
|
||||
let lib_cmd;
|
||||
|
||||
let os = sess.get_targ_cfg().os;
|
||||
if os == session::os_macos {
|
||||
lib_cmd = ~"-dynamiclib";
|
||||
} else { lib_cmd = ~"-shared"; }
|
||||
lib_cmd = "-dynamiclib";
|
||||
} else { lib_cmd = "-shared"; }
|
||||
|
||||
// Converts a library file name into a gcc -l argument
|
||||
fn unlib(config: @session::config, filename: &istr) -> istr {
|
||||
fn unlib(config: @session::config, filename: &str) -> str {
|
||||
let rmlib =
|
||||
bind fn (config: @session::config, filename: &istr) -> istr {
|
||||
if config.os == session::os_macos ||
|
||||
config.os == session::os_linux &&
|
||||
str::find(filename, ~"lib") == 0 {
|
||||
ret str::slice(filename, 3u,
|
||||
str::byte_len(filename));
|
||||
} else { ret filename; }
|
||||
}(config, _);
|
||||
fn rmext(filename: &istr) -> istr {
|
||||
bind fn (config: @session::config, filename: &str) -> str {
|
||||
if config.os == session::os_macos ||
|
||||
config.os == session::os_linux &&
|
||||
str::find(filename, "lib") == 0 {
|
||||
ret str::slice(filename, 3u,
|
||||
str::byte_len(filename));
|
||||
} else { ret filename; }
|
||||
}(config, _);
|
||||
fn rmext(filename: &str) -> str {
|
||||
let parts = str::split(filename, '.' as u8);
|
||||
vec::pop(parts);
|
||||
ret str::connect(parts, ~".");
|
||||
ret str::connect(parts, ".");
|
||||
}
|
||||
ret alt config.os {
|
||||
session::os_macos. { rmext(rmlib(filename)) }
|
||||
|
@ -607,53 +577,48 @@ fn main(args: [istr]) {
|
|||
}
|
||||
|
||||
let cstore = sess.get_cstore();
|
||||
for cratepath: istr in cstore::get_used_crate_files(cstore) {
|
||||
if str::ends_with(cratepath, ~".rlib") {
|
||||
for cratepath: str in cstore::get_used_crate_files(cstore) {
|
||||
if str::ends_with(cratepath, ".rlib") {
|
||||
gcc_args += [cratepath];
|
||||
cont;
|
||||
}
|
||||
let cratepath = cratepath;
|
||||
let dir = fs::dirname(cratepath);
|
||||
if dir != ~"" { gcc_args += [~"-L" + dir]; }
|
||||
if dir != "" { gcc_args += ["-L" + dir]; }
|
||||
let libarg = unlib(sess.get_targ_cfg(), fs::basename(cratepath));
|
||||
gcc_args += [~"-l" + libarg];
|
||||
gcc_args += ["-l" + libarg];
|
||||
}
|
||||
|
||||
let ula = cstore::get_used_link_args(cstore);
|
||||
for arg: istr in ula { gcc_args += [arg]; }
|
||||
for arg: str in ula { gcc_args += [arg]; }
|
||||
|
||||
let used_libs = cstore::get_used_libraries(cstore);
|
||||
for l: istr in used_libs { gcc_args += [~"-l" + l]; }
|
||||
for l: str in used_libs { gcc_args += ["-l" + l]; }
|
||||
|
||||
if sopts.library {
|
||||
gcc_args += [lib_cmd];
|
||||
} else {
|
||||
// FIXME: why do we hardcode -lm?
|
||||
gcc_args += [~"-lm", main];
|
||||
gcc_args += ["-lm", main];
|
||||
}
|
||||
// We run 'gcc' here
|
||||
|
||||
let err_code = run::run_program(prog, gcc_args);
|
||||
if 0 != err_code {
|
||||
sess.err(
|
||||
#fmt["linking with gcc failed with code %d", err_code]);
|
||||
sess.note(
|
||||
#fmt["gcc arguments: %s",
|
||||
str::connect(gcc_args, ~" ")]);
|
||||
sess.err(#fmt["linking with gcc failed with code %d", err_code]);
|
||||
sess.note(#fmt["gcc arguments: %s", str::connect(gcc_args, " ")]);
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
// Clean up on Darwin
|
||||
|
||||
if sess.get_targ_cfg().os == session::os_macos {
|
||||
run::run_program(~"dsymutil",
|
||||
[saved_out_filename]);
|
||||
run::run_program("dsymutil", [saved_out_filename]);
|
||||
}
|
||||
|
||||
|
||||
// Remove the temporary object file if we aren't saving temps
|
||||
if !sopts.save_temps {
|
||||
run::run_program(~"rm",
|
||||
[saved_out_filename + ~".o"]);
|
||||
run::run_program("rm", [saved_out_filename + ".o"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,13 +629,13 @@ mod test {
|
|||
#[test]
|
||||
fn test_switch_implies_cfg_test() {
|
||||
let match =
|
||||
alt getopts::getopts([~"--test"], opts()) {
|
||||
alt getopts::getopts(["--test"], opts()) {
|
||||
getopts::success(m) { m }
|
||||
};
|
||||
let sessopts = build_session_options(~"whatever", match, ~"whatever");
|
||||
let sessopts = build_session_options("whatever", match, "whatever");
|
||||
let sess = build_session(sessopts);
|
||||
let cfg = build_configuration(sess, ~"whatever", ~"whatever");
|
||||
assert (attr::contains_name(cfg, ~"test"));
|
||||
let cfg = build_configuration(sess, "whatever", "whatever");
|
||||
assert (attr::contains_name(cfg, "test"));
|
||||
}
|
||||
|
||||
// When the user supplies --test and --cfg test, don't implicitly add
|
||||
|
@ -678,13 +643,13 @@ mod test {
|
|||
#[test]
|
||||
fn test_switch_implies_cfg_test_unless_cfg_test() {
|
||||
let match =
|
||||
alt getopts::getopts([~"--test", ~"--cfg=test"], opts()) {
|
||||
alt getopts::getopts(["--test", "--cfg=test"], opts()) {
|
||||
getopts::success(m) { m }
|
||||
};
|
||||
let sessopts = build_session_options(~"whatever", match, ~"whatever");
|
||||
let sessopts = build_session_options("whatever", match, "whatever");
|
||||
let sess = build_session(sessopts);
|
||||
let cfg = build_configuration(sess, ~"whatever", ~"whatever");
|
||||
let test_items = attr::find_meta_items_by_name(cfg, ~"test");
|
||||
let cfg = build_configuration(sess, "whatever", "whatever");
|
||||
let test_items = attr::find_meta_items_by_name(cfg, "test");
|
||||
assert (vec::len(test_items) == 1u);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,15 +37,15 @@ type options =
|
|||
time_passes: bool,
|
||||
time_llvm_passes: bool,
|
||||
output_type: back::link::output_type,
|
||||
library_search_paths: [istr],
|
||||
sysroot: istr,
|
||||
library_search_paths: [str],
|
||||
sysroot: str,
|
||||
cfg: ast::crate_cfg,
|
||||
test: bool,
|
||||
parse_only: bool,
|
||||
no_trans: bool,
|
||||
do_gc: bool};
|
||||
|
||||
type crate_metadata = {name: istr, data: [u8]};
|
||||
type crate_metadata = {name: str, data: [u8]};
|
||||
|
||||
obj session(targ_cfg: @config,
|
||||
opts: @options,
|
||||
|
@ -58,54 +58,46 @@ obj session(targ_cfg: @config,
|
|||
fn get_targ_cfg() -> @config { ret targ_cfg; }
|
||||
fn get_opts() -> @options { ret opts; }
|
||||
fn get_cstore() -> metadata::cstore::cstore { cstore }
|
||||
fn span_fatal(sp: span, msg: &istr) -> ! {
|
||||
fn span_fatal(sp: span, msg: &str) -> ! {
|
||||
// FIXME: Use constants, but rustboot doesn't know how to export them.
|
||||
codemap::emit_error(some(sp), msg, parse_sess.cm);
|
||||
fail;
|
||||
}
|
||||
fn fatal(msg: &istr) -> ! {
|
||||
fn fatal(msg: &str) -> ! {
|
||||
codemap::emit_error(none, msg, parse_sess.cm);
|
||||
fail;
|
||||
}
|
||||
fn span_err(sp: span, msg: &istr) {
|
||||
fn span_err(sp: span, msg: &str) {
|
||||
codemap::emit_error(some(sp), msg, parse_sess.cm);
|
||||
err_count += 1u;
|
||||
}
|
||||
fn err(msg: &istr) {
|
||||
fn err(msg: &str) {
|
||||
codemap::emit_error(none, msg, parse_sess.cm);
|
||||
err_count += 1u;
|
||||
}
|
||||
fn abort_if_errors() {
|
||||
if err_count > 0u { self.fatal(~"aborting due to previous errors"); }
|
||||
if err_count > 0u { self.fatal("aborting due to previous errors"); }
|
||||
}
|
||||
fn span_warn(sp: span, msg: &istr) {
|
||||
fn span_warn(sp: span, msg: &str) {
|
||||
// FIXME: Use constants, but rustboot doesn't know how to export them.
|
||||
codemap::emit_warning(some(sp), msg, parse_sess.cm);
|
||||
}
|
||||
fn warn(msg: &istr) {
|
||||
codemap::emit_warning(none, msg, parse_sess.cm);
|
||||
}
|
||||
fn span_note(sp: span, msg: &istr) {
|
||||
fn warn(msg: &str) { codemap::emit_warning(none, msg, parse_sess.cm); }
|
||||
fn span_note(sp: span, msg: &str) {
|
||||
// FIXME: Use constants, but rustboot doesn't know how to export them.
|
||||
codemap::emit_note(some(sp), msg, parse_sess.cm);
|
||||
}
|
||||
fn note(msg: &istr) {
|
||||
codemap::emit_note(none, msg, parse_sess.cm);
|
||||
fn note(msg: &str) { codemap::emit_note(none, msg, parse_sess.cm); }
|
||||
fn span_bug(sp: span, msg: &str) -> ! {
|
||||
self.span_fatal(sp, #fmt["internal compiler error %s", msg]);
|
||||
}
|
||||
fn span_bug(sp: span, msg: &istr) -> ! {
|
||||
self.span_fatal(sp,
|
||||
#fmt["internal compiler error %s",
|
||||
msg]);
|
||||
fn bug(msg: &str) -> ! {
|
||||
self.fatal(#fmt["internal compiler error %s", msg]);
|
||||
}
|
||||
fn bug(msg: &istr) -> ! {
|
||||
self.fatal(
|
||||
#fmt["internal compiler error %s",
|
||||
msg]);
|
||||
fn span_unimpl(sp: span, msg: &str) -> ! {
|
||||
self.span_bug(sp, "unimplemented " + msg);
|
||||
}
|
||||
fn span_unimpl(sp: span, msg: &istr) -> ! {
|
||||
self.span_bug(sp, ~"unimplemented " + msg);
|
||||
}
|
||||
fn unimpl(msg: &istr) -> ! { self.bug(~"unimplemented " + msg); }
|
||||
fn unimpl(msg: &str) -> ! { self.bug("unimplemented " + msg); }
|
||||
fn get_codemap() -> codemap::codemap { ret parse_sess.cm; }
|
||||
fn lookup_pos(pos: uint) -> codemap::loc {
|
||||
ret codemap::lookup_char_pos(parse_sess.cm, pos);
|
||||
|
@ -114,7 +106,7 @@ obj session(targ_cfg: @config,
|
|||
fn next_node_id() -> ast::node_id {
|
||||
ret syntax::parse::parser::next_node_id(parse_sess);
|
||||
}
|
||||
fn span_str(sp: span) -> istr {
|
||||
fn span_str(sp: span) -> str {
|
||||
ret codemap::span_to_str(sp, self.get_codemap());
|
||||
}
|
||||
fn set_main_id(d: node_id) { main_fn = some(d); }
|
||||
|
|
|
@ -32,7 +32,7 @@ export mk_attr;
|
|||
// linkage
|
||||
fn find_linkage_metas(attrs: &[ast::attribute]) -> [@ast::meta_item] {
|
||||
let metas: [@ast::meta_item] = [];
|
||||
for attr: ast::attribute in find_attrs_by_name(attrs, ~"link") {
|
||||
for attr: ast::attribute in find_attrs_by_name(attrs, "link") {
|
||||
alt attr.node.value.node {
|
||||
ast::meta_list(_, items) { metas += items; }
|
||||
_ { log "ignoring link attribute that has incorrect type"; }
|
||||
|
@ -80,13 +80,10 @@ fn get_meta_item_name(meta: &@ast::meta_item) -> ast::ident {
|
|||
|
||||
// Gets the string value if the meta_item is a meta_name_value variant
|
||||
// containing a string, otherwise none
|
||||
fn get_meta_item_value_str(meta: &@ast::meta_item) -> option::t<istr> {
|
||||
fn get_meta_item_value_str(meta: &@ast::meta_item) -> option::t<str> {
|
||||
alt meta.node {
|
||||
ast::meta_name_value(_, v) {
|
||||
alt v.node {
|
||||
ast::lit_str(s) { option::some(s) }
|
||||
_ { option::none }
|
||||
}
|
||||
alt v.node { ast::lit_str(s) { option::some(s) } _ { option::none } }
|
||||
}
|
||||
_ { option::none }
|
||||
}
|
||||
|
@ -124,10 +121,10 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool {
|
|||
|
||||
fn contains(haystack: &[@ast::meta_item], needle: @ast::meta_item) -> bool {
|
||||
log #fmt["looking for %s",
|
||||
syntax::print::pprust::meta_item_to_str(*needle)];
|
||||
syntax::print::pprust::meta_item_to_str(*needle)];
|
||||
for item: @ast::meta_item in haystack {
|
||||
log #fmt["looking in %s",
|
||||
syntax::print::pprust::meta_item_to_str(*item)];
|
||||
syntax::print::pprust::meta_item_to_str(*item)];
|
||||
if eq(item, needle) { log "found it!"; ret true; }
|
||||
}
|
||||
log "found it not :(";
|
||||
|
@ -163,11 +160,11 @@ fn sort_meta_items(items: &[@ast::meta_item]) -> [@ast::meta_item] {
|
|||
ret v2;
|
||||
}
|
||||
|
||||
fn remove_meta_items_by_name(items: &[@ast::meta_item], name: &istr) ->
|
||||
fn remove_meta_items_by_name(items: &[@ast::meta_item], name: &str) ->
|
||||
[@ast::meta_item] {
|
||||
|
||||
let filter =
|
||||
bind fn (item: &@ast::meta_item, name: &istr) ->
|
||||
bind fn (item: &@ast::meta_item, name: &str) ->
|
||||
option::t<@ast::meta_item> {
|
||||
if get_meta_item_name(item) != name {
|
||||
option::some(item)
|
||||
|
@ -183,8 +180,7 @@ fn require_unique_names(sess: &session::session, metas: &[@ast::meta_item]) {
|
|||
let name = get_meta_item_name(meta);
|
||||
if map.contains_key(name) {
|
||||
sess.span_fatal(meta.span,
|
||||
#fmt["duplicate meta item `%s`",
|
||||
name]);
|
||||
#fmt["duplicate meta item `%s`", name]);
|
||||
}
|
||||
map.insert(name, ());
|
||||
}
|
||||
|
@ -194,8 +190,7 @@ fn span<@T>(item: &T) -> ast::spanned<T> {
|
|||
ret {node: item, span: ast_util::dummy_sp()};
|
||||
}
|
||||
|
||||
fn mk_name_value_item_str(name: ast::ident,
|
||||
value: &istr) -> @ast::meta_item {
|
||||
fn mk_name_value_item_str(name: ast::ident, value: &str) -> @ast::meta_item {
|
||||
let value_lit = span(ast::lit_str(value));
|
||||
ret mk_name_value_item(name, value_lit);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,8 @@ fn fold_block(cfg: &ast::crate_cfg, b: &ast::blk_, fld: fold::ast_fold) ->
|
|||
let filtered_stmts = vec::filter_map(filter, b.stmts);
|
||||
ret {stmts: vec::map(fld.fold_stmt, filtered_stmts),
|
||||
expr: option::map(fld.fold_expr, b.expr),
|
||||
id: b.id, rules: b.rules};
|
||||
id: b.id,
|
||||
rules: b.rules};
|
||||
}
|
||||
|
||||
fn item_in_cfg(cfg: &ast::crate_cfg, item: &@ast::item) -> bool {
|
||||
|
@ -94,7 +95,7 @@ fn native_item_in_cfg(cfg: &ast::crate_cfg, item: &@ast::native_item) ->
|
|||
fn in_cfg(cfg: &ast::crate_cfg, attrs: &[ast::attribute]) -> bool {
|
||||
|
||||
// The "cfg" attributes on the item
|
||||
let item_cfg_attrs = attr::find_attrs_by_name(attrs, ~"cfg");
|
||||
let item_cfg_attrs = attr::find_attrs_by_name(attrs, "cfg");
|
||||
let item_has_cfg_attrs = vec::len(item_cfg_attrs) > 0u;
|
||||
if !item_has_cfg_attrs { ret true; }
|
||||
|
||||
|
@ -108,7 +109,7 @@ fn in_cfg(cfg: &ast::crate_cfg, attrs: &[ast::attribute]) -> bool {
|
|||
[@ast::meta_item] {
|
||||
alt cfg_item.node {
|
||||
ast::meta_list(name, items) {
|
||||
assert (name == ~"cfg");
|
||||
assert (name == "cfg");
|
||||
inner_items + items
|
||||
}
|
||||
_ { inner_items }
|
||||
|
|
|
@ -65,7 +65,7 @@ fn fold_mod(_cx: &test_ctxt, m: &ast::_mod, fld: fold::ast_fold) ->
|
|||
fn nomain(item: &@ast::item) -> option::t<@ast::item> {
|
||||
alt item.node {
|
||||
ast::item_fn(f, _) {
|
||||
if item.ident == ~"main" {
|
||||
if item.ident == "main" {
|
||||
option::none
|
||||
} else { option::some(item) }
|
||||
}
|
||||
|
@ -92,8 +92,7 @@ fn fold_item(cx: &test_ctxt, i: &@ast::item, fld: fold::ast_fold) ->
|
|||
@ast::item {
|
||||
|
||||
cx.path += [i.ident];
|
||||
log #fmt["current path: %s",
|
||||
ast_util::path_name_i(cx.path)];
|
||||
log #fmt["current path: %s", ast_util::path_name_i(cx.path)];
|
||||
|
||||
if is_test_fn(i) {
|
||||
log "this is a test function";
|
||||
|
@ -109,7 +108,7 @@ fn fold_item(cx: &test_ctxt, i: &@ast::item, fld: fold::ast_fold) ->
|
|||
|
||||
fn is_test_fn(i: &@ast::item) -> bool {
|
||||
let has_test_attr =
|
||||
vec::len(attr::find_attrs_by_name(i.attrs, ~"test")) > 0u;
|
||||
vec::len(attr::find_attrs_by_name(i.attrs, "test")) > 0u;
|
||||
|
||||
fn has_test_signature(i: &@ast::item) -> bool {
|
||||
alt i.node {
|
||||
|
@ -127,7 +126,7 @@ fn is_test_fn(i: &@ast::item) -> bool {
|
|||
}
|
||||
|
||||
fn is_ignored(i: &@ast::item) -> bool {
|
||||
attr::contains_name(attr::attr_metas(i.attrs), ~"ignore")
|
||||
attr::contains_name(attr::attr_metas(i.attrs), "ignore")
|
||||
}
|
||||
|
||||
fn add_test_module(cx: &test_ctxt, m: &ast::_mod) -> ast::_mod {
|
||||
|
@ -162,21 +161,18 @@ fn mk_test_module(cx: &test_ctxt) -> @ast::item {
|
|||
let testmod: ast::_mod = {view_items: [], items: [mainfn, testsfn]};
|
||||
let item_ = ast::item_mod(testmod);
|
||||
let item: ast::item =
|
||||
{ident: ~"__test",
|
||||
{ident: "__test",
|
||||
attrs: [],
|
||||
id: cx.next_node_id(),
|
||||
node: item_,
|
||||
span: dummy_sp()};
|
||||
|
||||
log #fmt["Synthetic test module:\n%s\n",
|
||||
pprust::item_to_str(@item)];
|
||||
log #fmt["Synthetic test module:\n%s\n", pprust::item_to_str(@item)];
|
||||
|
||||
ret @item;
|
||||
}
|
||||
|
||||
fn nospan<@T>(t: &T) -> ast::spanned<T> {
|
||||
ret {node: t, span: dummy_sp()};
|
||||
}
|
||||
fn nospan<@T>(t: &T) -> ast::spanned<T> { ret {node: t, span: dummy_sp()}; }
|
||||
|
||||
fn mk_tests(cx: &test_ctxt) -> @ast::item {
|
||||
let ret_ty = mk_test_desc_vec_ty(cx);
|
||||
|
@ -193,15 +189,15 @@ fn mk_tests(cx: &test_ctxt) -> @ast::item {
|
|||
// The vector of test_descs for this crate
|
||||
let test_descs = mk_test_desc_vec(cx);
|
||||
|
||||
let body_: ast::blk_ = checked_blk([], option::some(test_descs),
|
||||
cx.next_node_id());
|
||||
let body_: ast::blk_ =
|
||||
checked_blk([], option::some(test_descs), cx.next_node_id());
|
||||
let body = nospan(body_);
|
||||
|
||||
let fn_ = {decl: decl, proto: proto, body: body};
|
||||
|
||||
let item_ = ast::item_fn(fn_, []);
|
||||
let item: ast::item =
|
||||
{ident: ~"tests",
|
||||
{ident: "tests",
|
||||
attrs: [],
|
||||
id: cx.next_node_id(),
|
||||
node: item_,
|
||||
|
@ -222,7 +218,7 @@ fn empty_fn_ty() -> ast::ty {
|
|||
fn mk_test_desc_vec_ty(cx: &test_ctxt) -> @ast::ty {
|
||||
let test_desc_ty_path: ast::path =
|
||||
nospan({global: false,
|
||||
idents: [~"std", ~"test", ~"test_desc"],
|
||||
idents: ["std", "test", "test_desc"],
|
||||
types: []});
|
||||
|
||||
let test_desc_ty: ast::ty =
|
||||
|
@ -249,8 +245,7 @@ fn mk_test_desc_vec(cx: &test_ctxt) -> @ast::expr {
|
|||
fn mk_test_desc_rec(cx: &test_ctxt, test: test) -> @ast::expr {
|
||||
let path = test.path;
|
||||
|
||||
log #fmt["encoding %s",
|
||||
ast_util::path_name_i(path)];
|
||||
log #fmt["encoding %s", ast_util::path_name_i(path)];
|
||||
|
||||
let name_lit: ast::lit =
|
||||
nospan(ast::lit_str(ast_util::path_name_i(path)));
|
||||
|
@ -260,7 +255,7 @@ fn mk_test_desc_rec(cx: &test_ctxt, test: test) -> @ast::expr {
|
|||
span: dummy_sp()};
|
||||
|
||||
let name_field: ast::field =
|
||||
nospan({mut: ast::imm, ident: ~"name", expr: @name_expr});
|
||||
nospan({mut: ast::imm, ident: "name", expr: @name_expr});
|
||||
|
||||
let fn_path: ast::path = nospan({global: false, idents: path, types: []});
|
||||
|
||||
|
@ -270,7 +265,7 @@ fn mk_test_desc_rec(cx: &test_ctxt, test: test) -> @ast::expr {
|
|||
span: dummy_sp()};
|
||||
|
||||
let fn_field: ast::field =
|
||||
nospan({mut: ast::imm, ident: ~"fn", expr: @fn_expr});
|
||||
nospan({mut: ast::imm, ident: "fn", expr: @fn_expr});
|
||||
|
||||
let ignore_lit: ast::lit = nospan(ast::lit_bool(test.ignore));
|
||||
|
||||
|
@ -280,7 +275,7 @@ fn mk_test_desc_rec(cx: &test_ctxt, test: test) -> @ast::expr {
|
|||
span: dummy_sp()};
|
||||
|
||||
let ignore_field: ast::field =
|
||||
nospan({mut: ast::imm, ident: ~"ignore", expr: @ignore_expr});
|
||||
nospan({mut: ast::imm, ident: "ignore", expr: @ignore_expr});
|
||||
|
||||
let desc_rec_: ast::expr_ =
|
||||
ast::expr_rec([name_field, fn_field, ignore_field], option::none);
|
||||
|
@ -295,7 +290,7 @@ fn mk_main(cx: &test_ctxt) -> @ast::item {
|
|||
let args_ty: ast::ty = nospan(ast::ty_vec(args_mt));
|
||||
|
||||
let args_arg: ast::arg =
|
||||
{mode: ast::val, ty: @args_ty, ident: ~"args", id: cx.next_node_id()};
|
||||
{mode: ast::val, ty: @args_ty, ident: "args", id: cx.next_node_id()};
|
||||
|
||||
let ret_ty = nospan(ast::ty_nil);
|
||||
|
||||
|
@ -310,15 +305,15 @@ fn mk_main(cx: &test_ctxt) -> @ast::item {
|
|||
|
||||
let test_main_call_expr = mk_test_main_call(cx);
|
||||
|
||||
let body_: ast::blk_ = checked_blk([], option::some(test_main_call_expr),
|
||||
cx.next_node_id());
|
||||
let body_: ast::blk_ =
|
||||
checked_blk([], option::some(test_main_call_expr), cx.next_node_id());
|
||||
let body = {node: body_, span: dummy_sp()};
|
||||
|
||||
let fn_ = {decl: decl, proto: proto, body: body};
|
||||
|
||||
let item_ = ast::item_fn(fn_, []);
|
||||
let item: ast::item =
|
||||
{ident: ~"main",
|
||||
{ident: "main",
|
||||
attrs: [],
|
||||
id: cx.next_node_id(),
|
||||
node: item_,
|
||||
|
@ -330,7 +325,7 @@ fn mk_test_main_call(cx: &test_ctxt) -> @ast::expr {
|
|||
|
||||
// Get the args passed to main so we can pass the to test_main
|
||||
let args_path: ast::path =
|
||||
nospan({global: false, idents: [~"args"], types: []});
|
||||
nospan({global: false, idents: ["args"], types: []});
|
||||
|
||||
let args_path_expr_: ast::expr_ = ast::expr_path(args_path);
|
||||
|
||||
|
@ -339,7 +334,7 @@ fn mk_test_main_call(cx: &test_ctxt) -> @ast::expr {
|
|||
|
||||
// Call __test::test to generate the vector of test_descs
|
||||
let test_path: ast::path =
|
||||
nospan({global: false, idents: [~"tests"], types: []});
|
||||
nospan({global: false, idents: ["tests"], types: []});
|
||||
|
||||
let test_path_expr_: ast::expr_ = ast::expr_path(test_path);
|
||||
|
||||
|
@ -354,24 +349,20 @@ fn mk_test_main_call(cx: &test_ctxt) -> @ast::expr {
|
|||
// Call std::test::test_main
|
||||
let test_main_path: ast::path =
|
||||
nospan({global: false,
|
||||
idents: [~"std", ~"test", ~"test_main"],
|
||||
idents: ["std", "test", "test_main"],
|
||||
types: []});
|
||||
|
||||
let test_main_path_expr_: ast::expr_ = ast::expr_path(test_main_path);
|
||||
|
||||
let test_main_path_expr: ast::expr =
|
||||
{id: cx.next_node_id(),
|
||||
node: test_main_path_expr_,
|
||||
span: dummy_sp()};
|
||||
{id: cx.next_node_id(), node: test_main_path_expr_, span: dummy_sp()};
|
||||
|
||||
let test_main_call_expr_: ast::expr_ =
|
||||
ast::expr_call(@test_main_path_expr,
|
||||
[@args_path_expr, @test_call_expr]);
|
||||
|
||||
let test_main_call_expr: ast::expr =
|
||||
{id: cx.next_node_id(),
|
||||
node: test_main_call_expr_,
|
||||
span: dummy_sp()};
|
||||
{id: cx.next_node_id(), node: test_main_call_expr_, span: dummy_sp()};
|
||||
|
||||
ret @test_main_call_expr;
|
||||
}
|
||||
|
|
|
@ -810,18 +810,14 @@ native "cdecl" mod llvm = "rustllvm" {
|
|||
fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: PassManagerBuilderRef,
|
||||
Value: Bool);
|
||||
fn LLVMPassManagerBuilderSetDisableSimplifyLibCalls(
|
||||
PMB: PassManagerBuilderRef,
|
||||
Value: Bool);
|
||||
PMB: PassManagerBuilderRef, Value: Bool);
|
||||
fn LLVMPassManagerBuilderUseInlinerWithThreshold(
|
||||
PMB: PassManagerBuilderRef,
|
||||
threshold: uint);
|
||||
PMB: PassManagerBuilderRef, threshold: uint);
|
||||
fn LLVMPassManagerBuilderPopulateModulePassManager(
|
||||
PMB: PassManagerBuilderRef,
|
||||
PM: PassManagerRef);
|
||||
PMB: PassManagerBuilderRef, PM: PassManagerRef);
|
||||
|
||||
fn LLVMPassManagerBuilderPopulateFunctionPassManager(
|
||||
PMB: PassManagerBuilderRef,
|
||||
PM: PassManagerRef);
|
||||
PMB: PassManagerBuilderRef, PM: PassManagerRef);
|
||||
|
||||
/** Destroys a memory buffer. */
|
||||
fn LLVMDisposeMemoryBuffer(MemBuf: MemoryBufferRef);
|
||||
|
@ -899,10 +895,10 @@ native "cdecl" mod llvm = "rustllvm" {
|
|||
|
||||
/* Memory-managed object interface to type handles. */
|
||||
|
||||
obj type_names(type_names: std::map::hashmap<TypeRef, istr>,
|
||||
named_types: std::map::hashmap<istr, TypeRef>) {
|
||||
obj type_names(type_names: std::map::hashmap<TypeRef, str>,
|
||||
named_types: std::map::hashmap<str, TypeRef>) {
|
||||
|
||||
fn associate(s: &istr, t: TypeRef) {
|
||||
fn associate(s: &str, t: TypeRef) {
|
||||
assert (!named_types.contains_key(s));
|
||||
assert (!type_names.contains_key(t));
|
||||
type_names.insert(t, s);
|
||||
|
@ -911,15 +907,11 @@ obj type_names(type_names: std::map::hashmap<TypeRef, istr>,
|
|||
|
||||
fn type_has_name(t: TypeRef) -> bool { ret type_names.contains_key(t); }
|
||||
|
||||
fn get_name(t: TypeRef) -> istr { ret type_names.get(t); }
|
||||
fn get_name(t: TypeRef) -> str { ret type_names.get(t); }
|
||||
|
||||
fn name_has_type(s: &istr) -> bool {
|
||||
ret named_types.contains_key(s);
|
||||
}
|
||||
fn name_has_type(s: &str) -> bool { ret named_types.contains_key(s); }
|
||||
|
||||
fn get_type(s: &istr) -> TypeRef {
|
||||
ret named_types.get(s);
|
||||
}
|
||||
fn get_type(s: &str) -> TypeRef { ret named_types.get(s); }
|
||||
}
|
||||
|
||||
fn mk_type_names() -> type_names {
|
||||
|
@ -931,17 +923,17 @@ fn mk_type_names() -> type_names {
|
|||
|
||||
let hasher: std::map::hashfn<TypeRef> = hash;
|
||||
let eqer: std::map::eqfn<TypeRef> = eq;
|
||||
let tn = std::map::mk_hashmap::<TypeRef, istr>(hasher, eqer);
|
||||
let tn = std::map::mk_hashmap::<TypeRef, str>(hasher, eqer);
|
||||
|
||||
ret type_names(tn, nt);
|
||||
}
|
||||
|
||||
fn type_to_str(names: type_names, ty: TypeRef) -> istr {
|
||||
fn type_to_str(names: type_names, ty: TypeRef) -> str {
|
||||
ret type_to_str_inner(names, [], ty);
|
||||
}
|
||||
|
||||
fn type_to_str_inner(names: type_names, outer0: &[TypeRef], ty: TypeRef) ->
|
||||
istr {
|
||||
str {
|
||||
|
||||
if names.type_has_name(ty) { ret names.get_name(ty); }
|
||||
|
||||
|
@ -949,12 +941,11 @@ fn type_to_str_inner(names: type_names, outer0: &[TypeRef], ty: TypeRef) ->
|
|||
|
||||
let kind: int = llvm::LLVMGetTypeKind(ty);
|
||||
|
||||
fn tys_str(names: type_names, outer: &[TypeRef],
|
||||
tys: &[TypeRef]) -> istr {
|
||||
let s: istr = ~"";
|
||||
fn tys_str(names: type_names, outer: &[TypeRef], tys: &[TypeRef]) -> str {
|
||||
let s: str = "";
|
||||
let first: bool = true;
|
||||
for t: TypeRef in tys {
|
||||
if first { first = false; } else { s += ~", "; }
|
||||
if first { first = false; } else { s += ", "; }
|
||||
s += type_to_str_inner(names, outer, t);
|
||||
}
|
||||
ret s;
|
||||
|
@ -965,81 +956,87 @@ fn type_to_str_inner(names: type_names, outer0: &[TypeRef], ty: TypeRef) ->
|
|||
|
||||
|
||||
|
||||
|
||||
// FIXME: more enum-as-int constants determined from Core::h;
|
||||
// horrible, horrible. Complete as needed.
|
||||
|
||||
0 {
|
||||
ret ~"Void";
|
||||
ret "Void";
|
||||
}
|
||||
1 { ret ~"Float"; }
|
||||
2 { ret ~"Double"; }
|
||||
3 { ret ~"X86_FP80"; }
|
||||
4 { ret ~"FP128"; }
|
||||
5 { ret ~"PPC_FP128"; }
|
||||
6 { ret ~"Label"; }
|
||||
1 { ret "Float"; }
|
||||
2 { ret "Double"; }
|
||||
3 { ret "X86_FP80"; }
|
||||
4 { ret "FP128"; }
|
||||
5 { ret "PPC_FP128"; }
|
||||
6 { ret "Label"; }
|
||||
|
||||
|
||||
|
||||
|
||||
7 {
|
||||
ret ~"i" + std::int::str(
|
||||
llvm::LLVMGetIntTypeWidth(ty) as int);
|
||||
ret "i" + std::int::str(llvm::LLVMGetIntTypeWidth(ty) as int);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
8 {
|
||||
let s = ~"fn(";
|
||||
let s = "fn(";
|
||||
let out_ty: TypeRef = llvm::LLVMGetReturnType(ty);
|
||||
let n_args: uint = llvm::LLVMCountParamTypes(ty);
|
||||
let args: [TypeRef] = vec::init_elt::<TypeRef>(0 as TypeRef, n_args);
|
||||
llvm::LLVMGetParamTypes(ty, vec::to_ptr(args));
|
||||
s += tys_str(names, outer, args);
|
||||
s += ~") -> ";
|
||||
s += ") -> ";
|
||||
s += type_to_str_inner(names, outer, out_ty);
|
||||
ret s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
9 {
|
||||
let s: istr = ~"{";
|
||||
let s: str = "{";
|
||||
let n_elts: uint = llvm::LLVMCountStructElementTypes(ty);
|
||||
let elts: [TypeRef] = vec::init_elt::<TypeRef>(0 as TypeRef, n_elts);
|
||||
llvm::LLVMGetStructElementTypes(ty, vec::to_ptr(elts));
|
||||
s += tys_str(names, outer, elts);
|
||||
s += ~"}";
|
||||
s += "}";
|
||||
ret s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
10 {
|
||||
let el_ty = llvm::LLVMGetElementType(ty);
|
||||
ret ~"[" + type_to_str_inner(names, outer, el_ty) + ~"]";
|
||||
ret "[" + type_to_str_inner(names, outer, el_ty) + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
11 {
|
||||
let i: uint = 0u;
|
||||
for tout: TypeRef in outer0 {
|
||||
i += 1u;
|
||||
if tout as int == ty as int {
|
||||
let n: uint = vec::len::<TypeRef>(outer0) - i;
|
||||
ret ~"*\\" + std::int::str(n as int);
|
||||
ret "*\\" + std::int::str(n as int);
|
||||
}
|
||||
}
|
||||
ret ~"*" +
|
||||
ret "*" +
|
||||
type_to_str_inner(names, outer, llvm::LLVMGetElementType(ty));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
12 {
|
||||
ret ~"Opaque";
|
||||
ret "Opaque";
|
||||
}
|
||||
13 { ret ~"Vector"; }
|
||||
14 { ret ~"Metadata"; }
|
||||
13 { ret "Vector"; }
|
||||
14 { ret "Metadata"; }
|
||||
_ { log_err #fmt["unknown TypeKind %d", kind as int]; fail; }
|
||||
}
|
||||
}
|
||||
|
@ -1069,10 +1066,9 @@ resource target_data_res(TD: TargetDataRef) {
|
|||
|
||||
type target_data = {lltd: TargetDataRef, dtor: @target_data_res};
|
||||
|
||||
fn mk_target_data(string_rep: &istr) -> target_data {
|
||||
let lltd = str::as_buf(string_rep, { |buf|
|
||||
llvm::LLVMCreateTargetData(buf)
|
||||
});
|
||||
fn mk_target_data(string_rep: &str) -> target_data {
|
||||
let lltd =
|
||||
str::as_buf(string_rep, {|buf| llvm::LLVMCreateTargetData(buf) });
|
||||
ret {lltd: lltd, dtor: @target_data_res(lltd)};
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ const tag_items_data_item_inlineness: uint = 0x27u;
|
|||
// djb's cdb hashes.
|
||||
fn hash_node_id(node_id: &int) -> uint { ret 177573u ^ (node_id as uint); }
|
||||
|
||||
fn hash_path(s: &istr) -> uint {
|
||||
fn hash_path(s: &str) -> uint {
|
||||
let h = 5381u;
|
||||
for ch: u8 in str::bytes(s) { h = (h << 5u) + h ^ (ch as uint); }
|
||||
ret h;
|
||||
|
|
|
@ -34,8 +34,7 @@ fn read_crates(sess: session::session, crate: &ast::crate) {
|
|||
let e =
|
||||
@{sess: sess,
|
||||
crate_cache: @std::map::new_str_hash::<int>(),
|
||||
library_search_paths:
|
||||
sess.get_opts().library_search_paths,
|
||||
library_search_paths: sess.get_opts().library_search_paths,
|
||||
mutable next_crate_num: 1};
|
||||
let v =
|
||||
visit::mk_simple_visitor(@{visit_view_item:
|
||||
|
@ -47,8 +46,8 @@ fn read_crates(sess: session::session, crate: &ast::crate) {
|
|||
|
||||
type env =
|
||||
@{sess: session::session,
|
||||
crate_cache: @hashmap<istr, int>,
|
||||
library_search_paths: [istr],
|
||||
crate_cache: @hashmap<str, int>,
|
||||
library_search_paths: [str],
|
||||
mutable next_crate_num: ast::crate_num};
|
||||
|
||||
fn visit_view_item(e: env, i: &@ast::view_item) {
|
||||
|
@ -68,14 +67,11 @@ fn visit_item(e: env, i: &@ast::item) {
|
|||
ret;
|
||||
}
|
||||
let cstore = e.sess.get_cstore();
|
||||
if !cstore::add_used_library(cstore,
|
||||
m.native_name) { ret; }
|
||||
if !cstore::add_used_library(cstore, m.native_name) { ret; }
|
||||
for a: ast::attribute in
|
||||
attr::find_attrs_by_name(i.attrs, ~"link_args") {
|
||||
attr::find_attrs_by_name(i.attrs, "link_args") {
|
||||
alt attr::get_meta_item_value_str(attr::attr_meta(a)) {
|
||||
some(linkarg) {
|
||||
cstore::add_used_link_args(cstore, linkarg);
|
||||
}
|
||||
some(linkarg) { cstore::add_used_link_args(cstore, linkarg); }
|
||||
none. {/* fallthrough */ }
|
||||
}
|
||||
}
|
||||
|
@ -85,12 +81,11 @@ fn visit_item(e: env, i: &@ast::item) {
|
|||
}
|
||||
|
||||
// A diagnostic function for dumping crate metadata to an output stream
|
||||
fn list_file_metadata(path: &istr, out: io::writer) {
|
||||
fn list_file_metadata(path: &str, out: io::writer) {
|
||||
alt get_metadata_section(path) {
|
||||
option::some(bytes) { decoder::list_crate_metadata(bytes, out); }
|
||||
option::none. {
|
||||
out.write_str(
|
||||
~"Could not find metadata in " + path + ~".\n");
|
||||
out.write_str("Could not find metadata in " + path + ".\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,8 +99,7 @@ fn metadata_matches(crate_data: &@[u8], metas: &[@ast::meta_item]) -> bool {
|
|||
|
||||
for needed: @ast::meta_item in metas {
|
||||
if !attr::contains(linkage_metas, needed) {
|
||||
log #fmt["missing %s",
|
||||
pprust::meta_item_to_str(*needed)];
|
||||
log #fmt["missing %s", pprust::meta_item_to_str(*needed)];
|
||||
ret false;
|
||||
}
|
||||
}
|
||||
|
@ -113,19 +107,18 @@ fn metadata_matches(crate_data: &@[u8], metas: &[@ast::meta_item]) -> bool {
|
|||
}
|
||||
|
||||
fn default_native_lib_naming(sess: session::session, static: bool) ->
|
||||
{prefix: istr, suffix: istr} {
|
||||
if static { ret {prefix: ~"lib", suffix: ~".rlib"}; }
|
||||
{prefix: str, suffix: str} {
|
||||
if static { ret {prefix: "lib", suffix: ".rlib"}; }
|
||||
alt sess.get_targ_cfg().os {
|
||||
session::os_win32. { ret {prefix: ~"", suffix: ~".dll"}; }
|
||||
session::os_macos. { ret {prefix: ~"lib", suffix: ~".dylib"}; }
|
||||
session::os_linux. { ret {prefix: ~"lib", suffix: ~".so"}; }
|
||||
session::os_win32. { ret {prefix: "", suffix: ".dll"}; }
|
||||
session::os_macos. { ret {prefix: "lib", suffix: ".dylib"}; }
|
||||
session::os_linux. { ret {prefix: "lib", suffix: ".so"}; }
|
||||
}
|
||||
}
|
||||
|
||||
fn find_library_crate(sess: &session::session, ident: &ast::ident,
|
||||
metas: &[@ast::meta_item],
|
||||
library_search_paths: &[istr])
|
||||
-> option::t<{ident: istr, data: @[u8]}> {
|
||||
metas: &[@ast::meta_item], library_search_paths: &[str])
|
||||
-> option::t<{ident: str, data: @[u8]}> {
|
||||
|
||||
attr::require_unique_names(sess, metas);
|
||||
|
||||
|
@ -133,7 +126,7 @@ fn find_library_crate(sess: &session::session, ident: &ast::ident,
|
|||
// is using the wrong type of meta item
|
||||
let crate_name =
|
||||
{
|
||||
let name_items = attr::find_meta_items_by_name(metas, ~"name");
|
||||
let name_items = attr::find_meta_items_by_name(metas, "name");
|
||||
alt vec::last(name_items) {
|
||||
some(i) {
|
||||
alt attr::get_meta_item_value_str(i) {
|
||||
|
@ -147,49 +140,41 @@ fn find_library_crate(sess: &session::session, ident: &ast::ident,
|
|||
|
||||
let nn = default_native_lib_naming(sess, sess.get_opts().static);
|
||||
let x =
|
||||
find_library_crate_aux(nn, crate_name,
|
||||
metas, library_search_paths);
|
||||
find_library_crate_aux(nn, crate_name, metas, library_search_paths);
|
||||
if x != none || sess.get_opts().static { ret x; }
|
||||
let nn2 = default_native_lib_naming(sess, true);
|
||||
ret find_library_crate_aux(nn2, crate_name,
|
||||
metas, library_search_paths);
|
||||
ret find_library_crate_aux(nn2, crate_name, metas, library_search_paths);
|
||||
}
|
||||
|
||||
fn find_library_crate_aux(nn: &{prefix: istr, suffix: istr},
|
||||
crate_name: &istr,
|
||||
fn find_library_crate_aux(nn: &{prefix: str, suffix: str}, crate_name: &str,
|
||||
metas: &[@ast::meta_item],
|
||||
library_search_paths: &[istr]) ->
|
||||
option::t<{ident: istr, data: @[u8]}> {
|
||||
let prefix: istr = nn.prefix + crate_name;
|
||||
let suffix: istr = nn.suffix;
|
||||
library_search_paths: &[str]) ->
|
||||
option::t<{ident: str, data: @[u8]}> {
|
||||
let prefix: str = nn.prefix + crate_name;
|
||||
let suffix: str = nn.suffix;
|
||||
// FIXME: we could probably use a 'glob' function in std::fs but it will
|
||||
// be much easier to write once the unsafe module knows more about FFI
|
||||
// tricks. Currently the glob(3) interface is a bit more than we can
|
||||
// stomach from here, and writing a C++ wrapper is more work than just
|
||||
// manually filtering fs::list_dir here.
|
||||
|
||||
for library_search_path: istr in library_search_paths {
|
||||
for library_search_path: str in library_search_paths {
|
||||
log #fmt["searching %s", library_search_path];
|
||||
for path: istr in fs::list_dir(library_search_path) {
|
||||
for path: str in fs::list_dir(library_search_path) {
|
||||
log #fmt["searching %s", path];
|
||||
let f: istr = fs::basename(path);
|
||||
if !(str::starts_with(f, prefix) && str::ends_with(f, suffix))
|
||||
{
|
||||
log #fmt["skipping %s, doesn't look like %s*%s",
|
||||
path,
|
||||
prefix,
|
||||
let f: str = fs::basename(path);
|
||||
if !(str::starts_with(f, prefix) && str::ends_with(f, suffix)) {
|
||||
log #fmt["skipping %s, doesn't look like %s*%s", path, prefix,
|
||||
suffix];
|
||||
cont;
|
||||
}
|
||||
alt get_metadata_section(path) {
|
||||
option::some(cvec) {
|
||||
if !metadata_matches(cvec, metas) {
|
||||
log #fmt["skipping %s, metadata doesn't match",
|
||||
path];
|
||||
log #fmt["skipping %s, metadata doesn't match", path];
|
||||
cont;
|
||||
}
|
||||
log #fmt["found %s with matching metadata",
|
||||
path];
|
||||
log #fmt["found %s with matching metadata", path];
|
||||
ret some({ident: path, data: cvec});
|
||||
}
|
||||
_ { }
|
||||
|
@ -199,10 +184,11 @@ fn find_library_crate_aux(nn: &{prefix: istr, suffix: istr},
|
|||
ret none;
|
||||
}
|
||||
|
||||
fn get_metadata_section(filename: &istr) -> option::t<@[u8]> {
|
||||
let mb = str::as_buf(filename, { |buf|
|
||||
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
|
||||
});
|
||||
fn get_metadata_section(filename: &str) -> option::t<@[u8]> {
|
||||
let mb =
|
||||
str::as_buf(filename, {|buf|
|
||||
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
|
||||
});
|
||||
if mb as int == 0 { ret option::none::<@[u8]>; }
|
||||
let of = mk_object_file(mb);
|
||||
let si = mk_section_iter(of.llof);
|
||||
|
@ -221,17 +207,14 @@ fn get_metadata_section(filename: &istr) -> option::t<@[u8]> {
|
|||
}
|
||||
|
||||
fn load_library_crate(sess: &session::session, span: span, ident: &ast::ident,
|
||||
metas: &[@ast::meta_item],
|
||||
library_search_paths: &[istr])
|
||||
-> {ident: istr, data: @[u8]} {
|
||||
metas: &[@ast::meta_item], library_search_paths: &[str])
|
||||
-> {ident: str, data: @[u8]} {
|
||||
|
||||
|
||||
alt find_library_crate(sess, ident, metas, library_search_paths) {
|
||||
some(t) { ret t; }
|
||||
none. {
|
||||
sess.span_fatal(span,
|
||||
#fmt["can't find crate for '%s'",
|
||||
ident]);
|
||||
sess.span_fatal(span, #fmt["can't find crate for '%s'", ident]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -254,13 +237,11 @@ fn resolve_crate(e: env, ident: &ast::ident, metas: [@ast::meta_item],
|
|||
// Now resolve the crates referenced by this crate
|
||||
let cnum_map = resolve_crate_deps(e, cdata);
|
||||
|
||||
let cmeta = {name: ident,
|
||||
data: cdata, cnum_map: cnum_map};
|
||||
let cmeta = {name: ident, data: cdata, cnum_map: cnum_map};
|
||||
|
||||
let cstore = e.sess.get_cstore();
|
||||
cstore::set_crate_data(cstore, cnum, cmeta);
|
||||
cstore::add_used_crate_file(cstore,
|
||||
cfilename);
|
||||
cstore::add_used_crate_file(cstore, cfilename);
|
||||
ret cnum;
|
||||
} else { ret e.crate_cache.get(ident); }
|
||||
}
|
||||
|
@ -285,9 +266,7 @@ fn resolve_crate_deps(e: env, cdata: &@[u8]) -> cstore::cnum_map {
|
|||
// This is a new one so we've got to load it
|
||||
// FIXME: Need better error reporting than just a bogus span
|
||||
let fake_span = ast_util::dummy_sp();
|
||||
let local_cnum = resolve_crate(e,
|
||||
cname,
|
||||
[], fake_span);
|
||||
let local_cnum = resolve_crate(e, cname, [], fake_span);
|
||||
cnum_map.insert(extrn_cnum, local_cnum);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ export lookup_defs;
|
|||
export get_tag_variants;
|
||||
export get_type;
|
||||
|
||||
fn get_symbol(cstore: &cstore::cstore, def: ast::def_id) -> istr {
|
||||
fn get_symbol(cstore: &cstore::cstore, def: ast::def_id) -> str {
|
||||
let cdata = cstore::get_crate_data(cstore, def.crate).data;
|
||||
ret decoder::get_symbol(cdata, def.node);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ fn translate_def_id(sess: &session::session, searched_crate: ast::crate_num,
|
|||
let local_cnum =
|
||||
alt cmeta.cnum_map.find(ext_cnum) {
|
||||
option::some(n) { n }
|
||||
option::none. { sess.bug(~"didn't find a crate in the cnum_map") }
|
||||
option::none. { sess.bug("didn't find a crate in the cnum_map") }
|
||||
};
|
||||
|
||||
ret {crate: local_cnum, node: node_id};
|
||||
|
|
|
@ -29,7 +29,7 @@ export get_use_stmt_cnum;
|
|||
// own crate numbers.
|
||||
type cnum_map = map::hashmap<ast::crate_num, ast::crate_num>;
|
||||
|
||||
type crate_metadata = {name: istr, data: @[u8], cnum_map: cnum_map};
|
||||
type crate_metadata = {name: str, data: @[u8], cnum_map: cnum_map};
|
||||
|
||||
// This is a bit of an experiment at encapsulating the data in cstore. By
|
||||
// keeping all the data in a non-exported tag variant, it's impossible for
|
||||
|
@ -41,9 +41,9 @@ tag cstore { private(cstore_private); }
|
|||
type cstore_private =
|
||||
@{metas: map::hashmap<ast::crate_num, crate_metadata>,
|
||||
use_crate_map: use_crate_map,
|
||||
mutable used_crate_files: [istr],
|
||||
mutable used_libraries: [istr],
|
||||
mutable used_link_args: [istr]};
|
||||
mutable used_crate_files: [str],
|
||||
mutable used_libraries: [str],
|
||||
mutable used_link_args: [str]};
|
||||
|
||||
// Map from node_id's of local use statements to crate numbers
|
||||
type use_crate_map = map::hashmap<ast::node_id, ast::crate_num>;
|
||||
|
@ -82,18 +82,18 @@ iter iter_crate_data(cstore: &cstore) ->
|
|||
}
|
||||
}
|
||||
|
||||
fn add_used_crate_file(cstore: &cstore, lib: &istr) {
|
||||
fn add_used_crate_file(cstore: &cstore, lib: &str) {
|
||||
if !vec::member(lib, p(cstore).used_crate_files) {
|
||||
p(cstore).used_crate_files += [lib];
|
||||
}
|
||||
}
|
||||
|
||||
fn get_used_crate_files(cstore: &cstore) -> [istr] {
|
||||
fn get_used_crate_files(cstore: &cstore) -> [str] {
|
||||
ret p(cstore).used_crate_files;
|
||||
}
|
||||
|
||||
fn add_used_library(cstore: &cstore, lib: &istr) -> bool {
|
||||
if lib == ~"" { ret false; }
|
||||
fn add_used_library(cstore: &cstore, lib: &str) -> bool {
|
||||
if lib == "" { ret false; }
|
||||
|
||||
if vec::member(lib, p(cstore).used_libraries) { ret false; }
|
||||
|
||||
|
@ -101,15 +101,15 @@ fn add_used_library(cstore: &cstore, lib: &istr) -> bool {
|
|||
ret true;
|
||||
}
|
||||
|
||||
fn get_used_libraries(cstore: &cstore) -> [istr] {
|
||||
fn get_used_libraries(cstore: &cstore) -> [str] {
|
||||
ret p(cstore).used_libraries;
|
||||
}
|
||||
|
||||
fn add_used_link_args(cstore: &cstore, args: &istr) {
|
||||
fn add_used_link_args(cstore: &cstore, args: &str) {
|
||||
p(cstore).used_link_args += str::split(args, ' ' as u8);
|
||||
}
|
||||
|
||||
fn get_used_link_args(cstore: &cstore) -> [istr] {
|
||||
fn get_used_link_args(cstore: &cstore) -> [str] {
|
||||
ret p(cstore).used_link_args;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ fn item_family(item: &ebml::doc) -> u8 {
|
|||
ret ebml::doc_as_uint(fam) as u8;
|
||||
}
|
||||
|
||||
fn item_symbol(item: &ebml::doc) -> istr {
|
||||
fn item_symbol(item: &ebml::doc) -> str {
|
||||
let sym = ebml::get_doc(item, tag_items_data_item_symbol);
|
||||
ret str::unsafe_from_bytes(ebml::doc_data(sym));
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ fn variant_tag_id(d: &ebml::doc) -> ast::def_id {
|
|||
fn item_type(item: &ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
|
||||
extres: &external_resolver) -> ty::t {
|
||||
fn parse_external_def_id(this_cnum: ast::crate_num,
|
||||
extres: &external_resolver, s: &istr) ->
|
||||
extres: &external_resolver, s: &str) ->
|
||||
ast::def_id {
|
||||
let buf = str::bytes(s);
|
||||
let external_def_id = parse_def_id(buf);
|
||||
|
@ -149,16 +149,15 @@ fn tag_variant_ids(item: &ebml::doc, this_cnum: ast::crate_num) ->
|
|||
// Given a path and serialized crate metadata, returns the ID of the
|
||||
// definition the path refers to.
|
||||
fn resolve_path(path: &[ast::ident], data: @[u8]) -> [ast::def_id] {
|
||||
fn eq_item(data: &[u8], s: &istr) -> bool {
|
||||
fn eq_item(data: &[u8], s: &str) -> bool {
|
||||
ret str::eq(str::unsafe_from_bytes(data), s);
|
||||
}
|
||||
let s = str::connect(path, ~"::");
|
||||
let s = str::connect(path, "::");
|
||||
let md = ebml::new_doc(data);
|
||||
let paths = ebml::get_doc(md, tag_paths);
|
||||
let eqer = bind eq_item(_, s);
|
||||
let result: [ast::def_id] = [];
|
||||
for doc: ebml::doc in lookup_hash(paths, eqer,
|
||||
hash_path(s)) {
|
||||
for doc: ebml::doc in lookup_hash(paths, eqer, hash_path(s)) {
|
||||
let did_doc = ebml::get_doc(doc, tag_def_id);
|
||||
result += [parse_def_id(ebml::doc_data(did_doc))];
|
||||
}
|
||||
|
@ -222,7 +221,7 @@ fn get_type_param_kinds(data: @[u8], id: ast::node_id) -> [ast::kind] {
|
|||
ret item_ty_param_kinds(lookup_item(id, data));
|
||||
}
|
||||
|
||||
fn get_symbol(data: @[u8], id: ast::node_id) -> istr {
|
||||
fn get_symbol(data: @[u8], id: ast::node_id) -> str {
|
||||
ret item_symbol(lookup_item(id, data));
|
||||
}
|
||||
|
||||
|
@ -268,7 +267,7 @@ fn family_has_type_params(fam_ch: u8) -> bool {
|
|||
};
|
||||
}
|
||||
|
||||
fn read_path(d: &ebml::doc) -> {path: istr, pos: uint} {
|
||||
fn read_path(d: &ebml::doc) -> {path: str, pos: uint} {
|
||||
let desc = ebml::doc_data(d);
|
||||
let pos = ebml::be_uint_from_bytes(@desc, 0u, 4u);
|
||||
let pathbytes = vec::slice::<u8>(desc, 4u, vec::len::<u8>(desc));
|
||||
|
@ -276,23 +275,23 @@ fn read_path(d: &ebml::doc) -> {path: istr, pos: uint} {
|
|||
ret {path: path, pos: pos};
|
||||
}
|
||||
|
||||
fn describe_def(items: &ebml::doc, id: ast::def_id) -> istr {
|
||||
if id.crate != ast::local_crate { ret ~"external"; }
|
||||
fn describe_def(items: &ebml::doc, id: ast::def_id) -> str {
|
||||
if id.crate != ast::local_crate { ret "external"; }
|
||||
ret item_family_to_str(item_family(find_item(id.node, items)));
|
||||
}
|
||||
|
||||
fn item_family_to_str(fam: u8) -> istr {
|
||||
fn item_family_to_str(fam: u8) -> str {
|
||||
alt fam as char {
|
||||
'c' { ret ~"const"; }
|
||||
'f' { ret ~"fn"; }
|
||||
'p' { ret ~"pure fn"; }
|
||||
'F' { ret ~"native fn"; }
|
||||
'y' { ret ~"type"; }
|
||||
'T' { ret ~"native type"; }
|
||||
't' { ret ~"type"; }
|
||||
'm' { ret ~"mod"; }
|
||||
'n' { ret ~"native mod"; }
|
||||
'v' { ret ~"tag"; }
|
||||
'c' { ret "const"; }
|
||||
'f' { ret "fn"; }
|
||||
'p' { ret "pure fn"; }
|
||||
'F' { ret "native fn"; }
|
||||
'y' { ret "type"; }
|
||||
'T' { ret "native type"; }
|
||||
't' { ret "type"; }
|
||||
'm' { ret "mod"; }
|
||||
'n' { ret "native mod"; }
|
||||
'v' { ret "tag"; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,29 +346,25 @@ fn get_attributes(md: &ebml::doc) -> [ast::attribute] {
|
|||
|
||||
fn list_meta_items(meta_items: &ebml::doc, out: io::writer) {
|
||||
for mi: @ast::meta_item in get_meta_items(meta_items) {
|
||||
out.write_str(
|
||||
#fmt["%s\n",
|
||||
pprust::meta_item_to_str(*mi)]);
|
||||
out.write_str(#fmt["%s\n", pprust::meta_item_to_str(*mi)]);
|
||||
}
|
||||
}
|
||||
|
||||
fn list_crate_attributes(md: &ebml::doc, out: io::writer) {
|
||||
out.write_str(~"=Crate Attributes=\n");
|
||||
out.write_str("=Crate Attributes=\n");
|
||||
|
||||
for attr: ast::attribute in get_attributes(md) {
|
||||
out.write_str(
|
||||
#fmt["%s\n",
|
||||
pprust::attribute_to_str(attr)]);
|
||||
out.write_str(#fmt["%s\n", pprust::attribute_to_str(attr)]);
|
||||
}
|
||||
|
||||
out.write_str(~"\n\n");
|
||||
out.write_str("\n\n");
|
||||
}
|
||||
|
||||
fn get_crate_attributes(data: @[u8]) -> [ast::attribute] {
|
||||
ret get_attributes(ebml::new_doc(data));
|
||||
}
|
||||
|
||||
type crate_dep = {cnum: ast::crate_num, ident: istr};
|
||||
type crate_dep = {cnum: ast::crate_num, ident: str};
|
||||
|
||||
fn get_crate_deps(data: @[u8]) -> [crate_dep] {
|
||||
let deps: [crate_dep] = [];
|
||||
|
@ -385,19 +380,17 @@ fn get_crate_deps(data: @[u8]) -> [crate_dep] {
|
|||
}
|
||||
|
||||
fn list_crate_deps(data: @[u8], out: io::writer) {
|
||||
out.write_str(~"=External Dependencies=\n");
|
||||
out.write_str("=External Dependencies=\n");
|
||||
|
||||
for dep: crate_dep in get_crate_deps(data) {
|
||||
out.write_str(
|
||||
#fmt["%d %s\n", dep.cnum,
|
||||
dep.ident]);
|
||||
out.write_str(#fmt["%d %s\n", dep.cnum, dep.ident]);
|
||||
}
|
||||
|
||||
out.write_str(~"\n");
|
||||
out.write_str("\n");
|
||||
}
|
||||
|
||||
fn list_crate_items(bytes: &@[u8], md: &ebml::doc, out: io::writer) {
|
||||
out.write_str(~"=Items=\n");
|
||||
out.write_str("=Items=\n");
|
||||
let paths = ebml::get_doc(md, tag_paths);
|
||||
let items = ebml::get_doc(md, tag_items);
|
||||
let index = ebml::get_doc(paths, tag_index);
|
||||
|
@ -410,13 +403,11 @@ fn list_crate_items(bytes: &@[u8], md: &ebml::doc, out: io::writer) {
|
|||
let def = ebml::doc_at(bytes, data.pos);
|
||||
let did_doc = ebml::get_doc(def, tag_def_id);
|
||||
let did = parse_def_id(ebml::doc_data(did_doc));
|
||||
out.write_str(
|
||||
#fmt["%s (%s)\n",
|
||||
data.path,
|
||||
describe_def(items, did)]);
|
||||
out.write_str(#fmt["%s (%s)\n", data.path,
|
||||
describe_def(items, did)]);
|
||||
}
|
||||
}
|
||||
out.write_str(~"\n");
|
||||
out.write_str("\n");
|
||||
}
|
||||
|
||||
fn list_crate_metadata(bytes: &@[u8], out: io::writer) {
|
||||
|
|
|
@ -26,7 +26,7 @@ type abbrev_map = map::hashmap<ty::t, tyencode::ty_abbrev>;
|
|||
type encode_ctxt = {ccx: @crate_ctxt, type_abbrevs: abbrev_map};
|
||||
|
||||
// Path table encoding
|
||||
fn encode_name(ebml_w: &ebml::writer, name: &istr) {
|
||||
fn encode_name(ebml_w: &ebml::writer, name: &str) {
|
||||
ebml::start_tag(ebml_w, tag_paths_data_name);
|
||||
ebml_w.writer.write(str::bytes(name));
|
||||
ebml::end_tag(ebml_w);
|
||||
|
@ -41,7 +41,7 @@ fn encode_def_id(ebml_w: &ebml::writer, id: &def_id) {
|
|||
type entry<T> = {val: T, pos: uint};
|
||||
|
||||
fn encode_tag_variant_paths(ebml_w: &ebml::writer, variants: &[variant],
|
||||
path: &[istr], index: &mutable [entry<istr>]) {
|
||||
path: &[str], index: &mutable [entry<str>]) {
|
||||
for variant: variant in variants {
|
||||
add_to_index(ebml_w, path, index, variant.node.name);
|
||||
ebml::start_tag(ebml_w, tag_paths_data_item);
|
||||
|
@ -51,16 +51,16 @@ fn encode_tag_variant_paths(ebml_w: &ebml::writer, variants: &[variant],
|
|||
}
|
||||
}
|
||||
|
||||
fn add_to_index(ebml_w: &ebml::writer, path: &[istr],
|
||||
index: &mutable [entry<istr>], name: &istr) {
|
||||
fn add_to_index(ebml_w: &ebml::writer, path: &[str],
|
||||
index: &mutable [entry<str>], name: &str) {
|
||||
let full_path = path + [name];
|
||||
index +=
|
||||
[{val: str::connect(full_path, ~"::"), pos: ebml_w.writer.tell()}];
|
||||
[{val: str::connect(full_path, "::"), pos: ebml_w.writer.tell()}];
|
||||
}
|
||||
|
||||
fn encode_native_module_item_paths(ebml_w: &ebml::writer, nmod: &native_mod,
|
||||
path: &[istr],
|
||||
index: &mutable [entry<istr>]) {
|
||||
path: &[str],
|
||||
index: &mutable [entry<str>]) {
|
||||
for nitem: @native_item in nmod.items {
|
||||
add_to_index(ebml_w, path, index, nitem.ident);
|
||||
ebml::start_tag(ebml_w, tag_paths_data_item);
|
||||
|
@ -71,7 +71,7 @@ fn encode_native_module_item_paths(ebml_w: &ebml::writer, nmod: &native_mod,
|
|||
}
|
||||
|
||||
fn encode_module_item_paths(ebml_w: &ebml::writer, module: &_mod,
|
||||
path: &[istr], index: &mutable [entry<istr>]) {
|
||||
path: &[str], index: &mutable [entry<str>]) {
|
||||
for it: @item in module.items {
|
||||
if !ast_util::is_exported(it.ident, module) { cont; }
|
||||
alt it.node {
|
||||
|
@ -94,9 +94,7 @@ fn encode_module_item_paths(ebml_w: &ebml::writer, module: &_mod,
|
|||
ebml::start_tag(ebml_w, tag_paths_data_mod);
|
||||
encode_name(ebml_w, it.ident);
|
||||
encode_def_id(ebml_w, local_def(it.id));
|
||||
encode_module_item_paths(ebml_w, _mod,
|
||||
path + [it.ident],
|
||||
index);
|
||||
encode_module_item_paths(ebml_w, _mod, path + [it.ident], index);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
item_native_mod(nmod) {
|
||||
|
@ -104,10 +102,8 @@ fn encode_module_item_paths(ebml_w: &ebml::writer, module: &_mod,
|
|||
ebml::start_tag(ebml_w, tag_paths_data_mod);
|
||||
encode_name(ebml_w, it.ident);
|
||||
encode_def_id(ebml_w, local_def(it.id));
|
||||
encode_native_module_item_paths(
|
||||
ebml_w, nmod,
|
||||
path + [it.ident],
|
||||
index);
|
||||
encode_native_module_item_paths(ebml_w, nmod, path + [it.ident],
|
||||
index);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
item_ty(_, tps) {
|
||||
|
@ -153,9 +149,9 @@ fn encode_module_item_paths(ebml_w: &ebml::writer, module: &_mod,
|
|||
}
|
||||
}
|
||||
|
||||
fn encode_item_paths(ebml_w: &ebml::writer, crate: &@crate) -> [entry<istr>] {
|
||||
let index: [entry<istr>] = [];
|
||||
let path: [istr] = [];
|
||||
fn encode_item_paths(ebml_w: &ebml::writer, crate: &@crate) -> [entry<str>] {
|
||||
let index: [entry<str>] = [];
|
||||
let path: [str] = [];
|
||||
ebml::start_tag(ebml_w, tag_paths);
|
||||
encode_module_item_paths(ebml_w, crate.node.module, path, index);
|
||||
ebml::end_tag(ebml_w);
|
||||
|
@ -176,9 +172,7 @@ fn encode_inlineness(ebml_w: &ebml::writer, c: u8) {
|
|||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn def_to_str(did: &def_id) -> istr {
|
||||
ret #fmt["%d:%d", did.crate, did.node];
|
||||
}
|
||||
fn def_to_str(did: &def_id) -> str { ret #fmt["%d:%d", did.crate, did.node]; }
|
||||
|
||||
fn encode_type_param_kinds(ebml_w: &ebml::writer, tps: &[ty_param]) {
|
||||
ebml::start_tag(ebml_w, tag_items_data_item_ty_param_kinds);
|
||||
|
@ -441,9 +435,7 @@ fn encode_index<T>(ebml_w: &ebml::writer, buckets: &[@[entry<T>]],
|
|||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn write_str(writer: &io::writer, s: &istr) {
|
||||
writer.write_str(s);
|
||||
}
|
||||
fn write_str(writer: &io::writer, s: &str) { writer.write_str(s); }
|
||||
|
||||
fn write_int(writer: &io::writer, n: &int) {
|
||||
writer.write_be_uint(n as uint, 4u);
|
||||
|
@ -505,24 +497,22 @@ fn synthesize_crate_attrs(ecx: &@encode_ctxt, crate: &@crate) -> [attribute] {
|
|||
fn synthesize_link_attr(ecx: &@encode_ctxt, items: &[@meta_item]) ->
|
||||
attribute {
|
||||
|
||||
assert (ecx.ccx.link_meta.name != ~"");
|
||||
assert (ecx.ccx.link_meta.vers != ~"");
|
||||
assert (ecx.ccx.link_meta.name != "");
|
||||
assert (ecx.ccx.link_meta.vers != "");
|
||||
|
||||
let name_item =
|
||||
attr::mk_name_value_item_str(
|
||||
~"name", ecx.ccx.link_meta.name);
|
||||
attr::mk_name_value_item_str("name", ecx.ccx.link_meta.name);
|
||||
let vers_item =
|
||||
attr::mk_name_value_item_str(
|
||||
~"vers", ecx.ccx.link_meta.vers);
|
||||
attr::mk_name_value_item_str("vers", ecx.ccx.link_meta.vers);
|
||||
|
||||
let other_items =
|
||||
{
|
||||
let tmp = attr::remove_meta_items_by_name(items, ~"name");
|
||||
attr::remove_meta_items_by_name(tmp, ~"vers")
|
||||
let tmp = attr::remove_meta_items_by_name(items, "name");
|
||||
attr::remove_meta_items_by_name(tmp, "vers")
|
||||
};
|
||||
|
||||
let meta_items = [name_item, vers_item] + other_items;
|
||||
let link_item = attr::mk_list_item(~"link", meta_items);
|
||||
let link_item = attr::mk_list_item("link", meta_items);
|
||||
|
||||
ret attr::mk_attr(link_item);
|
||||
}
|
||||
|
@ -531,7 +521,7 @@ fn synthesize_crate_attrs(ecx: &@encode_ctxt, crate: &@crate) -> [attribute] {
|
|||
let found_link_attr = false;
|
||||
for attr: attribute in crate.node.attrs {
|
||||
attrs +=
|
||||
if attr::get_attr_name(attr) != ~"link" {
|
||||
if attr::get_attr_name(attr) != "link" {
|
||||
[attr]
|
||||
} else {
|
||||
alt attr.node.value.node {
|
||||
|
@ -551,9 +541,9 @@ fn synthesize_crate_attrs(ecx: &@encode_ctxt, crate: &@crate) -> [attribute] {
|
|||
|
||||
fn encode_crate_deps(ebml_w: &ebml::writer, cstore: &cstore::cstore) {
|
||||
|
||||
fn get_ordered_names(cstore: &cstore::cstore) -> [istr] {
|
||||
fn get_ordered_names(cstore: &cstore::cstore) -> [str] {
|
||||
type hashkv = @{key: crate_num, val: cstore::crate_metadata};
|
||||
type numname = {crate: crate_num, ident: istr};
|
||||
type numname = {crate: crate_num, ident: str};
|
||||
|
||||
// Pull the cnums and names out of cstore
|
||||
let pairs: [mutable numname] = [mutable];
|
||||
|
@ -575,7 +565,7 @@ fn encode_crate_deps(ebml_w: &ebml::writer, cstore: &cstore::cstore) {
|
|||
}
|
||||
|
||||
// Return just the names
|
||||
fn name(kv: &numname) -> istr { kv.ident }
|
||||
fn name(kv: &numname) -> str { kv.ident }
|
||||
// mutable -> immutable hack for vec::map
|
||||
let immpairs = vec::slice(pairs, 0u, vec::len(pairs));
|
||||
ret vec::map(name, immpairs);
|
||||
|
@ -586,7 +576,7 @@ fn encode_crate_deps(ebml_w: &ebml::writer, cstore: &cstore::cstore) {
|
|||
// FIXME: This is not nearly enough to support correct versioning
|
||||
// but is enough to get transitive crate dependencies working.
|
||||
ebml::start_tag(ebml_w, tag_crate_deps);
|
||||
for cname: istr in get_ordered_names(cstore) {
|
||||
for cname: str in get_ordered_names(cstore) {
|
||||
ebml::start_tag(ebml_w, tag_crate_dep);
|
||||
ebml_w.writer.write(str::bytes(cname));
|
||||
ebml::end_tag(ebml_w);
|
||||
|
@ -594,7 +584,7 @@ fn encode_crate_deps(ebml_w: &ebml::writer, cstore: &cstore::cstore) {
|
|||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn encode_metadata(cx: &@crate_ctxt, crate: &@crate) -> istr {
|
||||
fn encode_metadata(cx: &@crate_ctxt, crate: &@crate) -> str {
|
||||
|
||||
let abbrevs = map::mk_hashmap(ty::hash_ty, ty::eq_ty);
|
||||
let ecx = @{ccx: cx, type_abbrevs: abbrevs};
|
||||
|
@ -630,7 +620,7 @@ fn encode_metadata(cx: &@crate_ctxt, crate: &@crate) -> istr {
|
|||
}
|
||||
|
||||
// Get the encoded string for a type
|
||||
fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> istr {
|
||||
fn encoded_ty(tcx: &ty::ctxt, t: ty::t) -> str {
|
||||
let cx = @{ds: def_to_str, tcx: tcx, abbrevs: tyencode::ac_no_abbrevs};
|
||||
let sw = io::string_writer();
|
||||
tyencode::enc_ty(sw.get_writer(), cx, t);
|
||||
|
|
|
@ -20,7 +20,7 @@ export parse_ty_data;
|
|||
// data buffer. Whatever format you choose should not contain pipe characters.
|
||||
|
||||
// Callback to translate defs to strs or back:
|
||||
type str_def = fn(&istr) -> ast::def_id;
|
||||
type str_def = fn(&str) -> ast::def_id;
|
||||
|
||||
type pstate =
|
||||
{data: @[u8], crate: int, mutable pos: uint, len: uint, tcx: ty::ctxt};
|
||||
|
@ -42,7 +42,7 @@ fn parse_ident(st: @pstate, sd: str_def, last: char) -> ast::ident {
|
|||
|
||||
fn parse_ident_(st: @pstate, _sd: str_def, is_last: fn(char) -> bool) ->
|
||||
ast::ident {
|
||||
let rslt = ~"";
|
||||
let rslt = "";
|
||||
while !is_last(peek(st) as char) {
|
||||
rslt += str::unsafe_from_byte(next(st));
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
|
|||
assert (next(st) as char == '[');
|
||||
let fields: [ty::field] = [];
|
||||
while peek(st) as char != ']' {
|
||||
let name = ~"";
|
||||
let name = "";
|
||||
while peek(st) as char != '=' {
|
||||
name += str::unsafe_from_byte(next(st));
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
|
|||
'W' { proto = ast::proto_iter; }
|
||||
'F' { proto = ast::proto_fn; }
|
||||
}
|
||||
let name = ~"";
|
||||
let name = "";
|
||||
while peek(st) as char != '[' {
|
||||
name += str::unsafe_from_byte(next(st));
|
||||
}
|
||||
|
@ -342,10 +342,8 @@ fn parse_mt(st: @pstate, sd: str_def) -> ty::mt {
|
|||
}
|
||||
|
||||
fn parse_def(st: @pstate, sd: str_def) -> ast::def_id {
|
||||
let def = ~"";
|
||||
while peek(st) as char != '|' {
|
||||
def += str::unsafe_from_byte(next(st));
|
||||
}
|
||||
let def = "";
|
||||
while peek(st) as char != '|' { def += str::unsafe_from_byte(next(st)); }
|
||||
st.pos = st.pos + 1u;
|
||||
ret sd(def);
|
||||
}
|
||||
|
|
|
@ -19,14 +19,14 @@ export ac_use_abbrevs;
|
|||
export enc_ty;
|
||||
|
||||
type ctxt =
|
||||
// Def -> str Callback:
|
||||
// The type context.
|
||||
{ds: fn(&def_id) -> istr, tcx: ty::ctxt, abbrevs: abbrev_ctxt};
|
||||
// Def -> str Callback:
|
||||
// The type context.
|
||||
{ds: fn(&def_id) -> str, tcx: ty::ctxt, abbrevs: abbrev_ctxt};
|
||||
|
||||
// Compact string representation for ty.t values. API ty_str & parse_from_str.
|
||||
// Extra parameters are for converting to/from def_ids in the string rep.
|
||||
// Whatever format you choose should not contain pipe characters.
|
||||
type ty_abbrev = {pos: uint, len: uint, s: @istr};
|
||||
type ty_abbrev = {pos: uint, len: uint, s: @str};
|
||||
|
||||
tag abbrev_ctxt { ac_no_abbrevs; ac_use_abbrevs(hashmap<ty::t, ty_abbrev>); }
|
||||
|
||||
|
@ -40,7 +40,7 @@ fn cx_uses_abbrevs(cx: &@ctxt) -> bool {
|
|||
fn enc_ty(w: &io::writer, cx: &@ctxt, t: ty::t) {
|
||||
alt cx.abbrevs {
|
||||
ac_no_abbrevs. {
|
||||
let result_str: @istr;
|
||||
let result_str: @str;
|
||||
alt cx.tcx.short_names_cache.find(t) {
|
||||
some(s) { result_str = s; }
|
||||
none. {
|
||||
|
@ -71,8 +71,8 @@ fn enc_ty(w: &io::writer, cx: &@ctxt, t: ty::t) {
|
|||
// I.e. it's actually an abbreviation.
|
||||
|
||||
let s =
|
||||
~"#" + uint::to_str(pos, 16u) + ~":" +
|
||||
uint::to_str(len, 16u) + ~"#";
|
||||
"#" + uint::to_str(pos, 16u) + ":" +
|
||||
uint::to_str(len, 16u) + "#";
|
||||
let a = {pos: pos, len: len, s: @s};
|
||||
abbrevs.insert(t, a);
|
||||
}
|
||||
|
@ -100,29 +100,29 @@ fn enc_sty(w: &io::writer, cx: &@ctxt, st: &ty::sty) {
|
|||
ty::ty_float. { w.write_char('l'); }
|
||||
ty::ty_machine(mach) {
|
||||
alt mach {
|
||||
ty_u8. { w.write_str(~"Mb"); }
|
||||
ty_u16. { w.write_str(~"Mw"); }
|
||||
ty_u32. { w.write_str(~"Ml"); }
|
||||
ty_u64. { w.write_str(~"Md"); }
|
||||
ty_i8. { w.write_str(~"MB"); }
|
||||
ty_i16. { w.write_str(~"MW"); }
|
||||
ty_i32. { w.write_str(~"ML"); }
|
||||
ty_i64. { w.write_str(~"MD"); }
|
||||
ty_f32. { w.write_str(~"Mf"); }
|
||||
ty_f64. { w.write_str(~"MF"); }
|
||||
ty_u8. { w.write_str("Mb"); }
|
||||
ty_u16. { w.write_str("Mw"); }
|
||||
ty_u32. { w.write_str("Ml"); }
|
||||
ty_u64. { w.write_str("Md"); }
|
||||
ty_i8. { w.write_str("MB"); }
|
||||
ty_i16. { w.write_str("MW"); }
|
||||
ty_i32. { w.write_str("ML"); }
|
||||
ty_i64. { w.write_str("MD"); }
|
||||
ty_f32. { w.write_str("Mf"); }
|
||||
ty_f64. { w.write_str("MF"); }
|
||||
}
|
||||
}
|
||||
ty::ty_char. { w.write_char('c'); }
|
||||
ty::ty_istr. { w.write_char('S'); }
|
||||
ty::ty_tag(def, tys) {
|
||||
w.write_str(~"t[");
|
||||
w.write_str("t[");
|
||||
w.write_str(cx.ds(def));
|
||||
w.write_char('|');
|
||||
for t: ty::t in tys { enc_ty(w, cx, t); }
|
||||
w.write_char(']');
|
||||
}
|
||||
ty::ty_tup(ts) {
|
||||
w.write_str(~"T[");
|
||||
w.write_str("T[");
|
||||
for t in ts { enc_ty(w, cx, t); }
|
||||
w.write_char(']');
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ fn enc_sty(w: &io::writer, cx: &@ctxt, st: &ty::sty) {
|
|||
ty::ty_ptr(mt) { w.write_char('*'); enc_mt(w, cx, mt); }
|
||||
ty::ty_vec(mt) { w.write_char('I'); enc_mt(w, cx, mt); }
|
||||
ty::ty_rec(fields) {
|
||||
w.write_str(~"R[");
|
||||
w.write_str("R[");
|
||||
for field: ty::field in fields {
|
||||
w.write_str(field.ident);
|
||||
w.write_char('=');
|
||||
|
@ -155,7 +155,7 @@ fn enc_sty(w: &io::writer, cx: &@ctxt, st: &ty::sty) {
|
|||
enc_ty_fn(w, cx, args, out, return, []);
|
||||
}
|
||||
ty::ty_obj(methods) {
|
||||
w.write_str(~"O[");
|
||||
w.write_str("O[");
|
||||
for m: ty::method in methods {
|
||||
enc_proto(w, m.proto);
|
||||
w.write_str(m.ident);
|
||||
|
@ -164,17 +164,14 @@ fn enc_sty(w: &io::writer, cx: &@ctxt, st: &ty::sty) {
|
|||
w.write_char(']');
|
||||
}
|
||||
ty::ty_res(def, ty, tps) {
|
||||
w.write_str(~"r[");
|
||||
w.write_str("r[");
|
||||
w.write_str(cx.ds(def));
|
||||
w.write_char('|');
|
||||
enc_ty(w, cx, ty);
|
||||
for t: ty::t in tps { enc_ty(w, cx, t); }
|
||||
w.write_char(']');
|
||||
}
|
||||
ty::ty_var(id) {
|
||||
w.write_char('X');
|
||||
w.write_str(int::str(id));
|
||||
}
|
||||
ty::ty_var(id) { w.write_char('X'); w.write_str(int::str(id)); }
|
||||
ty::ty_native(def) {
|
||||
w.write_char('E');
|
||||
w.write_str(cx.ds(def));
|
||||
|
@ -182,15 +179,15 @@ fn enc_sty(w: &io::writer, cx: &@ctxt, st: &ty::sty) {
|
|||
}
|
||||
ty::ty_param(id, k) {
|
||||
alt k {
|
||||
kind_unique. { w.write_str(~"pu"); }
|
||||
kind_shared. { w.write_str(~"ps"); }
|
||||
kind_pinned. { w.write_str(~"pp"); }
|
||||
kind_unique. { w.write_str("pu"); }
|
||||
kind_shared. { w.write_str("ps"); }
|
||||
kind_pinned. { w.write_str("pp"); }
|
||||
}
|
||||
w.write_str(uint::str(id));
|
||||
}
|
||||
ty::ty_type. { w.write_char('Y'); }
|
||||
ty::ty_constr(ty, cs) {
|
||||
w.write_str(~"A[");
|
||||
w.write_str("A[");
|
||||
enc_ty(w, cx, ty);
|
||||
for tc: @ty::type_constr in cs { enc_ty_constr(w, cx, tc); }
|
||||
w.write_char(']');
|
||||
|
@ -244,9 +241,7 @@ fn enc_constr(w: &io::writer, cx: &@ctxt, c: &@ty::constr) {
|
|||
alt a.node {
|
||||
carg_base. { w.write_char('*'); }
|
||||
carg_ident(i) { w.write_uint(i); }
|
||||
carg_lit(l) {
|
||||
w.write_str(lit_to_str(l));
|
||||
}
|
||||
carg_lit(l) { w.write_str(lit_to_str(l)); }
|
||||
}
|
||||
}
|
||||
w.write_char(')');
|
||||
|
@ -262,10 +257,8 @@ fn enc_ty_constr(w: &io::writer, cx: &@ctxt, c: &@ty::type_constr) {
|
|||
if semi { w.write_char(';'); } else { semi = true; }
|
||||
alt a.node {
|
||||
carg_base. { w.write_char('*'); }
|
||||
carg_ident(p) {
|
||||
w.write_str(path_to_str(p)); }
|
||||
carg_lit(l) {
|
||||
w.write_str(lit_to_str(l)); }
|
||||
carg_ident(p) { w.write_str(path_to_str(p)); }
|
||||
carg_lit(l) { w.write_str(lit_to_str(l)); }
|
||||
}
|
||||
}
|
||||
w.write_char(')');
|
||||
|
|
|
@ -32,37 +32,45 @@ type restrict =
|
|||
|
||||
type scope = @[restrict];
|
||||
|
||||
tag local_info {
|
||||
local(uint);
|
||||
}
|
||||
tag local_info { local(uint); }
|
||||
|
||||
type ctx = {tcx: ty::ctxt,
|
||||
local_map: std::map::hashmap<node_id, local_info>,
|
||||
mutable next_local: uint};
|
||||
type ctx =
|
||||
{tcx: ty::ctxt,
|
||||
local_map: std::map::hashmap<node_id, local_info>,
|
||||
mutable next_local: uint};
|
||||
|
||||
fn check_crate(tcx: ty::ctxt, crate: &@ast::crate) {
|
||||
// Stores information about object fields and function
|
||||
// arguments that's otherwise not easily available.
|
||||
let cx = @{tcx: tcx,
|
||||
local_map: std::map::new_int_hash(),
|
||||
mutable next_local: 0u};
|
||||
let v = @{visit_fn: visit_fn,
|
||||
visit_expr: bind visit_expr(cx, _, _, _),
|
||||
visit_decl: bind visit_decl(cx, _, _, _)
|
||||
with *visit::default_visitor::<scope>()};
|
||||
let cx =
|
||||
@{tcx: tcx,
|
||||
local_map: std::map::new_int_hash(),
|
||||
mutable next_local: 0u};
|
||||
let v =
|
||||
@{visit_fn: visit_fn,
|
||||
visit_expr: bind visit_expr(cx, _, _, _),
|
||||
visit_decl: bind visit_decl(cx, _, _, _)
|
||||
with *visit::default_visitor::<scope>()};
|
||||
visit::visit_crate(*crate, @[], visit::mk_vt(v));
|
||||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
fn visit_fn(f: &ast::_fn, _tp: &[ast::ty_param], _sp: &span,
|
||||
_name: &fn_ident, _id: ast::node_id, sc: &scope, v: &vt<scope>) {
|
||||
fn visit_fn(f: &ast::_fn, _tp: &[ast::ty_param], _sp: &span, _name: &fn_ident,
|
||||
_id: ast::node_id, sc: &scope, v: &vt<scope>) {
|
||||
visit::visit_fn_decl(f.decl, sc, v);
|
||||
let scope = alt f.proto {
|
||||
// Blocks need to obey any restrictions from the enclosing scope.
|
||||
ast::proto_block. | ast::proto_closure. { sc }
|
||||
// Non capturing functions start out fresh.
|
||||
_ { @[] }
|
||||
};
|
||||
let scope =
|
||||
alt f.proto {
|
||||
|
||||
// Blocks need to obey any restrictions from the enclosing scope.
|
||||
ast::proto_block. | ast::proto_closure. {
|
||||
sc
|
||||
}
|
||||
|
||||
// Non capturing functions start out fresh.
|
||||
_ {
|
||||
@[]
|
||||
}
|
||||
};
|
||||
v.visit_block(f.body, scope, v);
|
||||
}
|
||||
|
||||
|
@ -80,8 +88,8 @@ fn visit_expr(cx: &@ctx, ex: &@ast::expr, sc: &scope, v: &vt<scope>) {
|
|||
let root = expr_root(cx.tcx, ex, false);
|
||||
if mut_field(root.ds) {
|
||||
cx.tcx.sess.span_err(ex.span,
|
||||
~"result of put must be" +
|
||||
~" immutably rooted");
|
||||
"result of put must be" +
|
||||
" immutably rooted");
|
||||
}
|
||||
visit_expr(cx, ex, sc, v);
|
||||
}
|
||||
|
@ -140,8 +148,8 @@ fn visit_decl(cx: &@ctx, d: &@ast::decl, sc: &scope, v: &vt<scope>) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_call(cx: &ctx, f: &@ast::expr, args: &[@ast::expr], sc: &scope)
|
||||
-> [restrict] {
|
||||
fn check_call(cx: &ctx, f: &@ast::expr, args: &[@ast::expr], sc: &scope) ->
|
||||
[restrict] {
|
||||
let fty = ty::type_autoderef(cx.tcx, ty::expr_ty(cx.tcx, f));
|
||||
let arg_ts = ty::ty_fn_args(cx.tcx, fty);
|
||||
let mut_roots: [{arg: uint, node: node_id}] = [];
|
||||
|
@ -157,27 +165,27 @@ fn check_call(cx: &ctx, f: &@ast::expr, args: &[@ast::expr], sc: &scope)
|
|||
let dnum = ast_util::def_id_of_def(def).node;
|
||||
mut_roots += [{arg: i, node: dnum}];
|
||||
}
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
let root_var = path_def_id(cx, root.ex);
|
||||
let unsafe_t = alt inner_mut(root.ds) {
|
||||
some(t) { some(t) }
|
||||
_ { none }
|
||||
};
|
||||
restricts += [@{root_var: root_var,
|
||||
local_id: cx.next_local,
|
||||
bindings: [arg.id],
|
||||
unsafe_ty: unsafe_t,
|
||||
depends_on: deps(sc, root_var),
|
||||
mutable ok: valid}];
|
||||
let unsafe_t =
|
||||
alt inner_mut(root.ds) { some(t) { some(t) } _ { none } };
|
||||
restricts +=
|
||||
[@{root_var: root_var,
|
||||
local_id: cx.next_local,
|
||||
bindings: [arg.id],
|
||||
unsafe_ty: unsafe_t,
|
||||
depends_on: deps(sc, root_var),
|
||||
mutable ok: valid}];
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
let f_may_close = alt f.node {
|
||||
ast::expr_path(_) { def_is_local(cx.tcx.def_map.get(f.id), true) }
|
||||
_ { true }
|
||||
};
|
||||
let f_may_close =
|
||||
alt f.node {
|
||||
ast::expr_path(_) { def_is_local(cx.tcx.def_map.get(f.id), true) }
|
||||
_ { true }
|
||||
};
|
||||
if f_may_close {
|
||||
let i = 0u;
|
||||
for r in restricts {
|
||||
|
@ -185,37 +193,39 @@ fn check_call(cx: &ctx, f: &@ast::expr, args: &[@ast::expr], sc: &scope)
|
|||
cx.tcx.sess.span_err(f.span,
|
||||
#fmt["function may alias with argument \
|
||||
%u, which is not immutably rooted",
|
||||
i]);
|
||||
i]);
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
let j = 0u;
|
||||
for @{unsafe_ty, _} in restricts {
|
||||
for @{unsafe_ty: unsafe_ty, _} in restricts {
|
||||
alt unsafe_ty {
|
||||
some(ty) {
|
||||
let i = 0u;
|
||||
for arg_t: ty::arg in arg_ts {
|
||||
let mut_alias = arg_t.mode == ty::mo_alias(true);
|
||||
if i != j &&
|
||||
ty_can_unsafely_include(cx, ty, arg_t.ty, mut_alias) {
|
||||
cx.tcx.sess.span_err(args[i].span,
|
||||
ty_can_unsafely_include(cx, ty, arg_t.ty, mut_alias) {
|
||||
cx.tcx.sess.span_err(
|
||||
args[i].span,
|
||||
#fmt["argument %u may alias with argument %u, \
|
||||
which is not immutably rooted", i, j]);
|
||||
which is not immutably rooted",
|
||||
i, j]);
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
j += 1u;
|
||||
}
|
||||
// Ensure we're not passing a root by mutable alias.
|
||||
|
||||
for {node, arg} in mut_roots {
|
||||
for {node: node, arg: arg} in mut_roots {
|
||||
let mut_alias_to_root = false;
|
||||
let mut_alias_to_root_count = 0u;
|
||||
for @{root_var, _} in restricts {
|
||||
for @{root_var: root_var, _} in restricts {
|
||||
alt root_var {
|
||||
some(root) {
|
||||
if node == root {
|
||||
|
@ -226,13 +236,13 @@ fn check_call(cx: &ctx, f: &@ast::expr, args: &[@ast::expr], sc: &scope)
|
|||
}
|
||||
}
|
||||
}
|
||||
none. {}
|
||||
none. { }
|
||||
}
|
||||
}
|
||||
|
||||
if mut_alias_to_root {
|
||||
cx.tcx.sess.span_err(args[arg].span,
|
||||
~"passing a mutable alias to a variable \
|
||||
"passing a mutable alias to a variable \
|
||||
that roots another alias");
|
||||
}
|
||||
}
|
||||
|
@ -248,12 +258,14 @@ fn check_alt(cx: &ctx, input: &@ast::expr, arms: &[ast::arm], sc: &scope,
|
|||
let new_sc = sc;
|
||||
if vec::len(dnums) > 0u {
|
||||
let root_var = path_def_id(cx, root.ex);
|
||||
new_sc = @(*sc + [@{root_var: root_var,
|
||||
local_id: cx.next_local,
|
||||
bindings: dnums,
|
||||
unsafe_ty: inner_mut(root.ds),
|
||||
depends_on: deps(sc, root_var),
|
||||
mutable ok: valid}]);
|
||||
new_sc =
|
||||
@(*sc +
|
||||
[@{root_var: root_var,
|
||||
local_id: cx.next_local,
|
||||
bindings: dnums,
|
||||
unsafe_ty: inner_mut(root.ds),
|
||||
depends_on: deps(sc, root_var),
|
||||
mutable ok: valid}]);
|
||||
}
|
||||
register_locals(cx, a.pats[0]);
|
||||
visit::visit_arm(a, new_sc, v);
|
||||
|
@ -284,8 +296,9 @@ fn check_for(cx: &ctx, local: &@ast::local, seq: &@ast::expr, blk: &ast::blk,
|
|||
ty::ty_vec(mt) { if mt.mut != ast::imm { unsafe = some(seq_t); } }
|
||||
ty::ty_istr. {/* no-op */ }
|
||||
_ {
|
||||
cx.tcx.sess.span_unimpl(seq.span, ~"unknown seq type " +
|
||||
util::ppaux::ty_to_str(cx.tcx, seq_t));
|
||||
cx.tcx.sess.span_unimpl(seq.span,
|
||||
"unknown seq type " +
|
||||
util::ppaux::ty_to_str(cx.tcx, seq_t));
|
||||
}
|
||||
}
|
||||
let root_var = path_def_id(cx, root.ex);
|
||||
|
@ -305,12 +318,11 @@ fn check_var(cx: &ctx, ex: &@ast::expr, p: &ast::path, id: ast::node_id,
|
|||
let def = cx.tcx.def_map.get(id);
|
||||
if !def_is_local(def, true) { ret; }
|
||||
let my_defnum = ast_util::def_id_of_def(def).node;
|
||||
let my_local_id = alt cx.local_map.find(my_defnum) {
|
||||
some(local(id)) { id }
|
||||
_ { 0u }
|
||||
};
|
||||
let my_local_id =
|
||||
alt cx.local_map.find(my_defnum) { some(local(id)) { id } _ { 0u } };
|
||||
let var_t = ty::expr_ty(cx.tcx, ex);
|
||||
for r: restrict in *sc {
|
||||
|
||||
// excludes variables introduced since the alias was made
|
||||
if my_local_id < r.local_id {
|
||||
alt r.unsafe_ty {
|
||||
|
@ -319,7 +331,7 @@ fn check_var(cx: &ctx, ex: &@ast::expr, p: &ast::path, id: ast::node_id,
|
|||
r.ok = val_taken(ex.span, p);
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
} else if vec::member(my_defnum, r.bindings) {
|
||||
test_scope(cx, sc, r, p);
|
||||
|
@ -333,9 +345,7 @@ fn check_lval(cx: &@ctx, dest: &@ast::expr, sc: &scope, v: &vt<scope>) {
|
|||
let def = cx.tcx.def_map.get(dest.id);
|
||||
let dnum = ast_util::def_id_of_def(def).node;
|
||||
for r: restrict in *sc {
|
||||
if r.root_var == some(dnum) {
|
||||
r.ok = overwritten(dest.span, p);
|
||||
}
|
||||
if r.root_var == some(dnum) { r.ok = overwritten(dest.span, p); }
|
||||
}
|
||||
}
|
||||
_ { visit_expr(cx, dest, sc, v); }
|
||||
|
@ -358,19 +368,17 @@ fn test_scope(cx: &ctx, sc: &scope, r: &restrict, p: &ast::path) {
|
|||
let msg =
|
||||
alt prob {
|
||||
overwritten(sp, wpt) {
|
||||
{span: sp, msg: ~"overwriting " +
|
||||
ast_util::path_name(wpt)}
|
||||
{span: sp, msg: "overwriting " + ast_util::path_name(wpt)}
|
||||
}
|
||||
val_taken(sp, vpt) {
|
||||
{span: sp,
|
||||
msg: ~"taking the value of " +
|
||||
ast_util::path_name(vpt)}
|
||||
msg: "taking the value of " + ast_util::path_name(vpt)}
|
||||
}
|
||||
};
|
||||
cx.tcx.sess.span_err(msg.span,
|
||||
msg.msg + ~" will invalidate alias " +
|
||||
ast_util::path_name(p) +
|
||||
~", which is still used");
|
||||
msg.msg + " will invalidate alias " +
|
||||
ast_util::path_name(p) +
|
||||
", which is still used");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +392,7 @@ fn deps(sc: &scope, root: &option::t<node_id>) -> [uint] {
|
|||
i += 1u;
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
ret result;
|
||||
}
|
||||
|
@ -438,6 +446,7 @@ fn ty_can_unsafely_include(cx: &ctx, needle: ty::t, haystack: ty::t,
|
|||
}
|
||||
|
||||
|
||||
|
||||
// These may contain anything.
|
||||
ty::ty_fn(_, _, _, _, _) {
|
||||
ret true;
|
||||
|
@ -445,6 +454,7 @@ fn ty_can_unsafely_include(cx: &ctx, needle: ty::t, haystack: ty::t,
|
|||
ty::ty_obj(_) { ret true; }
|
||||
|
||||
|
||||
|
||||
// A type param may include everything, but can only be
|
||||
// treated as opaque downstream, and is thus safe unless we
|
||||
// saw mutable fields, in which case the whole thing can be
|
||||
|
@ -460,11 +470,13 @@ fn ty_can_unsafely_include(cx: &ctx, needle: ty::t, haystack: ty::t,
|
|||
|
||||
fn def_is_local(d: &ast::def, objfields_count: bool) -> bool {
|
||||
ret alt d {
|
||||
ast::def_local(_) | ast::def_arg(_, _) | ast::def_binding(_) |
|
||||
ast::def_upvar(_, _, _) { true }
|
||||
ast::def_obj_field(_, _) { objfields_count }
|
||||
_ { false }
|
||||
};
|
||||
ast::def_local(_) | ast::def_arg(_, _) | ast::def_binding(_) |
|
||||
ast::def_upvar(_, _, _) {
|
||||
true
|
||||
}
|
||||
ast::def_obj_field(_, _) { objfields_count }
|
||||
_ { false }
|
||||
};
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -131,7 +131,7 @@ mod test {
|
|||
fn test_node_span_item() {
|
||||
let expected: codemap::span = ast_util::mk_sp(20u, 30u);
|
||||
let node =
|
||||
node_item(@{ident: ~"test",
|
||||
node_item(@{ident: "test",
|
||||
attrs: [],
|
||||
id: 0,
|
||||
node: item_mod({view_items: [], items: []}),
|
||||
|
@ -143,7 +143,7 @@ mod test {
|
|||
fn test_node_span_obj_ctor() {
|
||||
let expected: codemap::span = ast_util::mk_sp(20u, 30u);
|
||||
let node =
|
||||
node_obj_ctor(@{ident: ~"test",
|
||||
node_obj_ctor(@{ident: "test",
|
||||
attrs: [],
|
||||
id: 0,
|
||||
node: item_mod({view_items: [], items: []}),
|
||||
|
@ -155,7 +155,7 @@ mod test {
|
|||
fn test_node_span_native_item() {
|
||||
let expected: codemap::span = ast_util::mk_sp(20u, 30u);
|
||||
let node =
|
||||
node_native_item(@{ident: ~"test",
|
||||
node_native_item(@{ident: "test",
|
||||
attrs: [],
|
||||
node: native_item_ty,
|
||||
id: 0,
|
||||
|
|
|
@ -34,7 +34,7 @@ fn check_arms(tcx: &ty::ctxt, arms: &[arm]) {
|
|||
j += 1;
|
||||
}
|
||||
if !reachable {
|
||||
tcx.sess.span_err(arm_pat.span, ~"unreachable pattern");
|
||||
tcx.sess.span_err(arm_pat.span, "unreachable pattern");
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
|
@ -106,7 +106,7 @@ fn check_local(tcx: &ty::ctxt, loc: &@local, s: &(), v: &visit::vt<()>) {
|
|||
visit::visit_local(loc, s, v);
|
||||
if is_refutable(tcx, loc.node.pat) {
|
||||
tcx.sess.span_err(loc.node.pat.span,
|
||||
~"refutable pattern in local binding");
|
||||
"refutable pattern in local binding");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,53 +29,50 @@ type freevar_map = hashmap<ast::node_id, freevar_info>;
|
|||
// Since we want to be able to collect upvars in some arbitrary piece
|
||||
// of the AST, we take a walker function that we invoke with a visitor
|
||||
// in order to start the search.
|
||||
fn collect_freevars(def_map: &resolve::def_map,
|
||||
walker: &fn(&visit::vt<int>)) -> freevar_info {
|
||||
fn collect_freevars(def_map: &resolve::def_map, walker: &fn(&visit::vt<int>))
|
||||
-> freevar_info {
|
||||
let seen = new_int_hash();
|
||||
let refs = @mutable [];
|
||||
|
||||
fn ignore_item(_i: &@ast::item, _depth: &int, _v: &visit::vt<int>) {}
|
||||
fn ignore_item(_i: &@ast::item, _depth: &int, _v: &visit::vt<int>) { }
|
||||
|
||||
let walk_expr = lambda(expr: &@ast::expr, depth: &int,
|
||||
v: &visit::vt<int>) {
|
||||
alt expr.node {
|
||||
ast::expr_fn(f) {
|
||||
if f.proto == ast::proto_block ||
|
||||
f.proto == ast::proto_closure {
|
||||
visit::visit_expr(expr, depth + 1, v);
|
||||
}
|
||||
}
|
||||
ast::expr_for_each(dcl, x, b) {
|
||||
v.visit_local(dcl, depth, v);
|
||||
v.visit_expr(x, depth, v);
|
||||
v.visit_block(b, depth + 1, v);
|
||||
}
|
||||
ast::expr_path(path) {
|
||||
let def = def_map.get(expr.id), i = 0;
|
||||
while i < depth {
|
||||
alt {def} {
|
||||
ast::def_upvar(_, inner, _) {
|
||||
def = *inner;
|
||||
}
|
||||
_ { break; }
|
||||
let walk_expr =
|
||||
lambda (expr: &@ast::expr, depth: &int, v: &visit::vt<int>) {
|
||||
alt expr.node {
|
||||
ast::expr_fn(f) {
|
||||
if f.proto == ast::proto_block ||
|
||||
f.proto == ast::proto_closure {
|
||||
visit::visit_expr(expr, depth + 1, v);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
if i == depth { // Made it to end of loop
|
||||
let dnum = ast_util::def_id_of_def(def).node;
|
||||
if !seen.contains_key(dnum) {
|
||||
*refs += [def];
|
||||
seen.insert(dnum, ());
|
||||
}
|
||||
ast::expr_for_each(dcl, x, b) {
|
||||
v.visit_local(dcl, depth, v);
|
||||
v.visit_expr(x, depth, v);
|
||||
v.visit_block(b, depth + 1, v);
|
||||
}
|
||||
ast::expr_path(path) {
|
||||
let def = def_map.get(expr.id), i = 0;
|
||||
while i < depth {
|
||||
alt { def } {
|
||||
ast::def_upvar(_, inner, _) { def = *inner; }
|
||||
_ { break; }
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
if i == depth { // Made it to end of loop
|
||||
let dnum = ast_util::def_id_of_def(def).node;
|
||||
if !seen.contains_key(dnum) {
|
||||
*refs += [def];
|
||||
seen.insert(dnum, ());
|
||||
}
|
||||
}
|
||||
}
|
||||
_ { visit::visit_expr(expr, depth, v); }
|
||||
}
|
||||
}
|
||||
_ { visit::visit_expr(expr, depth, v); }
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
walker(visit::mk_vt(@{visit_item: ignore_item,
|
||||
visit_expr: walk_expr
|
||||
with *visit::default_visitor()}));
|
||||
walker(visit::mk_vt(@{visit_item: ignore_item, visit_expr: walk_expr
|
||||
with *visit::default_visitor()}));
|
||||
ret @*refs;
|
||||
}
|
||||
|
||||
|
@ -84,30 +81,34 @@ fn collect_freevars(def_map: &resolve::def_map,
|
|||
// efficient as it fully recomputes the free variables at every
|
||||
// node of interest rather than building up the free variables in
|
||||
// one pass. This could be improved upon if it turns out to matter.
|
||||
fn annotate_freevars(def_map: &resolve::def_map,
|
||||
crate: &@ast::crate) -> freevar_map {
|
||||
fn annotate_freevars(def_map: &resolve::def_map, crate: &@ast::crate) ->
|
||||
freevar_map {
|
||||
let freevars = new_int_hash();
|
||||
|
||||
let walk_fn = lambda (f: &ast::_fn, tps: &[ast::ty_param], sp: &span,
|
||||
i: &ast::fn_ident, nid: ast::node_id) {
|
||||
let start_walk = lambda (v: &visit::vt<int>) {
|
||||
v.visit_fn(f, tps, sp, i, nid, 1, v);
|
||||
};
|
||||
let vars = collect_freevars(def_map, start_walk);
|
||||
freevars.insert(nid, vars);
|
||||
};
|
||||
let walk_expr = lambda (expr: &@ast::expr) {
|
||||
alt expr.node {
|
||||
ast::expr_for_each(local, _, body) {
|
||||
let start_walk = lambda (v: &visit::vt<int>) {
|
||||
v.visit_block(body, 1, v);
|
||||
};
|
||||
let walk_fn =
|
||||
lambda (f: &ast::_fn, tps: &[ast::ty_param], sp: &span,
|
||||
i: &ast::fn_ident, nid: ast::node_id) {
|
||||
let start_walk =
|
||||
lambda (v: &visit::vt<int>) {
|
||||
v.visit_fn(f, tps, sp, i, nid, 1, v);
|
||||
};
|
||||
let vars = collect_freevars(def_map, start_walk);
|
||||
freevars.insert(body.node.id, vars);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
};
|
||||
freevars.insert(nid, vars);
|
||||
};
|
||||
let walk_expr =
|
||||
lambda (expr: &@ast::expr) {
|
||||
alt expr.node {
|
||||
ast::expr_for_each(local, _, body) {
|
||||
let start_walk =
|
||||
lambda (v: &visit::vt<int>) {
|
||||
v.visit_block(body, 1, v);
|
||||
};
|
||||
let vars = collect_freevars(def_map, start_walk);
|
||||
freevars.insert(body.node.id, vars);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
};
|
||||
|
||||
let visitor =
|
||||
visit::mk_simple_visitor(@{visit_fn: walk_fn, visit_expr: walk_expr
|
||||
|
@ -119,10 +120,7 @@ fn annotate_freevars(def_map: &resolve::def_map,
|
|||
|
||||
fn get_freevars(tcx: &ty::ctxt, fid: ast::node_id) -> freevar_info {
|
||||
alt tcx.freevars.find(fid) {
|
||||
none. {
|
||||
fail ~"get_freevars: " + int::str(fid)
|
||||
+ ~" has no freevars";
|
||||
}
|
||||
none. { fail "get_freevars: " + int::str(fid) + " has no freevars"; }
|
||||
some(d) { ret d; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import lib::llvm::False;
|
|||
import lib::llvm::True;
|
||||
import lib::llvm::llvm::ValueRef;
|
||||
import middle::trans;
|
||||
import middle::trans::{ get_tydesc, tps_normal };
|
||||
import middle::trans::{get_tydesc, tps_normal};
|
||||
import middle::trans_common::*;
|
||||
import middle::ty;
|
||||
import std::option::none;
|
||||
|
@ -21,10 +21,12 @@ type ctxt = @{mutable next_tydesc_num: uint};
|
|||
|
||||
fn mk_ctxt() -> ctxt { ret @{mutable next_tydesc_num: 0u}; }
|
||||
|
||||
fn add_global(ccx: &@crate_ctxt, llval: ValueRef, name: &istr) -> ValueRef {
|
||||
let llglobal = str::as_buf(name, { |buf|
|
||||
lll::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
|
||||
});
|
||||
fn add_global(ccx: &@crate_ctxt, llval: ValueRef, name: &str) -> ValueRef {
|
||||
let llglobal =
|
||||
str::as_buf(name,
|
||||
{|buf|
|
||||
lll::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
|
||||
});
|
||||
lll::LLVMSetInitializer(llglobal, llval);
|
||||
lll::LLVMSetGlobalConstant(llglobal, True);
|
||||
ret llglobal;
|
||||
|
@ -48,7 +50,7 @@ fn add_gc_root(cx: &@block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
|
|||
bcx = td_r.result.bcx;
|
||||
let lltydesc = td_r.result.val;
|
||||
|
||||
let gcroot = bcx_ccx(bcx).intrinsics.get(~"llvm.gcroot");
|
||||
let gcroot = bcx_ccx(bcx).intrinsics.get("llvm.gcroot");
|
||||
let llvalptr = bld::PointerCast(bcx, llval, T_ptr(T_ptr(T_i8())));
|
||||
|
||||
alt td_r.kind {
|
||||
|
@ -65,30 +67,31 @@ fn add_gc_root(cx: &@block_ctxt, llval: ValueRef, ty: ty::t) -> @block_ctxt {
|
|||
|
||||
let lldestindex =
|
||||
add_global(bcx_ccx(bcx), C_struct([C_int(0), C_uint(number)]),
|
||||
~"rust_gc_tydesc_dest_index");
|
||||
"rust_gc_tydesc_dest_index");
|
||||
let llsrcindex =
|
||||
add_global(bcx_ccx(bcx), C_struct([C_int(1), C_uint(number)]),
|
||||
~"rust_gc_tydesc_src_index");
|
||||
"rust_gc_tydesc_src_index");
|
||||
|
||||
lldestindex = lll::LLVMConstPointerCast(lldestindex, T_ptr(T_i8()));
|
||||
llsrcindex = lll::LLVMConstPointerCast(llsrcindex, T_ptr(T_i8()));
|
||||
|
||||
lltydescptr = bld::PointerCast(llderivedtydescs, lltydescptr,
|
||||
T_ptr(T_ptr(T_i8())));
|
||||
lltydescptr =
|
||||
bld::PointerCast(llderivedtydescs, lltydescptr,
|
||||
T_ptr(T_ptr(T_i8())));
|
||||
|
||||
bld::Call(llderivedtydescs, gcroot, [lltydescptr, lldestindex]);
|
||||
bld::Call(bcx, gcroot, [llvalptr, llsrcindex]);
|
||||
}
|
||||
tk_param. {
|
||||
bcx_tcx(cx).sess.bug(~"we should never be trying to root values " +
|
||||
~"of a type parameter");
|
||||
bcx_tcx(cx).sess.bug("we should never be trying to root values " +
|
||||
"of a type parameter");
|
||||
}
|
||||
tk_static. {
|
||||
// Static type descriptor.
|
||||
|
||||
let llstaticgcmeta =
|
||||
add_global(bcx_ccx(bcx), C_struct([C_int(2), lltydesc]),
|
||||
~"rust_gc_tydesc_static_gc_meta");
|
||||
"rust_gc_tydesc_static_gc_meta");
|
||||
let llstaticgcmetaptr =
|
||||
lll::LLVMConstPointerCast(llstaticgcmeta, T_ptr(T_i8()));
|
||||
|
||||
|
@ -109,6 +112,7 @@ fn type_is_gc_relevant(cx: &ty::ctxt, ty: ty::t) -> bool {
|
|||
}
|
||||
|
||||
|
||||
|
||||
ty::ty_rec(fields) {
|
||||
for f in fields { if type_is_gc_relevant(cx, f.mt.ty) { ret true; } }
|
||||
ret false;
|
||||
|
@ -119,6 +123,7 @@ fn type_is_gc_relevant(cx: &ty::ctxt, ty: ty::t) -> bool {
|
|||
}
|
||||
|
||||
|
||||
|
||||
ty::ty_tag(did, tps) {
|
||||
let variants = ty::tag_variants(cx, did);
|
||||
for variant in variants {
|
||||
|
@ -131,19 +136,22 @@ fn type_is_gc_relevant(cx: &ty::ctxt, ty: ty::t) -> bool {
|
|||
}
|
||||
|
||||
|
||||
|
||||
ty::ty_vec(tm) {
|
||||
ret type_is_gc_relevant(cx, tm.ty);
|
||||
}
|
||||
ty::ty_constr(sub, _) { ret type_is_gc_relevant(cx, sub); }
|
||||
|
||||
|
||||
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_fn(_, _, _, _, _)
|
||||
| ty::ty_native_fn(_, _, _) | ty::ty_obj(_) | ty::ty_param(_, _) |
|
||||
|
||||
ty::ty_box(_) | ty::ty_uniq(_) | ty::ty_fn(_, _, _, _, _) |
|
||||
ty::ty_native_fn(_, _, _) | ty::ty_obj(_) | ty::ty_param(_, _) |
|
||||
ty::ty_res(_, _, _) {
|
||||
ret true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ty::ty_var(_) {
|
||||
fail "ty_var in type_is_gc_relevant";
|
||||
}
|
||||
|
|
|
@ -96,11 +96,11 @@ fn lower_kind(a: kind, b: kind) -> kind {
|
|||
if kind_lteq(a, b) { a } else { b }
|
||||
}
|
||||
|
||||
fn kind_to_str(k: kind) -> istr {
|
||||
fn kind_to_str(k: kind) -> str {
|
||||
alt k {
|
||||
ast::kind_pinned. { ~"pinned" }
|
||||
ast::kind_unique. { ~"unique" }
|
||||
ast::kind_shared. { ~"shared" }
|
||||
ast::kind_pinned. { "pinned" }
|
||||
ast::kind_unique. { "unique" }
|
||||
ast::kind_shared. { "shared" }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ fn type_and_kind(tcx: &ty::ctxt, e: &@ast::expr) ->
|
|||
}
|
||||
|
||||
fn need_expr_kind(tcx: &ty::ctxt, e: &@ast::expr, k_need: ast::kind,
|
||||
descr: &istr) {
|
||||
descr: &str) {
|
||||
let tk = type_and_kind(tcx, e);
|
||||
log #fmt["for %s: want %s type, got %s type %s", descr,
|
||||
kind_to_str(k_need), kind_to_str(tk.kind),
|
||||
|
@ -121,36 +121,35 @@ fn need_expr_kind(tcx: &ty::ctxt, e: &@ast::expr, k_need: ast::kind,
|
|||
if !kind_lteq(k_need, tk.kind) {
|
||||
let s =
|
||||
#fmt["mismatched kinds for %s: needed %s type, got %s type %s",
|
||||
descr, kind_to_str(k_need),
|
||||
kind_to_str(tk.kind),
|
||||
descr, kind_to_str(k_need), kind_to_str(tk.kind),
|
||||
util::ppaux::ty_to_str(tcx, tk.ty)];
|
||||
tcx.sess.span_err(e.span, s);
|
||||
}
|
||||
}
|
||||
|
||||
fn need_shared_lhs_rhs(tcx: &ty::ctxt, a: &@ast::expr, b: &@ast::expr,
|
||||
op: &istr) {
|
||||
need_expr_kind(tcx, a, ast::kind_shared, op + ~" lhs");
|
||||
need_expr_kind(tcx, b, ast::kind_shared, op + ~" rhs");
|
||||
op: &str) {
|
||||
need_expr_kind(tcx, a, ast::kind_shared, op + " lhs");
|
||||
need_expr_kind(tcx, b, ast::kind_shared, op + " rhs");
|
||||
}
|
||||
|
||||
fn check_expr(tcx: &ty::ctxt, e: &@ast::expr) {
|
||||
alt e.node {
|
||||
ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, ~"<-"); }
|
||||
ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, ~"="); }
|
||||
ast::expr_assign_op(_, a, b) { need_shared_lhs_rhs(tcx, a, b, ~"op="); }
|
||||
ast::expr_swap(a, b) { need_shared_lhs_rhs(tcx, a, b, ~"<->"); }
|
||||
ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); }
|
||||
ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, "="); }
|
||||
ast::expr_assign_op(_, a, b) { need_shared_lhs_rhs(tcx, a, b, "op="); }
|
||||
ast::expr_swap(a, b) { need_shared_lhs_rhs(tcx, a, b, "<->"); }
|
||||
ast::expr_copy(a) {
|
||||
need_expr_kind(tcx, a, ast::kind_shared, ~"'copy' operand");
|
||||
need_expr_kind(tcx, a, ast::kind_shared, "'copy' operand");
|
||||
}
|
||||
ast::expr_ret(option::some(a)) {
|
||||
need_expr_kind(tcx, a, ast::kind_shared, ~"'ret' operand");
|
||||
need_expr_kind(tcx, a, ast::kind_shared, "'ret' operand");
|
||||
}
|
||||
ast::expr_be(a) {
|
||||
need_expr_kind(tcx, a, ast::kind_shared, ~"'be' operand");
|
||||
need_expr_kind(tcx, a, ast::kind_shared, "'be' operand");
|
||||
}
|
||||
ast::expr_fail(option::some(a)) {
|
||||
need_expr_kind(tcx, a, ast::kind_shared, ~"'fail' operand");
|
||||
need_expr_kind(tcx, a, ast::kind_shared, "'fail' operand");
|
||||
}
|
||||
ast::expr_call(callee, _) {
|
||||
let tpt = ty::expr_ty_params_and_ty(tcx, callee);
|
||||
|
@ -159,8 +158,8 @@ fn check_expr(tcx: &ty::ctxt, e: &@ast::expr) {
|
|||
// that all the types we're supplying as typarams conform to the
|
||||
// typaram kind constraints on that item.
|
||||
if vec::len(tpt.params) != 0u {
|
||||
let callee_def = ast_util::def_id_of_def(
|
||||
tcx.def_map.get(callee.id));
|
||||
let callee_def =
|
||||
ast_util::def_id_of_def(tcx.def_map.get(callee.id));
|
||||
let item_tk = ty::lookup_item_type(tcx, callee_def);
|
||||
let i = 0;
|
||||
assert (vec::len(item_tk.kinds) == vec::len(tpt.params));
|
||||
|
|
|
@ -12,8 +12,8 @@ type deref = @{mut: bool, kind: deref_t, outer_t: ty::t};
|
|||
// vec of dereferences that were used on this root. Note that, in this vec,
|
||||
// the inner derefs come in front, so foo.bar[1] becomes rec(ex=foo,
|
||||
// ds=[index,field])
|
||||
fn expr_root(tcx: &ty::ctxt, ex: @expr, autoderef: bool)
|
||||
-> {ex: @expr, ds: @[deref]} {
|
||||
fn expr_root(tcx: &ty::ctxt, ex: @expr, autoderef: bool) ->
|
||||
{ex: @expr, ds: @[deref]} {
|
||||
fn maybe_auto_unbox(tcx: &ty::ctxt, t: ty::t) -> {t: ty::t, ds: [deref]} {
|
||||
let ds = [];
|
||||
while true {
|
||||
|
@ -32,13 +32,11 @@ fn expr_root(tcx: &ty::ctxt, ex: @expr, autoderef: bool)
|
|||
ty::ty_tag(did, tps) {
|
||||
let variants = ty::tag_variants(tcx, did);
|
||||
if vec::len(variants) != 1u ||
|
||||
vec::len(variants[0].args) != 1u {
|
||||
vec::len(variants[0].args) != 1u {
|
||||
break;
|
||||
}
|
||||
ds += [@{mut: false, kind: unbox, outer_t: t}];
|
||||
t =
|
||||
ty::substitute_type_params(tcx, tps,
|
||||
variants[0].args[0]);
|
||||
t = ty::substitute_type_params(tcx, tps, variants[0].args[0]);
|
||||
}
|
||||
_ { break; }
|
||||
}
|
||||
|
@ -121,21 +119,25 @@ type ctx = {tcx: ty::ctxt, mut_map: mut_map};
|
|||
|
||||
fn check_crate(tcx: ty::ctxt, crate: &@crate) -> mut_map {
|
||||
let cx = @{tcx: tcx, mut_map: std::map::new_int_hash()};
|
||||
let v = @{visit_expr: bind visit_expr(cx, _, _, _),
|
||||
visit_decl: bind visit_decl(cx, _, _, _)
|
||||
with *visit::default_visitor::<()>()};
|
||||
let v =
|
||||
@{visit_expr: bind visit_expr(cx, _, _, _),
|
||||
visit_decl: bind visit_decl(cx, _, _, _)
|
||||
with *visit::default_visitor::<()>()};
|
||||
visit::visit_crate(*crate, (), visit::mk_vt(v));
|
||||
ret cx.mut_map;
|
||||
}
|
||||
|
||||
tag msg { msg_assign; msg_move_out; msg_mut_alias; }
|
||||
|
||||
fn mk_err(cx: &@ctx, span: &syntax::codemap::span, msg: msg, name: &istr) {
|
||||
cx.tcx.sess.span_err(span, alt msg {
|
||||
msg_assign. { ~"assigning to " + name }
|
||||
msg_move_out. { ~"moving out of " + name }
|
||||
msg_mut_alias. { ~"passing " + name + ~" by mutable alias" }
|
||||
});
|
||||
fn mk_err(cx: &@ctx, span: &syntax::codemap::span, msg: msg, name: &str) {
|
||||
cx.tcx.sess.span_err(span,
|
||||
alt msg {
|
||||
msg_assign. { "assigning to " + name }
|
||||
msg_move_out. { "moving out of " + name }
|
||||
msg_mut_alias. {
|
||||
"passing " + name + " by mutable alias"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_decl(cx: &@ctx, d: &@decl, e: &(), v: &visit::vt<()>) {
|
||||
|
@ -145,9 +147,7 @@ fn visit_decl(cx: &@ctx, d: &@decl, e: &(), v: &visit::vt<()>) {
|
|||
for loc: @local in locs {
|
||||
alt loc.node.init {
|
||||
some(init) {
|
||||
if init.op == init_move {
|
||||
check_move_rhs(cx, init.expr);
|
||||
}
|
||||
if init.op == init_move { check_move_rhs(cx, init.expr); }
|
||||
}
|
||||
none. { }
|
||||
}
|
||||
|
@ -159,9 +159,7 @@ fn visit_decl(cx: &@ctx, d: &@decl, e: &(), v: &visit::vt<()>) {
|
|||
|
||||
fn visit_expr(cx: &@ctx, ex: &@expr, e: &(), v: &visit::vt<()>) {
|
||||
alt ex.node {
|
||||
expr_call(f, args) {
|
||||
check_call(cx, f, args);
|
||||
}
|
||||
expr_call(f, args) { check_call(cx, f, args); }
|
||||
expr_swap(lhs, rhs) {
|
||||
check_lval(cx, lhs, msg_assign);
|
||||
check_lval(cx, rhs, msg_assign);
|
||||
|
@ -173,7 +171,7 @@ fn visit_expr(cx: &@ctx, ex: &@expr, e: &(), v: &visit::vt<()>) {
|
|||
expr_assign(dest, src) | expr_assign_op(_, dest, src) {
|
||||
check_lval(cx, dest, msg_assign);
|
||||
}
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
visit::visit_expr(ex, e, v);
|
||||
}
|
||||
|
@ -184,20 +182,21 @@ fn check_lval(cx: &@ctx, dest: &@expr, msg: msg) {
|
|||
let def = cx.tcx.def_map.get(dest.id);
|
||||
alt is_immutable_def(def) {
|
||||
some(name) { mk_err(cx, dest.span, msg, name); }
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
cx.mut_map.insert(ast_util::def_id_of_def(def).node, ());
|
||||
}
|
||||
_ {
|
||||
let root = expr_root(cx.tcx, dest, false);
|
||||
if vec::len(*root.ds) == 0u {
|
||||
mk_err(cx, dest.span, msg, ~"non-lvalue");
|
||||
mk_err(cx, dest.span, msg, "non-lvalue");
|
||||
} else if !root.ds[0].mut {
|
||||
let name = alt root.ds[0].kind {
|
||||
mut::unbox. { ~"immutable box" }
|
||||
mut::field. { ~"immutable field" }
|
||||
mut::index. { ~"immutable vec content" }
|
||||
};
|
||||
let name =
|
||||
alt root.ds[0].kind {
|
||||
mut::unbox. { "immutable box" }
|
||||
mut::field. { "immutable field" }
|
||||
mut::index. { "immutable vec content" }
|
||||
};
|
||||
mk_err(cx, dest.span, msg, name);
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +208,7 @@ fn check_move_rhs(cx: &@ctx, src: &@expr) {
|
|||
expr_path(p) {
|
||||
alt cx.tcx.def_map.get(src.id) {
|
||||
def_obj_field(_, _) {
|
||||
mk_err(cx, src.span, msg_move_out, ~"object field");
|
||||
mk_err(cx, src.span, msg_move_out, "object field");
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
|
@ -217,17 +216,19 @@ fn check_move_rhs(cx: &@ctx, src: &@expr) {
|
|||
}
|
||||
_ {
|
||||
let root = expr_root(cx.tcx, src, false);
|
||||
|
||||
// Not a path and no-derefs means this is a temporary.
|
||||
if vec::len(*root.ds) != 0u {
|
||||
cx.tcx.sess.span_err(src.span, ~"moving out of a data structure");
|
||||
cx.tcx.sess.span_err(src.span, "moving out of a data structure");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_call(cx: &@ctx, f: &@expr, args: &[@expr]) {
|
||||
let arg_ts = ty::ty_fn_args(cx.tcx, ty::type_autoderef
|
||||
(cx.tcx, ty::expr_ty(cx.tcx, f)));
|
||||
let arg_ts =
|
||||
ty::ty_fn_args(cx.tcx,
|
||||
ty::type_autoderef(cx.tcx, ty::expr_ty(cx.tcx, f)));
|
||||
let i = 0u;
|
||||
for arg_t: ty::arg in arg_ts {
|
||||
if arg_t.mode == ty::mo_alias(true) {
|
||||
|
@ -237,17 +238,18 @@ fn check_call(cx: &@ctx, f: &@expr, args: &[@expr]) {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_immutable_def(def: &def) -> option::t<istr> {
|
||||
fn is_immutable_def(def: &def) -> option::t<str> {
|
||||
alt def {
|
||||
def_fn(_, _) | def_mod(_) | def_native_mod(_) | def_const(_) |
|
||||
def_use(_) { some(~"static item") }
|
||||
def_obj_field(_, imm.) { some(~"immutable object field") }
|
||||
def_arg(_, alias(false)) { some(~"immutable alias") }
|
||||
def_upvar(_, inner, mut) {
|
||||
if !mut { some(~"upvar") }
|
||||
else { is_immutable_def(*inner) }
|
||||
def_use(_) {
|
||||
some("static item")
|
||||
}
|
||||
def_binding(_) { some(~"binding") }
|
||||
def_obj_field(_, imm.) { some("immutable object field") }
|
||||
def_arg(_, alias(false)) { some("immutable alias") }
|
||||
def_upvar(_, inner, mut) {
|
||||
if !mut { some("upvar") } else { is_immutable_def(*inner) }
|
||||
}
|
||||
def_binding(_) { some("binding") }
|
||||
_ { none }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,10 +74,10 @@ tag import_state {
|
|||
option::t<def>); /* module */
|
||||
}
|
||||
|
||||
type ext_hash = hashmap<{did: def_id, ident: istr, ns: namespace}, def>;
|
||||
type ext_hash = hashmap<{did: def_id, ident: str, ns: namespace}, def>;
|
||||
|
||||
fn new_ext_hash() -> ext_hash {
|
||||
type key = {did: def_id, ident: istr, ns: namespace};
|
||||
type key = {did: def_id, ident: str, ns: namespace};
|
||||
fn hash(v: &key) -> uint {
|
||||
ret str::hash(v.ident) + util::common::hash_def(v.did) +
|
||||
alt v.ns {
|
||||
|
@ -110,7 +110,7 @@ type indexed_mod =
|
|||
{m: option::t<ast::_mod>,
|
||||
index: mod_index,
|
||||
mutable glob_imports: [glob_imp_def],
|
||||
glob_imported_names: hashmap<istr, import_state>};
|
||||
glob_imported_names: hashmap<str, import_state>};
|
||||
|
||||
|
||||
/* native modules can't contain tags, and we don't store their ASTs because we
|
||||
|
@ -127,7 +127,7 @@ type env =
|
|||
mod_map: hashmap<ast::node_id, @indexed_mod>,
|
||||
ext_map: hashmap<def_id, [ident]>,
|
||||
ext_cache: ext_hash,
|
||||
mutable reported: [{ident: istr, sc: scope}],
|
||||
mutable reported: [{ident: str, sc: scope}],
|
||||
sess: session};
|
||||
|
||||
|
||||
|
@ -242,6 +242,7 @@ fn map_crate(e: &@env, c: &@ast::crate) {
|
|||
alt vi.node {
|
||||
|
||||
|
||||
|
||||
//if it really is a glob import, that is
|
||||
ast::view_item_import_glob(path, _) {
|
||||
let imp = follow_import(*e, sc, path, vi.span);
|
||||
|
@ -323,8 +324,8 @@ fn resolve_names(e: &@env, c: &@ast::crate) {
|
|||
}
|
||||
_ {
|
||||
e.sess.span_err(p.span,
|
||||
~"not a tag variant: " +
|
||||
ast_util::path_name(p));
|
||||
"not a tag variant: " +
|
||||
ast_util::path_name(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -430,8 +431,8 @@ fn follow_import(e: &env, sc: &scopes, path: &[ident], sp: &span) ->
|
|||
ast::def_mod(_) | ast::def_native_mod(_) { ret dcur; }
|
||||
_ {
|
||||
e.sess.span_err(sp,
|
||||
str::connect(path, ~"::") +
|
||||
~" does not name a module.");
|
||||
str::connect(path, "::") +
|
||||
" does not name a module.");
|
||||
ret none;
|
||||
}
|
||||
}
|
||||
|
@ -448,8 +449,8 @@ fn resolve_constr(e: @env, c: &@ast::constr, sc: &scopes, _v: &vt<scopes>) {
|
|||
}
|
||||
_ {
|
||||
e.sess.span_err(c.span,
|
||||
~"Non-predicate in constraint: " +
|
||||
path_to_str(c.node.path));
|
||||
"Non-predicate in constraint: " +
|
||||
path_to_str(c.node.path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -475,8 +476,7 @@ fn resolve_import(e: &env, defid: ast::def_id, name: &ast::ident,
|
|||
alt lookup_in_scope(e, sc, sp, ids[0], ns_module) {
|
||||
some(dcur) { dcur }
|
||||
none. {
|
||||
unresolved_err(e, sc, sp, ids[0],
|
||||
ns_name(ns_module));
|
||||
unresolved_err(e, sc, sp, ids[0], ns_name(ns_module));
|
||||
remove_if_unresolved(e.imports, defid.node);
|
||||
ret ()
|
||||
}
|
||||
|
@ -498,8 +498,7 @@ fn resolve_import(e: &env, defid: ast::def_id, name: &ast::ident,
|
|||
{
|
||||
some(dcur) { dcur }
|
||||
none. {
|
||||
unresolved_err(e, sc, sp, ids[i],
|
||||
ns_name(ns_module));
|
||||
unresolved_err(e, sc, sp, ids[i], ns_name(ns_module));
|
||||
remove_if_unresolved(e.imports, defid.node);
|
||||
ret () // FIXME (issue #521)
|
||||
}
|
||||
|
@ -512,7 +511,7 @@ fn resolve_import(e: &env, defid: ast::def_id, name: &ast::ident,
|
|||
val: &option::t<def>, typ: &option::t<def>,
|
||||
md: &option::t<def>) {
|
||||
if is_none(val) && is_none(typ) && is_none(md) {
|
||||
unresolved_err(e, sc, sp, name, ~"import");
|
||||
unresolved_err(e, sc, sp, name, "import");
|
||||
} else { e.imports.insert(defid.node, resolved(val, typ, md)); }
|
||||
}
|
||||
fn remove_if_unresolved(imports: hashmap<ast::node_id, import_state>,
|
||||
|
@ -532,16 +531,15 @@ fn resolve_import(e: &env, defid: ast::def_id, name: &ast::ident,
|
|||
|
||||
|
||||
// Utilities
|
||||
fn ns_name(ns: namespace) -> istr {
|
||||
fn ns_name(ns: namespace) -> str {
|
||||
alt ns {
|
||||
ns_type. { ret ~"typename"; }
|
||||
ns_value. { ret ~"name"; }
|
||||
ns_module. { ret ~"modulename"; }
|
||||
ns_type. { ret "typename"; }
|
||||
ns_value. { ret "name"; }
|
||||
ns_module. { ret "modulename"; }
|
||||
}
|
||||
}
|
||||
|
||||
fn unresolved_err(e: &env, sc: &scopes, sp: &span,
|
||||
name: &ident, kind: &istr) {
|
||||
fn unresolved_err(e: &env, sc: &scopes, sp: &span, name: &ident, kind: &str) {
|
||||
fn find_fn_or_mod_scope(sc: scopes) -> scope {
|
||||
while true {
|
||||
alt sc {
|
||||
|
@ -559,19 +557,18 @@ fn unresolved_err(e: &env, sc: &scopes, sp: &span,
|
|||
fail;
|
||||
}
|
||||
let err_scope = find_fn_or_mod_scope(sc);
|
||||
for rs: {ident: istr, sc: scope} in e.reported {
|
||||
if str::eq(rs.ident, name)
|
||||
&& err_scope == rs.sc { ret; }
|
||||
for rs: {ident: str, sc: scope} in e.reported {
|
||||
if str::eq(rs.ident, name) && err_scope == rs.sc { ret; }
|
||||
}
|
||||
e.reported += [{ident: name, sc: err_scope}];
|
||||
e.sess.span_err(sp, mk_unresolved_msg(name, kind));
|
||||
}
|
||||
|
||||
fn unresolved_fatal(e: &env, sp: &span, id: &ident, kind: &istr) -> ! {
|
||||
fn unresolved_fatal(e: &env, sp: &span, id: &ident, kind: &str) -> ! {
|
||||
e.sess.span_fatal(sp, mk_unresolved_msg(id, kind));
|
||||
}
|
||||
|
||||
fn mk_unresolved_msg(id: &ident, kind: &istr) -> istr {
|
||||
fn mk_unresolved_msg(id: &ident, kind: &str) -> str {
|
||||
ret #fmt["unresolved %s: %s", kind, id];
|
||||
}
|
||||
|
||||
|
@ -603,8 +600,7 @@ fn lookup_path_strict(e: &env, sc: &scopes, sp: &span, pth: &ast::path_,
|
|||
fn lookup_in_scope_strict(e: &env, sc: scopes, sp: &span, name: &ident,
|
||||
ns: namespace) -> option::t<def> {
|
||||
alt lookup_in_scope(e, sc, sp, name, ns) {
|
||||
none. { unresolved_err(e, sc, sp, name,
|
||||
ns_name(ns)); ret none; }
|
||||
none. { unresolved_err(e, sc, sp, name, ns_name(ns)); ret none; }
|
||||
some(d) { ret some(d); }
|
||||
}
|
||||
}
|
||||
|
@ -629,10 +625,12 @@ fn scope_closes(sc: &scope) -> option::t<bool> {
|
|||
|
||||
fn def_is_local(d: &def) -> bool {
|
||||
ret alt d {
|
||||
ast::def_arg(_, _) | ast::def_local(_) | ast::def_binding(_) |
|
||||
ast::def_upvar(_, _, _) { true }
|
||||
_ { false }
|
||||
};
|
||||
ast::def_arg(_, _) | ast::def_local(_) | ast::def_binding(_) |
|
||||
ast::def_upvar(_, _, _) {
|
||||
true
|
||||
}
|
||||
_ { false }
|
||||
};
|
||||
}
|
||||
|
||||
fn def_is_obj_field(d: &def) -> bool {
|
||||
|
@ -715,24 +713,23 @@ fn lookup_in_scope(e: &env, sc: scopes, sp: &span, name: &ident,
|
|||
if !is_none(fnd) {
|
||||
let df = option::get(fnd);
|
||||
let local = def_is_local(df);
|
||||
if left_fn && local ||
|
||||
left_fn_level2 && def_is_obj_field(df) ||
|
||||
scope_is_fn(hd) && left_fn && def_is_ty_arg(df) {
|
||||
let msg = alt ns {
|
||||
ns_type. {
|
||||
~"Attempt to use a type argument out of scope"
|
||||
}
|
||||
_ {
|
||||
~"attempted dynamic environment-capture"
|
||||
}
|
||||
};
|
||||
if left_fn && local || left_fn_level2 && def_is_obj_field(df)
|
||||
|| scope_is_fn(hd) && left_fn && def_is_ty_arg(df) {
|
||||
let msg =
|
||||
alt ns {
|
||||
ns_type. {
|
||||
"Attempt to use a type argument out of scope"
|
||||
}
|
||||
_ { "attempted dynamic environment-capture" }
|
||||
};
|
||||
e.sess.span_fatal(sp, msg);
|
||||
} else if local {
|
||||
let i = vec::len(closing);
|
||||
while i > 0u {
|
||||
i -= 1u;
|
||||
df = ast::def_upvar(ast_util::def_id_of_def(df),
|
||||
@df, closing[i]);
|
||||
df =
|
||||
ast::def_upvar(ast_util::def_id_of_def(df), @df,
|
||||
closing[i]);
|
||||
fnd = some(df);
|
||||
}
|
||||
}
|
||||
|
@ -742,16 +739,13 @@ fn lookup_in_scope(e: &env, sc: scopes, sp: &span, name: &ident,
|
|||
left_fn_level2 = true;
|
||||
} else if ns == ns_value || ns == ns_type {
|
||||
left_fn = scope_is_fn(hd);
|
||||
alt scope_closes(hd) {
|
||||
some(mut) { closing += [mut]; }
|
||||
_ {}
|
||||
}
|
||||
alt scope_closes(hd) { some(mut) { closing += [mut]; } _ { } }
|
||||
}
|
||||
sc = *tl;
|
||||
}
|
||||
}
|
||||
}
|
||||
e.sess.bug(~"reached unreachable code in lookup_in_scope"); // sigh
|
||||
e.sess.bug("reached unreachable code in lookup_in_scope"); // sigh
|
||||
|
||||
}
|
||||
|
||||
|
@ -912,8 +906,7 @@ fn found_def_item(i: &@ast::item, ns: namespace) -> option::t<def> {
|
|||
fn lookup_in_mod_strict(e: &env, sc: &scopes, m: def, sp: &span, name: &ident,
|
||||
ns: namespace, dr: dir) -> option::t<def> {
|
||||
alt lookup_in_mod(e, m, sp, name, ns, dr) {
|
||||
none. { unresolved_err(e, sc, sp, name,
|
||||
ns_name(ns)); ret none; }
|
||||
none. { unresolved_err(e, sc, sp, name, ns_name(ns)); ret none; }
|
||||
some(d) { ret some(d); }
|
||||
}
|
||||
}
|
||||
|
@ -924,15 +917,13 @@ fn lookup_in_mod(e: &env, m: &def, sp: &span, name: &ident, ns: namespace,
|
|||
if defid.crate != ast::local_crate {
|
||||
// examining a module in an external crate
|
||||
|
||||
let cached = e.ext_cache.find({did: defid,
|
||||
ident: name, ns: ns});
|
||||
let cached = e.ext_cache.find({did: defid, ident: name, ns: ns});
|
||||
if !is_none(cached) { ret cached; }
|
||||
let path = [name];
|
||||
if defid.node != -1 { path = e.ext_map.get(defid) + path; }
|
||||
let fnd = lookup_external(e, defid.crate, path, ns);
|
||||
if !is_none(fnd) {
|
||||
e.ext_cache.insert({did: defid,
|
||||
ident: name, ns: ns},
|
||||
e.ext_cache.insert({did: defid, ident: name, ns: ns},
|
||||
option::get(fnd));
|
||||
}
|
||||
ret fnd;
|
||||
|
@ -962,7 +953,7 @@ fn lookup_import(e: &env, defid: def_id, ns: namespace) -> option::t<def> {
|
|||
resolve_import(e, local_def(node_id), name, path, span, scopes);
|
||||
ret lookup_import(e, defid, ns);
|
||||
}
|
||||
resolving(sp) { e.sess.span_err(sp, ~"cyclic import"); ret none; }
|
||||
resolving(sp) { e.sess.span_err(sp, "cyclic import"); ret none; }
|
||||
resolved(val, typ, md) {
|
||||
ret alt ns { ns_value. { val } ns_type. { typ } ns_module. { md } };
|
||||
}
|
||||
|
@ -1026,13 +1017,11 @@ fn lookup_glob_in_mod(e: &env, info: @indexed_mod, sp: &span, id: &ident,
|
|||
} else {
|
||||
for match: glob_imp_def in matches {
|
||||
let sp = match.item.span;
|
||||
e.sess.span_note(
|
||||
sp, #fmt["'%s' is imported here", id]);
|
||||
e.sess.span_note(sp, #fmt["'%s' is imported here", id]);
|
||||
}
|
||||
e.sess.span_fatal(sp,
|
||||
~"'" + id
|
||||
+ ~"' is glob-imported from" +
|
||||
~" multiple different modules.");
|
||||
"'" + id + "' is glob-imported from" +
|
||||
" multiple different modules.");
|
||||
}
|
||||
}
|
||||
// since we don't know what names we have in advance,
|
||||
|
@ -1043,11 +1032,10 @@ fn lookup_glob_in_mod(e: &env, info: @indexed_mod, sp: &span, id: &ident,
|
|||
let val = per_ns(e, info, sp, id, ns_value, dr);
|
||||
let typ = per_ns(e, info, sp, id, ns_type, dr);
|
||||
let md = per_ns(e, info, sp, id, ns_module, dr);
|
||||
info.glob_imported_names.insert(id,
|
||||
resolved(val, typ, md));
|
||||
info.glob_imported_names.insert(id, resolved(val, typ, md));
|
||||
}
|
||||
alt info.glob_imported_names.get(id) {
|
||||
todo(_, _, _, _, _) { e.sess.bug(~"Shouldn't've put a todo in."); }
|
||||
todo(_, _, _, _, _) { e.sess.bug("Shouldn't've put a todo in."); }
|
||||
resolving(sp) {
|
||||
ret none::<def>; //circularity is okay in import globs
|
||||
|
||||
|
@ -1101,11 +1089,10 @@ fn lookup_in_mie(e: &env, mie: &mod_index_entry, ns: namespace) ->
|
|||
|
||||
|
||||
// Module indexing
|
||||
fn add_to_index(index: &hashmap<ident, list<mod_index_entry>>,
|
||||
id: &ident, ent: &mod_index_entry) {
|
||||
fn add_to_index(index: &hashmap<ident, list<mod_index_entry>>, id: &ident,
|
||||
ent: &mod_index_entry) {
|
||||
alt index.find(id) {
|
||||
none. { index.insert(id,
|
||||
cons(ent, @nil::<mod_index_entry>)); }
|
||||
none. { index.insert(id, cons(ent, @nil::<mod_index_entry>)); }
|
||||
some(prev) { index.insert(id, cons(ent, @prev)); }
|
||||
}
|
||||
}
|
||||
|
@ -1119,11 +1106,13 @@ fn index_mod(md: &ast::_mod) -> mod_index {
|
|||
}
|
||||
|
||||
|
||||
|
||||
ast::view_item_import(ident, _, id) {
|
||||
add_to_index(index, ident, mie_import_ident(id, it.span));
|
||||
}
|
||||
|
||||
|
||||
|
||||
ast::view_item_import_from(_, idents, _) {
|
||||
for ident in idents {
|
||||
add_to_index(index, ident.node.name,
|
||||
|
@ -1132,6 +1121,7 @@ fn index_mod(md: &ast::_mod) -> mod_index {
|
|||
}
|
||||
|
||||
|
||||
|
||||
//globbed imports have to be resolved lazily.
|
||||
ast::view_item_import_glob(_, _) | ast::view_item_export(_, _) {
|
||||
}
|
||||
|
@ -1238,26 +1228,25 @@ fn check_mod_name(e: &env, name: &ident, entries: list<mod_index_entry>) {
|
|||
let saw_mod = false;
|
||||
let saw_type = false;
|
||||
let saw_value = false;
|
||||
fn dup(e: &env, sp: &span, word: &istr, name: &ident) {
|
||||
e.sess.span_fatal(sp, ~"duplicate definition of " +
|
||||
word + name);
|
||||
fn dup(e: &env, sp: &span, word: &str, name: &ident) {
|
||||
e.sess.span_fatal(sp, "duplicate definition of " + word + name);
|
||||
}
|
||||
while true {
|
||||
alt entries {
|
||||
cons(entry, rest) {
|
||||
if !is_none(lookup_in_mie(e, entry, ns_value)) {
|
||||
if saw_value {
|
||||
dup(e, mie_span(entry), ~"", name);
|
||||
dup(e, mie_span(entry), "", name);
|
||||
} else { saw_value = true; }
|
||||
}
|
||||
if !is_none(lookup_in_mie(e, entry, ns_type)) {
|
||||
if saw_type {
|
||||
dup(e, mie_span(entry), ~"type ", name);
|
||||
dup(e, mie_span(entry), "type ", name);
|
||||
} else { saw_type = true; }
|
||||
}
|
||||
if !is_none(lookup_in_mie(e, entry, ns_module)) {
|
||||
if saw_mod {
|
||||
dup(e, mie_span(entry), ~"module ", name);
|
||||
dup(e, mie_span(entry), "module ", name);
|
||||
} else { saw_mod = true; }
|
||||
}
|
||||
entries = *rest;
|
||||
|
@ -1288,20 +1277,20 @@ fn check_item(e: &@env, i: &@ast::item, x: &(), v: &vt<()>) {
|
|||
ast::item_fn(f, ty_params) {
|
||||
check_fn(*e, i.span, f);
|
||||
ensure_unique(*e, i.span, typaram_names(ty_params), ident_id,
|
||||
~"type parameter");
|
||||
"type parameter");
|
||||
}
|
||||
ast::item_obj(ob, ty_params, _) {
|
||||
fn field_name(field: &ast::obj_field) -> ident { ret field.ident; }
|
||||
ensure_unique(*e, i.span, ob.fields, field_name, ~"object field");
|
||||
ensure_unique(*e, i.span, ob.fields, field_name, "object field");
|
||||
for m: @ast::method in ob.methods {
|
||||
check_fn(*e, m.span, m.node.meth);
|
||||
}
|
||||
ensure_unique(*e, i.span, typaram_names(ty_params), ident_id,
|
||||
~"type parameter");
|
||||
"type parameter");
|
||||
}
|
||||
ast::item_tag(_, ty_params) {
|
||||
ensure_unique(*e, i.span, typaram_names(ty_params), ident_id,
|
||||
~"type parameter");
|
||||
"type parameter");
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
|
@ -1316,28 +1305,28 @@ fn check_pat(ch: checker, p: &@ast::pat) {
|
|||
|
||||
fn check_arm(e: &@env, a: &ast::arm, x: &(), v: &vt<()>) {
|
||||
visit::visit_arm(a, x, v);
|
||||
let ch0 = checker(*e, ~"binding");
|
||||
let ch0 = checker(*e, "binding");
|
||||
check_pat(ch0, a.pats[0]);
|
||||
let seen0 = ch0.seen;
|
||||
let i = vec::len(a.pats);
|
||||
while i > 1u {
|
||||
i -= 1u;
|
||||
let ch = checker(*e, ~"binding");
|
||||
let ch = checker(*e, "binding");
|
||||
check_pat(ch, a.pats[i]);
|
||||
|
||||
// Ensure the bindings introduced in this pattern are the same as in
|
||||
// the first pattern.
|
||||
if vec::len(ch.seen) != vec::len(seen0) {
|
||||
e.sess.span_err(a.pats[i].span,
|
||||
~"inconsistent number of bindings");
|
||||
"inconsistent number of bindings");
|
||||
} else {
|
||||
for name: ident in ch.seen {
|
||||
if is_none(vec::find(bind str::eq(name, _), seen0)) {
|
||||
// Fight the alias checker
|
||||
let name_ = name;
|
||||
e.sess.span_err(a.pats[i].span,
|
||||
~"binding " + name_ +
|
||||
~" does not occur in first pattern");
|
||||
"binding " + name_ +
|
||||
" does not occur in first pattern");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1346,15 +1335,15 @@ fn check_arm(e: &@env, a: &ast::arm, x: &(), v: &vt<()>) {
|
|||
|
||||
fn check_block(e: &@env, b: &ast::blk, x: &(), v: &vt<()>) {
|
||||
visit::visit_block(b, x, v);
|
||||
let values = checker(*e, ~"value");
|
||||
let types = checker(*e, ~"type");
|
||||
let mods = checker(*e, ~"module");
|
||||
let values = checker(*e, "value");
|
||||
let types = checker(*e, "type");
|
||||
let mods = checker(*e, "module");
|
||||
for st: @ast::stmt in b.node.stmts {
|
||||
alt st.node {
|
||||
ast::stmt_decl(d, _) {
|
||||
alt d.node {
|
||||
ast::decl_local(locs) {
|
||||
let local_values = checker(*e, ~"value");
|
||||
let local_values = checker(*e, "value");
|
||||
for loc in locs {
|
||||
for each p in ast_util::pat_bindings(loc.node.pat) {
|
||||
let ident = alt p.node { pat_bind(n) { n } };
|
||||
|
@ -1394,14 +1383,14 @@ fn check_block(e: &@env, b: &ast::blk, x: &(), v: &vt<()>) {
|
|||
|
||||
fn check_fn(e: &env, sp: &span, f: &ast::_fn) {
|
||||
fn arg_name(a: &ast::arg) -> ident { ret a.ident; }
|
||||
ensure_unique(e, sp, f.decl.inputs, arg_name, ~"argument");
|
||||
ensure_unique(e, sp, f.decl.inputs, arg_name, "argument");
|
||||
}
|
||||
|
||||
fn check_expr(e: &@env, ex: &@ast::expr, x: &(), v: &vt<()>) {
|
||||
alt ex.node {
|
||||
ast::expr_rec(fields, _) {
|
||||
fn field_name(f: &ast::field) -> ident { ret f.node.ident; }
|
||||
ensure_unique(*e, ex.span, fields, field_name, ~"field");
|
||||
ensure_unique(*e, ex.span, fields, field_name, "field");
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
|
@ -1412,16 +1401,16 @@ fn check_ty(e: &@env, ty: &@ast::ty, x: &(), v: &vt<()>) {
|
|||
alt ty.node {
|
||||
ast::ty_rec(fields) {
|
||||
fn field_name(f: &ast::ty_field) -> ident { ret f.node.ident; }
|
||||
ensure_unique(*e, ty.span, fields, field_name, ~"field");
|
||||
ensure_unique(*e, ty.span, fields, field_name, "field");
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
visit::visit_ty(ty, x, v);
|
||||
}
|
||||
|
||||
type checker = @{mutable seen: [ident], kind: istr, sess: session};
|
||||
type checker = @{mutable seen: [ident], kind: str, sess: session};
|
||||
|
||||
fn checker(e: &env, kind: &istr) -> checker {
|
||||
fn checker(e: &env, kind: &str) -> checker {
|
||||
let seen: [ident] = [];
|
||||
ret @{mutable seen: seen, kind: kind, sess: e.sess};
|
||||
}
|
||||
|
@ -1429,8 +1418,7 @@ fn checker(e: &env, kind: &istr) -> checker {
|
|||
fn check_name(ch: &checker, sp: &span, name: &ident) {
|
||||
for s: ident in ch.seen {
|
||||
if str::eq(s, name) {
|
||||
ch.sess.span_fatal(sp, ~"duplicate " + ch.kind
|
||||
+ ~" name: " + name);
|
||||
ch.sess.span_fatal(sp, "duplicate " + ch.kind + " name: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1442,23 +1430,23 @@ fn add_name(ch: &checker, sp: &span, name: &ident) {
|
|||
fn ident_id(i: &ident) -> ident { ret i; }
|
||||
|
||||
fn ensure_unique<T>(e: &env, sp: &span, elts: &[T], id: fn(&T) -> ident,
|
||||
kind: &istr) {
|
||||
kind: &str) {
|
||||
let ch = checker(e, kind);
|
||||
for elt: T in elts { add_name(ch, sp, id(elt)); }
|
||||
}
|
||||
|
||||
fn check_bad_exports(e: &@env) {
|
||||
fn lookup_glob_any(e: &env, info: &@indexed_mod, sp: &span,
|
||||
ident: &ident) -> bool {
|
||||
ret !option::is_none(lookup_glob_in_mod(e, info, sp, ident,
|
||||
ns_module, inside)) ||
|
||||
!option::is_none(lookup_glob_in_mod(e, info, sp, ident,
|
||||
ns_value, inside)) ||
|
||||
!option::is_none(lookup_glob_in_mod(e, info, sp, ident,
|
||||
ns_type, inside));
|
||||
fn lookup_glob_any(e: &env, info: &@indexed_mod, sp: &span, ident: &ident)
|
||||
-> bool {
|
||||
ret !option::is_none(lookup_glob_in_mod(e, info, sp, ident, ns_module,
|
||||
inside)) ||
|
||||
!option::is_none(lookup_glob_in_mod(e, info, sp, ident,
|
||||
ns_value, inside)) ||
|
||||
!option::is_none(lookup_glob_in_mod(e, info, sp, ident,
|
||||
ns_type, inside));
|
||||
}
|
||||
|
||||
for each @{val, _} in e.mod_map.items() {
|
||||
for each @{val: val, _} in e.mod_map.items() {
|
||||
alt val.m {
|
||||
some(m) {
|
||||
for vi in m.view_items {
|
||||
|
@ -1466,17 +1454,18 @@ fn check_bad_exports(e: &@env) {
|
|||
ast::view_item_export(idents, _) {
|
||||
for ident in idents {
|
||||
if !val.index.contains_key(ident) &&
|
||||
!lookup_glob_any(*e, val, vi.span, ident) {
|
||||
e.sess.span_warn(vi.span, ~"exported item " +
|
||||
ident + ~" is not defined");
|
||||
!lookup_glob_any(*e, val, vi.span, ident) {
|
||||
e.sess.span_warn(vi.span,
|
||||
"exported item " + ident +
|
||||
" is not defined");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
}
|
||||
none. {}
|
||||
none. { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,15 +84,18 @@ fn eq_res_info(a: &res_info, b: &res_info) -> bool {
|
|||
ret a.did.crate == b.did.crate && a.did.node == b.did.node && a.t == b.t;
|
||||
}
|
||||
|
||||
fn mk_global(ccx: &@crate_ctxt, name: &istr, llval: ValueRef,
|
||||
internal: bool) -> ValueRef {
|
||||
let llglobal = str::as_buf(name, { |buf|
|
||||
lib::llvm::llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf)
|
||||
});
|
||||
fn mk_global(ccx: &@crate_ctxt, name: &str, llval: ValueRef, internal: bool)
|
||||
-> ValueRef {
|
||||
let llglobal =
|
||||
str::as_buf(name,
|
||||
{|buf|
|
||||
lib::llvm::llvm::LLVMAddGlobal(ccx.llmod,
|
||||
val_ty(llval), buf)
|
||||
});
|
||||
lib::llvm::llvm::LLVMSetInitializer(llglobal, llval);
|
||||
lib::llvm::llvm::LLVMSetGlobalConstant(llglobal, True);
|
||||
|
||||
if (internal) {
|
||||
if internal {
|
||||
lib::llvm::llvm::LLVMSetLinkage(llglobal,
|
||||
lib::llvm::LLVMInternalLinkage as
|
||||
lib::llvm::llvm::Linkage);
|
||||
|
@ -256,10 +259,13 @@ fn s_float(_tcx: &ty_ctxt) -> u8 {
|
|||
}
|
||||
|
||||
fn mk_ctxt(llmod: ModuleRef) -> ctxt {
|
||||
let llshapetablesty = trans_common::T_named_struct(~"shapes");
|
||||
let llshapetables = str::as_buf(~"shapes", { |buf|
|
||||
lib::llvm::llvm::LLVMAddGlobal(llmod, llshapetablesty, buf)
|
||||
});
|
||||
let llshapetablesty = trans_common::T_named_struct("shapes");
|
||||
let llshapetables =
|
||||
str::as_buf("shapes",
|
||||
{|buf|
|
||||
lib::llvm::llvm::LLVMAddGlobal(llmod, llshapetablesty,
|
||||
buf)
|
||||
});
|
||||
|
||||
ret {mutable next_tag_id: 0u16,
|
||||
pad: 0u16,
|
||||
|
@ -292,17 +298,20 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
}
|
||||
|
||||
|
||||
|
||||
ty::ty_int. {
|
||||
s += [s_int(ccx.tcx)];
|
||||
}
|
||||
ty::ty_float. { s += [s_float(ccx.tcx)]; }
|
||||
|
||||
|
||||
|
||||
ty::ty_uint. | ty::ty_ptr(_) | ty::ty_type. | ty::ty_native(_) {
|
||||
s += [s_uint(ccx.tcx)];
|
||||
}
|
||||
|
||||
|
||||
|
||||
ty::ty_machine(ast::ty_i8.) {
|
||||
s += [shape_i8];
|
||||
}
|
||||
|
@ -314,6 +323,7 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
ty::ty_machine(ast::ty_i64.) { s += [shape_i64]; }
|
||||
|
||||
|
||||
|
||||
ty::ty_istr. {
|
||||
s += [shape_vec];
|
||||
add_bool(s, true); // type is POD
|
||||
|
@ -321,6 +331,7 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
add_substr(s, shape_of(ccx, unit_ty, ty_param_map));
|
||||
}
|
||||
|
||||
|
||||
ty::ty_tag(did, tps) {
|
||||
alt tag_kind(ccx, did) {
|
||||
tk_unit. {
|
||||
|
@ -358,6 +369,7 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
}
|
||||
|
||||
|
||||
|
||||
ty::ty_box(mt) {
|
||||
s += [shape_box];
|
||||
add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
|
||||
|
@ -387,6 +399,7 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
}
|
||||
|
||||
|
||||
|
||||
ty::ty_fn(_, _, _, _, _) {
|
||||
s += [shape_fn];
|
||||
}
|
||||
|
@ -394,6 +407,7 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
ty::ty_obj(_) { s += [shape_obj]; }
|
||||
|
||||
|
||||
|
||||
ty::ty_res(did, raw_subt, tps) {
|
||||
let subt = ty::substitute_type_params(ccx.tcx, tps, raw_subt);
|
||||
let ri = {did: did, t: subt};
|
||||
|
@ -409,15 +423,17 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
|
||||
}
|
||||
|
||||
|
||||
ty::ty_var(n) {
|
||||
fail "shape_of ty_var";
|
||||
}
|
||||
|
||||
|
||||
ty::ty_param(n, _) {
|
||||
// Find the type parameter in the parameter list.
|
||||
let found = false;
|
||||
let i = 0u;
|
||||
while (i < vec::len(ty_param_map)) {
|
||||
while i < vec::len(ty_param_map) {
|
||||
if n == ty_param_map[i] {
|
||||
s += [shape_var, i as u8];
|
||||
found = true;
|
||||
|
@ -425,7 +441,7 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
}
|
||||
i += 1u;
|
||||
}
|
||||
assert found;
|
||||
assert (found);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -433,15 +449,11 @@ fn shape_of(ccx: &@crate_ctxt, t: ty::t, ty_param_map: &[uint]) -> [u8] {
|
|||
}
|
||||
|
||||
// FIXME: We might discover other variants as we traverse these. Handle this.
|
||||
fn shape_of_variant(ccx: &@crate_ctxt,
|
||||
v: &ty::variant_info,
|
||||
fn shape_of_variant(ccx: &@crate_ctxt, v: &ty::variant_info,
|
||||
ty_param_count: uint) -> [u8] {
|
||||
let ty_param_map = [];
|
||||
let i = 0u;
|
||||
while (i < ty_param_count) {
|
||||
ty_param_map += [i];
|
||||
i += 1u;
|
||||
}
|
||||
while i < ty_param_count { ty_param_map += [i]; i += 1u; }
|
||||
|
||||
let s = [];
|
||||
for t: ty::t in v.args { s += shape_of(ccx, t, ty_param_map); }
|
||||
|
@ -540,7 +552,7 @@ fn gen_tag_shapes(ccx: &@crate_ctxt) -> ValueRef {
|
|||
header += data;
|
||||
header += lv_table;
|
||||
|
||||
ret mk_global(ccx, ~"tag_shapes", C_bytes(header), true);
|
||||
ret mk_global(ccx, "tag_shapes", C_bytes(header), true);
|
||||
}
|
||||
|
||||
fn gen_resource_shapes(ccx: &@crate_ctxt) -> ValueRef {
|
||||
|
@ -553,7 +565,7 @@ fn gen_resource_shapes(ccx: &@crate_ctxt) -> ValueRef {
|
|||
i += 1u;
|
||||
}
|
||||
|
||||
ret mk_global(ccx, ~"resource_shapes", C_struct(dtors), true);
|
||||
ret mk_global(ccx, "resource_shapes", C_struct(dtors), true);
|
||||
}
|
||||
|
||||
fn gen_shape_tables(ccx: &@crate_ctxt) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -57,7 +57,7 @@ fn variant_opt(ccx: &@crate_ctxt, pat_id: ast::node_id) -> opt {
|
|||
}
|
||||
|
||||
type bind_map = [{ident: ast::ident, val: ValueRef}];
|
||||
fn assoc(key: &istr, list: &bind_map) -> option::t<ValueRef> {
|
||||
fn assoc(key: &str, list: &bind_map) -> option::t<ValueRef> {
|
||||
for elt: {ident: ast::ident, val: ValueRef} in list {
|
||||
if str::eq(elt.ident, key) { ret some(elt.val); }
|
||||
}
|
||||
|
@ -67,9 +67,10 @@ fn assoc(key: &istr, list: &bind_map) -> option::t<ValueRef> {
|
|||
type match_branch =
|
||||
@{pats: [@ast::pat],
|
||||
bound: bind_map,
|
||||
data: @{body: BasicBlockRef,
|
||||
guard: option::t<@ast::expr>,
|
||||
id_map: ast_util::pat_id_map}};
|
||||
data:
|
||||
@{body: BasicBlockRef,
|
||||
guard: option::t<@ast::expr>,
|
||||
id_map: ast_util::pat_id_map}};
|
||||
type match = [match_branch];
|
||||
|
||||
fn matches_always(p: &@ast::pat) -> bool {
|
||||
|
@ -89,16 +90,18 @@ fn enter_match(m: &match, col: uint, val: ValueRef, e: &enter_pat) -> match {
|
|||
for br: match_branch in m {
|
||||
alt e(br.pats[col]) {
|
||||
some(sub) {
|
||||
let pats = vec::slice(br.pats, 0u, col) + sub +
|
||||
let pats =
|
||||
vec::slice(br.pats, 0u, col) + sub +
|
||||
vec::slice(br.pats, col + 1u, vec::len(br.pats));
|
||||
let new_br = @{pats: pats,
|
||||
bound: alt br.pats[col].node {
|
||||
ast::pat_bind(name) {
|
||||
br.bound + [{ident: name, val: val}]
|
||||
}
|
||||
_ { br.bound }
|
||||
}
|
||||
with *br};
|
||||
let new_br =
|
||||
@{pats: pats,
|
||||
bound:
|
||||
alt br.pats[col].node {
|
||||
ast::pat_bind(name) {
|
||||
br.bound + [{ident: name, val: val}]
|
||||
}
|
||||
_ { br.bound }
|
||||
} with *br};
|
||||
result += [new_br];
|
||||
}
|
||||
none. { }
|
||||
|
@ -211,15 +214,14 @@ fn extract_variant_args(bcx: @block_ctxt, pat_id: ast::node_id,
|
|||
vec::len(ty::tag_variant_with_id(ccx.tcx, vdefs.tg, vdefs.var).args);
|
||||
if size > 0u && vec::len(variants) != 1u {
|
||||
let tagptr =
|
||||
PointerCast(bcx, val,
|
||||
trans_common::T_opaque_tag_ptr(ccx.tn));
|
||||
PointerCast(bcx, val, trans_common::T_opaque_tag_ptr(ccx.tn));
|
||||
blobptr = GEP(bcx, tagptr, [C_int(0), C_int(1)]);
|
||||
}
|
||||
let i = 0u;
|
||||
let vdefs_tg = vdefs.tg;
|
||||
let vdefs_var = vdefs.var;
|
||||
while i < size {
|
||||
check valid_variant_index(i, bcx, vdefs_tg, vdefs_var);
|
||||
check (valid_variant_index(i, bcx, vdefs_tg, vdefs_var));
|
||||
let r =
|
||||
trans::GEP_tag(bcx, blobptr, vdefs_tg, vdefs_var, ty_param_substs,
|
||||
i);
|
||||
|
@ -298,26 +300,25 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
|||
let data = m[0].data;
|
||||
alt data.guard {
|
||||
some(e) {
|
||||
let guard_cx = new_scope_block_ctxt(bcx, ~"submatch_guard");
|
||||
let next_cx = new_sub_block_ctxt(bcx, ~"submatch_next");
|
||||
let else_cx = new_sub_block_ctxt(bcx, ~"submatch_else");
|
||||
let guard_cx = new_scope_block_ctxt(bcx, "submatch_guard");
|
||||
let next_cx = new_sub_block_ctxt(bcx, "submatch_next");
|
||||
let else_cx = new_sub_block_ctxt(bcx, "submatch_else");
|
||||
Br(bcx, guard_cx.llbb);
|
||||
// Temporarily set bindings. They'll be rewritten to PHI nodes for
|
||||
// the actual arm block.
|
||||
for each @{key, val} in data.id_map.items() {
|
||||
bcx.fcx.lllocals.insert
|
||||
(val, option::get(assoc(key,
|
||||
m[0].bound)));
|
||||
for each @{key: key, val: val} in data.id_map.items() {
|
||||
bcx.fcx.lllocals.insert(val,
|
||||
option::get(assoc(key, m[0].bound)));
|
||||
}
|
||||
let {bcx: guard_bcx, val: guard_val} =
|
||||
trans::trans_expr(guard_cx, e);
|
||||
guard_bcx = trans::trans_block_cleanups(guard_bcx, guard_cx);
|
||||
CondBr(guard_bcx, guard_val, next_cx.llbb, else_cx.llbb);
|
||||
compile_submatch(else_cx, vec::slice(m, 1u, vec::len(m)),
|
||||
vals, f, exits);
|
||||
compile_submatch(else_cx, vec::slice(m, 1u, vec::len(m)), vals, f,
|
||||
exits);
|
||||
bcx = next_cx;
|
||||
}
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
exits += [{bound: m[0].bound, from: bcx.llbb, to: data.body}];
|
||||
Br(bcx, data.body);
|
||||
|
@ -380,8 +381,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
|||
let box = Load(bcx, val);
|
||||
let unboxed =
|
||||
InBoundsGEP(bcx, box,
|
||||
[C_int(0),
|
||||
C_int(back::abi::box_rc_field_body)]);
|
||||
[C_int(0), C_int(back::abi::box_rc_field_body)]);
|
||||
compile_submatch(bcx, enter_box(m, col, val), [unboxed] + vals_left,
|
||||
f, exits);
|
||||
ret;
|
||||
|
@ -400,7 +400,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
|||
} else {
|
||||
let tagptr =
|
||||
PointerCast(bcx, val,
|
||||
trans_common::T_opaque_tag_ptr(ccx.tn));
|
||||
trans_common::T_opaque_tag_ptr(ccx.tn));
|
||||
let discrimptr = GEP(bcx, tagptr, [C_int(0), C_int(0)]);
|
||||
test_val = Load(bcx, discrimptr);
|
||||
kind = switch;
|
||||
|
@ -415,7 +415,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
|||
let else_cx =
|
||||
alt kind {
|
||||
no_branch. | single. { bcx }
|
||||
_ { new_sub_block_ctxt(bcx, ~"match_else") }
|
||||
_ { new_sub_block_ctxt(bcx, "match_else") }
|
||||
};
|
||||
let sw =
|
||||
if kind == switch {
|
||||
|
@ -424,7 +424,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
|||
|
||||
// Compile subtrees for each option
|
||||
for opt: opt in opts {
|
||||
let opt_cx = new_sub_block_ctxt(bcx, ~"match_case");
|
||||
let opt_cx = new_sub_block_ctxt(bcx, "match_case");
|
||||
alt kind {
|
||||
single. { Br(bcx, opt_cx.llbb); }
|
||||
switch. {
|
||||
|
@ -433,7 +433,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
|||
llvm::LLVMAddCase(sw, r.val, opt_cx.llbb);
|
||||
}
|
||||
compare. {
|
||||
let compare_cx = new_scope_block_ctxt(bcx, ~"compare_scope");
|
||||
let compare_cx = new_scope_block_ctxt(bcx, "compare_scope");
|
||||
Br(bcx, compare_cx.llbb);
|
||||
bcx = compare_cx;
|
||||
let r = trans_opt(bcx, opt);
|
||||
|
@ -442,7 +442,7 @@ fn compile_submatch(bcx: @block_ctxt, m: &match, vals: [ValueRef],
|
|||
let eq =
|
||||
trans::trans_compare(bcx, ast::eq, test_val, t, r.val, t);
|
||||
let cleanup_cx = trans::trans_block_cleanups(bcx, compare_cx);
|
||||
bcx = new_sub_block_ctxt(bcx, ~"compare_next");
|
||||
bcx = new_sub_block_ctxt(bcx, "compare_next");
|
||||
CondBr(cleanup_cx, eq.val, opt_cx.llbb, bcx.llbb);
|
||||
}
|
||||
_ { }
|
||||
|
@ -509,15 +509,14 @@ fn trans_alt(cx: &@block_ctxt, expr: &@ast::expr, arms: &[ast::arm],
|
|||
}
|
||||
|
||||
for a: ast::arm in arms {
|
||||
let body = new_scope_block_ctxt(cx, ~"case_body");
|
||||
let body = new_scope_block_ctxt(cx, "case_body");
|
||||
let id_map = ast_util::pat_id_map(a.pats[0]);
|
||||
bodies += [body];
|
||||
for p: @ast::pat in a.pats {
|
||||
match += [@{pats: [p],
|
||||
bound: [],
|
||||
data: @{body: body.llbb,
|
||||
guard: a.guard,
|
||||
id_map: id_map}}];
|
||||
match +=
|
||||
[@{pats: [p],
|
||||
bound: [],
|
||||
data: @{body: body.llbb, guard: a.guard, id_map: id_map}}];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,8 +525,8 @@ fn trans_alt(cx: &@block_ctxt, expr: &@ast::expr, arms: &[ast::arm],
|
|||
fn mk_fail(cx: &@block_ctxt, sp: &span,
|
||||
done: @mutable option::t<BasicBlockRef>) -> BasicBlockRef {
|
||||
alt *done { some(bb) { ret bb; } _ { } }
|
||||
let fail_cx = new_sub_block_ctxt(cx, ~"case_fallthrough");
|
||||
trans::trans_fail(fail_cx, some(sp), ~"non-exhaustive match failure");
|
||||
let fail_cx = new_sub_block_ctxt(cx, "case_fallthrough");
|
||||
trans::trans_fail(fail_cx, some(sp), "non-exhaustive match failure");;
|
||||
*done = some(fail_cx.llbb);
|
||||
ret fail_cx.llbb;
|
||||
}
|
||||
|
@ -568,8 +567,9 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef,
|
|||
check type_has_static_size(ccx, ty);
|
||||
let llty = trans::type_of(ccx, pat.span, ty);
|
||||
let alloc = trans::alloca(bcx, llty);
|
||||
bcx = trans::copy_val(bcx, trans::INIT, alloc,
|
||||
trans::load_if_immediate(bcx, val, ty), ty);
|
||||
bcx =
|
||||
trans::copy_val(bcx, trans::INIT, alloc,
|
||||
trans::load_if_immediate(bcx, val, ty), ty);
|
||||
table.insert(pat.id, alloc);
|
||||
trans_common::add_clean(bcx, alloc, ty);
|
||||
} else { table.insert(pat.id, val); }
|
||||
|
@ -606,9 +606,9 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: &@ast::pat, val: ValueRef,
|
|||
}
|
||||
ast::pat_box(inner) {
|
||||
let box = Load(bcx, val);
|
||||
let unboxed = InBoundsGEP(bcx, box,
|
||||
[C_int(0),
|
||||
C_int(back::abi::box_rc_field_body)]);
|
||||
let unboxed =
|
||||
InBoundsGEP(bcx, box,
|
||||
[C_int(0), C_int(back::abi::box_rc_field_body)]);
|
||||
bcx = bind_irrefutable_pat(bcx, inner, unboxed, table, true);
|
||||
}
|
||||
ast::pat_wild. | ast::pat_lit(_) { }
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import std::{vec, str};
|
||||
import std::str::sbuf;
|
||||
import lib::llvm::llvm;
|
||||
import llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef,
|
||||
Opcode, ModuleRef};
|
||||
import llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, Opcode,
|
||||
ModuleRef};
|
||||
import trans_common::block_ctxt;
|
||||
|
||||
fn B(cx: &@block_ctxt) -> BuilderRef {
|
||||
|
@ -12,277 +12,212 @@ fn B(cx: &@block_ctxt) -> BuilderRef {
|
|||
}
|
||||
|
||||
fn RetVoid(cx: &@block_ctxt) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret llvm::LLVMBuildRetVoid(B(cx));
|
||||
}
|
||||
|
||||
fn Ret(cx: &@block_ctxt, V: ValueRef) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret llvm::LLVMBuildRet(B(cx), V);
|
||||
}
|
||||
|
||||
fn AggregateRet(cx: &@block_ctxt, RetVals: &[ValueRef]) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret llvm::LLVMBuildAggregateRet(B(cx), vec::to_ptr(RetVals),
|
||||
vec::len(RetVals));
|
||||
}
|
||||
|
||||
fn Br(cx: &@block_ctxt, Dest: BasicBlockRef) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret llvm::LLVMBuildBr(B(cx), Dest);
|
||||
}
|
||||
|
||||
fn CondBr(cx: &@block_ctxt, If: ValueRef, Then: BasicBlockRef,
|
||||
Else: BasicBlockRef) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
|
||||
}
|
||||
|
||||
fn Switch(cx: &@block_ctxt, V: ValueRef, Else: BasicBlockRef,
|
||||
NumCases: uint) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
fn Switch(cx: &@block_ctxt, V: ValueRef, Else: BasicBlockRef, NumCases: uint)
|
||||
-> ValueRef {
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret llvm::LLVMBuildSwitch(B(cx), V, Else, NumCases);
|
||||
}
|
||||
|
||||
fn IndirectBr(cx: &@block_ctxt, Addr: ValueRef,
|
||||
NumDests: uint) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
fn IndirectBr(cx: &@block_ctxt, Addr: ValueRef, NumDests: uint) -> ValueRef {
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests);
|
||||
}
|
||||
|
||||
fn Invoke(cx: &@block_ctxt, Fn: ValueRef, Args: &[ValueRef],
|
||||
Then: BasicBlockRef, Catch: BasicBlockRef) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), Then, Catch, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildInvoke(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), Then, Catch,
|
||||
buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn Unreachable(cx: &@block_ctxt) -> ValueRef {
|
||||
assert (!cx.terminated);;
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
ret llvm::LLVMBuildUnreachable(B(cx));
|
||||
}
|
||||
|
||||
/* Arithmetic */
|
||||
fn Add(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildAdd(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildAdd(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn NSWAdd(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn NUWAdd(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn FAdd(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFAdd(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildFAdd(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn Sub(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildSub(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildSub(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn NSWSub(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn NUWSub(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn FSub(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFSub(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildFSub(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn Mul(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildMul(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildMul(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn NSWMul(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn NUWMul(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn FMul(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFMul(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildFMul(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn UDiv(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildUDiv(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildUDiv(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn SDiv(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildSDiv(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildSDiv(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn ExactSDiv(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn FDiv(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFDiv(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildFDiv(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn URem(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildURem(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildURem(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn SRem(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildSRem(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildSRem(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn FRem(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFRem(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildFRem(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn Shl(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildShl(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildShl(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn LShr(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildLShr(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildLShr(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn AShr(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildAShr(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildAShr(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn And(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildAnd(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildAnd(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn Or(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildOr(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildOr(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn Xor(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildXor(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildXor(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn BinOp(cx: &@block_ctxt, Op: Opcode, LHS: ValueRef,
|
||||
RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, buf)
|
||||
});
|
||||
fn BinOp(cx: &@block_ctxt, Op: Opcode, LHS: ValueRef, RHS: ValueRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn Neg(cx: &@block_ctxt, V: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNeg(B(cx), V, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNeg(B(cx), V, buf) });
|
||||
}
|
||||
|
||||
fn NSWNeg(cx: &@block_ctxt, V: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNSWNeg(B(cx), V, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNSWNeg(B(cx), V, buf) });
|
||||
}
|
||||
|
||||
fn NUWNeg(cx: &@block_ctxt, V: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNUWNeg(B(cx), V, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNUWNeg(B(cx), V, buf) });
|
||||
}
|
||||
fn FNeg(cx: &@block_ctxt, V: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFNeg(B(cx), V, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildFNeg(B(cx), V, buf) });
|
||||
}
|
||||
|
||||
fn Not(cx: &@block_ctxt, V: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildNot(B(cx), V, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildNot(B(cx), V, buf) });
|
||||
}
|
||||
|
||||
/* Memory */
|
||||
fn Malloc(cx: &@block_ctxt, Ty: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildMalloc(B(cx), Ty, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildMalloc(B(cx), Ty, buf) });
|
||||
}
|
||||
|
||||
fn ArrayMalloc(cx: &@block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, buf) });
|
||||
}
|
||||
|
||||
fn Alloca(cx: &@block_ctxt, Ty: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildAlloca(B(cx), Ty, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildAlloca(B(cx), Ty, buf) });
|
||||
}
|
||||
|
||||
fn ArrayAlloca(cx: &@block_ctxt, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, buf) });
|
||||
}
|
||||
|
||||
fn Free(cx: &@block_ctxt, PointerVal: ValueRef) -> ValueRef {
|
||||
|
@ -290,194 +225,185 @@ fn Free(cx: &@block_ctxt, PointerVal: ValueRef) -> ValueRef {
|
|||
}
|
||||
|
||||
fn Load(cx: &@block_ctxt, PointerVal: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildLoad(B(cx), PointerVal, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildLoad(B(cx), PointerVal, buf) });
|
||||
}
|
||||
|
||||
fn Store(cx: &@block_ctxt, Val: ValueRef, Ptr: ValueRef) -> ValueRef {
|
||||
ret llvm::LLVMBuildStore(B(cx), Val, Ptr);
|
||||
}
|
||||
|
||||
fn GEP(cx: &@block_ctxt, Pointer: ValueRef,
|
||||
Indices: &[ValueRef]) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildGEP(B(cx), Pointer, vec::to_ptr(Indices),
|
||||
vec::len(Indices), buf)
|
||||
});
|
||||
fn GEP(cx: &@block_ctxt, Pointer: ValueRef, Indices: &[ValueRef]) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildGEP(B(cx), Pointer,
|
||||
vec::to_ptr(Indices),
|
||||
vec::len(Indices), buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn InBoundsGEP(cx: &@block_ctxt, Pointer: ValueRef,
|
||||
Indices: &[ValueRef]) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, vec::to_ptr(Indices),
|
||||
vec::len(Indices), buf)
|
||||
});
|
||||
fn InBoundsGEP(cx: &@block_ctxt, Pointer: ValueRef, Indices: &[ValueRef]) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
|
||||
vec::to_ptr(Indices),
|
||||
vec::len(Indices), buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn StructGEP(cx: &@block_ctxt, Pointer: ValueRef, Idx: uint) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn GlobalString(cx: &@block_ctxt, _Str: sbuf) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildGlobalString(B(cx), _Str, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildGlobalString(B(cx), _Str, buf) });
|
||||
}
|
||||
|
||||
fn GlobalStringPtr(cx: &@block_ctxt, _Str: sbuf) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, buf)
|
||||
});
|
||||
}
|
||||
|
||||
/* Casts */
|
||||
fn Trunc(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildTrunc(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildTrunc(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn ZExt(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildZExt(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildZExt(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn SExt(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildSExt(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildSExt(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn FPToUI(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn FPToSI(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn UIToFP(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn SIToFP(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn FPTrunc(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn FPExt(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFPExt(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildFPExt(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn PtrToInt(cx: &@block_ctxt, Val: ValueRef,
|
||||
DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
fn PtrToInt(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn IntToPtr(cx: &@block_ctxt, Val: ValueRef,
|
||||
DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
fn IntToPtr(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn BitCast(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildBitCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildBitCast(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn ZExtOrBitCast(cx: &@block_ctxt, Val: ValueRef,
|
||||
DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
fn ZExtOrBitCast(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn SExtOrBitCast(cx: &@block_ctxt, Val: ValueRef,
|
||||
DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
fn SExtOrBitCast(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn TruncOrBitCast(cx: &@block_ctxt, Val: ValueRef,
|
||||
DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
fn TruncOrBitCast(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn Cast(cx: &@block_ctxt, Op: Opcode, Val: ValueRef,
|
||||
DestTy: TypeRef, _Name: sbuf) ->
|
||||
ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, buf)
|
||||
});
|
||||
fn Cast(cx: &@block_ctxt, Op: Opcode, Val: ValueRef, DestTy: TypeRef,
|
||||
_Name: sbuf) -> ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn PointerCast(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn IntCast(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildIntCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildIntCast(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
fn FPCast(cx: &@block_ctxt, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFPCast(B(cx), Val, DestTy, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildFPCast(B(cx), Val, DestTy, buf) });
|
||||
}
|
||||
|
||||
|
||||
/* Comparisons */
|
||||
fn ICmp(cx: &@block_ctxt, Op: uint, LHS: ValueRef,
|
||||
RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, buf)
|
||||
});
|
||||
fn ICmp(cx: &@block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildICmp(B(cx), Op, LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn FCmp(cx: &@block_ctxt, Op: uint, LHS: ValueRef,
|
||||
RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, buf)
|
||||
});
|
||||
fn FCmp(cx: &@block_ctxt, Op: uint, LHS: ValueRef, RHS: ValueRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildFCmp(B(cx), Op, LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
fn Phi(cx: &@block_ctxt, Ty: TypeRef, vals: &[ValueRef],
|
||||
bbs: &[BasicBlockRef]) -> ValueRef {
|
||||
let phi = str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildPhi(B(cx), Ty, buf)
|
||||
});
|
||||
let phi = str::as_buf("", {|buf| llvm::LLVMBuildPhi(B(cx), Ty, buf) });
|
||||
assert (vec::len::<ValueRef>(vals) == vec::len::<BasicBlockRef>(bbs));
|
||||
llvm::LLVMAddIncoming(phi, vec::to_ptr(vals), vec::to_ptr(bbs),
|
||||
vec::len(vals));
|
||||
|
@ -491,93 +417,101 @@ fn AddIncomingToPhi(phi: ValueRef, vals: &[ValueRef], bbs: &[BasicBlockRef]) {
|
|||
}
|
||||
|
||||
fn Call(cx: &@block_ctxt, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn FastCall(cx: &@block_ctxt, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
|
||||
let v = str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), buf)
|
||||
});
|
||||
let v =
|
||||
str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), buf)
|
||||
});
|
||||
llvm::LLVMSetInstructionCallConv(v, lib::llvm::LLVMFastCallConv);
|
||||
ret v;
|
||||
}
|
||||
|
||||
fn CallWithConv(cx: &@block_ctxt, Fn: ValueRef, Args: &[ValueRef],
|
||||
Conv: uint) -> ValueRef {
|
||||
let v = str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args), vec::len(Args), buf)
|
||||
});
|
||||
fn CallWithConv(cx: &@block_ctxt, Fn: ValueRef, Args: &[ValueRef], Conv: uint)
|
||||
-> ValueRef {
|
||||
let v =
|
||||
str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildCall(B(cx), Fn, vec::to_ptr(Args),
|
||||
vec::len(Args), buf)
|
||||
});
|
||||
llvm::LLVMSetInstructionCallConv(v, Conv);
|
||||
ret v;
|
||||
}
|
||||
|
||||
fn Select(cx: &@block_ctxt, If: ValueRef, Then: ValueRef,
|
||||
Else: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildSelect(B(cx), If, Then, Else, buf)
|
||||
});
|
||||
fn Select(cx: &@block_ctxt, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildSelect(B(cx), If, Then, Else, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn VAArg(cx: &@block_ctxt, list: ValueRef, Ty: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildVAArg(B(cx), list, Ty, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildVAArg(B(cx), list, Ty, buf) });
|
||||
}
|
||||
|
||||
fn ExtractElement(cx: &@block_ctxt, VecVal: ValueRef,
|
||||
Index: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, buf)
|
||||
});
|
||||
fn ExtractElement(cx: &@block_ctxt, VecVal: ValueRef, Index: ValueRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildExtractElement(B(cx), VecVal, Index,
|
||||
buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn InsertElement(cx: &@block_ctxt, VecVal: ValueRef, EltVal: ValueRef,
|
||||
Index: ValueRef) ->
|
||||
ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, buf)
|
||||
});
|
||||
Index: ValueRef) -> ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal,
|
||||
Index, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn ShuffleVector(cx: &@block_ctxt, V1: ValueRef, V2: ValueRef,
|
||||
Mask: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, buf)
|
||||
});
|
||||
fn ShuffleVector(cx: &@block_ctxt, V1: ValueRef, V2: ValueRef, Mask: ValueRef)
|
||||
-> ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn ExtractValue(cx: &@block_ctxt, AggVal: ValueRef, Index: uint) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildExtractValue(B(cx), AggVal, Index, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn InsertValue(cx: &@block_ctxt, AggVal: ValueRef,
|
||||
EltVal: ValueRef, Index: uint) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index, buf)
|
||||
});
|
||||
fn InsertValue(cx: &@block_ctxt, AggVal: ValueRef, EltVal: ValueRef,
|
||||
Index: uint) -> ValueRef {
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal,
|
||||
Index, buf)
|
||||
});
|
||||
}
|
||||
|
||||
fn IsNull(cx: &@block_ctxt, Val: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildIsNull(B(cx), Val, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildIsNull(B(cx), Val, buf) });
|
||||
}
|
||||
|
||||
fn IsNotNull(cx: &@block_ctxt, Val: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildIsNotNull(B(cx), Val, buf)
|
||||
});
|
||||
ret str::as_buf("", {|buf| llvm::LLVMBuildIsNotNull(B(cx), Val, buf) });
|
||||
}
|
||||
|
||||
fn PtrDiff(cx: &@block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf| llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, buf) });
|
||||
}
|
||||
|
||||
fn Trap(cx: &@block_ctxt) -> ValueRef {
|
||||
|
@ -585,14 +519,15 @@ fn Trap(cx: &@block_ctxt) -> ValueRef {
|
|||
let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(b);
|
||||
let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
|
||||
let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
|
||||
let T: ValueRef = str::as_buf(~"llvm.trap", { |buf|
|
||||
llvm::LLVMGetNamedFunction(M, buf)
|
||||
});
|
||||
let T: ValueRef =
|
||||
str::as_buf("llvm.trap", {|buf| llvm::LLVMGetNamedFunction(M, buf) });
|
||||
assert (T as int != 0);
|
||||
let Args: [ValueRef] = [];
|
||||
ret str::as_buf(~"", { |buf|
|
||||
llvm::LLVMBuildCall(b, T, vec::to_ptr(Args), vec::len(Args), buf)
|
||||
});
|
||||
ret str::as_buf("",
|
||||
{|buf|
|
||||
llvm::LLVMBuildCall(b, T, vec::to_ptr(Args),
|
||||
vec::len(Args), buf)
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -62,9 +62,7 @@ import trans::type_of_fn_full;
|
|||
import trans::drop_ty;
|
||||
|
||||
obj namegen(mutable i: int) {
|
||||
fn next(prefix: &istr) -> istr {
|
||||
i += 1; ret prefix + int::str(i);
|
||||
}
|
||||
fn next(prefix: &str) -> str { i += 1; ret prefix + int::str(i); }
|
||||
}
|
||||
|
||||
type derived_tydesc_info = {lltydesc: ValueRef, escapes: bool};
|
||||
|
@ -109,11 +107,9 @@ type stats =
|
|||
mutable n_glues_created: uint,
|
||||
mutable n_null_glues: uint,
|
||||
mutable n_real_glues: uint,
|
||||
fn_times: @mutable [{ident: istr, time: int}]};
|
||||
fn_times: @mutable [{ident: str, time: int}]};
|
||||
|
||||
resource BuilderRef_res(B: llvm::BuilderRef) {
|
||||
llvm::LLVMDisposeBuilder(B);
|
||||
}
|
||||
resource BuilderRef_res(B: llvm::BuilderRef) { llvm::LLVMDisposeBuilder(B); }
|
||||
|
||||
// Crate context. Every crate we compile has one of these.
|
||||
type crate_ctxt =
|
||||
|
@ -125,27 +121,27 @@ type crate_ctxt =
|
|||
llmod: ModuleRef,
|
||||
td: target_data,
|
||||
tn: type_names,
|
||||
externs: hashmap<istr, ValueRef>,
|
||||
intrinsics: hashmap<istr, ValueRef>,
|
||||
externs: hashmap<str, ValueRef>,
|
||||
intrinsics: hashmap<str, ValueRef>,
|
||||
item_ids: hashmap<ast::node_id, ValueRef>,
|
||||
ast_map: ast_map::map,
|
||||
item_symbols: hashmap<ast::node_id, istr>,
|
||||
item_symbols: hashmap<ast::node_id, str>,
|
||||
mutable main_fn: option::t<ValueRef>,
|
||||
link_meta: link::link_meta,
|
||||
tag_sizes: hashmap<ty::t, uint>,
|
||||
discrims: hashmap<ast::node_id, ValueRef>,
|
||||
discrim_symbols: hashmap<ast::node_id, istr>,
|
||||
discrim_symbols: hashmap<ast::node_id, str>,
|
||||
fn_pairs: hashmap<ast::node_id, ValueRef>,
|
||||
consts: hashmap<ast::node_id, ValueRef>,
|
||||
obj_methods: hashmap<ast::node_id, ()>,
|
||||
tydescs: hashmap<ty::t, @tydesc_info>,
|
||||
module_data: hashmap<istr, ValueRef>,
|
||||
module_data: hashmap<str, ValueRef>,
|
||||
lltypes: hashmap<ty::t, TypeRef>,
|
||||
glues: @glue_fns,
|
||||
names: namegen,
|
||||
sha: std::sha1::sha1,
|
||||
type_sha1s: hashmap<ty::t, istr>,
|
||||
type_short_names: hashmap<ty::t, istr>,
|
||||
type_sha1s: hashmap<ty::t, str>,
|
||||
type_short_names: hashmap<ty::t, str>,
|
||||
tcx: ty::ctxt,
|
||||
mut_map: mut::mut_map,
|
||||
stats: stats,
|
||||
|
@ -158,8 +154,8 @@ type crate_ctxt =
|
|||
gc_cx: gc::ctxt};
|
||||
|
||||
type local_ctxt =
|
||||
{path: [istr],
|
||||
module_path: [istr],
|
||||
{path: [str],
|
||||
module_path: [str],
|
||||
obj_typarams: [ast::ty_param],
|
||||
obj_fields: [ast::obj_field],
|
||||
ccx: @crate_ctxt};
|
||||
|
@ -302,11 +298,12 @@ fn add_clean(cx: &@block_ctxt, val: ValueRef, ty: ty::t) {
|
|||
find_scope_cx(cx).cleanups += [clean(bind drop_ty(_, val, ty))];
|
||||
}
|
||||
fn add_clean_temp(cx: &@block_ctxt, val: ValueRef, ty: ty::t) {
|
||||
fn spill_and_drop(cx: &@block_ctxt, val: ValueRef, ty: ty::t)
|
||||
-> @block_ctxt {
|
||||
fn spill_and_drop(cx: &@block_ctxt, val: ValueRef, ty: ty::t) ->
|
||||
@block_ctxt {
|
||||
let bcx = cx;
|
||||
let r = trans::spill_if_immediate(bcx, val, ty);
|
||||
let spilled = r.val; bcx = r.bcx;
|
||||
let spilled = r.val;
|
||||
bcx = r.bcx;
|
||||
ret drop_ty(bcx, spilled, ty);
|
||||
}
|
||||
find_scope_cx(cx).cleanups +=
|
||||
|
@ -345,7 +342,7 @@ fn get_res_dtor(ccx: &@crate_ctxt, sp: &span, did: &ast::def_id,
|
|||
if did.crate == ast::local_crate {
|
||||
alt ccx.fn_pairs.find(did.node) {
|
||||
some(x) { ret x; }
|
||||
_ { ccx.tcx.sess.bug(~"get_res_dtor: can't find resource dtor!"); }
|
||||
_ { ccx.tcx.sess.bug("get_res_dtor: can't find resource dtor!"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,9 +352,8 @@ fn get_res_dtor(ccx: &@crate_ctxt, sp: &span, did: &ast::def_id,
|
|||
[{mode: ty::mo_alias(false), ty: inner_t}],
|
||||
ty::mk_nil(ccx.tcx), params);
|
||||
ret trans::get_extern_const(ccx.externs, ccx.llmod,
|
||||
csearch::get_symbol(
|
||||
ccx.sess.get_cstore(),
|
||||
did),
|
||||
csearch::get_symbol(ccx.sess.get_cstore(),
|
||||
did),
|
||||
T_fn_pair(*ccx, f_t));
|
||||
}
|
||||
|
||||
|
@ -396,26 +392,24 @@ type block_ctxt =
|
|||
// llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
|
||||
// block to the function pointed to by llfn. We insert
|
||||
// instructions into that block by way of this block context.
|
||||
// The block pointing to this one in the function's digraph.
|
||||
// The 'kind' of basic block this is.
|
||||
// A list of functions that run at the end of translating this
|
||||
// block, cleaning up any variables that were introduced in the
|
||||
// block and need to go out of scope at the end of it.
|
||||
// The source span where this block comes from, for error
|
||||
// reporting. FIXME this is not currently reliable
|
||||
// The function context for the function to which this block is
|
||||
// attached.
|
||||
{llbb: BasicBlockRef,
|
||||
mutable terminated: bool,
|
||||
// The block pointing to this one in the function's digraph.
|
||||
parent: block_parent,
|
||||
// The 'kind' of basic block this is.
|
||||
kind: block_kind,
|
||||
// A list of functions that run at the end of translating this
|
||||
// block, cleaning up any variables that were introduced in the
|
||||
// block and need to go out of scope at the end of it.
|
||||
mutable cleanups: [cleanup],
|
||||
// The source span where this block comes from, for error
|
||||
// reporting. FIXME this is not currently reliable
|
||||
sp: span,
|
||||
// The function context for the function to which this block is
|
||||
// attached.
|
||||
fcx: @fn_ctxt};
|
||||
|
||||
fn is_terminated(cx: &@block_ctxt) -> bool {
|
||||
ret cx.terminated;
|
||||
}
|
||||
fn is_terminated(cx: &@block_ctxt) -> bool { ret cx.terminated; }
|
||||
|
||||
// FIXME: we should be able to use option::t<@block_parent> here but
|
||||
// the infinite-tag check in rustboot gets upset.
|
||||
|
@ -424,7 +418,7 @@ tag block_parent { parent_none; parent_some(@block_ctxt); }
|
|||
type result = {bcx: @block_ctxt, val: ValueRef};
|
||||
type result_t = {bcx: @block_ctxt, val: ValueRef, ty: ty::t};
|
||||
|
||||
fn extend_path(cx: @local_ctxt, name: &istr) -> @local_ctxt {
|
||||
fn extend_path(cx: @local_ctxt, name: &str) -> @local_ctxt {
|
||||
ret @{path: cx.path + [name] with *cx};
|
||||
}
|
||||
|
||||
|
@ -432,15 +426,13 @@ fn rslt(bcx: @block_ctxt, val: ValueRef) -> result {
|
|||
ret {bcx: bcx, val: val};
|
||||
}
|
||||
|
||||
fn ty_str(tn: type_names, t: TypeRef) -> istr {
|
||||
fn ty_str(tn: type_names, t: TypeRef) -> str {
|
||||
ret lib::llvm::type_to_str(tn, t);
|
||||
}
|
||||
|
||||
fn val_ty(v: ValueRef) -> TypeRef { ret llvm::LLVMTypeOf(v); }
|
||||
|
||||
fn val_str(tn: type_names, v: ValueRef) -> istr {
|
||||
ret ty_str(tn, val_ty(v));
|
||||
}
|
||||
fn val_str(tn: type_names, v: ValueRef) -> str { ret ty_str(tn, val_ty(v)); }
|
||||
|
||||
// Returns the nth element of the given LLVM structure type.
|
||||
fn struct_elt(llstructty: TypeRef, n: uint) -> TypeRef {
|
||||
|
@ -456,8 +448,8 @@ fn find_scope_cx(cx: &@block_ctxt) -> @block_ctxt {
|
|||
alt cx.parent {
|
||||
parent_some(b) { ret find_scope_cx(b); }
|
||||
parent_none. {
|
||||
cx.fcx.lcx.ccx.sess.bug(~"trans::find_scope_cx() " +
|
||||
~"called on parentless block_ctxt");
|
||||
cx.fcx.lcx.ccx.sess.bug("trans::find_scope_cx() " +
|
||||
"called on parentless block_ctxt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -543,20 +535,16 @@ fn T_fn_pair(cx: &crate_ctxt, tfn: TypeRef) -> TypeRef {
|
|||
fn T_ptr(t: TypeRef) -> TypeRef { ret llvm::LLVMPointerType(t, 0u); }
|
||||
|
||||
fn T_struct(elts: &[TypeRef]) -> TypeRef {
|
||||
ret llvm::LLVMStructType(to_ptr(elts),
|
||||
std::vec::len(elts), False);
|
||||
ret llvm::LLVMStructType(to_ptr(elts), std::vec::len(elts), False);
|
||||
}
|
||||
|
||||
fn T_named_struct(name: &istr) -> TypeRef {
|
||||
fn T_named_struct(name: &str) -> TypeRef {
|
||||
let c = llvm::LLVMGetGlobalContext();
|
||||
ret str::as_buf(name, { |buf|
|
||||
llvm::LLVMStructCreateNamed(c, buf)
|
||||
});
|
||||
ret str::as_buf(name, {|buf| llvm::LLVMStructCreateNamed(c, buf) });
|
||||
}
|
||||
|
||||
fn set_struct_body(t: TypeRef, elts: &[TypeRef]) {
|
||||
llvm::LLVMStructSetBody(t, to_ptr(elts),
|
||||
std::vec::len(elts), False);
|
||||
llvm::LLVMStructSetBody(t, to_ptr(elts), std::vec::len(elts), False);
|
||||
}
|
||||
|
||||
fn T_empty_struct() -> TypeRef { ret T_struct([]); }
|
||||
|
@ -566,25 +554,25 @@ fn T_empty_struct() -> TypeRef { ret T_struct([]); }
|
|||
// existing objects, use ccx.rust_object_type. Calling
|
||||
// T_rust_object() again will return a different one.
|
||||
fn T_rust_object() -> TypeRef {
|
||||
let t = T_named_struct(~"rust_object");
|
||||
let t = T_named_struct("rust_object");
|
||||
let e = T_ptr(T_empty_struct());
|
||||
set_struct_body(t, [e, e]);
|
||||
ret t;
|
||||
}
|
||||
|
||||
fn T_task() -> TypeRef {
|
||||
let t = T_named_struct(~"task");
|
||||
let t = T_named_struct("task");
|
||||
|
||||
// Refcount
|
||||
// Delegate pointer
|
||||
// Stack segment pointer
|
||||
// Runtime SP
|
||||
// Rust SP
|
||||
// GC chain
|
||||
// Refcount
|
||||
// Delegate pointer
|
||||
// Stack segment pointer
|
||||
// Runtime SP
|
||||
// Rust SP
|
||||
// GC chain
|
||||
|
||||
|
||||
// Domain pointer
|
||||
// Crate cache pointer
|
||||
// Domain pointer
|
||||
// Crate cache pointer
|
||||
|
||||
let elems =
|
||||
[T_int(), T_int(), T_int(), T_int(), T_int(), T_int(), T_int(),
|
||||
|
@ -605,7 +593,7 @@ fn T_tydesc_field(cx: &crate_ctxt, field: int) -> TypeRef {
|
|||
}
|
||||
|
||||
fn T_glue_fn(cx: &crate_ctxt) -> TypeRef {
|
||||
let s = ~"glue_fn";
|
||||
let s = "glue_fn";
|
||||
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
|
||||
let t = T_tydesc_field(cx, abi::tydesc_field_drop_glue);
|
||||
cx.tn.associate(s, t);
|
||||
|
@ -613,7 +601,7 @@ fn T_glue_fn(cx: &crate_ctxt) -> TypeRef {
|
|||
}
|
||||
|
||||
fn T_cmp_glue_fn(cx: &crate_ctxt) -> TypeRef {
|
||||
let s = ~"cmp_glue_fn";
|
||||
let s = "cmp_glue_fn";
|
||||
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
|
||||
let t = T_tydesc_field(cx, abi::tydesc_field_cmp_glue);
|
||||
cx.tn.associate(s, t);
|
||||
|
@ -621,7 +609,7 @@ fn T_cmp_glue_fn(cx: &crate_ctxt) -> TypeRef {
|
|||
}
|
||||
|
||||
fn T_tydesc(taskptr_type: TypeRef) -> TypeRef {
|
||||
let tydesc = T_named_struct(~"tydesc");
|
||||
let tydesc = T_named_struct("tydesc");
|
||||
let tydescpp = T_ptr(T_ptr(tydesc));
|
||||
let pvoid = T_ptr(T_i8());
|
||||
let glue_fn_ty =
|
||||
|
@ -652,9 +640,7 @@ fn T_vec(t: TypeRef) -> TypeRef {
|
|||
}
|
||||
|
||||
// Note that the size of this one is in bytes.
|
||||
fn T_opaque_vec() -> TypeRef {
|
||||
ret T_vec(T_i8());
|
||||
}
|
||||
fn T_opaque_vec() -> TypeRef { ret T_vec(T_i8()); }
|
||||
|
||||
fn T_box(t: TypeRef) -> TypeRef { ret T_struct([T_int(), t]); }
|
||||
|
||||
|
@ -673,7 +659,7 @@ fn T_taskptr(cx: &crate_ctxt) -> TypeRef { ret T_ptr(cx.task_type); }
|
|||
|
||||
// This type must never be used directly; it must always be cast away.
|
||||
fn T_typaram(tn: &type_names) -> TypeRef {
|
||||
let s = ~"typaram";
|
||||
let s = "typaram";
|
||||
if tn.name_has_type(s) { ret tn.get_type(s); }
|
||||
let t = T_i8();
|
||||
tn.associate(s, t);
|
||||
|
@ -692,7 +678,7 @@ fn T_closure_ptr(cx: &crate_ctxt, llbindings_ty: TypeRef, n_ty_params: uint)
|
|||
}
|
||||
|
||||
fn T_opaque_closure_ptr(cx: &crate_ctxt) -> TypeRef {
|
||||
let s = ~"*closure";
|
||||
let s = "*closure";
|
||||
if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); }
|
||||
let t = T_closure_ptr(cx, T_nil(), 0u);
|
||||
cx.tn.associate(s, t);
|
||||
|
@ -700,7 +686,7 @@ fn T_opaque_closure_ptr(cx: &crate_ctxt) -> TypeRef {
|
|||
}
|
||||
|
||||
fn T_tag(tn: &type_names, size: uint) -> TypeRef {
|
||||
let s = ~"tag_" + uint::to_str(size, 10u);
|
||||
let s = "tag_" + uint::to_str(size, 10u);
|
||||
if tn.name_has_type(s) { ret tn.get_type(s); }
|
||||
let t = T_struct([T_int(), T_array(T_i8(), size)]);
|
||||
tn.associate(s, t);
|
||||
|
@ -708,7 +694,7 @@ fn T_tag(tn: &type_names, size: uint) -> TypeRef {
|
|||
}
|
||||
|
||||
fn T_opaque_tag(tn: &type_names) -> TypeRef {
|
||||
let s = ~"opaque_tag";
|
||||
let s = "opaque_tag";
|
||||
if tn.name_has_type(s) { ret tn.get_type(s); }
|
||||
let t = T_struct([T_int(), T_i8()]);
|
||||
tn.associate(s, t);
|
||||
|
@ -754,16 +740,12 @@ fn C_integral(t: TypeRef, u: uint, sign_extend: Bool) -> ValueRef {
|
|||
ret llvm::LLVMRustConstSmallInt(t, u, sign_extend);
|
||||
}
|
||||
|
||||
fn C_float(s: &istr) -> ValueRef {
|
||||
ret str::as_buf(s, { |buf|
|
||||
llvm::LLVMConstRealOfString(T_float(), buf)
|
||||
});
|
||||
fn C_float(s: &str) -> ValueRef {
|
||||
ret str::as_buf(s, {|buf| llvm::LLVMConstRealOfString(T_float(), buf) });
|
||||
}
|
||||
|
||||
fn C_floating(s: &istr, t: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(s, { |buf|
|
||||
llvm::LLVMConstRealOfString(t, buf)
|
||||
});
|
||||
fn C_floating(s: &str, t: TypeRef) -> ValueRef {
|
||||
ret str::as_buf(s, {|buf| llvm::LLVMConstRealOfString(t, buf) });
|
||||
}
|
||||
|
||||
fn C_nil() -> ValueRef {
|
||||
|
@ -787,13 +769,15 @@ fn C_u8(i: uint) -> ValueRef { ret C_integral(T_i8(), i, False); }
|
|||
|
||||
// This is a 'c-like' raw string, which differs from
|
||||
// our boxed-and-length-annotated strings.
|
||||
fn C_cstr(cx: &@crate_ctxt, s: &istr) -> ValueRef {
|
||||
let sc = str::as_buf(s, { |buf|
|
||||
llvm::LLVMConstString(buf, str::byte_len(s), False)
|
||||
});
|
||||
let g = str::as_buf(cx.names.next(~"str"), { |buf|
|
||||
llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf)
|
||||
});
|
||||
fn C_cstr(cx: &@crate_ctxt, s: &str) -> ValueRef {
|
||||
let sc =
|
||||
str::as_buf(s,
|
||||
{|buf|
|
||||
llvm::LLVMConstString(buf, str::byte_len(s), False)
|
||||
});
|
||||
let g =
|
||||
str::as_buf(cx.names.next("str"),
|
||||
{|buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf) });
|
||||
llvm::LLVMSetInitializer(g, sc);
|
||||
llvm::LLVMSetGlobalConstant(g, True);
|
||||
llvm::LLVMSetLinkage(g, lib::llvm::LLVMInternalLinkage as llvm::Linkage);
|
||||
|
@ -801,10 +785,11 @@ fn C_cstr(cx: &@crate_ctxt, s: &istr) -> ValueRef {
|
|||
}
|
||||
|
||||
// Returns a Plain Old LLVM String:
|
||||
fn C_postr(s: &istr) -> ValueRef {
|
||||
ret str::as_buf(s, { |buf|
|
||||
llvm::LLVMConstString(buf, str::byte_len(s), False)
|
||||
});
|
||||
fn C_postr(s: &str) -> ValueRef {
|
||||
ret str::as_buf(s,
|
||||
{|buf|
|
||||
llvm::LLVMConstString(buf, str::byte_len(s), False)
|
||||
});
|
||||
}
|
||||
|
||||
fn C_zero_byte_arr(size: uint) -> ValueRef {
|
||||
|
@ -836,9 +821,11 @@ fn C_bytes(bytes: &[u8]) -> ValueRef {
|
|||
|
||||
fn C_shape(ccx: &@crate_ctxt, bytes: &[u8]) -> ValueRef {
|
||||
let llshape = C_bytes(bytes);
|
||||
let llglobal = str::as_buf(ccx.names.next(~"shape"), { |buf|
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
|
||||
});
|
||||
let llglobal =
|
||||
str::as_buf(ccx.names.next("shape"),
|
||||
{|buf|
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf)
|
||||
});
|
||||
llvm::LLVMSetInitializer(llglobal, llshape);
|
||||
llvm::LLVMSetGlobalConstant(llglobal, True);
|
||||
llvm::LLVMSetLinkage(llglobal,
|
||||
|
@ -847,14 +834,16 @@ fn C_shape(ccx: &@crate_ctxt, bytes: &[u8]) -> ValueRef {
|
|||
}
|
||||
|
||||
|
||||
pure fn valid_variant_index(ix:uint, cx:@block_ctxt, tag_id: &ast::def_id,
|
||||
pure fn valid_variant_index(ix: uint, cx: @block_ctxt, tag_id: &ast::def_id,
|
||||
variant_id: &ast::def_id) -> bool {
|
||||
|
||||
// Handwaving: it's ok to pretend this code is referentially
|
||||
// transparent, because the relevant parts of the type context don't
|
||||
// change. (We're not adding new variants during trans.)
|
||||
unchecked {
|
||||
let variant = ty::tag_variant_with_id(bcx_tcx(cx), tag_id, variant_id);
|
||||
ix < vec::len(variant.args)
|
||||
unchecked{
|
||||
let variant =
|
||||
ty::tag_variant_with_id(bcx_tcx(cx), tag_id, variant_id);
|
||||
ix < vec::len(variant.args)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
|||
let llctor_decl;
|
||||
alt ccx.item_ids.find(ctor_id) {
|
||||
some(x) { llctor_decl = x; }
|
||||
_ { cx.ccx.sess.span_fatal(sp, ~"unbound llctor_decl in trans_obj"); }
|
||||
_ { cx.ccx.sess.span_fatal(sp, "unbound llctor_decl in trans_obj"); }
|
||||
}
|
||||
|
||||
// Much like trans_fn, we must create an LLVM function, but since we're
|
||||
|
@ -79,8 +79,7 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
|||
// Grab onto the first and second elements of the pair.
|
||||
// abi::obj_field_vtbl and abi::obj_field_box simply specify words 0 and 1
|
||||
// of 'pair'.
|
||||
let pair_vtbl =
|
||||
GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||
let pair_vtbl = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
|
||||
|
||||
// Make a vtable for this object: a static array of pointers to functions.
|
||||
|
@ -135,8 +134,8 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
|||
bcx = body_tydesc.bcx;
|
||||
let ti = none::<@tydesc_info>;
|
||||
|
||||
let r = GEP_tup_like(bcx, body_ty, body,
|
||||
[0, abi::obj_body_elt_typarams]);
|
||||
let r =
|
||||
GEP_tup_like(bcx, body_ty, body, [0, abi::obj_body_elt_typarams]);
|
||||
bcx = r.bcx;
|
||||
let body_typarams = r.val;
|
||||
|
||||
|
@ -186,7 +185,7 @@ fn trans_obj(cx: @local_ctxt, sp: &span, ob: &ast::_obj,
|
|||
}
|
||||
none. {
|
||||
bcx_ccx(bcx).sess.span_fatal(f.ty.span,
|
||||
~"internal error in trans_obj");
|
||||
"internal error in trans_obj");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -285,8 +284,7 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
|
|||
add_clean_temp(bcx, pair, t);
|
||||
|
||||
// Grab onto the first and second elements of the pair.
|
||||
let pair_vtbl =
|
||||
GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||
let pair_vtbl = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||
let pair_box = GEP(bcx, pair, [C_int(0), C_int(abi::obj_field_box)]);
|
||||
|
||||
vtbl = PointerCast(bcx, vtbl, T_ptr(T_empty_struct()));
|
||||
|
@ -370,8 +368,9 @@ fn trans_anon_obj(bcx: @block_ctxt, sp: &span, anon_obj: &ast::anon_obj,
|
|||
GEP_tup_like(bcx, body_ty, body,
|
||||
[0, abi::obj_body_elt_inner_obj]);
|
||||
bcx = body_inner_obj.bcx;
|
||||
bcx = copy_val(bcx, INIT, body_inner_obj.val, inner_obj_val.val,
|
||||
inner_obj_ty);
|
||||
bcx =
|
||||
copy_val(bcx, INIT, body_inner_obj.val, inner_obj_val.val,
|
||||
inner_obj_ty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,7 +434,7 @@ fn filtering_fn(cx: @local_ctxt, m: &vtbl_mthd, addtl_meths: [@ast::method])
|
|||
ret some(fwding_mthd(fm));
|
||||
}
|
||||
normal_mthd(_) {
|
||||
cx.ccx.sess.bug(~"create_vtbl(): shouldn't be any \
|
||||
cx.ccx.sess.bug("create_vtbl(): shouldn't be any \
|
||||
normal_mthds in meths here");
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +484,7 @@ fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t,
|
|||
}
|
||||
}
|
||||
_ {
|
||||
cx.ccx.sess.bug(~"create_vtbl(): trying to extend a \
|
||||
cx.ccx.sess.bug("create_vtbl(): trying to extend a \
|
||||
non-object");
|
||||
}
|
||||
}
|
||||
|
@ -526,7 +525,7 @@ fn create_vtbl(cx: @local_ctxt, sp: &span, outer_obj_ty: ty::t,
|
|||
}
|
||||
}
|
||||
|
||||
ret finish_vtbl(cx, llmethods, ~"vtbl");
|
||||
ret finish_vtbl(cx, llmethods, "vtbl");
|
||||
}
|
||||
|
||||
// create_backwarding_vtbl: Create a vtable for the inner object of an
|
||||
|
@ -549,7 +548,7 @@ fn create_backwarding_vtbl(cx: @local_ctxt, sp: &span, inner_obj_ty: ty::t,
|
|||
}
|
||||
_ {
|
||||
// Shouldn't happen.
|
||||
cx.ccx.sess.bug(~"create_backwarding_vtbl(): trying to extend a \
|
||||
cx.ccx.sess.bug("create_backwarding_vtbl(): trying to extend a \
|
||||
non-object");
|
||||
}
|
||||
}
|
||||
|
@ -560,19 +559,20 @@ fn create_backwarding_vtbl(cx: @local_ctxt, sp: &span, inner_obj_ty: ty::t,
|
|||
// being forwarded to.
|
||||
llmethods += [process_bkwding_mthd(cx, sp, @m, [], outer_obj_ty, [])];
|
||||
}
|
||||
ret finish_vtbl(cx, llmethods, ~"backwarding_vtbl");
|
||||
ret finish_vtbl(cx, llmethods, "backwarding_vtbl");
|
||||
}
|
||||
|
||||
// finish_vtbl: Given a vector of vtable entries, create the table in
|
||||
// read-only memory and return a pointer to it.
|
||||
fn finish_vtbl(cx: @local_ctxt, llmethods: [ValueRef], name: &istr) ->
|
||||
fn finish_vtbl(cx: @local_ctxt, llmethods: [ValueRef], name: &str) ->
|
||||
ValueRef {
|
||||
let vtbl = C_struct(llmethods);
|
||||
let vtbl_name = mangle_internal_name_by_path(
|
||||
cx.ccx, cx.path + [name]);
|
||||
let gvar = str::as_buf(vtbl_name, { |buf|
|
||||
llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl), buf)
|
||||
});
|
||||
let vtbl_name = mangle_internal_name_by_path(cx.ccx, cx.path + [name]);
|
||||
let gvar =
|
||||
str::as_buf(vtbl_name,
|
||||
{|buf|
|
||||
llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl), buf)
|
||||
});
|
||||
llvm::LLVMSetInitializer(gvar, vtbl);
|
||||
llvm::LLVMSetGlobalConstant(gvar, True);
|
||||
llvm::LLVMSetLinkage(gvar,
|
||||
|
@ -600,22 +600,19 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
|
||||
// Create a local context that's aware of the name of the method we're
|
||||
// creating.
|
||||
let mcx: @local_ctxt = @{path: cx.path
|
||||
+ [~"method", m.ident] with *cx};
|
||||
let mcx: @local_ctxt = @{path: cx.path + ["method", m.ident] with *cx};
|
||||
|
||||
// Make up a name for the backwarding function.
|
||||
let fn_name: istr = ~"backwarding_fn";
|
||||
let s: istr =
|
||||
mangle_internal_name_by_path_and_seq(
|
||||
mcx.ccx, mcx.path, fn_name);
|
||||
let fn_name: str = "backwarding_fn";
|
||||
let s: str =
|
||||
mangle_internal_name_by_path_and_seq(mcx.ccx, mcx.path, fn_name);
|
||||
|
||||
// Get the backwarding function's type and declare it.
|
||||
let llbackwarding_fn_ty: TypeRef =
|
||||
type_of_fn_full(cx.ccx, sp, m.proto, true, m.inputs, m.output,
|
||||
std::vec::len::<ast::ty_param>(ty_params));
|
||||
let llbackwarding_fn: ValueRef =
|
||||
decl_internal_fastcall_fn(
|
||||
cx.ccx.llmod, s, llbackwarding_fn_ty);
|
||||
decl_internal_fastcall_fn(cx.ccx.llmod, s, llbackwarding_fn_ty);
|
||||
|
||||
// Create a new function context and block context for the backwarding
|
||||
// function, holding onto a pointer to the first block.
|
||||
|
@ -630,8 +627,8 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
// Cast to self-stack's type.
|
||||
let llenv =
|
||||
PointerCast(bcx, fcx.llenv,
|
||||
T_ptr(T_struct([cx.ccx.rust_object_type,
|
||||
T_ptr(cx.ccx.rust_object_type)])));
|
||||
T_ptr(T_struct([cx.ccx.rust_object_type,
|
||||
T_ptr(cx.ccx.rust_object_type)])));
|
||||
let llself_obj_ptr = GEP(bcx, llenv, [C_int(0), C_int(1)]);
|
||||
llself_obj_ptr = Load(bcx, llself_obj_ptr);
|
||||
|
||||
|
@ -656,7 +653,7 @@ fn process_bkwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
}
|
||||
_ {
|
||||
// Shouldn't happen.
|
||||
cx.ccx.sess.bug(~"process_bkwding_mthd(): non-object type passed \
|
||||
cx.ccx.sess.bug("process_bkwding_mthd(): non-object type passed \
|
||||
as outer_obj_ty");
|
||||
}
|
||||
}
|
||||
|
@ -731,22 +728,19 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
|
||||
// Create a local context that's aware of the name of the method we're
|
||||
// creating.
|
||||
let mcx: @local_ctxt = @{path: cx.path
|
||||
+ [~"method", m.ident] with *cx};
|
||||
let mcx: @local_ctxt = @{path: cx.path + ["method", m.ident] with *cx};
|
||||
|
||||
// Make up a name for the forwarding function.
|
||||
let fn_name: istr = ~"forwarding_fn";
|
||||
let s: istr =
|
||||
mangle_internal_name_by_path_and_seq(
|
||||
mcx.ccx, mcx.path, fn_name);
|
||||
let fn_name: str = "forwarding_fn";
|
||||
let s: str =
|
||||
mangle_internal_name_by_path_and_seq(mcx.ccx, mcx.path, fn_name);
|
||||
|
||||
// Get the forwarding function's type and declare it.
|
||||
let llforwarding_fn_ty: TypeRef =
|
||||
type_of_fn_full(cx.ccx, sp, m.proto, true, m.inputs, m.output,
|
||||
std::vec::len::<ast::ty_param>(ty_params));
|
||||
let llforwarding_fn: ValueRef =
|
||||
decl_internal_fastcall_fn(
|
||||
cx.ccx.llmod, s, llforwarding_fn_ty);
|
||||
decl_internal_fastcall_fn(cx.ccx.llmod, s, llforwarding_fn_ty);
|
||||
|
||||
// Create a new function context and block context for the forwarding
|
||||
// function, holding onto a pointer to the first block.
|
||||
|
@ -782,8 +776,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
|
||||
// Now, reach into the box and grab the body.
|
||||
let llself_obj_body =
|
||||
GEP(bcx, llself_obj_box,
|
||||
[C_int(0), C_int(abi::box_rc_field_body)]);
|
||||
GEP(bcx, llself_obj_box, [C_int(0), C_int(abi::box_rc_field_body)]);
|
||||
|
||||
// Now, we need to figure out exactly what type the body is supposed to be
|
||||
// cast to.
|
||||
|
@ -811,8 +804,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
// method's entry out of the vtable so that the forwarding function can
|
||||
// call it.
|
||||
let llinner_obj_vtbl =
|
||||
GEP(bcx, llinner_obj.val,
|
||||
[C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||
GEP(bcx, llinner_obj.val, [C_int(0), C_int(abi::obj_field_vtbl)]);
|
||||
llinner_obj_vtbl = Load(bcx, llinner_obj_vtbl);
|
||||
|
||||
let llinner_obj_body =
|
||||
|
@ -827,7 +819,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
}
|
||||
_ {
|
||||
// Shouldn't happen.
|
||||
cx.ccx.sess.bug(~"process_fwding_mthd(): non-object type passed \
|
||||
cx.ccx.sess.bug("process_fwding_mthd(): non-object type passed \
|
||||
as target_obj_ty");
|
||||
}
|
||||
}
|
||||
|
@ -846,8 +838,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
ty::ty_fn_proto(bcx_tcx(bcx), orig_mthd_ty), true,
|
||||
m.inputs, m.output,
|
||||
std::vec::len::<ast::ty_param>(ty_params));
|
||||
llorig_mthd =
|
||||
PointerCast(bcx, llorig_mthd, T_ptr(T_ptr(llorig_mthd_ty)));
|
||||
llorig_mthd = PointerCast(bcx, llorig_mthd, T_ptr(T_ptr(llorig_mthd_ty)));
|
||||
llorig_mthd = Load(bcx, llorig_mthd);
|
||||
|
||||
// Set up the self-stack.
|
||||
|
@ -860,8 +851,7 @@ fn process_fwding_mthd(cx: @local_ctxt, sp: &span, m: @ty::method,
|
|||
llinner_obj_body);
|
||||
|
||||
// Cast self_stack back to pointer-to-object-type to make LLVM happy.
|
||||
self_stack =
|
||||
PointerCast(bcx, self_stack, T_ptr(cx.ccx.rust_object_type));
|
||||
self_stack = PointerCast(bcx, self_stack, T_ptr(cx.ccx.rust_object_type));
|
||||
|
||||
// Set up the three implicit arguments to the original method we'll need
|
||||
// to call.
|
||||
|
@ -930,11 +920,9 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t,
|
|||
}
|
||||
}
|
||||
let mcx: @local_ctxt =
|
||||
@{path: cx.path + [~"method", m.node.ident] with *cx};
|
||||
let s: istr = mangle_internal_name_by_path(mcx.ccx,
|
||||
mcx.path);
|
||||
let llfn: ValueRef = decl_internal_fastcall_fn(
|
||||
cx.ccx.llmod, s, llfnty);
|
||||
@{path: cx.path + ["method", m.node.ident] with *cx};
|
||||
let s: str = mangle_internal_name_by_path(mcx.ccx, mcx.path);
|
||||
let llfn: ValueRef = decl_internal_fastcall_fn(cx.ccx.llmod, s, llfnty);
|
||||
|
||||
// Every method on an object gets its node_id inserted into the crate-wide
|
||||
// item_ids map, together with the ValueRef that points to where that
|
||||
|
|
|
@ -3,12 +3,11 @@ import std::option::none;
|
|||
import syntax::ast;
|
||||
import lib::llvm::llvm::{ValueRef, TypeRef};
|
||||
import back::abi;
|
||||
import trans::{call_memmove, trans_shared_malloc, llsize_of,
|
||||
type_of_or_i8, incr_ptr, INIT, copy_val, load_if_immediate,
|
||||
alloca, size_of, llderivedtydescs_block_ctxt,
|
||||
lazily_emit_tydesc_glue, get_tydesc, load_inbounds,
|
||||
move_val_if_temp, trans_lval, node_id_type,
|
||||
new_sub_block_ctxt, tps_normal, do_spill_noroot};
|
||||
import trans::{call_memmove, trans_shared_malloc, llsize_of, type_of_or_i8,
|
||||
incr_ptr, INIT, copy_val, load_if_immediate, alloca, size_of,
|
||||
llderivedtydescs_block_ctxt, lazily_emit_tydesc_glue,
|
||||
get_tydesc, load_inbounds, move_val_if_temp, trans_lval,
|
||||
node_id_type, new_sub_block_ctxt, tps_normal, do_spill_noroot};
|
||||
import trans_build::*;
|
||||
import trans_common::*;
|
||||
|
||||
|
@ -18,14 +17,14 @@ fn get_fill(bcx: &@block_ctxt, vptr: ValueRef) -> ValueRef {
|
|||
fn get_alloc(bcx: &@block_ctxt, vptr: ValueRef) -> ValueRef {
|
||||
Load(bcx, InBoundsGEP(bcx, vptr, [C_int(0), C_uint(abi::vec_elt_alloc)]))
|
||||
}
|
||||
fn get_dataptr(bcx: &@block_ctxt, vpt: ValueRef,
|
||||
unit_ty: TypeRef) -> ValueRef {
|
||||
fn get_dataptr(bcx: &@block_ctxt, vpt: ValueRef, unit_ty: TypeRef) ->
|
||||
ValueRef {
|
||||
let ptr = InBoundsGEP(bcx, vpt, [C_int(0), C_uint(abi::vec_elt_elems)]);
|
||||
PointerCast(bcx, ptr, T_ptr(unit_ty))
|
||||
}
|
||||
|
||||
fn pointer_add(bcx: &@block_ctxt, ptr: ValueRef, bytes: ValueRef)
|
||||
-> ValueRef {
|
||||
fn pointer_add(bcx: &@block_ctxt, ptr: ValueRef, bytes: ValueRef) ->
|
||||
ValueRef {
|
||||
let old_ty = val_ty(ptr);
|
||||
let bptr = PointerCast(bcx, ptr, T_ptr(T_i8()));
|
||||
ret PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty);
|
||||
|
@ -34,53 +33,58 @@ fn pointer_add(bcx: &@block_ctxt, ptr: ValueRef, bytes: ValueRef)
|
|||
fn alloc_raw(bcx: &@block_ctxt, fill: ValueRef, alloc: ValueRef) -> result {
|
||||
let llvecty = T_opaque_vec();
|
||||
let vecsize = Add(bcx, alloc, llsize_of(llvecty));
|
||||
let {bcx, val: vecptr} =
|
||||
let {bcx: bcx, val: vecptr} =
|
||||
trans_shared_malloc(bcx, T_ptr(llvecty), vecsize);
|
||||
Store(bcx, fill, InBoundsGEP
|
||||
(bcx, vecptr, [C_int(0), C_uint(abi::vec_elt_fill)]));
|
||||
Store(bcx, alloc, InBoundsGEP
|
||||
(bcx, vecptr, [C_int(0), C_uint(abi::vec_elt_alloc)]));
|
||||
Store(bcx, fill,
|
||||
InBoundsGEP(bcx, vecptr, [C_int(0), C_uint(abi::vec_elt_fill)]));
|
||||
Store(bcx, alloc,
|
||||
InBoundsGEP(bcx, vecptr, [C_int(0), C_uint(abi::vec_elt_alloc)]));
|
||||
ret {bcx: bcx, val: vecptr};
|
||||
}
|
||||
|
||||
type alloc_result = {bcx: @block_ctxt,
|
||||
val: ValueRef,
|
||||
unit_ty: ty::t,
|
||||
llunitsz: ValueRef,
|
||||
llunitty: TypeRef};
|
||||
type alloc_result =
|
||||
{bcx: @block_ctxt,
|
||||
val: ValueRef,
|
||||
unit_ty: ty::t,
|
||||
llunitsz: ValueRef,
|
||||
llunitty: TypeRef};
|
||||
|
||||
fn alloc(bcx: &@block_ctxt, vec_ty: &ty::t, elts: uint) -> alloc_result {
|
||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||
let llunitty = type_of_or_i8(bcx, unit_ty);
|
||||
let llvecty = T_vec(llunitty);
|
||||
let {bcx, val: unit_sz} = size_of(bcx, unit_ty);
|
||||
let {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty);
|
||||
|
||||
let fill = Mul(bcx, C_uint(elts), unit_sz);
|
||||
let alloc = if elts < 4u { Mul(bcx, C_int(4), unit_sz) } else { fill };
|
||||
let {bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
|
||||
let {bcx: bcx, val: vptr} = alloc_raw(bcx, fill, alloc);
|
||||
let vptr = PointerCast(bcx, vptr, T_ptr(llvecty));
|
||||
add_clean_temp(bcx, vptr, vec_ty);
|
||||
ret {bcx: bcx, val: vptr, unit_ty: unit_ty,
|
||||
llunitsz: unit_sz, llunitty: llunitty};
|
||||
ret {bcx: bcx,
|
||||
val: vptr,
|
||||
unit_ty: unit_ty,
|
||||
llunitsz: unit_sz,
|
||||
llunitty: llunitty};
|
||||
}
|
||||
|
||||
fn duplicate(bcx: &@block_ctxt, vptrptr: ValueRef) -> @block_ctxt {
|
||||
let vptr = Load(bcx, vptrptr);
|
||||
let fill = get_fill(bcx, vptr);
|
||||
let size = Add(bcx, fill, llsize_of(T_opaque_vec()));
|
||||
let {bcx, val: newptr} = trans_shared_malloc(bcx, val_ty(vptr), size);
|
||||
let {bcx: bcx, val: newptr} =
|
||||
trans_shared_malloc(bcx, val_ty(vptr), size);
|
||||
let bcx = call_memmove(bcx, newptr, vptr, size).bcx;
|
||||
Store(bcx, fill,
|
||||
InBoundsGEP(bcx, newptr, [C_int(0), C_uint(abi::vec_elt_alloc)]));
|
||||
Store(bcx, newptr, vptrptr);
|
||||
ret bcx;
|
||||
}
|
||||
fn make_drop_glue(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t)
|
||||
-> @block_ctxt {
|
||||
fn make_drop_glue(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t) ->
|
||||
@block_ctxt {
|
||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||
let vptr = Load(bcx, vptrptr);
|
||||
let drop_cx = new_sub_block_ctxt(bcx, ~"drop");
|
||||
let next_cx = new_sub_block_ctxt(bcx, ~"next");
|
||||
let drop_cx = new_sub_block_ctxt(bcx, "drop");
|
||||
let next_cx = new_sub_block_ctxt(bcx, "next");
|
||||
let null_test = IsNull(bcx, vptr);
|
||||
CondBr(bcx, null_test, next_cx.llbb, drop_cx.llbb);
|
||||
if ty::type_needs_drop(bcx_tcx(bcx), unit_ty) {
|
||||
|
@ -92,10 +96,14 @@ fn make_drop_glue(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t)
|
|||
ret next_cx;
|
||||
}
|
||||
|
||||
fn trans_vec(bcx: &@block_ctxt, args: &[@ast::expr],
|
||||
id: ast::node_id) -> result {
|
||||
fn trans_vec(bcx: &@block_ctxt, args: &[@ast::expr], id: ast::node_id) ->
|
||||
result {
|
||||
let vec_ty = node_id_type(bcx_ccx(bcx), id);
|
||||
let {bcx, val: vptr, llunitsz, unit_ty, llunitty} =
|
||||
let {bcx: bcx,
|
||||
val: vptr,
|
||||
llunitsz: llunitsz,
|
||||
unit_ty: unit_ty,
|
||||
llunitty: llunitty} =
|
||||
alloc(bcx, vec_ty, vec::len(args));
|
||||
|
||||
// Store the individual elements.
|
||||
|
@ -104,24 +112,24 @@ fn trans_vec(bcx: &@block_ctxt, args: &[@ast::expr],
|
|||
for e in args {
|
||||
let lv = trans_lval(bcx, e);
|
||||
bcx = lv.res.bcx;
|
||||
let lleltptr = if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
||||
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(i), llunitsz)])
|
||||
} else {
|
||||
InBoundsGEP(bcx, dataptr, [C_uint(i)])
|
||||
};
|
||||
let lleltptr =
|
||||
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
||||
InBoundsGEP(bcx, dataptr, [Mul(bcx, C_uint(i), llunitsz)])
|
||||
} else { InBoundsGEP(bcx, dataptr, [C_uint(i)]) };
|
||||
bcx = move_val_if_temp(bcx, INIT, lleltptr, lv, unit_ty);
|
||||
i += 1u;
|
||||
}
|
||||
ret rslt(bcx, vptr);
|
||||
}
|
||||
fn trans_istr(bcx: &@block_ctxt, s: istr) -> result {
|
||||
fn trans_istr(bcx: &@block_ctxt, s: str) -> result {
|
||||
let veclen = std::str::byte_len(s) + 1u; // +1 for \0
|
||||
let {bcx, val: sptr, _} =
|
||||
let {bcx: bcx, val: sptr, _} =
|
||||
alloc(bcx, ty::mk_istr(bcx_tcx(bcx)), veclen);
|
||||
|
||||
let llcstr = C_cstr(bcx_ccx(bcx), s);
|
||||
let bcx = call_memmove(bcx, get_dataptr(bcx, sptr, T_i8()),
|
||||
llcstr, C_uint(veclen)).bcx;
|
||||
let bcx =
|
||||
call_memmove(bcx, get_dataptr(bcx, sptr, T_i8()), llcstr,
|
||||
C_uint(veclen)).bcx;
|
||||
|
||||
ret rslt(bcx, sptr);
|
||||
}
|
||||
|
@ -135,12 +143,13 @@ fn trans_append(cx: &@block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
|||
lhsptr = PointerCast(cx, lhsptr, T_ptr(T_ptr(T_opaque_vec())));
|
||||
rhs = PointerCast(cx, rhs, T_ptr(T_opaque_vec()));
|
||||
}
|
||||
let strings = alt ty::struct(bcx_tcx(cx), vec_ty) {
|
||||
ty::ty_istr. { true }
|
||||
ty::ty_vec(_) { false }
|
||||
};
|
||||
let strings =
|
||||
alt ty::struct(bcx_tcx(cx), vec_ty) {
|
||||
ty::ty_istr. { true }
|
||||
ty::ty_vec(_) { false }
|
||||
};
|
||||
|
||||
let {bcx, val: unit_sz} = size_of(cx, unit_ty);
|
||||
let {bcx: bcx, val: unit_sz} = size_of(cx, unit_ty);
|
||||
let llunitty = type_of_or_i8(cx, unit_ty);
|
||||
|
||||
let lhs = Load(bcx, lhsptr);
|
||||
|
@ -161,18 +170,23 @@ fn trans_append(cx: &@block_ctxt, vec_ty: ty::t, lhsptr: ValueRef,
|
|||
if strings { lhs_off = Sub(bcx, lhs_off, C_int(1)); }
|
||||
let write_ptr = pointer_add(bcx, lhs_data, lhs_off);
|
||||
let write_ptr_ptr = do_spill_noroot(bcx, write_ptr);
|
||||
let bcx = iter_vec_raw(bcx, rhs, vec_ty, rfill, { | &bcx, addr, _ty |
|
||||
let write_ptr = Load(bcx, write_ptr_ptr);
|
||||
let bcx = copy_val(bcx, INIT, write_ptr,
|
||||
load_if_immediate(bcx, addr, unit_ty), unit_ty);
|
||||
if dynamic {
|
||||
// We have to increment by the dynamically-computed size.
|
||||
incr_ptr(bcx, write_ptr, unit_sz, write_ptr_ptr);
|
||||
} else {
|
||||
incr_ptr(bcx, write_ptr, C_int(1), write_ptr_ptr);
|
||||
}
|
||||
ret bcx;
|
||||
});
|
||||
let bcx =
|
||||
iter_vec_raw(bcx, rhs, vec_ty, rfill,
|
||||
// We have to increment by the dynamically-computed size.
|
||||
{|&bcx, addr, _ty|
|
||||
let write_ptr = Load(bcx, write_ptr_ptr);
|
||||
let bcx =
|
||||
copy_val(bcx, INIT, write_ptr,
|
||||
load_if_immediate(bcx, addr, unit_ty),
|
||||
unit_ty);
|
||||
if dynamic {
|
||||
incr_ptr(bcx, write_ptr, unit_sz, write_ptr_ptr);
|
||||
} else {
|
||||
incr_ptr(bcx, write_ptr, C_int(1),
|
||||
write_ptr_ptr);
|
||||
}
|
||||
ret bcx;
|
||||
});
|
||||
ret rslt(bcx, C_nil());
|
||||
}
|
||||
|
||||
|
@ -180,7 +194,7 @@ fn trans_append_literal(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
|||
vals: &[@ast::expr]) -> @block_ctxt {
|
||||
let elt_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||
let ti = none;
|
||||
let {bcx, val: td} =
|
||||
let {bcx: bcx, val: td} =
|
||||
get_tydesc(bcx, elt_ty, false, tps_normal, ti).result;
|
||||
trans::lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, ti);
|
||||
let opaque_v = PointerCast(bcx, vptrptr, T_ptr(T_ptr(T_opaque_vec())));
|
||||
|
@ -188,7 +202,8 @@ fn trans_append_literal(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
|||
let {bcx: e_bcx, val: elt} = trans::trans_expr(bcx, val);
|
||||
bcx = e_bcx;
|
||||
let r = trans::spill_if_immediate(bcx, elt, elt_ty);
|
||||
let spilled = r.val; bcx = r.bcx;
|
||||
let spilled = r.val;
|
||||
bcx = r.bcx;
|
||||
Call(bcx, bcx_ccx(bcx).upcalls.vec_push,
|
||||
[bcx.fcx.lltaskptr, opaque_v, td,
|
||||
PointerCast(bcx, spilled, T_ptr(T_i8()))]);
|
||||
|
@ -196,40 +211,41 @@ fn trans_append_literal(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
|||
ret bcx;
|
||||
}
|
||||
|
||||
fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef,
|
||||
rhs: ValueRef) -> result {
|
||||
let strings = alt ty::struct(bcx_tcx(bcx), vec_ty) {
|
||||
ty::ty_istr. { true }
|
||||
ty::ty_vec(_) { false }
|
||||
};
|
||||
fn trans_add(bcx: &@block_ctxt, vec_ty: ty::t, lhs: ValueRef, rhs: ValueRef)
|
||||
-> result {
|
||||
let strings =
|
||||
alt ty::struct(bcx_tcx(bcx), vec_ty) {
|
||||
ty::ty_istr. { true }
|
||||
ty::ty_vec(_) { false }
|
||||
};
|
||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||
let llunitty = type_of_or_i8(bcx, unit_ty);
|
||||
let {bcx, val: llunitsz} = size_of(bcx, unit_ty);
|
||||
let {bcx: bcx, val: llunitsz} = size_of(bcx, unit_ty);
|
||||
|
||||
let lhs_fill = get_fill(bcx, lhs);
|
||||
if strings { lhs_fill = Sub(bcx, lhs_fill, C_int(1)); }
|
||||
let rhs_fill = get_fill(bcx, rhs);
|
||||
let new_fill = Add(bcx, lhs_fill, rhs_fill);
|
||||
let {bcx, val: new_vec} = alloc_raw(bcx, new_fill, new_fill);
|
||||
let {bcx: bcx, val: new_vec} = alloc_raw(bcx, new_fill, new_fill);
|
||||
let new_vec = PointerCast(bcx, new_vec, T_ptr(T_vec(llunitty)));
|
||||
add_clean_temp(bcx, new_vec, vec_ty);
|
||||
|
||||
let write_ptr_ptr = do_spill_noroot(bcx,
|
||||
get_dataptr(bcx, new_vec, llunitty));
|
||||
let copy_fn = bind fn(bcx: &@block_ctxt, addr: ValueRef, _ty: ty::t,
|
||||
write_ptr_ptr: ValueRef, unit_ty: ty::t,
|
||||
llunitsz: ValueRef) -> @block_ctxt {
|
||||
let write_ptr = Load(bcx, write_ptr_ptr);
|
||||
let bcx = copy_val(bcx, INIT, write_ptr,
|
||||
load_if_immediate(bcx, addr, unit_ty), unit_ty);
|
||||
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
||||
// We have to increment by the dynamically-computed size.
|
||||
incr_ptr(bcx, write_ptr, llunitsz, write_ptr_ptr);
|
||||
} else {
|
||||
incr_ptr(bcx, write_ptr, C_int(1), write_ptr_ptr);
|
||||
}
|
||||
ret bcx;
|
||||
} (_, _, _, write_ptr_ptr, unit_ty, llunitsz);
|
||||
let write_ptr_ptr =
|
||||
do_spill_noroot(bcx, get_dataptr(bcx, new_vec, llunitty));
|
||||
let copy_fn =
|
||||
bind fn (bcx: &@block_ctxt, addr: ValueRef, _ty: ty::t,
|
||||
write_ptr_ptr: ValueRef, unit_ty: ty::t, llunitsz: ValueRef)
|
||||
-> @block_ctxt {
|
||||
let write_ptr = Load(bcx, write_ptr_ptr);
|
||||
let bcx =
|
||||
copy_val(bcx, INIT, write_ptr,
|
||||
load_if_immediate(bcx, addr, unit_ty), unit_ty);
|
||||
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
||||
// We have to increment by the dynamically-computed size.
|
||||
incr_ptr(bcx, write_ptr, llunitsz, write_ptr_ptr);
|
||||
} else { incr_ptr(bcx, write_ptr, C_int(1), write_ptr_ptr); }
|
||||
ret bcx;
|
||||
}(_, _, _, write_ptr_ptr, unit_ty, llunitsz);
|
||||
|
||||
let bcx = iter_vec_raw(bcx, lhs, vec_ty, lhs_fill, copy_fn);
|
||||
let bcx = iter_vec_raw(bcx, rhs, vec_ty, rhs_fill, copy_fn);
|
||||
|
@ -241,10 +257,10 @@ type val_and_ty_fn = fn(&@block_ctxt, ValueRef, ty::t) -> result;
|
|||
type iter_vec_block = block(&@block_ctxt, ValueRef, ty::t) -> @block_ctxt;
|
||||
|
||||
fn iter_vec_raw(bcx: &@block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
||||
fill: ValueRef, f: &iter_vec_block) -> @block_ctxt {
|
||||
fill: ValueRef, f: &iter_vec_block) -> @block_ctxt {
|
||||
let unit_ty = ty::sequence_element_type(bcx_tcx(bcx), vec_ty);
|
||||
let llunitty = type_of_or_i8(bcx, unit_ty);
|
||||
let {bcx, val: unit_sz} = size_of(bcx, unit_ty);
|
||||
let {bcx: bcx, val: unit_sz} = size_of(bcx, unit_ty);
|
||||
let vptr = PointerCast(bcx, vptr, T_ptr(T_vec(llunitty)));
|
||||
let data_ptr = get_dataptr(bcx, vptr, llunitty);
|
||||
|
||||
|
@ -255,18 +271,19 @@ fn iter_vec_raw(bcx: &@block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
|||
let data_ptr_ptr = do_spill_noroot(bcx, data_ptr);
|
||||
|
||||
// Now perform the iteration.
|
||||
let header_cx = new_sub_block_ctxt(bcx, ~"iter_vec_loop_header");
|
||||
let header_cx = new_sub_block_ctxt(bcx, "iter_vec_loop_header");
|
||||
Br(bcx, header_cx.llbb);
|
||||
let data_ptr = Load(header_cx, data_ptr_ptr);
|
||||
let not_yet_at_end = ICmp(header_cx, lib::llvm::LLVMIntULT,
|
||||
data_ptr, data_end_ptr);
|
||||
let body_cx = new_sub_block_ctxt(bcx, ~"iter_vec_loop_body");
|
||||
let next_cx = new_sub_block_ctxt(bcx, ~"iter_vec_next");
|
||||
let not_yet_at_end =
|
||||
ICmp(header_cx, lib::llvm::LLVMIntULT, data_ptr, data_end_ptr);
|
||||
let body_cx = new_sub_block_ctxt(bcx, "iter_vec_loop_body");
|
||||
let next_cx = new_sub_block_ctxt(bcx, "iter_vec_next");
|
||||
CondBr(header_cx, not_yet_at_end, body_cx.llbb, next_cx.llbb);
|
||||
body_cx = f(body_cx, data_ptr, unit_ty);
|
||||
let increment = if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
||||
unit_sz
|
||||
} else { C_int(1) };
|
||||
let increment =
|
||||
if ty::type_has_dynamic_size(bcx_tcx(bcx), unit_ty) {
|
||||
unit_sz
|
||||
} else { C_int(1) };
|
||||
incr_ptr(body_cx, data_ptr, increment, data_ptr_ptr);
|
||||
Br(body_cx, header_cx.llbb);
|
||||
|
||||
|
@ -274,9 +291,9 @@ fn iter_vec_raw(bcx: &@block_ctxt, vptr: ValueRef, vec_ty: ty::t,
|
|||
}
|
||||
|
||||
fn iter_vec(bcx: &@block_ctxt, vptrptr: ValueRef, vec_ty: ty::t,
|
||||
f: &iter_vec_block) -> @block_ctxt {
|
||||
let vptr = Load(bcx, PointerCast(bcx, vptrptr,
|
||||
T_ptr(T_ptr(T_opaque_vec()))));
|
||||
f: &iter_vec_block) -> @block_ctxt {
|
||||
let vptr =
|
||||
Load(bcx, PointerCast(bcx, vptrptr, T_ptr(T_ptr(T_opaque_vec()))));
|
||||
ret iter_vec_raw(bcx, vptr, vec_ty, get_fill(bcx, vptr), f);
|
||||
}
|
||||
|
||||
|
|
|
@ -239,8 +239,8 @@ fn implies(a: t, b: t) -> bool {
|
|||
ret tritv_doesntcare(tmp);
|
||||
}
|
||||
|
||||
fn trit_str(t: trit) -> istr {
|
||||
alt t { dont_care. { ~"?" } ttrue. { ~"1" } tfalse. { ~"0" } }
|
||||
fn trit_str(t: trit) -> str {
|
||||
alt t { dont_care. { "?" } ttrue. { "1" } tfalse. { "0" } }
|
||||
}
|
||||
//
|
||||
// Local Variables:
|
||||
|
|
|
@ -32,12 +32,12 @@ fn collect_ids_block(b: &blk, rs: @mutable [node_id]) { *rs += [b.node.id]; }
|
|||
fn collect_ids_stmt(s: &@stmt, rs: @mutable [node_id]) {
|
||||
alt s.node {
|
||||
stmt_decl(_, id) {
|
||||
log ~"node_id " + int::str(id);
|
||||
log "node_id " + int::str(id);
|
||||
log_stmt(*s);;
|
||||
*rs += [id];
|
||||
}
|
||||
stmt_expr(_, id) {
|
||||
log ~"node_id " + int::str(id);
|
||||
log "node_id " + int::str(id);
|
||||
log_stmt(*s);;
|
||||
*rs += [id];
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ fn node_ids_in_fn(f: &_fn, tps: &[ty_param], sp: &span, i: &fn_ident,
|
|||
|
||||
fn init_vecs(ccx: &crate_ctxt, node_ids: &[node_id], len: uint) {
|
||||
for i: node_id in node_ids {
|
||||
log int::str(i) + ~" |-> " + uint::str(len);
|
||||
log int::str(i) + " |-> " + uint::str(len);
|
||||
add_node(ccx, i, empty_ann(len));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,17 +55,17 @@ tag oper_type {
|
|||
}
|
||||
|
||||
/* logging funs */
|
||||
fn def_id_to_str(d: def_id) -> istr {
|
||||
ret int::str(d.crate) + ~"," + int::str(d.node);
|
||||
fn def_id_to_str(d: def_id) -> str {
|
||||
ret int::str(d.crate) + "," + int::str(d.node);
|
||||
}
|
||||
|
||||
fn comma_str(args: &[@constr_arg_use]) -> istr {
|
||||
let rslt = ~"";
|
||||
fn comma_str(args: &[@constr_arg_use]) -> str {
|
||||
let rslt = "";
|
||||
let comma = false;
|
||||
for a: @constr_arg_use in args {
|
||||
if comma { rslt += ~", "; } else { comma = true; }
|
||||
if comma { rslt += ", "; } else { comma = true; }
|
||||
alt a.node {
|
||||
carg_base. { rslt += ~"*"; }
|
||||
carg_base. { rslt += "*"; }
|
||||
carg_ident(i) { rslt += i.ident; }
|
||||
carg_lit(l) { rslt += lit_to_str(l); }
|
||||
}
|
||||
|
@ -73,30 +73,28 @@ fn comma_str(args: &[@constr_arg_use]) -> istr {
|
|||
ret rslt;
|
||||
}
|
||||
|
||||
fn constraint_to_str(tcx: &ty::ctxt, c: &sp_constr) -> istr {
|
||||
fn constraint_to_str(tcx: &ty::ctxt, c: &sp_constr) -> str {
|
||||
alt c.node {
|
||||
ninit(_, i) {
|
||||
ret ~"init(" + i + ~" [" +
|
||||
tcx.sess.span_str(c.span) + ~"])";
|
||||
ret "init(" + i + " [" + tcx.sess.span_str(c.span) + "])";
|
||||
}
|
||||
npred(p, _, args) {
|
||||
ret path_to_str(p) + ~"(" +
|
||||
comma_str(args) + ~")" + ~"[" +
|
||||
tcx.sess.span_str(c.span) + ~"]";
|
||||
ret path_to_str(p) + "(" + comma_str(args) + ")" + "[" +
|
||||
tcx.sess.span_str(c.span) + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tritv_to_str(fcx: fn_ctxt, v: &tritv::t) -> istr {
|
||||
let s = ~"";
|
||||
fn tritv_to_str(fcx: fn_ctxt, v: &tritv::t) -> str {
|
||||
let s = "";
|
||||
let comma = false;
|
||||
for p: norm_constraint in constraints(fcx) {
|
||||
alt tritv_get(v, p.bit_num) {
|
||||
dont_care. { }
|
||||
t {
|
||||
s +=
|
||||
if comma { ~", " } else { comma = true; ~"" } +
|
||||
if t == tfalse { ~"!" } else { ~"" } +
|
||||
if comma { ", " } else { comma = true; "" } +
|
||||
if t == tfalse { "!" } else { "" } +
|
||||
constraint_to_str(fcx.ccx.tcx, p.c);
|
||||
}
|
||||
}
|
||||
|
@ -107,8 +105,8 @@ fn tritv_to_str(fcx: fn_ctxt, v: &tritv::t) -> istr {
|
|||
fn log_tritv(fcx: &fn_ctxt, v: &tritv::t) { log tritv_to_str(fcx, v); }
|
||||
|
||||
fn first_difference_string(fcx: &fn_ctxt, expected: &tritv::t,
|
||||
actual: &tritv::t) -> istr {
|
||||
let s: istr = ~"";
|
||||
actual: &tritv::t) -> str {
|
||||
let s: str = "";
|
||||
for c: norm_constraint in constraints(fcx) {
|
||||
if tritv_get(expected, c.bit_num) == ttrue &&
|
||||
tritv_get(actual, c.bit_num) != ttrue {
|
||||
|
@ -120,12 +118,12 @@ fn first_difference_string(fcx: &fn_ctxt, expected: &tritv::t,
|
|||
|
||||
fn log_tritv_err(fcx: fn_ctxt, v: tritv::t) { log_err tritv_to_str(fcx, v); }
|
||||
|
||||
fn tos(v: &[uint]) -> istr {
|
||||
let rslt = ~"";
|
||||
fn tos(v: &[uint]) -> str {
|
||||
let rslt = "";
|
||||
for i: uint in v {
|
||||
if i == 0u {
|
||||
rslt += ~"0";
|
||||
} else if i == 1u { rslt += ~"1"; } else { rslt += ~"?"; }
|
||||
rslt += "0";
|
||||
} else if i == 1u { rslt += "1"; } else { rslt += "?"; }
|
||||
}
|
||||
ret rslt;
|
||||
}
|
||||
|
@ -170,11 +168,11 @@ fn log_states_err(pp: &pre_and_post_state) {
|
|||
log_cond_err(p2);
|
||||
}
|
||||
|
||||
fn print_ident(i: &ident) { log ~" " + i + ~" "; }
|
||||
fn print_ident(i: &ident) { log " " + i + " "; }
|
||||
|
||||
fn print_idents(idents: &mutable [ident]) {
|
||||
if vec::len::<ident>(idents) == 0u { ret; }
|
||||
log ~"an ident: " + vec::pop::<ident>(idents);
|
||||
log "an ident: " + vec::pop::<ident>(idents);
|
||||
print_idents(idents);
|
||||
}
|
||||
|
||||
|
@ -272,15 +270,15 @@ So we need context. And so it seems clearer to just have separate
|
|||
constraints.
|
||||
*/
|
||||
type fn_info =
|
||||
/* list, accumulated during pre/postcondition
|
||||
computation, of all local variables that may be
|
||||
used */
|
||||
// Doesn't seem to work without the @ -- bug
|
||||
{constrs: constr_map,
|
||||
num_constraints: uint,
|
||||
cf: controlflow,
|
||||
i_return: tsconstr,
|
||||
i_diverge: tsconstr,
|
||||
/* list, accumulated during pre/postcondition
|
||||
computation, of all local variables that may be
|
||||
used */
|
||||
// Doesn't seem to work without the @ -- bug
|
||||
used_vars: @mutable [node_id]};
|
||||
|
||||
fn tsconstr_to_def_id(t: &tsconstr) -> def_id {
|
||||
|
@ -330,8 +328,7 @@ fn get_ts_ann(ccx: &crate_ctxt, i: node_id) -> option::t<ts_ann> {
|
|||
fn node_id_to_ts_ann(ccx: &crate_ctxt, id: node_id) -> ts_ann {
|
||||
alt get_ts_ann(ccx, id) {
|
||||
none. {
|
||||
log_err ~"node_id_to_ts_ann: no ts_ann for node_id "
|
||||
+ int::str(id);
|
||||
log_err "node_id_to_ts_ann: no ts_ann for node_id " + int::str(id);
|
||||
fail;
|
||||
}
|
||||
some(t) { ret t; }
|
||||
|
@ -533,8 +530,7 @@ fn constraints_expr(cx: &ty::ctxt, e: @expr) -> [@ty::constr] {
|
|||
fn node_id_to_def_strict(cx: &ty::ctxt, id: node_id) -> def {
|
||||
alt cx.def_map.find(id) {
|
||||
none. {
|
||||
log_err ~"node_id_to_def: node_id "
|
||||
+ int::str(id) + ~" has no def";
|
||||
log_err "node_id_to_def: node_id " + int::str(id) + " has no def";
|
||||
fail;
|
||||
}
|
||||
some(d) { ret d; }
|
||||
|
@ -579,26 +575,23 @@ fn constraints(fcx: &fn_ctxt) -> [norm_constraint] {
|
|||
// should freeze it at some earlier point.
|
||||
fn match_args(fcx: &fn_ctxt, occs: &@mutable [pred_args],
|
||||
occ: &[@constr_arg_use]) -> uint {
|
||||
log ~"match_args: looking at " +
|
||||
constr_args_to_str(fn (i: &inst) -> istr {
|
||||
ret i.ident;
|
||||
}, occ);
|
||||
log "match_args: looking at " +
|
||||
constr_args_to_str(fn (i: &inst) -> str { ret i.ident; }, occ);
|
||||
for pd: pred_args in *occs {
|
||||
log ~"match_args: candidate " + pred_args_to_str(pd);
|
||||
log "match_args: candidate " + pred_args_to_str(pd);
|
||||
fn eq(p: &inst, q: &inst) -> bool { ret p.node == q.node; }
|
||||
if ty::args_eq(eq, pd.node.args, occ) { ret pd.node.bit_num; }
|
||||
}
|
||||
fcx.ccx.tcx.sess.bug(~"match_args: no match for occurring args");
|
||||
fcx.ccx.tcx.sess.bug("match_args: no match for occurring args");
|
||||
}
|
||||
|
||||
fn def_id_for_constr(tcx: ty::ctxt, t: node_id) -> def_id {
|
||||
alt tcx.def_map.find(t) {
|
||||
none. {
|
||||
tcx.sess.bug(~"node_id_for_constr: bad node_id "
|
||||
+ int::str(t));
|
||||
tcx.sess.bug("node_id_for_constr: bad node_id " + int::str(t));
|
||||
}
|
||||
some(def_fn(i, _)) { ret i; }
|
||||
_ { tcx.sess.bug(~"node_id_for_constr: pred is not a function"); }
|
||||
_ { tcx.sess.bug("node_id_for_constr: pred is not a function"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,12 +605,11 @@ fn expr_to_constr_arg(tcx: ty::ctxt, e: &@expr) -> @constr_arg_use {
|
|||
carg_ident({ident: p.node.idents[0], node: id.node}));
|
||||
}
|
||||
some(_) {
|
||||
tcx.sess.bug(~"exprs_to_constr_args: non-local variable " +
|
||||
~"as pred arg");
|
||||
tcx.sess.bug("exprs_to_constr_args: non-local variable " +
|
||||
"as pred arg");
|
||||
}
|
||||
none {
|
||||
tcx.sess.bug(~"exprs_to_constr_args: NONE " +
|
||||
~"as pred arg");
|
||||
tcx.sess.bug("exprs_to_constr_args: NONE " + "as pred arg");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -625,8 +617,8 @@ fn expr_to_constr_arg(tcx: ty::ctxt, e: &@expr) -> @constr_arg_use {
|
|||
expr_lit(l) { ret @respan(e.span, carg_lit(l)); }
|
||||
_ {
|
||||
tcx.sess.span_fatal(e.span,
|
||||
~"Arguments to constrained functions must be " +
|
||||
~"literals or local variables");
|
||||
"Arguments to constrained functions must be " +
|
||||
"literals or local variables");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -649,25 +641,23 @@ fn expr_to_constr(tcx: ty::ctxt, e: &@expr) -> sp_constr {
|
|||
}
|
||||
_ {
|
||||
tcx.sess.span_fatal(operator.span,
|
||||
~"Internal error: " +
|
||||
~" ill-formed operator \
|
||||
"Internal error: " +
|
||||
" ill-formed operator \
|
||||
in predicate");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ {
|
||||
tcx.sess.span_fatal(e.span,
|
||||
~"Internal error: " + ~" ill-formed predicate");
|
||||
"Internal error: " + " ill-formed predicate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn pred_args_to_str(p: &pred_args) -> istr {
|
||||
~"<" + uint::str(p.node.bit_num) + ~", " +
|
||||
constr_args_to_str(fn (i: &inst) -> istr {
|
||||
ret i.ident;
|
||||
}, p.node.args)
|
||||
+ ~">"
|
||||
fn pred_args_to_str(p: &pred_args) -> str {
|
||||
"<" + uint::str(p.node.bit_num) + ", " +
|
||||
constr_args_to_str(fn (i: &inst) -> str { ret i.ident; }, p.node.args)
|
||||
+ ">"
|
||||
}
|
||||
|
||||
fn substitute_constr_args(cx: &ty::ctxt, actuals: &[@expr], c: &@ty::constr)
|
||||
|
@ -687,7 +677,7 @@ fn substitute_arg(cx: &ty::ctxt, actuals: &[@expr], a: @constr_arg) ->
|
|||
if i < num_actuals {
|
||||
ret expr_to_constr_arg(cx, actuals[i]);
|
||||
} else {
|
||||
cx.sess.span_fatal(a.span, ~"Constraint argument out of bounds");
|
||||
cx.sess.span_fatal(a.span, "Constraint argument out of bounds");
|
||||
}
|
||||
}
|
||||
carg_base. { ret @respan(a.span, carg_base); }
|
||||
|
@ -766,18 +756,18 @@ fn find_in_subst_bool(s: &subst, id: node_id) -> bool {
|
|||
is_some(find_in_subst(id, s))
|
||||
}
|
||||
|
||||
fn insts_to_str(stuff: &[constr_arg_general_<inst>]) -> istr {
|
||||
let rslt = ~"<";
|
||||
fn insts_to_str(stuff: &[constr_arg_general_<inst>]) -> str {
|
||||
let rslt = "<";
|
||||
for i: constr_arg_general_<inst> in stuff {
|
||||
rslt +=
|
||||
~" " +
|
||||
" " +
|
||||
alt i {
|
||||
carg_ident(p) { p.ident }
|
||||
carg_base. { ~"*" }
|
||||
carg_lit(_) { ~"[lit]" }
|
||||
} + ~" ";
|
||||
carg_base. { "*" }
|
||||
carg_lit(_) { "[lit]" }
|
||||
} + " ";
|
||||
}
|
||||
rslt += ~">";
|
||||
rslt += ">";
|
||||
rslt
|
||||
}
|
||||
|
||||
|
@ -814,7 +804,7 @@ fn replace(subst: subst, d: pred_args) -> [constr_arg_general_<inst>] {
|
|||
|
||||
fn path_to_ident(cx: &ty::ctxt, p: &path) -> ident {
|
||||
alt vec::last(p.node.idents) {
|
||||
none. { cx.sess.span_fatal(p.span, ~"Malformed path"); }
|
||||
none. { cx.sess.span_fatal(p.span, "Malformed path"); }
|
||||
some(i) { ret i; }
|
||||
}
|
||||
}
|
||||
|
@ -829,13 +819,13 @@ fn local_node_id_to_def_id_strict(fcx: &fn_ctxt, sp: &span, i: &node_id) ->
|
|||
}
|
||||
some(_) {
|
||||
fcx.ccx.tcx.sess.span_fatal(sp,
|
||||
~"local_node_id_to_def_id: id \
|
||||
"local_node_id_to_def_id: id \
|
||||
isn't a local");
|
||||
}
|
||||
none. {
|
||||
// should really be bug. span_bug()?
|
||||
fcx.ccx.tcx.sess.span_fatal(sp,
|
||||
~"local_node_id_to_def_id: id \
|
||||
"local_node_id_to_def_id: id \
|
||||
is unbound");
|
||||
}
|
||||
}
|
||||
|
@ -848,7 +838,9 @@ fn local_node_id_to_def(fcx: &fn_ctxt, i: &node_id) -> option::t<def> {
|
|||
fn local_node_id_to_def_id(fcx: &fn_ctxt, i: &node_id) -> option::t<def_id> {
|
||||
alt local_node_id_to_def(fcx, i) {
|
||||
some(def_local(id)) | some(def_arg(id, _)) | some(def_binding(id)) |
|
||||
some(def_upvar(id, _, _)) { some(id) }
|
||||
some(def_upvar(id, _, _)) {
|
||||
some(id)
|
||||
}
|
||||
_ { none }
|
||||
}
|
||||
}
|
||||
|
@ -1048,23 +1040,27 @@ fn do_nothing<T>(_f: &_fn, _tp: &[ty_param], _sp: &span, _i: &fn_ident,
|
|||
|
||||
|
||||
fn args_to_constr_args(tcx: &ty::ctxt, args: &[arg],
|
||||
indices:&[@sp_constr_arg<uint>]) -> [@constr_arg_use] {
|
||||
indices: &[@sp_constr_arg<uint>]) ->
|
||||
[@constr_arg_use] {
|
||||
let actuals: [@constr_arg_use] = [];
|
||||
let num_args = vec::len(args);
|
||||
for a:@sp_constr_arg<uint> in indices {
|
||||
actuals += [@respan(a.span, alt a.node {
|
||||
carg_base. { carg_base }
|
||||
carg_ident(i) {
|
||||
if i < num_args {
|
||||
carg_ident({ident: args[i].ident, node:args[i].id})
|
||||
}
|
||||
else {
|
||||
tcx.sess.span_bug(a.span, ~"Index out of bounds in \
|
||||
for a: @sp_constr_arg<uint> in indices {
|
||||
actuals +=
|
||||
[@respan(a.span,
|
||||
alt a.node {
|
||||
carg_base. { carg_base }
|
||||
carg_ident(i) {
|
||||
if i < num_args {
|
||||
carg_ident({ident: args[i].ident,
|
||||
node: args[i].id})
|
||||
} else {
|
||||
tcx.sess.span_bug(a.span,
|
||||
"Index out of bounds in \
|
||||
constraint arg");
|
||||
}
|
||||
}
|
||||
carg_lit(l) { carg_lit(l) }
|
||||
})];
|
||||
}
|
||||
}
|
||||
carg_lit(l) { carg_lit(l) }
|
||||
})];
|
||||
}
|
||||
ret actuals;
|
||||
}
|
||||
|
@ -1073,7 +1069,7 @@ fn ast_constr_to_ts_constr(tcx: &ty::ctxt, args: &[arg], c: &@constr) ->
|
|||
tsconstr {
|
||||
let tconstr = ty::ast_constr_to_constr(tcx, c);
|
||||
ret npred(tconstr.node.path, tconstr.node.id,
|
||||
args_to_constr_args(tcx, args, tconstr.node.args));
|
||||
args_to_constr_args(tcx, args, tconstr.node.args));
|
||||
}
|
||||
|
||||
fn ast_constr_to_sp_constr(tcx: &ty::ctxt, args: &[arg], c: &@constr) ->
|
||||
|
@ -1109,9 +1105,8 @@ fn callee_modes(fcx: &fn_ctxt, callee: node_id) -> [ty::mode] {
|
|||
}
|
||||
_ {
|
||||
// Shouldn't happen; callee should be ty_fn.
|
||||
fcx.ccx.tcx.sess.bug(
|
||||
~"non-fn callee type in callee_modes: " +
|
||||
util::ppaux::ty_to_str(fcx.ccx.tcx, ty));
|
||||
fcx.ccx.tcx.sess.bug("non-fn callee type in callee_modes: " +
|
||||
util::ppaux::ty_to_str(fcx.ccx.tcx, ty));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ fn bit_num(fcx: &fn_ctxt, c: &tsconstr) -> uint {
|
|||
alt rslt {
|
||||
cinit(n, _, _) { ret n; }
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.bug(~"bit_num: asked for init constraint," +
|
||||
~" found a pred constraint");
|
||||
fcx.ccx.tcx.sess.bug("bit_num: asked for init constraint," +
|
||||
" found a pred constraint");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,8 +45,8 @@ fn bit_num(fcx: &fn_ctxt, c: &tsconstr) -> uint {
|
|||
alt rslt {
|
||||
cpred(_, descs) { ret match_args(fcx, descs, args); }
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.bug(~"bit_num: asked for pred constraint," +
|
||||
~" found an init constraint");
|
||||
fcx.ccx.tcx.sess.bug("bit_num: asked for pred constraint," +
|
||||
" found an init constraint");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,12 +205,12 @@ fn clear_in_poststate_expr(fcx: &fn_ctxt, e: &@expr, t: &poststate) {
|
|||
}
|
||||
some(_) {/* ignore args (for now...) */ }
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.bug(~"clear_in_poststate_expr: \
|
||||
fcx.ccx.tcx.sess.bug("clear_in_poststate_expr: \
|
||||
unbound var");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ { fcx.ccx.tcx.sess.bug(~"clear_in_poststate_expr"); }
|
||||
_ { fcx.ccx.tcx.sess.bug("clear_in_poststate_expr"); }
|
||||
}
|
||||
}
|
||||
_ {/* do nothing */ }
|
||||
|
|
|
@ -55,9 +55,7 @@ fn check_unused_vars(fcx: &fn_ctxt) {
|
|||
ninit(id, v) {
|
||||
if !vec_contains(fcx.enclosing.used_vars, id) && v[0] != '_' as u8
|
||||
{
|
||||
fcx.ccx.tcx.sess.span_warn(c.c.span,
|
||||
~"unused variable "
|
||||
+ v);
|
||||
fcx.ccx.tcx.sess.span_warn(c.c.span, "unused variable " + v);
|
||||
}
|
||||
}
|
||||
_ {/* ignore pred constraints */ }
|
||||
|
@ -82,15 +80,15 @@ fn check_states_expr(e: &@expr, fcx: &fn_ctxt, v: &visit::vt<fn_ctxt>) {
|
|||
*/
|
||||
|
||||
if !implies(pres, prec) {
|
||||
let s = ~"";
|
||||
let s = "";
|
||||
let diff = first_difference_string(fcx, prec, pres);
|
||||
s +=
|
||||
~"Unsatisfied precondition constraint (for example, " + diff +
|
||||
~") for expression:\n";
|
||||
"Unsatisfied precondition constraint (for example, " + diff +
|
||||
") for expression:\n";
|
||||
s += syntax::print::pprust::expr_to_str(e);
|
||||
s += ~"\nPrecondition:\n";
|
||||
s += "\nPrecondition:\n";
|
||||
s += tritv_to_str(fcx, prec);
|
||||
s += ~"\nPrestate:\n";
|
||||
s += "\nPrestate:\n";
|
||||
s += tritv_to_str(fcx, pres);
|
||||
fcx.ccx.tcx.sess.span_fatal(e.span, s);
|
||||
}
|
||||
|
@ -114,15 +112,15 @@ fn check_states_stmt(s: &@stmt, fcx: &fn_ctxt, v: &visit::vt<fn_ctxt>) {
|
|||
*/
|
||||
|
||||
if !implies(pres, prec) {
|
||||
let ss = ~"";
|
||||
let ss = "";
|
||||
let diff = first_difference_string(fcx, prec, pres);
|
||||
ss +=
|
||||
~"Unsatisfied precondition constraint (for example, " + diff +
|
||||
~") for statement:\n";
|
||||
"Unsatisfied precondition constraint (for example, " + diff +
|
||||
") for statement:\n";
|
||||
ss += syntax::print::pprust::stmt_to_str(*s);
|
||||
ss += ~"\nPrecondition:\n";
|
||||
ss += "\nPrecondition:\n";
|
||||
ss += tritv_to_str(fcx, prec);
|
||||
ss += ~"\nPrestate: \n";
|
||||
ss += "\nPrestate: \n";
|
||||
ss += tritv_to_str(fcx, pres);
|
||||
fcx.ccx.tcx.sess.span_fatal(s.span, ss);
|
||||
}
|
||||
|
@ -150,14 +148,12 @@ fn check_states_against_conditions(fcx: &fn_ctxt, f: &_fn,
|
|||
!type_is_nil(fcx.ccx.tcx, ret_ty_of_fn(fcx.ccx.tcx, id)) &&
|
||||
f.decl.cf == return {
|
||||
fcx.ccx.tcx.sess.span_err(f.body.span,
|
||||
~"In function " +
|
||||
fcx.name +
|
||||
~", not all control paths \
|
||||
"In function " + fcx.name +
|
||||
", not all control paths \
|
||||
return a value");
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
f.decl.output.span,
|
||||
~"see declared return type of '" +
|
||||
ty_to_str(f.decl.output) + ~"'");
|
||||
fcx.ccx.tcx.sess.span_fatal(f.decl.output.span,
|
||||
"see declared return type of '" +
|
||||
ty_to_str(f.decl.output) + "'");
|
||||
} else if f.decl.cf == noreturn {
|
||||
|
||||
// check that this really always fails
|
||||
|
@ -166,9 +162,9 @@ fn check_states_against_conditions(fcx: &fn_ctxt, f: &_fn,
|
|||
|
||||
if !promises(fcx, post, fcx.enclosing.i_diverge) {
|
||||
fcx.ccx.tcx.sess.span_fatal(f.body.span,
|
||||
~"In non-returning function " +
|
||||
"In non-returning function " +
|
||||
fcx.name +
|
||||
~", some control paths may \
|
||||
", some control paths may \
|
||||
return to the caller");
|
||||
}
|
||||
}
|
||||
|
@ -197,11 +193,8 @@ fn fn_states(f: &_fn, tps: &[ast::ty_param], sp: &span, i: &fn_ident,
|
|||
|
||||
assert (ccx.fm.contains_key(id));
|
||||
let f_info = ccx.fm.get(id);
|
||||
let name = option::from_maybe(~"anon", i);
|
||||
let fcx = {enclosing: f_info,
|
||||
id: id,
|
||||
name: name,
|
||||
ccx: ccx};
|
||||
let name = option::from_maybe("anon", i);
|
||||
let fcx = {enclosing: f_info, id: id, name: name, ccx: ccx};
|
||||
check_fn_states(fcx, f, tps, id, sp, i);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ type ctxt = {cs: @mutable [sp_constr], tcx: ty::ctxt};
|
|||
fn collect_local(loc: &@local, cx: &ctxt, v: &visit::vt<ctxt>) {
|
||||
for each p: @pat in pat_bindings(loc.node.pat) {
|
||||
let ident = alt p.node { pat_bind(id) { id } };
|
||||
log ~"collect_local: pushing " + ident;;
|
||||
log "collect_local: pushing " + ident;;
|
||||
*cx.cs += [respan(loc.span, ninit(p.id, ident))];
|
||||
}
|
||||
visit::visit_local(loc, cx, v);
|
||||
|
@ -30,6 +30,7 @@ fn collect_pred(e: &@expr, cx: &ctxt, v: &visit::vt<ctxt>) {
|
|||
expr_if_check(ex, _, _) { *cx.cs += [expr_to_constr(cx.tcx, ex)]; }
|
||||
|
||||
|
||||
|
||||
// If it's a call, generate appropriate instances of the
|
||||
// call's constraints.
|
||||
expr_call(operator, operands) {
|
||||
|
@ -61,8 +62,7 @@ fn find_locals(tcx: &ty::ctxt, f: &_fn, tps: &[ty_param], sp: &span,
|
|||
|
||||
fn add_constraint(tcx: &ty::ctxt, c: sp_constr, next: uint, tbl: constr_map)
|
||||
-> uint {
|
||||
log constraint_to_str(tcx, c) + ~" |-> "
|
||||
+ std::uint::str(next);
|
||||
log constraint_to_str(tcx, c) + " |-> " + std::uint::str(next);
|
||||
alt c.node {
|
||||
ninit(id, i) { tbl.insert(local_def(id), cinit(next, c.span, i)); }
|
||||
npred(p, d_id, args) {
|
||||
|
@ -70,8 +70,8 @@ fn add_constraint(tcx: &ty::ctxt, c: sp_constr, next: uint, tbl: constr_map)
|
|||
some(ct) {
|
||||
alt ct {
|
||||
cinit(_, _, _) {
|
||||
tcx.sess.bug(~"add_constraint: same def_id used" +
|
||||
~" as a variable and a pred");
|
||||
tcx.sess.bug("add_constraint: same def_id used" +
|
||||
" as a variable and a pred");
|
||||
}
|
||||
cpred(_, pds) {
|
||||
*pds += [respan(c.span, {args: args, bit_num: next})];
|
||||
|
@ -130,7 +130,7 @@ fn mk_fn_info(ccx: &crate_ctxt, f: &_fn, tp: &[ty_param], f_sp: &span,
|
|||
// and the name of the function, with a '!' appended to it, for the
|
||||
// "diverges" constraint
|
||||
let diverges_id = ccx.tcx.sess.next_node_id();
|
||||
let diverges_name = name + ~"!";
|
||||
let diverges_name = name + "!";
|
||||
add_constraint(cx.tcx, respan(f_sp, ninit(diverges_id, diverges_name)),
|
||||
next, res_map);
|
||||
|
||||
|
@ -147,9 +147,8 @@ fn mk_fn_info(ccx: &crate_ctxt, f: &_fn, tp: &[ty_param], f_sp: &span,
|
|||
i_diverge: ninit(diverges_id, diverges_name),
|
||||
used_vars: v};
|
||||
ccx.fm.insert(id, rslt);
|
||||
log name + ~" has "
|
||||
+ std::uint::str(num_constraints(rslt))
|
||||
+ ~" constraints";
|
||||
log name + " has " + std::uint::str(num_constraints(rslt)) +
|
||||
" constraints";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,11 +69,11 @@ fn find_pre_post_item(ccx: &crate_ctxt, i: &item) {
|
|||
{constrs: @new_def_hash::<constraint>(),
|
||||
num_constraints: 0u,
|
||||
cf: return,
|
||||
i_return: ninit(0, ~""),
|
||||
i_diverge: ninit(0, ~""),
|
||||
i_return: ninit(0, ""),
|
||||
i_diverge: ninit(0, ""),
|
||||
used_vars: v},
|
||||
id: 0,
|
||||
name: ~"",
|
||||
name: "",
|
||||
ccx: ccx};
|
||||
find_pre_post_expr(fake_fcx, e);
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ fn find_pre_post_expr(fcx: &fn_ctxt, e: @expr) {
|
|||
let rslt = expr_pp(fcx.ccx, e);
|
||||
clear_pp(rslt);
|
||||
for def in *freevars::get_freevars(fcx.ccx.tcx, e.id) {
|
||||
handle_var_def(fcx, rslt, def, ~"upvar");
|
||||
handle_var_def(fcx, rslt, def, "upvar");
|
||||
}
|
||||
}
|
||||
expr_block(b) {
|
||||
|
@ -481,7 +481,7 @@ fn find_pre_post_expr(fcx: &fn_ctxt, e: @expr) {
|
|||
let rslt = expr_pp(fcx.ccx, e);
|
||||
clear_pp(rslt);
|
||||
for def in *freevars::get_freevars(fcx.ccx.tcx, body.node.id) {
|
||||
handle_var_def(fcx, rslt, def, ~"upvar");
|
||||
handle_var_def(fcx, rslt, def, "upvar");
|
||||
}
|
||||
}
|
||||
expr_index(val, sub) { find_pre_post_exprs(fcx, [val, sub], e.id); }
|
||||
|
@ -545,6 +545,7 @@ fn find_pre_post_expr(fcx: &fn_ctxt, e: @expr) {
|
|||
|
||||
|
||||
|
||||
|
||||
expr_bind(operator, maybe_args) {
|
||||
let args = [];
|
||||
let cmodes = callee_modes(fcx, operator.id);
|
||||
|
@ -563,7 +564,7 @@ fn find_pre_post_expr(fcx: &fn_ctxt, e: @expr) {
|
|||
}
|
||||
expr_break. { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||
expr_cont. { clear_pp(expr_pp(fcx.ccx, e)); }
|
||||
expr_mac(_) { fcx.ccx.tcx.sess.bug(~"unexpanded macro"); }
|
||||
expr_mac(_) { fcx.ccx.tcx.sess.bug("unexpanded macro"); }
|
||||
expr_anon_obj(anon_obj) {
|
||||
alt anon_obj.inner_obj {
|
||||
some(ex) {
|
||||
|
@ -614,7 +615,7 @@ fn find_pre_post_stmt(fcx: &fn_ctxt, s: &stmt) {
|
|||
pat_bind(n) { n }
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_bug(pat.span,
|
||||
~"Impossible LHS");
|
||||
"Impossible LHS");
|
||||
}
|
||||
};
|
||||
alt p {
|
||||
|
@ -651,7 +652,7 @@ fn find_pre_post_stmt(fcx: &fn_ctxt, s: &stmt) {
|
|||
}
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_bug(pat.span,
|
||||
~"Impossible LHS");
|
||||
"Impossible LHS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -358,7 +358,7 @@ fn find_pre_post_state_expr(fcx: &fn_ctxt, pres: &prestate, e: @expr) ->
|
|||
expr_log(_, ex) {
|
||||
ret find_pre_post_state_sub(fcx, pres, ex, e.id, none);
|
||||
}
|
||||
expr_mac(_) { fcx.ccx.tcx.sess.bug(~"unexpanded macro"); }
|
||||
expr_mac(_) { fcx.ccx.tcx.sess.bug("unexpanded macro"); }
|
||||
expr_put(maybe_e) {
|
||||
alt maybe_e {
|
||||
some(arg) {
|
||||
|
@ -751,6 +751,7 @@ fn find_pre_post_state_fn(fcx: &fn_ctxt, f: &_fn) -> bool {
|
|||
// Treat the tail expression as a return statement
|
||||
alt f.body.node.expr {
|
||||
some(tailexpr) {
|
||||
|
||||
// We don't want to clear the diverges bit for bottom typed things,
|
||||
// which really do diverge. I feel like there is a cleaner way
|
||||
// to do this than checking the type.
|
||||
|
|
|
@ -55,6 +55,7 @@ fn trit_minus(a: trit, b: trit) -> trit {
|
|||
ttrue. { dont_care }
|
||||
tfalse. { ttrue }
|
||||
|
||||
|
||||
/* internally contradictory, but
|
||||
I guess it'll get flagged? */
|
||||
dont_care. {
|
||||
|
@ -66,6 +67,7 @@ fn trit_minus(a: trit, b: trit) -> trit {
|
|||
alt b {
|
||||
ttrue. { tfalse }
|
||||
|
||||
|
||||
/* see above comment */
|
||||
_ {
|
||||
tfalse
|
||||
|
@ -83,6 +85,7 @@ fn trit_or(a: trit, b: trit) -> trit {
|
|||
alt b {
|
||||
ttrue. { dont_care }
|
||||
|
||||
|
||||
/* FIXME: ?????? */
|
||||
_ {
|
||||
tfalse
|
||||
|
@ -101,17 +104,20 @@ fn trit_and(a: trit, b: trit) -> trit {
|
|||
alt a {
|
||||
dont_care. { b }
|
||||
|
||||
|
||||
// also seems wrong for case b = ttrue
|
||||
ttrue. {
|
||||
alt b {
|
||||
dont_care. { ttrue }
|
||||
|
||||
|
||||
// ??? Seems wrong
|
||||
ttrue. {
|
||||
ttrue
|
||||
}
|
||||
|
||||
|
||||
|
||||
// false wins, since if something is uninit
|
||||
// on one path, we care
|
||||
// (Rationale: it's always safe to assume that
|
||||
|
@ -124,6 +130,7 @@ fn trit_and(a: trit, b: trit) -> trit {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Rationale: if it's uninit on one path,
|
||||
// we can consider it as uninit on all paths
|
||||
tfalse. {
|
||||
|
@ -261,15 +268,15 @@ fn to_vec(v: &t) -> [uint] {
|
|||
ret rslt;
|
||||
}
|
||||
|
||||
fn to_str(v: &t) -> istr {
|
||||
fn to_str(v: &t) -> str {
|
||||
let i: uint = 0u;
|
||||
let rs: istr = ~"";
|
||||
let rs: str = "";
|
||||
while i < v.nbits {
|
||||
rs +=
|
||||
alt tritv_get(v, i) {
|
||||
dont_care. { ~"?" }
|
||||
ttrue. { ~"1" }
|
||||
tfalse. { ~"0" }
|
||||
dont_care. { "?" }
|
||||
ttrue. { "1" }
|
||||
tfalse. { "0" }
|
||||
};
|
||||
i += 1u;
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ type ctxt =
|
|||
freevars: freevars::freevar_map,
|
||||
tcache: type_cache,
|
||||
rcache: creader_cache,
|
||||
short_names_cache: hashmap<t, @istr>,
|
||||
short_names_cache: hashmap<t, @str>,
|
||||
has_pointer_cache: hashmap<t, bool>,
|
||||
kind_cache: hashmap<t, ast::kind>,
|
||||
ast_ty_to_ty_cache: hashmap<@ast::ty, option::t<t>>};
|
||||
|
@ -230,7 +230,7 @@ fn method_ty_to_fn_ty(cx: &ctxt, m: method) -> t {
|
|||
// Never construct these manually. These are interned.
|
||||
type raw_t =
|
||||
{struct: sty,
|
||||
cname: option::t<istr>,
|
||||
cname: option::t<str>,
|
||||
hash: uint,
|
||||
has_params: bool,
|
||||
has_vars: bool};
|
||||
|
@ -401,16 +401,16 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map,
|
|||
short_names_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty),
|
||||
has_pointer_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty),
|
||||
kind_cache: map::mk_hashmap(ty::hash_ty, ty::eq_ty),
|
||||
ast_ty_to_ty_cache: map::mk_hashmap(ast_util::hash_ty,
|
||||
ast_util::eq_ty)};
|
||||
ast_ty_to_ty_cache:
|
||||
map::mk_hashmap(ast_util::hash_ty, ast_util::eq_ty)};
|
||||
populate_type_store(cx);
|
||||
ret cx;
|
||||
}
|
||||
|
||||
|
||||
// Type constructors
|
||||
fn mk_raw_ty(cx: &ctxt, st: &sty, _in_cname: &option::t<istr>) -> @raw_t {
|
||||
let cname: option::t<istr> = none;
|
||||
fn mk_raw_ty(cx: &ctxt, st: &sty, _in_cname: &option::t<str>) -> @raw_t {
|
||||
let cname: option::t<str> = none;
|
||||
let h = hash_type_info(st, cname);
|
||||
let has_params: bool = false;
|
||||
let has_vars: bool = false;
|
||||
|
@ -486,11 +486,11 @@ fn mk_raw_ty(cx: &ctxt, st: &sty, _in_cname: &option::t<istr>) -> @raw_t {
|
|||
has_vars: has_vars};
|
||||
}
|
||||
|
||||
fn intern(cx: &ctxt, st: &sty, cname: &option::t<istr>) {
|
||||
fn intern(cx: &ctxt, st: &sty, cname: &option::t<str>) {
|
||||
interner::intern(*cx.ts, mk_raw_ty(cx, st, cname));
|
||||
}
|
||||
|
||||
fn gen_ty_full(cx: &ctxt, st: &sty, cname: &option::t<istr>) -> t {
|
||||
fn gen_ty_full(cx: &ctxt, st: &sty, cname: &option::t<str>) -> t {
|
||||
let raw_type = mk_raw_ty(cx, st, cname);
|
||||
ret interner::intern(*cx.ts, raw_type);
|
||||
}
|
||||
|
@ -559,8 +559,8 @@ fn mk_constr(cx: &ctxt, t: t, cs: &[@type_constr]) -> t {
|
|||
|
||||
fn mk_tup(cx: &ctxt, ts: &[t]) -> t { ret gen_ty(cx, ty_tup(ts)); }
|
||||
|
||||
fn mk_fn(cx: &ctxt, proto: &ast::proto, args: &[arg], ty: t,
|
||||
cf: &controlflow, constrs: &[@constr]) -> t {
|
||||
fn mk_fn(cx: &ctxt, proto: &ast::proto, args: &[arg], ty: t, cf: &controlflow,
|
||||
constrs: &[@constr]) -> t {
|
||||
ret gen_ty(cx, ty_fn(proto, args, ty, cf, constrs));
|
||||
}
|
||||
|
||||
|
@ -590,13 +590,11 @@ fn mk_iter_body_fn(cx: &ctxt, output: t) -> t {
|
|||
}
|
||||
|
||||
// Returns the one-level-deep type structure of the given type.
|
||||
fn struct(cx: &ctxt, typ: t) -> sty {
|
||||
ret interner::get(*cx.ts, typ).struct;
|
||||
}
|
||||
fn struct(cx: &ctxt, typ: t) -> sty { ret interner::get(*cx.ts, typ).struct; }
|
||||
|
||||
|
||||
// Returns the canonical name of the given type.
|
||||
fn cname(cx: &ctxt, typ: t) -> option::t<istr> {
|
||||
fn cname(cx: &ctxt, typ: t) -> option::t<str> {
|
||||
ret interner::get(*cx.ts, typ).cname;
|
||||
}
|
||||
|
||||
|
@ -771,7 +769,7 @@ fn fold_ty(cx: &ctxt, fld: fold_mode, ty_0: t) -> t {
|
|||
|
||||
// Type utilities
|
||||
|
||||
fn rename(cx: &ctxt, typ: t, new_cname: &istr) -> t {
|
||||
fn rename(cx: &ctxt, typ: t, new_cname: &str) -> t {
|
||||
ret gen_ty_full(cx, struct(cx, typ), some(new_cname));
|
||||
}
|
||||
|
||||
|
@ -826,18 +824,14 @@ fn type_is_sequence(cx: &ctxt, ty: t) -> bool {
|
|||
}
|
||||
|
||||
fn type_is_str(cx: &ctxt, ty: t) -> bool {
|
||||
alt struct(cx, ty) {
|
||||
ty_istr. { ret true; }
|
||||
_ { ret false; }
|
||||
}
|
||||
alt struct(cx, ty) { ty_istr. { ret true; } _ { ret false; } }
|
||||
}
|
||||
|
||||
fn sequence_element_type(cx: &ctxt, ty: t) -> t {
|
||||
alt struct(cx, ty) {
|
||||
ty_istr. { ret mk_mach(cx, ast::ty_u8); }
|
||||
ty_vec(mt) { ret mt.ty; }
|
||||
_ { cx.sess.bug(
|
||||
~"sequence_element_type called on non-sequence value"); }
|
||||
_ { cx.sess.bug("sequence_element_type called on non-sequence value"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,9 +850,8 @@ fn get_element_type(cx: &ctxt, ty: t, i: uint) -> t {
|
|||
ty_rec(flds) { ret flds[i].mt.ty; }
|
||||
ty_tup(ts) { ret ts[i]; }
|
||||
_ {
|
||||
cx.sess.bug(~"get_element_type called on type " +
|
||||
ty_to_str(cx, ty) +
|
||||
~" - expected a \
|
||||
cx.sess.bug("get_element_type called on type " + ty_to_str(cx, ty) +
|
||||
" - expected a \
|
||||
tuple or record");
|
||||
}
|
||||
}
|
||||
|
@ -871,18 +864,15 @@ fn type_is_box(cx: &ctxt, ty: t) -> bool {
|
|||
}
|
||||
|
||||
fn type_is_boxed(cx: &ctxt, ty: t) -> bool {
|
||||
alt struct(cx, ty) {
|
||||
ty_box(_) { ret true; }
|
||||
_ { ret false; }
|
||||
}
|
||||
alt struct(cx, ty) { ty_box(_) { ret true; } _ { ret false; } }
|
||||
}
|
||||
|
||||
fn type_is_vec(cx: &ctxt, ty: t) -> bool {
|
||||
ret alt struct(cx, ty) {
|
||||
ty_vec(_) { true }
|
||||
ty_istr. { true }
|
||||
_ { false }
|
||||
};
|
||||
ty_vec(_) { true }
|
||||
ty_istr. { true }
|
||||
_ { false }
|
||||
};
|
||||
}
|
||||
|
||||
fn type_is_unique(cx: &ctxt, ty: t) -> bool {
|
||||
|
@ -890,7 +880,8 @@ fn type_is_unique(cx: &ctxt, ty: t) -> bool {
|
|||
ty_uniq(_) { ret true; }
|
||||
ty_vec(_) { true }
|
||||
ty_istr. { true }
|
||||
_ { ret false; } }
|
||||
_ { ret false; }
|
||||
}
|
||||
}
|
||||
|
||||
fn type_is_scalar(cx: &ctxt, ty: t) -> bool {
|
||||
|
@ -917,8 +908,12 @@ fn type_has_pointers(cx: &ctxt, ty: t) -> bool {
|
|||
|
||||
let result = false;
|
||||
alt struct(cx, ty) {
|
||||
|
||||
// scalar types
|
||||
ty_nil. {/* no-op */ }
|
||||
ty_nil. {
|
||||
/* no-op */
|
||||
|
||||
}
|
||||
ty_bot. {/* no-op */ }
|
||||
ty_bool. {/* no-op */ }
|
||||
ty_int. {/* no-op */ }
|
||||
|
@ -980,6 +975,7 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
alt struct(cx, ty) {
|
||||
|
||||
|
||||
|
||||
// Scalar types are unique-kind, no substructure.
|
||||
ty_nil. | ty_bot. | ty_bool. | ty_int. | ty_uint. | ty_float. |
|
||||
ty_machine(_) | ty_char. | ty_native(_) {
|
||||
|
@ -987,12 +983,14 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// A handful of other built-in are unique too.
|
||||
ty_type. | ty_istr. | ty_native_fn(_, _, _) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
|
||||
|
||||
// FIXME: obj is broken for now, since we aren't asserting
|
||||
// anything about its fields.
|
||||
ty_obj(_) {
|
||||
|
@ -1000,6 +998,7 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// FIXME: the environment capture mode is not fully encoded
|
||||
// here yet, leading to weirdness around closure.
|
||||
ty_fn(proto, _, _, _, _) {
|
||||
|
@ -1012,6 +1011,7 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Those with refcounts-to-inner raise pinned to shared,
|
||||
// lower unique to shared. Therefore just set result to shared.
|
||||
ty_box(mt) {
|
||||
|
@ -1019,6 +1019,7 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Pointers and unique boxes / vecs raise pinned to shared,
|
||||
// otherwise pass through their pointee kind.
|
||||
ty_ptr(tm) | ty_vec(tm) {
|
||||
|
@ -1028,6 +1029,7 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Records lower to the lowest of their members.
|
||||
ty_rec(flds) {
|
||||
for f: field in flds {
|
||||
|
@ -1036,6 +1038,7 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Tuples lower to the lowest of their members.
|
||||
ty_tup(tys) {
|
||||
for ty: t in tys {
|
||||
|
@ -1045,6 +1048,7 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Tags lower to the lowest of their variants.
|
||||
ty_tag(did, tps) {
|
||||
let variants = tag_variants(cx, did);
|
||||
|
@ -1060,29 +1064,34 @@ fn type_kind(cx: &ctxt, ty: t) -> ast::kind {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Resources are always pinned.
|
||||
ty_res(did, inner, tps) {
|
||||
result = ast::kind_pinned;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ty_var(_) {
|
||||
fail;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ty_param(_, k) {
|
||||
result = kind::lower_kind(result, k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ty_constr(t, _) {
|
||||
result = type_kind(cx, t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_ {
|
||||
cx.sess.bug(~"missed case: " + ty_to_str(cx, ty));
|
||||
cx.sess.bug("missed case: " + ty_to_str(cx, ty));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1098,8 +1107,8 @@ fn type_is_native(cx: &ctxt, ty: t) -> bool {
|
|||
alt struct(cx, ty) { ty_native(_) { ret true; } _ { ret false; } }
|
||||
}
|
||||
|
||||
fn type_structurally_contains(cx: &ctxt, ty: t,
|
||||
test: fn(&sty) -> bool) -> bool {
|
||||
fn type_structurally_contains(cx: &ctxt, ty: t, test: fn(&sty) -> bool) ->
|
||||
bool {
|
||||
let sty = struct(cx, ty);
|
||||
if test(sty) { ret true; }
|
||||
alt sty {
|
||||
|
@ -1209,6 +1218,7 @@ fn type_is_pod(cx: &ctxt, ty: t) -> bool {
|
|||
let result = true;
|
||||
alt struct(cx, ty) {
|
||||
|
||||
|
||||
// Scalar types
|
||||
ty_nil. | ty_bot. | ty_bool. | ty_int. | ty_float. | ty_uint. |
|
||||
ty_machine(_) | ty_char. | ty_type. | ty_native(_) | ty_ptr(_) {
|
||||
|
@ -1216,6 +1226,7 @@ fn type_is_pod(cx: &ctxt, ty: t) -> bool {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Boxed types
|
||||
ty_istr. | ty_box(_) | ty_vec(_) | ty_fn(_, _, _, _, _) |
|
||||
ty_native_fn(_, _, _) | ty_obj(_) {
|
||||
|
@ -1223,6 +1234,7 @@ fn type_is_pod(cx: &ctxt, ty: t) -> bool {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Structural types
|
||||
ty_tag(did, tps) {
|
||||
let variants = tag_variants(cx, did);
|
||||
|
@ -1248,6 +1260,7 @@ fn type_is_pod(cx: &ctxt, ty: t) -> bool {
|
|||
ty_constr(subt, _) { result = type_is_pod(cx, subt); }
|
||||
|
||||
|
||||
|
||||
ty_var(_) {
|
||||
fail "ty_var in type_is_pod";
|
||||
}
|
||||
|
@ -1389,6 +1402,7 @@ fn hash_type_structure(st: &sty) -> uint {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// ???
|
||||
ty_fn(_, args, rty, _, _) {
|
||||
ret hash_fn(27u, args, rty);
|
||||
|
@ -1419,7 +1433,7 @@ fn hash_type_structure(st: &sty) -> uint {
|
|||
}
|
||||
}
|
||||
|
||||
fn hash_type_info(st: &sty, cname_opt: &option::t<istr>) -> uint {
|
||||
fn hash_type_info(st: &sty, cname_opt: &option::t<str>) -> uint {
|
||||
let h = hash_type_structure(st);
|
||||
alt cname_opt {
|
||||
none. {/* no-op */ }
|
||||
|
@ -1511,10 +1525,9 @@ fn node_id_to_ty_param_substs_opt_and_ty(cx: &ctxt, id: &ast::node_id) ->
|
|||
// Pull out the node type table.
|
||||
alt smallintmap::find(*cx.node_types, id as uint) {
|
||||
none. {
|
||||
cx.sess.bug(~"node_id_to_ty_param_substs_opt_and_ty() called on " +
|
||||
~"an untyped node (" +
|
||||
std::int::to_str(id, 10u) +
|
||||
~")");
|
||||
cx.sess.bug("node_id_to_ty_param_substs_opt_and_ty() called on " +
|
||||
"an untyped node (" + std::int::to_str(id, 10u) +
|
||||
")");
|
||||
}
|
||||
some(tpot) { ret tpot; }
|
||||
}
|
||||
|
@ -1589,21 +1602,21 @@ fn ty_fn_args(cx: &ctxt, fty: t) -> [arg] {
|
|||
alt struct(cx, fty) {
|
||||
ty::ty_fn(_, a, _, _, _) { ret a; }
|
||||
ty::ty_native_fn(_, a, _) { ret a; }
|
||||
_ { cx.sess.bug(~"ty_fn_args() called on non-fn type"); }
|
||||
_ { cx.sess.bug("ty_fn_args() called on non-fn type"); }
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_fn_proto(cx: &ctxt, fty: t) -> ast::proto {
|
||||
alt struct(cx, fty) {
|
||||
ty::ty_fn(p, _, _, _, _) { ret p; }
|
||||
_ { cx.sess.bug(~"ty_fn_proto() called on non-fn type"); }
|
||||
_ { cx.sess.bug("ty_fn_proto() called on non-fn type"); }
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_fn_abi(cx: &ctxt, fty: t) -> ast::native_abi {
|
||||
alt struct(cx, fty) {
|
||||
ty::ty_native_fn(a, _, _) { ret a; }
|
||||
_ { cx.sess.bug(~"ty_fn_abi() called on non-native-fn type"); }
|
||||
_ { cx.sess.bug("ty_fn_abi() called on non-native-fn type"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1611,7 +1624,7 @@ fn ty_fn_ret(cx: &ctxt, fty: t) -> t {
|
|||
alt struct(cx, fty) {
|
||||
ty::ty_fn(_, _, r, _, _) { ret r; }
|
||||
ty::ty_native_fn(_, _, r) { ret r; }
|
||||
_ { cx.sess.bug(~"ty_fn_ret() called on non-fn type"); }
|
||||
_ { cx.sess.bug("ty_fn_ret() called on non-fn type"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1625,7 +1638,7 @@ fn is_fn_ty(cx: &ctxt, fty: t) -> bool {
|
|||
|
||||
// Just checks whether it's a fn that returns bool,
|
||||
// not its purity.
|
||||
fn is_pred_ty(cx: &ctxt, fty:t) -> bool {
|
||||
fn is_pred_ty(cx: &ctxt, fty: t) -> bool {
|
||||
is_fn_ty(cx, fty) && type_is_bool(cx, ty_fn_ret(cx, fty))
|
||||
}
|
||||
|
||||
|
@ -1685,15 +1698,14 @@ fn field_idx(sess: &session::session, sp: &span, id: &ast::ident,
|
|||
fields: &[field]) -> uint {
|
||||
let i: uint = 0u;
|
||||
for f: field in fields { if str::eq(f.ident, id) { ret i; } i += 1u; }
|
||||
sess.span_fatal(sp, ~"unknown field '" +
|
||||
id + ~"' of record");
|
||||
sess.span_fatal(sp, "unknown field '" + id + "' of record");
|
||||
}
|
||||
|
||||
fn method_idx(sess: &session::session, sp: &span, id: &ast::ident,
|
||||
meths: &[method]) -> uint {
|
||||
let i: uint = 0u;
|
||||
for m: method in meths { if str::eq(m.ident, id) { ret i; } i += 1u; }
|
||||
sess.span_fatal(sp, ~"unknown method '" + id + ~"' of obj");
|
||||
sess.span_fatal(sp, "unknown method '" + id + "' of obj");
|
||||
}
|
||||
|
||||
fn sort_methods(meths: &[method]) -> [method] {
|
||||
|
@ -1729,12 +1741,11 @@ fn occurs_check_fails(tcx: &ctxt, sp: &option::t<span>, vid: int, rt: t) ->
|
|||
// variables, so in this case we have to be sure to die.
|
||||
tcx.sess.span_fatal(
|
||||
s,
|
||||
~"Type inference failed because I \
|
||||
"Type inference failed because I \
|
||||
could not find a type\n that's both of the form "
|
||||
+ ty_to_str(tcx, ty::mk_var(tcx, vid)) +
|
||||
~" and of the form " +
|
||||
ty_to_str(tcx, rt) +
|
||||
~". Such a type would have to be infinitely \
|
||||
" and of the form " + ty_to_str(tcx, rt) +
|
||||
". Such a type would have to be infinitely \
|
||||
large.");
|
||||
}
|
||||
_ { ret true; }
|
||||
|
@ -1927,9 +1938,9 @@ mod unify {
|
|||
|
||||
let result_mode;
|
||||
if expected_input.mode != actual_input.mode {
|
||||
ret fn_common_res_err(
|
||||
ures_err(terr_mode_mismatch(expected_input.mode,
|
||||
actual_input.mode)));
|
||||
ret fn_common_res_err(ures_err(
|
||||
terr_mode_mismatch(expected_input.mode,
|
||||
actual_input.mode)));
|
||||
} else { result_mode = expected_input.mode; }
|
||||
let result = unify_step(cx, expected_input.ty, actual_input.ty);
|
||||
alt result {
|
||||
|
@ -1956,6 +1967,7 @@ mod unify {
|
|||
alt expected_cf {
|
||||
ast::return. { }
|
||||
|
||||
|
||||
// ok
|
||||
ast::noreturn. {
|
||||
alt actual_cf {
|
||||
|
@ -2069,6 +2081,7 @@ mod unify {
|
|||
alt struct(cx.tcx, actual) {
|
||||
|
||||
|
||||
|
||||
// If the RHS is a variable type, then just do the
|
||||
// appropriate binding.
|
||||
ty::ty_var(actual_id) {
|
||||
|
@ -2117,6 +2130,7 @@ mod unify {
|
|||
ty::ty_nil. { ret struct_cmp(cx, expected, actual); }
|
||||
|
||||
|
||||
|
||||
// _|_ unifies with anything
|
||||
ty::ty_bot. {
|
||||
ret ures_ok(actual);
|
||||
|
@ -2410,7 +2424,7 @@ mod unify {
|
|||
fn dump_var_bindings(tcx: ty_ctxt, vb: @var_bindings) {
|
||||
let i = 0u;
|
||||
while i < vec::len::<ufind::node>(vb.sets.nodes) {
|
||||
let sets = ~"";
|
||||
let sets = "";
|
||||
let j = 0u;
|
||||
while j < vec::len::<option::t<uint>>(vb.sets.nodes) {
|
||||
if ufind::find(vb.sets, j) == i { sets += #fmt[" %u", j]; }
|
||||
|
@ -2418,10 +2432,8 @@ mod unify {
|
|||
}
|
||||
let typespec;
|
||||
alt smallintmap::find::<t>(vb.types, i) {
|
||||
none. { typespec = ~""; }
|
||||
some(typ) {
|
||||
typespec = ~" =" + ty_to_str(tcx, typ);
|
||||
}
|
||||
none. { typespec = ""; }
|
||||
some(typ) { typespec = " =" + ty_to_str(tcx, typ); }
|
||||
}
|
||||
log_err #fmt["set %u:%s%s", i, typespec, sets];
|
||||
i += 1u;
|
||||
|
@ -2478,54 +2490,49 @@ mod unify {
|
|||
}
|
||||
}
|
||||
|
||||
fn type_err_to_str(err: &ty::type_err) -> istr {
|
||||
fn type_err_to_str(err: &ty::type_err) -> str {
|
||||
alt err {
|
||||
terr_mismatch. { ret ~"types differ"; }
|
||||
terr_mismatch. { ret "types differ"; }
|
||||
terr_controlflow_mismatch. {
|
||||
ret ~"returning function used where non-returning function" +
|
||||
~" was expected";
|
||||
ret "returning function used where non-returning function" +
|
||||
" was expected";
|
||||
}
|
||||
terr_box_mutability. { ret ~"boxed values differ in mutability"; }
|
||||
terr_vec_mutability. { ret ~"vectors differ in mutability"; }
|
||||
terr_box_mutability. { ret "boxed values differ in mutability"; }
|
||||
terr_vec_mutability. { ret "vectors differ in mutability"; }
|
||||
terr_tuple_size(e_sz, a_sz) {
|
||||
ret ~"expected a tuple with " +
|
||||
uint::to_str(e_sz, 10u) +
|
||||
~" elements but found one with " +
|
||||
uint::to_str(a_sz, 10u) +
|
||||
~" elements";
|
||||
ret "expected a tuple with " + uint::to_str(e_sz, 10u) +
|
||||
" elements but found one with " + uint::to_str(a_sz, 10u) +
|
||||
" elements";
|
||||
}
|
||||
terr_record_size(e_sz, a_sz) {
|
||||
ret ~"expected a record with " +
|
||||
uint::to_str(e_sz, 10u) +
|
||||
~" fields but found one with " +
|
||||
uint::to_str(a_sz, 10u) +
|
||||
~" fields";
|
||||
ret "expected a record with " + uint::to_str(e_sz, 10u) +
|
||||
" fields but found one with " + uint::to_str(a_sz, 10u) +
|
||||
" fields";
|
||||
}
|
||||
terr_record_mutability. { ret ~"record elements differ in mutability"; }
|
||||
terr_record_mutability. { ret "record elements differ in mutability"; }
|
||||
terr_record_fields(e_fld, a_fld) {
|
||||
ret ~"expected a record with field '" + e_fld +
|
||||
~"' but found one with field '" + a_fld + ~"'";
|
||||
ret "expected a record with field '" + e_fld +
|
||||
"' but found one with field '" + a_fld + "'";
|
||||
}
|
||||
terr_arg_count. { ret ~"incorrect number of function parameters"; }
|
||||
terr_meth_count. { ret ~"incorrect number of object methods"; }
|
||||
terr_arg_count. { ret "incorrect number of function parameters"; }
|
||||
terr_meth_count. { ret "incorrect number of object methods"; }
|
||||
terr_obj_meths(e_meth, a_meth) {
|
||||
ret ~"expected an obj with method '" + e_meth +
|
||||
~"' but found one with method '" + a_meth + ~"'";
|
||||
ret "expected an obj with method '" + e_meth +
|
||||
"' but found one with method '" + a_meth + "'";
|
||||
}
|
||||
terr_mode_mismatch(e_mode, a_mode) {
|
||||
ret ~"expected argument mode " + mode_str_1(e_mode) + ~" but found " +
|
||||
ret "expected argument mode " + mode_str_1(e_mode) + " but found " +
|
||||
mode_str_1(a_mode);
|
||||
}
|
||||
terr_constr_len(e_len, a_len) {
|
||||
ret ~"Expected a type with " +
|
||||
uint::str(e_len) +
|
||||
~" constraints, but found one with " +
|
||||
uint::str(a_len) + ~" constraints";
|
||||
ret "Expected a type with " + uint::str(e_len) +
|
||||
" constraints, but found one with " + uint::str(a_len) +
|
||||
" constraints";
|
||||
}
|
||||
terr_constr_mismatch(e_constr, a_constr) {
|
||||
ret ~"Expected a type with constraint " + ty_constr_to_str(e_constr) +
|
||||
~" but found one with constraint " +
|
||||
ty_constr_to_str(a_constr);
|
||||
ret "Expected a type with constraint " + ty_constr_to_str(e_constr) +
|
||||
" but found one with constraint " +
|
||||
ty_constr_to_str(a_constr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2543,8 +2550,7 @@ fn bind_params_in_type(sp: &span, cx: &ctxt, next_ty_var: fn() -> int, typ: t,
|
|||
if index < vec::len(*param_var_ids) {
|
||||
ret mk_var(cx, param_var_ids[index]);
|
||||
} else {
|
||||
cx.sess.span_fatal(
|
||||
sp, ~"Unbound type parameter in callee's type");
|
||||
cx.sess.span_fatal(sp, "Unbound type parameter in callee's type");
|
||||
}
|
||||
}
|
||||
let new_typ =
|
||||
|
@ -2595,7 +2601,7 @@ fn tag_variants(cx: &ctxt, id: &ast::def_id) -> [variant_info] {
|
|||
let item =
|
||||
alt cx.items.find(id.node) {
|
||||
some(i) { i }
|
||||
none. { cx.sess.bug(~"expected to find cached node_item") }
|
||||
none. { cx.sess.bug("expected to find cached node_item") }
|
||||
};
|
||||
alt item {
|
||||
ast_map::node_item(item) {
|
||||
|
@ -2634,7 +2640,7 @@ fn tag_variant_with_id(cx: &ctxt, tag_id: &ast::def_id,
|
|||
if def_eq(variant.id, variant_id) { ret variant; }
|
||||
i += 1u;
|
||||
}
|
||||
cx.sess.bug(~"tag_variant_with_id(): no variant exists with that ID");
|
||||
cx.sess.bug("tag_variant_with_id(): no variant exists with that ID");
|
||||
}
|
||||
|
||||
|
||||
|
@ -2662,8 +2668,8 @@ fn ret_ty_of_fn_ty(cx: ctxt, a_ty: t) -> t {
|
|||
ty::ty_fn(_, _, ret_ty, _, _) { ret ret_ty; }
|
||||
ty::ty_native_fn(_, _, ret_ty) { ret ret_ty; }
|
||||
_ {
|
||||
cx.sess.bug(~"ret_ty_of_fn_ty() called on non-function type: " +
|
||||
ty_to_str(cx, a_ty));
|
||||
cx.sess.bug("ret_ty_of_fn_ty() called on non-function type: " +
|
||||
ty_to_str(cx, a_ty));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2750,13 +2756,13 @@ fn is_binopable(cx: &ctxt, ty: t, op: ast::binop) -> bool {
|
|||
/*. add, shift, bit
|
||||
. sub, rel, logic
|
||||
. mult, eq, */
|
||||
/*other*/
|
||||
/*bool*/
|
||||
/*int*/
|
||||
/*float*/
|
||||
/*str*/
|
||||
/*vec*/
|
||||
/*bot*/
|
||||
/*other*/
|
||||
/*bool*/
|
||||
/*int*/
|
||||
/*float*/
|
||||
/*str*/
|
||||
/*vec*/
|
||||
/*bot*/
|
||||
let tbl =
|
||||
[[f, f, f, f, t, t, f, f], [f, f, f, f, t, t, t, t],
|
||||
[t, t, t, t, t, t, t, f], [t, t, t, f, t, t, f, f],
|
||||
|
@ -2776,11 +2782,11 @@ fn ast_constr_to_constr<T>(tcx: ty::ctxt, c: &@ast::constr_general<T>) ->
|
|||
id: pred_id});
|
||||
}
|
||||
_ {
|
||||
tcx.sess.span_fatal(c.span,
|
||||
~"Predicate " +
|
||||
path_to_str(c.node.path) +
|
||||
~" is unbound or bound to a non-function or an \
|
||||
impure function");
|
||||
tcx.sess.span_fatal(
|
||||
c.span,
|
||||
"Predicate " + path_to_str(c.node.path) +
|
||||
" is unbound or bound to a non-function or an \
|
||||
impure function");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ fn lookup_local(fcx: &@fn_ctxt, sp: &span, id: ast::node_id) -> int {
|
|||
some(x) { x }
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal(sp,
|
||||
~"internal error looking up a local var")
|
||||
"internal error looking up a local var")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ fn lookup_def(fcx: &@fn_ctxt, sp: &span, id: ast::node_id) -> ast::def {
|
|||
some(x) { x }
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal(sp,
|
||||
~"internal error looking up a definition")
|
||||
"internal error looking up a definition")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ fn lookup_def(fcx: &@fn_ctxt, sp: &span, id: ast::node_id) -> ast::def {
|
|||
fn ident_for_local(loc: &@ast::local) -> ast::ident {
|
||||
ret alt loc.node.pat.node {
|
||||
ast::pat_bind(name) { name }
|
||||
_ { ~"local" }
|
||||
_ { "local" }
|
||||
}; // FIXME DESTR
|
||||
}
|
||||
|
||||
|
@ -145,14 +145,14 @@ fn ty_param_kinds_and_ty_for_def(fcx: &@fn_ctxt, sp: &span, defn: &ast::def)
|
|||
ret {kinds: no_kinds, ty: ty::mk_nil(fcx.ccx.tcx)};
|
||||
}
|
||||
ast::def_ty(_) {
|
||||
fcx.ccx.tcx.sess.span_fatal(sp, ~"expected value but found type");
|
||||
fcx.ccx.tcx.sess.span_fatal(sp, "expected value but found type");
|
||||
}
|
||||
ast::def_upvar(_, inner, _) {
|
||||
ret ty_param_kinds_and_ty_for_def(fcx, sp, *inner);
|
||||
}
|
||||
_ {
|
||||
// FIXME: handle other names.
|
||||
fcx.ccx.tcx.sess.unimpl(~"definition variant");
|
||||
fcx.ccx.tcx.sess.unimpl("definition variant");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,15 +175,15 @@ fn instantiate_path(fcx: &@fn_ctxt, pth: &ast::path,
|
|||
if param_var_len == 0u {
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
sp,
|
||||
~"this item does not take type parameters");
|
||||
"this item does not take type parameters");
|
||||
} else if ty_substs_len > param_var_len {
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
sp,
|
||||
~"too many type parameter provided for this item");
|
||||
"too many type parameter provided for this item");
|
||||
} else if ty_substs_len < param_var_len {
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
sp,
|
||||
~"not enough type parameters provided for this item");
|
||||
"not enough type parameters provided for this item");
|
||||
}
|
||||
let ty_substs: [ty::t] = [];
|
||||
let i = 0u;
|
||||
|
@ -197,7 +197,7 @@ fn instantiate_path(fcx: &@fn_ctxt, pth: &ast::path,
|
|||
ty_substs_opt = some::<[ty::t]>(ty_substs);
|
||||
if ty_param_count == 0u {
|
||||
fcx.ccx.tcx.sess.span_fatal(sp,
|
||||
~"this item does not take type \
|
||||
"this item does not take type \
|
||||
parameters");
|
||||
}
|
||||
} else {
|
||||
|
@ -229,7 +229,7 @@ fn structurally_resolved_type(fcx: &@fn_ctxt, sp: &span, tp: ty::t) -> ty::t {
|
|||
fix_err(_) {
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
sp,
|
||||
~"the type of this value must be known in this context");
|
||||
"the type of this value must be known in this context");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ fn ast_ty_to_ty(tcx: &ty::ctxt, getter: &ty_getter, ast_ty: &@ast::ty) ->
|
|||
some(some(ty)) { ret ty; }
|
||||
some(none.) {
|
||||
tcx.sess.span_fatal(ast_ty.span,
|
||||
~"illegal recursive type \
|
||||
"illegal recursive type \
|
||||
insert a tag in the cycle, \
|
||||
if this is desired)");
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ fn ast_ty_to_ty(tcx: &ty::ctxt, getter: &ty_getter, ast_ty: &@ast::ty) ->
|
|||
}
|
||||
if vec::len(param_bindings) != vec::len(ty_param_kinds_and_ty.kinds) {
|
||||
tcx.sess.span_fatal(sp,
|
||||
~"Wrong number of type arguments for a \
|
||||
"Wrong number of type arguments for a \
|
||||
polymorphic type");
|
||||
}
|
||||
let typ =
|
||||
|
@ -316,7 +316,7 @@ fn ast_ty_to_ty(tcx: &ty::ctxt, getter: &ty_getter, ast_ty: &@ast::ty) ->
|
|||
ret typ;
|
||||
}
|
||||
let typ;
|
||||
let cname = none::<istr>;
|
||||
let cname = none::<str>;
|
||||
alt ast_ty.node {
|
||||
ast::ty_nil. { typ = ty::mk_nil(tcx); }
|
||||
ast::ty_bot. { typ = ty::mk_bot(tcx); }
|
||||
|
@ -370,11 +370,10 @@ fn ast_ty_to_ty(tcx: &ty::ctxt, getter: &ty_getter, ast_ty: &@ast::ty) ->
|
|||
some(ast::def_ty_arg(id, k)) { typ = ty::mk_param(tcx, id, k); }
|
||||
some(_) {
|
||||
tcx.sess.span_fatal(ast_ty.span,
|
||||
~"found type name used as a variable");
|
||||
"found type name used as a variable");
|
||||
}
|
||||
_ {
|
||||
tcx.sess.span_fatal(
|
||||
ast_ty.span, ~"internal error in instantiate");
|
||||
tcx.sess.span_fatal(ast_ty.span, "internal error in instantiate");
|
||||
}
|
||||
}
|
||||
cname = some(path_to_str(path));
|
||||
|
@ -411,14 +410,12 @@ fn ast_ty_to_ty(tcx: &ty::ctxt, getter: &ty_getter, ast_ty: &@ast::ty) ->
|
|||
typ = ty::mk_constr(tcx, ast_ty_to_ty(tcx, getter, t), out_cs);
|
||||
}
|
||||
ast::ty_infer. {
|
||||
tcx.sess.span_bug(ast_ty.span, ~"found ty_infer in unexpected place");
|
||||
tcx.sess.span_bug(ast_ty.span, "found ty_infer in unexpected place");
|
||||
}
|
||||
}
|
||||
alt cname {
|
||||
none. {/* no-op */ }
|
||||
some(cname_str) {
|
||||
typ = ty::rename(tcx, typ, cname_str);
|
||||
}
|
||||
some(cname_str) { typ = ty::rename(tcx, typ, cname_str); }
|
||||
}
|
||||
tcx.ast_ty_to_ty_cache.insert(ast_ty, some(typ));
|
||||
ret typ;
|
||||
|
@ -590,10 +587,7 @@ mod collect {
|
|||
some(ast_map::node_native_item(native_item)) {
|
||||
tpt = ty_of_native_item(cx, native_item, ast::native_abi_cdecl);
|
||||
}
|
||||
_ {
|
||||
cx.tcx.sess.fatal(
|
||||
~"internal error " + std::int::str(id.node));
|
||||
}
|
||||
_ { cx.tcx.sess.fatal("internal error " + std::int::str(id.node)); }
|
||||
}
|
||||
ret tpt;
|
||||
}
|
||||
|
@ -871,9 +865,9 @@ mod collect {
|
|||
let visit =
|
||||
visit::mk_simple_visitor(@{visit_item: bind convert(cx, abi, _),
|
||||
visit_native_item:
|
||||
bind convert_native(cx, abi, _)
|
||||
with
|
||||
*visit::default_simple_visitor()});
|
||||
bind convert_native(cx, abi, _)
|
||||
with
|
||||
*visit::default_simple_visitor()});
|
||||
visit::visit_crate(*crate, (), visit);
|
||||
}
|
||||
}
|
||||
|
@ -965,14 +959,13 @@ mod demand {
|
|||
ty::t {
|
||||
full(fcx, sp, expected, actual, [], false).ty
|
||||
}
|
||||
fn block_coerce(fcx: &@fn_ctxt, sp: &span, expected: ty::t,
|
||||
actual: ty::t) -> ty::t {
|
||||
fn block_coerce(fcx: &@fn_ctxt, sp: &span, expected: ty::t, actual: ty::t)
|
||||
-> ty::t {
|
||||
full(fcx, sp, expected, actual, [], true).ty
|
||||
}
|
||||
|
||||
fn with_substs(fcx: &@fn_ctxt, sp: &span, expected: ty::t,
|
||||
actual: ty::t, ty_param_substs_0: &[ty::t]) ->
|
||||
ty_param_substs_and_ty {
|
||||
fn with_substs(fcx: &@fn_ctxt, sp: &span, expected: ty::t, actual: ty::t,
|
||||
ty_param_substs_0: &[ty::t]) -> ty_param_substs_and_ty {
|
||||
full(fcx, sp, expected, actual, ty_param_substs_0, false)
|
||||
}
|
||||
|
||||
|
@ -1013,14 +1006,12 @@ mod demand {
|
|||
ures_err(err) {
|
||||
let e_err = resolve_type_vars_if_possible(fcx, expected);
|
||||
let a_err = resolve_type_vars_if_possible(fcx, actual);
|
||||
fcx.ccx.tcx.sess.span_err(
|
||||
sp,
|
||||
~"mismatched types: expected " +
|
||||
ty_to_str(fcx.ccx.tcx, e_err) +
|
||||
~" but found " +
|
||||
ty_to_str(fcx.ccx.tcx, a_err) + ~" ("
|
||||
+ ty::type_err_to_str(err)
|
||||
+ ~")");
|
||||
fcx.ccx.tcx.sess.span_err(sp,
|
||||
"mismatched types: expected " +
|
||||
ty_to_str(fcx.ccx.tcx, e_err) +
|
||||
" but found " +
|
||||
ty_to_str(fcx.ccx.tcx, a_err) + " ("
|
||||
+ ty::type_err_to_str(err) + ")");
|
||||
ret mk_result(fcx, expected, ty_param_subst_var_ids);
|
||||
}
|
||||
}
|
||||
|
@ -1083,7 +1074,7 @@ mod writeback {
|
|||
fix_ok(new_type) { ret some(new_type); }
|
||||
fix_err(vid) {
|
||||
fcx.ccx.tcx.sess.span_err(sp,
|
||||
~"cannot determine a type \
|
||||
"cannot determine a type \
|
||||
for this expression");
|
||||
ret none;
|
||||
}
|
||||
|
@ -1135,7 +1126,7 @@ mod writeback {
|
|||
resolve_type_vars_for_node(wbcx, e.span, input.id);
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
_ { }
|
||||
}
|
||||
visit::visit_expr(e, wbcx, v);
|
||||
}
|
||||
|
@ -1159,7 +1150,7 @@ mod writeback {
|
|||
fix_ok(lty) { write::ty_only(wbcx.fcx.ccx.tcx, l.node.id, lty); }
|
||||
fix_err(_) {
|
||||
wbcx.fcx.ccx.tcx.sess.span_err(l.span,
|
||||
~"cannot determine a type \
|
||||
"cannot determine a type \
|
||||
for this local variable");
|
||||
wbcx.success = false;
|
||||
}
|
||||
|
@ -1381,10 +1372,9 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
|
|||
#fmt["this pattern has %u field%s, but the \
|
||||
corresponding variant has %u field%s",
|
||||
subpats_len,
|
||||
if subpats_len == 1u { ~"" } else { ~"s" },
|
||||
arg_len, if arg_len == 1u { ~"" } else { ~"s" }];
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
pat.span, s);
|
||||
if subpats_len == 1u { "" } else { "s" },
|
||||
arg_len, if arg_len == 1u { "" } else { "s" }];
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span, s);
|
||||
}
|
||||
|
||||
// TODO: vec::iter2
|
||||
|
@ -1401,10 +1391,10 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
|
|||
#fmt["this pattern has %u field%s, \
|
||||
but the corresponding \
|
||||
variant has no fields",
|
||||
subpats_len,
|
||||
if subpats_len == 1u {
|
||||
~""
|
||||
} else { ~"s" }]);
|
||||
subpats_len,
|
||||
if subpats_len == 1u {
|
||||
""
|
||||
} else { "s" }]);
|
||||
}
|
||||
write::ty_fixup(fcx, pat.id, path_tpot);
|
||||
}
|
||||
|
@ -1414,7 +1404,8 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
|
|||
fcx.ccx.tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
#fmt["mismatched types: expected %s, found tag",
|
||||
ty_to_str(fcx.ccx.tcx, expected)]);
|
||||
ty_to_str(fcx.ccx.tcx,
|
||||
expected)]);
|
||||
}
|
||||
}
|
||||
write::ty_fixup(fcx, pat.id, path_tpot);
|
||||
|
@ -1427,7 +1418,8 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
|
|||
fcx.ccx.tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
#fmt["mismatched types: expected %s, found record",
|
||||
ty_to_str(fcx.ccx.tcx, expected)]);
|
||||
ty_to_str(fcx.ccx.tcx,
|
||||
expected)]);
|
||||
}
|
||||
}
|
||||
let f_count = vec::len(fields);
|
||||
|
@ -1438,9 +1430,9 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
|
|||
#fmt["mismatched types: expected a record \
|
||||
with %u fields, found one with %u \
|
||||
fields",
|
||||
ex_f_count, f_count]);
|
||||
ex_f_count, f_count]);
|
||||
}
|
||||
fn matches(name: &istr, f: &ty::field) -> bool {
|
||||
fn matches(name: &str, f: &ty::field) -> bool {
|
||||
ret str::eq(name, f.ident);
|
||||
}
|
||||
for f: ast::field_pat in fields {
|
||||
|
@ -1464,7 +1456,8 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
|
|||
fcx.ccx.tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
#fmt["mismatched types: expected %s, found tuple",
|
||||
ty_to_str(fcx.ccx.tcx, expected)]);
|
||||
ty_to_str(fcx.ccx.tcx,
|
||||
expected)]);
|
||||
}
|
||||
}
|
||||
let e_count = vec::len(elts);
|
||||
|
@ -1474,7 +1467,7 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
|
|||
#fmt["mismatched types: expected a tuple \
|
||||
with %u fields, found one with %u \
|
||||
fields",
|
||||
vec::len(ex_elts), e_count]);
|
||||
vec::len(ex_elts), e_count]);
|
||||
}
|
||||
let i = 0u;
|
||||
for elt in elts { check_pat(fcx, map, elt, ex_elts[i]); i += 1u; }
|
||||
|
@ -1487,11 +1480,10 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast_util::pat_id_map, pat: &@ast::pat,
|
|||
write::ty_only_fixup(fcx, pat.id, expected);
|
||||
}
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
pat.span,
|
||||
~"mismatched types: expected " +
|
||||
ty_to_str(fcx.ccx.tcx, expected) +
|
||||
~" found box");
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||
"mismatched types: expected " +
|
||||
ty_to_str(fcx.ccx.tcx, expected) +
|
||||
" found box");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1503,7 +1495,7 @@ fn require_impure(sess: &session::session, f_purity: &ast::purity,
|
|||
alt f_purity {
|
||||
ast::impure_fn. { ret; }
|
||||
ast::pure_fn. {
|
||||
sess.span_fatal(sp, ~"Found impure expression in pure function decl");
|
||||
sess.span_fatal(sp, "Found impure expression in pure function decl");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1518,7 +1510,7 @@ fn require_pure_call(ccx: @crate_ctxt, caller_purity: &ast::purity,
|
|||
_ {
|
||||
ccx.tcx.sess.span_fatal(
|
||||
sp,
|
||||
~"Pure function calls function not known to be pure");
|
||||
"Pure function calls function not known to be pure");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1569,14 +1561,14 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
if call_kind != kind_for_each {
|
||||
fcx.ccx.tcx.sess.span_err(
|
||||
sp,
|
||||
~"calling iter outside of for each loop");
|
||||
"calling iter outside of for each loop");
|
||||
}
|
||||
}
|
||||
_ {
|
||||
if call_kind == kind_for_each {
|
||||
fcx.ccx.tcx.sess.span_err(
|
||||
sp,
|
||||
~"calling non-iter as sequence of for each loop");
|
||||
"calling non-iter as sequence of for each loop");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1589,12 +1581,11 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
arg_tys
|
||||
}
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
f.span,
|
||||
~"mismatched types: \
|
||||
fcx.ccx.tcx.sess.span_fatal(f.span,
|
||||
"mismatched types: \
|
||||
expected function or native \
|
||||
function but found "
|
||||
+ ty_to_str(fcx.ccx.tcx, fty))
|
||||
+ ty_to_str(fcx.ccx.tcx, fty))
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1602,17 +1593,16 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
let expected_arg_count = vec::len(arg_tys);
|
||||
let supplied_arg_count = vec::len(args);
|
||||
if expected_arg_count != supplied_arg_count {
|
||||
fcx.ccx.tcx.sess.span_err(
|
||||
sp,
|
||||
#fmt["this function takes %u \
|
||||
fcx.ccx.tcx.sess.span_err(sp,
|
||||
#fmt["this function takes %u \
|
||||
parameter%s but %u parameter%s supplied",
|
||||
expected_arg_count,
|
||||
if expected_arg_count == 1u {
|
||||
~""
|
||||
} else { ~"s" }, supplied_arg_count,
|
||||
if supplied_arg_count == 1u {
|
||||
~" was"
|
||||
} else { ~"s were" }]);
|
||||
expected_arg_count,
|
||||
if expected_arg_count == 1u {
|
||||
""
|
||||
} else { "s" }, supplied_arg_count,
|
||||
if supplied_arg_count == 1u {
|
||||
" was"
|
||||
} else { "s were" }]);
|
||||
// HACK: build an arguments list with dummy arguments to
|
||||
// check against
|
||||
let dummy = {mode: ty::mo_val, ty: ty::mk_bot(fcx.ccx.tcx)};
|
||||
|
@ -1753,9 +1743,8 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
let binopstr = ast_util::binop_to_str(binop);
|
||||
let t_str = ty_to_str(fcx.ccx.tcx, resolved_t);
|
||||
let errmsg =
|
||||
~"binary operation " + binopstr +
|
||||
~" cannot be applied to type `" +
|
||||
t_str + ~"`";
|
||||
"binary operation " + binopstr +
|
||||
" cannot be applied to type `" + t_str + "`";
|
||||
fcx.ccx.tcx.sess.span_err(span, errmsg);
|
||||
}
|
||||
}
|
||||
|
@ -1804,31 +1793,29 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
vec::len(variants[0].args) != 1u {
|
||||
tcx.sess.span_fatal(
|
||||
expr.span,
|
||||
~"can only dereference tags " +
|
||||
~"with a single variant which has a "
|
||||
+ ~"single argument");
|
||||
"can only dereference tags " +
|
||||
"with a single variant which has a "
|
||||
+ "single argument");
|
||||
}
|
||||
oper_t =
|
||||
ty::substitute_type_params(tcx, tps, variants[0].args[0]);
|
||||
}
|
||||
ty::ty_ptr(inner) { oper_t = inner.ty; }
|
||||
_ {
|
||||
tcx.sess.span_fatal(
|
||||
expr.span,
|
||||
~"dereferencing non-" +
|
||||
~"dereferenceable type: " +
|
||||
ty_to_str(tcx, oper_t));
|
||||
tcx.sess.span_fatal(expr.span,
|
||||
"dereferencing non-" +
|
||||
"dereferenceable type: " +
|
||||
ty_to_str(tcx, oper_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::not. {
|
||||
if !type_is_integral(fcx, oper.span, oper_t) &&
|
||||
structure_of(fcx, oper.span, oper_t) != ty::ty_bool {
|
||||
tcx.sess.span_err(
|
||||
expr.span,
|
||||
#fmt["mismatched types: expected bool \
|
||||
tcx.sess.span_err(expr.span,
|
||||
#fmt["mismatched types: expected bool \
|
||||
or integer but found %s",
|
||||
ty_to_str(tcx, oper_t)]);
|
||||
ty_to_str(tcx, oper_t)]);
|
||||
}
|
||||
}
|
||||
ast::neg. {
|
||||
|
@ -1836,9 +1823,9 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
if !(ty::type_is_integral(tcx, oper_t) ||
|
||||
ty::type_is_fp(tcx, oper_t)) {
|
||||
tcx.sess.span_err(expr.span,
|
||||
~"applying unary minus to \
|
||||
"applying unary minus to \
|
||||
non-numeric type "
|
||||
+ ty_to_str(tcx, oper_t));
|
||||
+ ty_to_str(tcx, oper_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1855,20 +1842,18 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
// supplied some, that's an error.
|
||||
if vec::len::<@ast::ty>(pth.node.types) > 0u {
|
||||
tcx.sess.span_fatal(expr.span,
|
||||
~"this kind of value does not \
|
||||
"this kind of value does not \
|
||||
take type parameters");
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, tpt.ty);
|
||||
}
|
||||
}
|
||||
ast::expr_mac(_) { tcx.sess.bug(~"unexpanded macro"); }
|
||||
ast::expr_mac(_) { tcx.sess.bug("unexpanded macro"); }
|
||||
ast::expr_fail(expr_opt) {
|
||||
bot = true;
|
||||
alt expr_opt {
|
||||
none. {/* do nothing */ }
|
||||
some(e) {
|
||||
check_expr_with(fcx, e, ty::mk_istr(tcx));
|
||||
}
|
||||
some(e) { check_expr_with(fcx, e, ty::mk_istr(tcx)); }
|
||||
}
|
||||
write::bot_ty(tcx, id);
|
||||
}
|
||||
|
@ -1881,7 +1866,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
let nil = ty::mk_nil(tcx);
|
||||
if !are_compatible(fcx, fcx.ret_ty, nil) {
|
||||
tcx.sess.span_err(expr.span,
|
||||
~"ret; in function returning non-nil");
|
||||
"ret; in function returning non-nil");
|
||||
}
|
||||
}
|
||||
some(e) { check_expr_with(fcx, e, fcx.ret_ty); }
|
||||
|
@ -1891,14 +1876,14 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
ast::expr_put(expr_opt) {
|
||||
require_impure(tcx.sess, fcx.purity, expr.span);
|
||||
if fcx.proto != ast::proto_iter {
|
||||
tcx.sess.span_err(expr.span, ~"put in non-iterator");
|
||||
tcx.sess.span_err(expr.span, "put in non-iterator");
|
||||
}
|
||||
alt expr_opt {
|
||||
none. {
|
||||
let nil = ty::mk_nil(tcx);
|
||||
if !are_compatible(fcx, fcx.ret_ty, nil) {
|
||||
tcx.sess.span_err(expr.span,
|
||||
~"put; in iterator yielding non-nil");
|
||||
"put; in iterator yielding non-nil");
|
||||
}
|
||||
}
|
||||
some(e) { bot = check_expr_with(fcx, e, fcx.ret_ty); }
|
||||
|
@ -1971,8 +1956,8 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
_ {
|
||||
tcx.sess.span_fatal(
|
||||
expr.span,
|
||||
~"mismatched types: expected vector or string but "
|
||||
+ ~"found " + ty_to_str(tcx, ety));
|
||||
"mismatched types: expected vector or string but "
|
||||
+ "found " + ty_to_str(tcx, ety));
|
||||
}
|
||||
}
|
||||
bot |= check_for_or_for_each(fcx, decl, elt_ty, body, id);
|
||||
|
@ -1986,7 +1971,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
}
|
||||
_ {
|
||||
tcx.sess.span_fatal(expr.span,
|
||||
~"sequence in for each loop not a call");
|
||||
"sequence in for each loop not a call");
|
||||
}
|
||||
}
|
||||
bot |= check_for_or_for_each(fcx, decl, expr_ty(tcx, seq), body, id);
|
||||
|
@ -2017,10 +2002,8 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
let arm_non_bot = false;
|
||||
for arm: ast::arm in arms {
|
||||
alt arm.guard {
|
||||
some(e) {
|
||||
check_expr_with(fcx, e, ty::mk_bool(tcx));
|
||||
}
|
||||
none. {}
|
||||
some(e) { check_expr_with(fcx, e, ty::mk_bool(tcx)); }
|
||||
none. { }
|
||||
}
|
||||
if !check_block(fcx, arm.body) { arm_non_bot = true; }
|
||||
let bty = block_ty(tcx, arm.body);
|
||||
|
@ -2054,10 +2037,11 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
}
|
||||
ast::expr_block(b) {
|
||||
// If this is an unchecked block, turn off purity-checking
|
||||
let fcx_for_block = alt b.node.rules {
|
||||
ast::unchecked. { @{ purity: ast::impure_fn with *fcx } }
|
||||
_ { fcx }
|
||||
};
|
||||
let fcx_for_block =
|
||||
alt b.node.rules {
|
||||
ast::unchecked. { @{purity: ast::impure_fn with *fcx} }
|
||||
_ { fcx }
|
||||
};
|
||||
bot = check_block(fcx_for_block, b);
|
||||
let typ =
|
||||
alt b.node.expr {
|
||||
|
@ -2124,9 +2108,8 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
this_obj_sty = some(structure_of(fcx, expr.span, tpt.ty));
|
||||
}
|
||||
none. {
|
||||
tcx.sess.bug(~"didn't find " +
|
||||
int::str(did.node) +
|
||||
~" in type cache");
|
||||
tcx.sess.bug("didn't find " + int::str(did.node) +
|
||||
" in type cache");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2135,7 +2118,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
}
|
||||
none. {
|
||||
// Shouldn't happen.
|
||||
tcx.sess.span_err(expr.span, ~"self-call in non-object context");
|
||||
tcx.sess.span_err(expr.span, "self-call in non-object context");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2166,10 +2149,9 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
if !(type_is_scalar(fcx, expr.span, expr_ty(tcx, e)) &&
|
||||
type_is_scalar(fcx, expr.span, t_1)) {
|
||||
tcx.sess.span_err(expr.span,
|
||||
~"non-scalar cast: " +
|
||||
ty_to_str(tcx, expr_ty(tcx, e))
|
||||
+ ~" as " +
|
||||
ty_to_str(tcx, t_1));
|
||||
"non-scalar cast: " +
|
||||
ty_to_str(tcx, expr_ty(tcx, e)) + " as " +
|
||||
ty_to_str(tcx, t_1));
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, t_1);
|
||||
}
|
||||
|
@ -2217,7 +2199,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
ty::ty_rec(flds) { base_fields = flds; }
|
||||
_ {
|
||||
tcx.sess.span_fatal(expr.span,
|
||||
~"record update has non-record base");
|
||||
"record update has non-record base");
|
||||
}
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, bexpr_t);
|
||||
|
@ -2231,8 +2213,8 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
}
|
||||
if !found {
|
||||
tcx.sess.span_fatal(f.span,
|
||||
~"unknown field in record update: " +
|
||||
f.node.ident);
|
||||
"unknown field in record update: " +
|
||||
f.node.ident);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2246,7 +2228,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
ty::ty_rec(fields) {
|
||||
let ix: uint = ty::field_idx(tcx.sess, expr.span, field, fields);
|
||||
if ix >= vec::len::<ty::field>(fields) {
|
||||
tcx.sess.span_fatal(expr.span, ~"bad index on record");
|
||||
tcx.sess.span_fatal(expr.span, "bad index on record");
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, fields[ix].mt.ty);
|
||||
}
|
||||
|
@ -2254,7 +2236,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
let ix: uint =
|
||||
ty::method_idx(tcx.sess, expr.span, field, methods);
|
||||
if ix >= vec::len::<ty::method>(methods) {
|
||||
tcx.sess.span_fatal(expr.span, ~"bad index on obj");
|
||||
tcx.sess.span_fatal(expr.span, "bad index on obj");
|
||||
}
|
||||
let meth = methods[ix];
|
||||
let t =
|
||||
|
@ -2279,9 +2261,9 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
let idx_t = expr_ty(tcx, idx);
|
||||
if !type_is_integral(fcx, idx.span, idx_t) {
|
||||
tcx.sess.span_err(idx.span,
|
||||
~"mismatched types: expected \
|
||||
"mismatched types: expected \
|
||||
integer but found "
|
||||
+ ty_to_str(tcx, idx_t));
|
||||
+ ty_to_str(tcx, idx_t));
|
||||
}
|
||||
alt structure_of(fcx, expr.span, base_t) {
|
||||
ty::ty_vec(mt) { write::ty_only_fixup(fcx, id, mt.ty); }
|
||||
|
@ -2291,8 +2273,8 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
}
|
||||
_ {
|
||||
tcx.sess.span_fatal(expr.span,
|
||||
~"vector-indexing bad type: " +
|
||||
ty_to_str(tcx, base_t));
|
||||
"vector-indexing bad type: " +
|
||||
ty_to_str(tcx, base_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2362,9 +2344,9 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
// The user is trying to extend a non-object.
|
||||
tcx.sess.span_fatal(
|
||||
e.span,
|
||||
syntax::print::pprust::expr_to_str(e)
|
||||
syntax::print::pprust::expr_to_str(e)
|
||||
+
|
||||
~" does not have object type");
|
||||
" does not have object type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2391,9 +2373,9 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
if new_type != m {
|
||||
ccx.tcx.sess.span_fatal(
|
||||
om.span,
|
||||
~"Attempted to override method "
|
||||
"Attempted to override method "
|
||||
+ m.ident +
|
||||
~" with one of a different type");
|
||||
" with one of a different type");
|
||||
}
|
||||
ret none;
|
||||
}
|
||||
|
@ -2435,7 +2417,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
|
|||
check_expr_with(fcx, x, t);
|
||||
write::ty_only_fixup(fcx, id, ty::mk_uniq(tcx, t));
|
||||
}
|
||||
_ { tcx.sess.unimpl(~"expr type in typeck::check_expr"); }
|
||||
_ { tcx.sess.unimpl("expr type in typeck::check_expr"); }
|
||||
}
|
||||
if bot { write::ty_only_fixup(fcx, expr.id, ty::mk_bot(tcx)); }
|
||||
|
||||
|
@ -2468,8 +2450,8 @@ fn check_decl_local(fcx: &@fn_ctxt, local: &@ast::local) -> bool {
|
|||
|
||||
alt fcx.locals.find(local.node.id) {
|
||||
none. {
|
||||
fcx.ccx.tcx.sess.bug(~"check_decl_local: local id not found " +
|
||||
ident_for_local(local));
|
||||
fcx.ccx.tcx.sess.bug("check_decl_local: local id not found " +
|
||||
ident_for_local(local));
|
||||
}
|
||||
some(i) {
|
||||
let t = ty::mk_var(fcx.ccx.tcx, i);
|
||||
|
@ -2518,7 +2500,7 @@ fn check_block(fcx: &@fn_ctxt, blk: &ast::blk) -> bool {
|
|||
}
|
||||
_ { false }
|
||||
} {
|
||||
fcx.ccx.tcx.sess.span_warn(s.span, ~"unreachable statement");
|
||||
fcx.ccx.tcx.sess.span_warn(s.span, "unreachable statement");
|
||||
warned = true;
|
||||
}
|
||||
bot |= check_stmt(fcx, s);
|
||||
|
@ -2527,7 +2509,7 @@ fn check_block(fcx: &@fn_ctxt, blk: &ast::blk) -> bool {
|
|||
none. { write::nil_ty(fcx.ccx.tcx, blk.node.id); }
|
||||
some(e) {
|
||||
if bot && !warned {
|
||||
fcx.ccx.tcx.sess.span_warn(e.span, ~"unreachable expression");
|
||||
fcx.ccx.tcx.sess.span_warn(e.span, "unreachable expression");
|
||||
}
|
||||
bot |= check_expr(fcx, e);
|
||||
let ety = expr_ty(fcx.ccx.tcx, e);
|
||||
|
@ -2569,8 +2551,9 @@ fn check_pred_expr(fcx: &@fn_ctxt, e: &@ast::expr) -> bool {
|
|||
alt e.node {
|
||||
ast::expr_call(operator, operands) {
|
||||
if !ty::is_pred_ty(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, operator)) {
|
||||
fcx.ccx.tcx.sess.span_fatal(operator.span,
|
||||
~"Operator in constraint has non-boolean return type");
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
operator.span,
|
||||
"Operator in constraint has non-boolean return type");
|
||||
}
|
||||
|
||||
alt operator.node {
|
||||
|
@ -2581,14 +2564,14 @@ fn check_pred_expr(fcx: &@fn_ctxt, e: &@ast::expr) -> bool {
|
|||
}
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal(operator.span,
|
||||
~"Impure function as operator \
|
||||
"Impure function as operator \
|
||||
in constraint");
|
||||
}
|
||||
}
|
||||
for operand: @ast::expr in operands {
|
||||
if !ast_util::is_constraint_arg(operand) {
|
||||
let s =
|
||||
~"Constraint args must be \
|
||||
"Constraint args must be \
|
||||
slot variables or literals";
|
||||
fcx.ccx.tcx.sess.span_fatal(e.span, s);
|
||||
}
|
||||
|
@ -2596,70 +2579,76 @@ slot variables or literals";
|
|||
}
|
||||
_ {
|
||||
let s =
|
||||
~"In a constraint, expected the \
|
||||
"In a constraint, expected the \
|
||||
constraint name to be an explicit name";
|
||||
fcx.ccx.tcx.sess.span_fatal(e.span, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ { fcx.ccx.tcx.sess.span_fatal(
|
||||
e.span, ~"check on non-predicate"); }
|
||||
_ { fcx.ccx.tcx.sess.span_fatal(e.span, "check on non-predicate"); }
|
||||
}
|
||||
ret bot;
|
||||
}
|
||||
|
||||
fn check_constraints(fcx: &@fn_ctxt, cs: [@ast::constr], args:[ast::arg]) {
|
||||
fn check_constraints(fcx: &@fn_ctxt, cs: [@ast::constr], args: [ast::arg]) {
|
||||
let c_args;
|
||||
let num_args = vec::len(args);
|
||||
for c: @ast::constr in cs {
|
||||
c_args = [];
|
||||
for a: @spanned<ast::fn_constr_arg> in c.node.args {
|
||||
c_args += [@(alt a.node {
|
||||
ast::carg_base. {
|
||||
// "base" should not occur in a fn type thing, as of
|
||||
// yet, b/c we don't allow constraints on the return type
|
||||
c_args +=
|
||||
[
|
||||
// "base" should not occur in a fn type thing, as of
|
||||
// yet, b/c we don't allow constraints on the return type
|
||||
|
||||
fcx.ccx.tcx.sess.span_bug(a.span, ~"check_constraints:\
|
||||
// Works b/c no higher-order polymorphism
|
||||
/*
|
||||
This is kludgy, and we probably shouldn't be assigning
|
||||
node IDs here, but we're creating exprs that are
|
||||
ephemeral, just for the purposes of typechecking. So
|
||||
that's my justification.
|
||||
*/
|
||||
@alt a.node {
|
||||
ast::carg_base. {
|
||||
fcx.ccx.tcx.sess.span_bug(a.span,
|
||||
"check_constraints:\
|
||||
unexpected carg_base");
|
||||
}
|
||||
ast::carg_lit(l) {
|
||||
let tmp_node_id = fcx.ccx.tcx.sess.next_node_id();
|
||||
{id:tmp_node_id, node: ast::expr_lit(l), span:a.span} }
|
||||
ast::carg_ident(i) {
|
||||
if i < num_args {
|
||||
let p : ast::path_ =
|
||||
{global:false, idents:[(args[i]).ident],
|
||||
// Works b/c no higher-order polymorphism
|
||||
types:[]};
|
||||
/*
|
||||
This is kludgy, and we probably shouldn't be assigning
|
||||
node IDs here, but we're creating exprs that are
|
||||
ephemeral, just for the purposes of typechecking. So
|
||||
that's my justification.
|
||||
*/
|
||||
let arg_occ_node_id = fcx.ccx.tcx.sess.next_node_id();
|
||||
fcx.ccx.tcx.def_map.insert
|
||||
(arg_occ_node_id, ast::def_arg(local_def(args[i].id),
|
||||
args[i].mode));
|
||||
{id:arg_occ_node_id,
|
||||
node: ast::expr_path(respan(a.span, p)),
|
||||
span:a.span}
|
||||
}
|
||||
else {
|
||||
fcx.ccx.tcx.sess.span_bug(a.span, ~"check_constraints:\
|
||||
}
|
||||
ast::carg_lit(l) {
|
||||
let tmp_node_id = fcx.ccx.tcx.sess.next_node_id();
|
||||
{id: tmp_node_id, node: ast::expr_lit(l), span: a.span}
|
||||
}
|
||||
ast::carg_ident(i) {
|
||||
if i < num_args {
|
||||
let p: ast::path_ =
|
||||
{global: false,
|
||||
idents: [args[i].ident],
|
||||
types: []};
|
||||
let arg_occ_node_id =
|
||||
fcx.ccx.tcx.sess.next_node_id();
|
||||
fcx.ccx.tcx.def_map.insert(
|
||||
arg_occ_node_id,
|
||||
ast::def_arg(local_def(args[i].id),
|
||||
args[i].mode));
|
||||
{id: arg_occ_node_id,
|
||||
node: ast::expr_path(respan(a.span, p)),
|
||||
span: a.span}
|
||||
} else {
|
||||
fcx.ccx.tcx.sess.span_bug(a.span,
|
||||
"check_constraints:\
|
||||
carg_ident index out of bounds");
|
||||
}
|
||||
}
|
||||
})]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
let p_op: ast::expr_ = ast::expr_path(c.node.path);
|
||||
let oper: @ast::expr = @{id:c.node.id,
|
||||
node: p_op, span:c.span};
|
||||
let oper: @ast::expr = @{id: c.node.id, node: p_op, span: c.span};
|
||||
// Another ephemeral expr
|
||||
let call_expr_id = fcx.ccx.tcx.sess.next_node_id();
|
||||
let call_expr = @{id: call_expr_id,
|
||||
node: ast::expr_call(oper, c_args),
|
||||
span: c.span};
|
||||
let call_expr =
|
||||
@{id: call_expr_id,
|
||||
node: ast::expr_call(oper, c_args),
|
||||
span: c.span};
|
||||
check_pred_expr(fcx, call_expr);
|
||||
}
|
||||
}
|
||||
|
@ -2688,14 +2677,14 @@ fn check_fn(ccx: &@crate_ctxt, f: &ast::_fn, id: &ast::node_id,
|
|||
// function result type, if there is a tail expr.
|
||||
// We don't do this check for an iterator, as the tail expr doesn't
|
||||
// have to have the result type of the iterator.
|
||||
alt (body.node.expr) {
|
||||
alt body.node.expr {
|
||||
some(tail_expr) {
|
||||
if f.proto != ast::proto_iter {
|
||||
let tail_expr_ty = expr_ty(ccx.tcx, tail_expr);
|
||||
demand::simple(fcx, tail_expr.span, fcx.ret_ty, tail_expr_ty);
|
||||
}
|
||||
}
|
||||
none. {}
|
||||
none. { }
|
||||
}
|
||||
|
||||
let args = ty::ty_fn_args(ccx.tcx, ty::node_id_to_type(ccx.tcx, id));
|
||||
|
@ -2762,15 +2751,15 @@ fn check_main_fn_ty(tcx: &ty::ctxt, main_id: &ast::node_id) {
|
|||
if !ok {
|
||||
let span = ast_map::node_span(tcx.items.get(main_id));
|
||||
tcx.sess.span_err(span,
|
||||
~"wrong type in main function: found " +
|
||||
ty_to_str(tcx, main_t));
|
||||
"wrong type in main function: found " +
|
||||
ty_to_str(tcx, main_t));
|
||||
}
|
||||
}
|
||||
_ {
|
||||
let span = ast_map::node_span(tcx.items.get(main_id));
|
||||
tcx.sess.span_bug(span,
|
||||
~"main has a non-function type: found" +
|
||||
ty_to_str(tcx, main_t));
|
||||
"main has a non-function type: found" +
|
||||
ty_to_str(tcx, main_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2779,7 +2768,7 @@ fn check_for_main_fn(tcx: &ty::ctxt, crate: &@ast::crate) {
|
|||
if !tcx.sess.get_opts().library {
|
||||
alt tcx.sess.get_main_id() {
|
||||
some(id) { check_main_fn_ty(tcx, id); }
|
||||
none. { tcx.sess.span_err(crate.span, ~"main function not found"); }
|
||||
none. { tcx.sess.span_err(crate.span, "main function not found"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import codemap::filename;
|
|||
|
||||
type spanned<T> = {node: T, span: span};
|
||||
|
||||
type ident = istr;
|
||||
type ident = str;
|
||||
|
||||
// Functions may or may not have names.
|
||||
type fn_ident = option::t<ident>;
|
||||
|
@ -43,7 +43,7 @@ tag def {
|
|||
def_use(def_id);
|
||||
def_native_ty(def_id);
|
||||
def_native_fn(def_id);
|
||||
def_upvar(def_id, @def, bool /* writable */);
|
||||
def_upvar(def_id, @def, /* writable */bool);
|
||||
}
|
||||
|
||||
// The set of meta_items that define the compilation environment of the crate,
|
||||
|
@ -78,8 +78,8 @@ tag meta_item_ {
|
|||
|
||||
type blk = spanned<blk_>;
|
||||
|
||||
type blk_ = {stmts: [@stmt], expr: option::t<@expr>,
|
||||
id: node_id, rules: check_mode};
|
||||
type blk_ =
|
||||
{stmts: [@stmt], expr: option::t<@expr>, id: node_id, rules: check_mode};
|
||||
|
||||
type pat = {id: node_id, node: pat_, span: span};
|
||||
|
||||
|
@ -229,7 +229,7 @@ tag blk_sort {
|
|||
type mac = spanned<mac_>;
|
||||
|
||||
tag mac_ {
|
||||
mac_invoc(path, @expr, option::t<istr>);
|
||||
mac_invoc(path, @expr, option::t<str>);
|
||||
mac_embed_type(@ty);
|
||||
mac_embed_block(blk);
|
||||
mac_ellipsis;
|
||||
|
@ -238,13 +238,13 @@ tag mac_ {
|
|||
type lit = spanned<lit_>;
|
||||
|
||||
tag lit_ {
|
||||
lit_str(istr);
|
||||
lit_str(str);
|
||||
lit_char(char);
|
||||
lit_int(int);
|
||||
lit_uint(uint);
|
||||
lit_mach_int(ty_mach, int);
|
||||
lit_float(istr);
|
||||
lit_mach_float(ty_mach, istr);
|
||||
lit_float(str);
|
||||
lit_mach_float(ty_mach, str);
|
||||
lit_nil;
|
||||
lit_bool(bool);
|
||||
}
|
||||
|
@ -292,6 +292,7 @@ tag ty_ {
|
|||
ret/fail/break/cont. there is no syntax
|
||||
for this type. */
|
||||
|
||||
|
||||
/* bot represents the value of functions that don't return a value
|
||||
locally to their context. in contrast, things like log that do
|
||||
return, but don't return a meaningful value, have result type nil. */
|
||||
|
@ -379,6 +380,7 @@ tag controlflow {
|
|||
noreturn; // functions with return type _|_ that always
|
||||
// raise an error or exit (i.e. never return to the caller)
|
||||
|
||||
|
||||
return; // everything else
|
||||
}
|
||||
|
||||
|
@ -412,7 +414,7 @@ tag native_abi {
|
|||
}
|
||||
|
||||
type native_mod =
|
||||
{native_name: istr,
|
||||
{native_name: str,
|
||||
abi: native_abi,
|
||||
view_items: [@view_item],
|
||||
items: [@native_item]};
|
||||
|
@ -467,9 +469,11 @@ tag item_ {
|
|||
item_tag([variant], [ty_param]);
|
||||
item_obj(_obj, [ty_param], /* constructor id */node_id);
|
||||
item_res(_fn,
|
||||
/* dtor */
|
||||
|
||||
/* dtor */
|
||||
node_id,
|
||||
/* dtor id */
|
||||
|
||||
/* dtor id */
|
||||
[ty_param],
|
||||
|
||||
/* ctor id */
|
||||
|
@ -485,7 +489,7 @@ type native_item =
|
|||
|
||||
tag native_item_ {
|
||||
native_item_ty;
|
||||
native_item_fn(option::t<istr>, fn_decl, [ty_param]);
|
||||
native_item_fn(option::t<str>, fn_decl, [ty_param]);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -13,11 +13,9 @@ fn mk_sp(lo: uint, hi: uint) -> span {
|
|||
// make this a const, once the compiler supports it
|
||||
fn dummy_sp() -> span { ret mk_sp(0u, 0u); }
|
||||
|
||||
fn path_name(p: &path) -> istr { path_name_i(p.node.idents) }
|
||||
fn path_name(p: &path) -> str { path_name_i(p.node.idents) }
|
||||
|
||||
fn path_name_i(idents: &[ident]) -> istr {
|
||||
str::connect(idents, ~"::")
|
||||
}
|
||||
fn path_name_i(idents: &[ident]) -> str { str::connect(idents, "::") }
|
||||
|
||||
fn local_def(id: node_id) -> def_id { ret {crate: local_crate, node: id}; }
|
||||
|
||||
|
@ -45,7 +43,7 @@ fn def_id_of_def(d: def) -> def_id {
|
|||
}
|
||||
}
|
||||
|
||||
type pat_id_map = std::map::hashmap<istr, node_id>;
|
||||
type pat_id_map = std::map::hashmap<str, node_id>;
|
||||
|
||||
// This is used because same-named variables in alternative patterns need to
|
||||
// use the node_id of their namesake in the first pattern.
|
||||
|
@ -82,27 +80,27 @@ fn pat_binding_ids(pat: &@pat) -> [node_id] {
|
|||
ret found;
|
||||
}
|
||||
|
||||
fn binop_to_str(op: binop) -> istr {
|
||||
fn binop_to_str(op: binop) -> str {
|
||||
alt op {
|
||||
add. { ret ~"+"; }
|
||||
sub. { ret ~"-"; }
|
||||
mul. { ret ~"*"; }
|
||||
div. { ret ~"/"; }
|
||||
rem. { ret ~"%"; }
|
||||
and. { ret ~"&&"; }
|
||||
or. { ret ~"||"; }
|
||||
bitxor. { ret ~"^"; }
|
||||
bitand. { ret ~"&"; }
|
||||
bitor. { ret ~"|"; }
|
||||
lsl. { ret ~"<<"; }
|
||||
lsr. { ret ~">>"; }
|
||||
asr. { ret ~">>>"; }
|
||||
eq. { ret ~"=="; }
|
||||
lt. { ret ~"<"; }
|
||||
le. { ret ~"<="; }
|
||||
ne. { ret ~"!="; }
|
||||
ge. { ret ~">="; }
|
||||
gt. { ret ~">"; }
|
||||
add. { ret "+"; }
|
||||
sub. { ret "-"; }
|
||||
mul. { ret "*"; }
|
||||
div. { ret "/"; }
|
||||
rem. { ret "%"; }
|
||||
and. { ret "&&"; }
|
||||
or. { ret "||"; }
|
||||
bitxor. { ret "^"; }
|
||||
bitand. { ret "&"; }
|
||||
bitor. { ret "|"; }
|
||||
lsl. { ret "<<"; }
|
||||
lsr. { ret ">>"; }
|
||||
asr. { ret ">>>"; }
|
||||
eq. { ret "=="; }
|
||||
lt. { ret "<"; }
|
||||
le. { ret "<="; }
|
||||
ne. { ret "!="; }
|
||||
ge. { ret ">="; }
|
||||
gt. { ret ">"; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,12 +108,12 @@ pure fn lazy_binop(b: binop) -> bool {
|
|||
alt b { and. { true } or. { true } _ { false } }
|
||||
}
|
||||
|
||||
fn unop_to_str(op: unop) -> istr {
|
||||
fn unop_to_str(op: unop) -> str {
|
||||
alt op {
|
||||
box(mt) { if mt == mut { ret ~"@mutable "; } ret ~"@"; }
|
||||
deref. { ret ~"*"; }
|
||||
not. { ret ~"!"; }
|
||||
neg. { ret ~"-"; }
|
||||
box(mt) { if mt == mut { ret "@mutable "; } ret "@"; }
|
||||
deref. { ret "*"; }
|
||||
not. { ret "!"; }
|
||||
neg. { ret "-"; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,18 +121,18 @@ fn is_path(e: &@expr) -> bool {
|
|||
ret alt e.node { expr_path(_) { true } _ { false } };
|
||||
}
|
||||
|
||||
fn ty_mach_to_str(tm: ty_mach) -> istr {
|
||||
fn ty_mach_to_str(tm: ty_mach) -> str {
|
||||
alt tm {
|
||||
ty_u8. { ret ~"u8"; }
|
||||
ty_u16. { ret ~"u16"; }
|
||||
ty_u32. { ret ~"u32"; }
|
||||
ty_u64. { ret ~"u64"; }
|
||||
ty_i8. { ret ~"i8"; }
|
||||
ty_i16. { ret ~"i16"; }
|
||||
ty_i32. { ret ~"i32"; }
|
||||
ty_i64. { ret ~"i64"; }
|
||||
ty_f32. { ret ~"f32"; }
|
||||
ty_f64. { ret ~"f64"; }
|
||||
ty_u8. { ret "u8"; }
|
||||
ty_u16. { ret "u16"; }
|
||||
ty_u32. { ret "u32"; }
|
||||
ty_u64. { ret "u64"; }
|
||||
ty_i8. { ret "i8"; }
|
||||
ty_i16. { ret "i16"; }
|
||||
ty_i32. { ret "i32"; }
|
||||
ty_i64. { ret "i64"; }
|
||||
ty_f32. { ret "f32"; }
|
||||
ty_f64. { ret "f64"; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,8 +188,8 @@ fn block_from_expr(e: @expr) -> blk {
|
|||
ret {node: blk_, span: e.span};
|
||||
}
|
||||
|
||||
fn checked_blk(stmts1: [@stmt], expr1: option::t<@expr>, id1: node_id)
|
||||
-> blk_ {
|
||||
fn checked_blk(stmts1: [@stmt], expr1: option::t<@expr>, id1: node_id) ->
|
||||
blk_ {
|
||||
ret {stmts: stmts1, expr: expr1, id: id1, rules: checked};
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import std::option;
|
|||
import std::option::some;
|
||||
import std::option::none;
|
||||
|
||||
type filename = istr;
|
||||
type filename = str;
|
||||
|
||||
type file_pos = {ch: uint, byte: uint};
|
||||
|
||||
|
@ -66,15 +66,16 @@ fn lookup_byte_pos(map: codemap, pos: uint) -> loc {
|
|||
}
|
||||
|
||||
tag opt_span {
|
||||
//hack (as opposed to option::t), to make `span` compile
|
||||
|
||||
//hack (as opposed to option::t), to make `span` compile
|
||||
os_none;
|
||||
os_some(@span);
|
||||
}
|
||||
type span = {lo: uint, hi: uint, expanded_from: opt_span};
|
||||
|
||||
fn span_to_str(sp: &span, cm: &codemap) -> istr {
|
||||
fn span_to_str(sp: &span, cm: &codemap) -> str {
|
||||
let cur = sp;
|
||||
let res = ~"";
|
||||
let res = "";
|
||||
let prev_file = none;
|
||||
while true {
|
||||
let lo = lookup_char_pos(cm, cur.lo);
|
||||
|
@ -82,16 +83,14 @@ fn span_to_str(sp: &span, cm: &codemap) -> istr {
|
|||
res +=
|
||||
#fmt["%s:%u:%u: %u:%u",
|
||||
if some(lo.filename) == prev_file {
|
||||
~"-"
|
||||
} else {
|
||||
lo.filename
|
||||
}, lo.line, lo.col, hi.line, hi.col];
|
||||
"-"
|
||||
} else { lo.filename }, lo.line, lo.col, hi.line, hi.col];
|
||||
alt cur.expanded_from {
|
||||
os_none. { break; }
|
||||
os_some(new_sp) {
|
||||
cur = *new_sp;
|
||||
prev_file = some(lo.filename);
|
||||
res += ~"<<";
|
||||
res += "<<";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,13 +98,13 @@ fn span_to_str(sp: &span, cm: &codemap) -> istr {
|
|||
ret res;
|
||||
}
|
||||
|
||||
fn emit_diagnostic(sp: &option::t<span>, msg: &istr, kind: &istr, color: u8,
|
||||
fn emit_diagnostic(sp: &option::t<span>, msg: &str, kind: &str, color: u8,
|
||||
cm: &codemap) {
|
||||
let ss = ~"";
|
||||
let ss = "";
|
||||
let maybe_lines: option::t<@file_lines> = none;
|
||||
alt sp {
|
||||
some(ssp) {
|
||||
ss = span_to_str(ssp, cm) + ~" ";
|
||||
ss = span_to_str(ssp, cm) + " ";
|
||||
maybe_lines = some(span_to_lines(ssp, cm));
|
||||
}
|
||||
none. { }
|
||||
|
@ -114,9 +113,9 @@ fn emit_diagnostic(sp: &option::t<span>, msg: &istr, kind: &istr, color: u8,
|
|||
if term::color_supported() {
|
||||
term::fg(io::stdout().get_buf_writer(), color);
|
||||
}
|
||||
io::stdout().write_str(#fmt[~"%s:", kind]);
|
||||
io::stdout().write_str(#fmt["%s:", kind]);
|
||||
if term::color_supported() { term::reset(io::stdout().get_buf_writer()); }
|
||||
io::stdout().write_str(#fmt[~" %s\n", msg]);
|
||||
io::stdout().write_str(#fmt[" %s\n", msg]);
|
||||
|
||||
maybe_highlight_lines(sp, cm, maybe_lines);
|
||||
}
|
||||
|
@ -128,7 +127,7 @@ fn maybe_highlight_lines(sp: &option::t<span>, cm: &codemap,
|
|||
some(lines) {
|
||||
// If we're not looking at a real file then we can't re-open it to
|
||||
// pull out the lines
|
||||
if lines.name == ~"-" { ret; }
|
||||
if lines.name == "-" { ret; }
|
||||
|
||||
// FIXME: reading in the entire file is the worst possible way to
|
||||
// get access to the necessary lines.
|
||||
|
@ -145,19 +144,18 @@ fn maybe_highlight_lines(sp: &option::t<span>, cm: &codemap,
|
|||
}
|
||||
// Print the offending lines
|
||||
for line: uint in display_lines {
|
||||
io::stdout().write_str(
|
||||
#fmt[~"%s:%u ", fm.name, line + 1u]);
|
||||
io::stdout().write_str(#fmt["%s:%u ", fm.name, line + 1u]);
|
||||
let s = get_line(fm, line as int, file);
|
||||
if !str::ends_with(s, ~"\n") { s += ~"\n"; }
|
||||
if !str::ends_with(s, "\n") { s += "\n"; }
|
||||
io::stdout().write_str(s);
|
||||
}
|
||||
if elided {
|
||||
let last_line = display_lines[vec::len(display_lines) - 1u];
|
||||
let s = #fmt[~"%s:%u ", fm.name, last_line + 1u];
|
||||
let s = #fmt["%s:%u ", fm.name, last_line + 1u];
|
||||
let indent = str::char_len(s);
|
||||
let out = ~"";
|
||||
while indent > 0u { out += ~" "; indent -= 1u; }
|
||||
out += ~"...\n";
|
||||
let out = "";
|
||||
while indent > 0u { out += " "; indent -= 1u; }
|
||||
out += "...\n";
|
||||
io::stdout().write_str(out);
|
||||
}
|
||||
|
||||
|
@ -173,34 +171,34 @@ fn maybe_highlight_lines(sp: &option::t<span>, cm: &codemap,
|
|||
|
||||
// indent past |name:## | and the 0-offset column location
|
||||
let left = str::char_len(fm.name) + digits + lo.col + 3u;
|
||||
let s = ~"";
|
||||
let s = "";
|
||||
while left > 0u { str::push_char(s, ' '); left -= 1u; }
|
||||
|
||||
s += ~"^";
|
||||
s += "^";
|
||||
let hi = lookup_char_pos(cm, option::get(sp).hi);
|
||||
if hi.col != lo.col {
|
||||
// the ^ already takes up one space
|
||||
let width = hi.col - lo.col - 1u;
|
||||
while width > 0u { str::push_char(s, '~'); width -= 1u; }
|
||||
}
|
||||
io::stdout().write_str(s + ~"\n");
|
||||
io::stdout().write_str(s + "\n");
|
||||
}
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_warning(sp: &option::t<span>, msg: &istr, cm: &codemap) {
|
||||
emit_diagnostic(sp, msg, ~"warning", 11u8, cm);
|
||||
fn emit_warning(sp: &option::t<span>, msg: &str, cm: &codemap) {
|
||||
emit_diagnostic(sp, msg, "warning", 11u8, cm);
|
||||
}
|
||||
fn emit_error(sp: &option::t<span>, msg: &istr, cm: &codemap) {
|
||||
emit_diagnostic(sp, msg, ~"error", 9u8, cm);
|
||||
fn emit_error(sp: &option::t<span>, msg: &str, cm: &codemap) {
|
||||
emit_diagnostic(sp, msg, "error", 9u8, cm);
|
||||
}
|
||||
fn emit_note(sp: &option::t<span>, msg: &istr, cm: &codemap) {
|
||||
emit_diagnostic(sp, msg, ~"note", 10u8, cm);
|
||||
fn emit_note(sp: &option::t<span>, msg: &str, cm: &codemap) {
|
||||
emit_diagnostic(sp, msg, "note", 10u8, cm);
|
||||
}
|
||||
|
||||
type file_lines = {name: istr, lines: [uint]};
|
||||
type file_lines = {name: str, lines: [uint]};
|
||||
|
||||
fn span_to_lines(sp: span, cm: codemap::codemap) -> @file_lines {
|
||||
let lo = lookup_char_pos(cm, sp.lo);
|
||||
|
@ -212,7 +210,7 @@ fn span_to_lines(sp: span, cm: codemap::codemap) -> @file_lines {
|
|||
ret @{name: lo.filename, lines: lines};
|
||||
}
|
||||
|
||||
fn get_line(fm: filemap, line: int, file: &istr) -> istr {
|
||||
fn get_line(fm: filemap, line: int, file: &str) -> str {
|
||||
let begin: uint = fm.lines[line].byte - fm.start_pos.byte;
|
||||
let end: uint;
|
||||
if line as uint < vec::len(fm.lines) - 1u {
|
||||
|
@ -229,10 +227,8 @@ fn get_line(fm: filemap, line: int, file: &istr) -> istr {
|
|||
ret str::slice(file, begin, end);
|
||||
}
|
||||
|
||||
fn get_filemap(cm: codemap, filename: istr) -> filemap {
|
||||
for fm: filemap in cm.files {
|
||||
if fm.name == filename { ret fm; }
|
||||
}
|
||||
fn get_filemap(cm: codemap, filename: str) -> filemap {
|
||||
for fm: filemap in cm.files { if fm.name == filename { ret fm; } }
|
||||
//XXjdm the following triggers a mismatched type bug
|
||||
// (or expected function, found _|_)
|
||||
fail; // ("asking for " + filename + " which we don't know about");
|
||||
|
|
|
@ -8,10 +8,10 @@ import std::map::new_str_hash;
|
|||
import codemap;
|
||||
|
||||
type syntax_expander =
|
||||
fn(&ext_ctxt, span, @ast::expr, &option::t<istr>) -> @ast::expr;
|
||||
type macro_def = {ident: istr, ext: syntax_extension};
|
||||
fn(&ext_ctxt, span, @ast::expr, &option::t<str>) -> @ast::expr;
|
||||
type macro_def = {ident: str, ext: syntax_extension};
|
||||
type macro_definer =
|
||||
fn(&ext_ctxt, span, @ast::expr, &option::t<istr>) -> macro_def;
|
||||
fn(&ext_ctxt, span, @ast::expr, &option::t<str>) -> macro_def;
|
||||
|
||||
tag syntax_extension {
|
||||
normal(syntax_expander);
|
||||
|
@ -20,25 +20,25 @@ tag syntax_extension {
|
|||
|
||||
// A temporary hard-coded map of methods for expanding syntax extension
|
||||
// AST nodes into full ASTs
|
||||
fn syntax_expander_table() -> hashmap<istr, syntax_extension> {
|
||||
fn syntax_expander_table() -> hashmap<str, syntax_extension> {
|
||||
let syntax_expanders = new_str_hash::<syntax_extension>();
|
||||
syntax_expanders.insert(~"fmt", normal(ext::fmt::expand_syntax_ext));
|
||||
syntax_expanders.insert(~"env", normal(ext::env::expand_syntax_ext));
|
||||
syntax_expanders.insert(~"macro",
|
||||
syntax_expanders.insert("fmt", normal(ext::fmt::expand_syntax_ext));
|
||||
syntax_expanders.insert("env", normal(ext::env::expand_syntax_ext));
|
||||
syntax_expanders.insert("macro",
|
||||
macro_defining(ext::simplext::add_new_extension));
|
||||
syntax_expanders.insert(~"concat_idents",
|
||||
syntax_expanders.insert("concat_idents",
|
||||
normal(ext::concat_idents::expand_syntax_ext));
|
||||
syntax_expanders.insert(~"ident_to_str",
|
||||
syntax_expanders.insert("ident_to_str",
|
||||
normal(ext::ident_to_str::expand_syntax_ext));
|
||||
syntax_expanders.insert(~"log_syntax",
|
||||
syntax_expanders.insert("log_syntax",
|
||||
normal(ext::log_syntax::expand_syntax_ext));
|
||||
ret syntax_expanders;
|
||||
}
|
||||
|
||||
obj ext_ctxt(sess: @session,
|
||||
crate_file_name_hack: istr,
|
||||
crate_file_name_hack: str,
|
||||
mutable backtrace: codemap::opt_span) {
|
||||
fn crate_file_name() -> istr { ret crate_file_name_hack; }
|
||||
fn crate_file_name() -> str { ret crate_file_name_hack; }
|
||||
|
||||
fn session() -> @session { ret sess; }
|
||||
|
||||
|
@ -58,30 +58,27 @@ obj ext_ctxt(sess: @session,
|
|||
let tmp = pre;
|
||||
backtrace = tmp;
|
||||
}
|
||||
_ { self.bug(~"tried to pop without a push"); }
|
||||
_ { self.bug("tried to pop without a push"); }
|
||||
}
|
||||
}
|
||||
|
||||
fn span_fatal(sp: span, msg: istr) -> ! {
|
||||
fn span_fatal(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
sess.span_fatal(sp, msg);
|
||||
}
|
||||
fn span_err(sp: span, msg: istr) {
|
||||
fn span_err(sp: span, msg: str) {
|
||||
self.print_backtrace();
|
||||
sess.span_err(sp, msg);
|
||||
}
|
||||
fn span_unimpl(sp: span, msg: istr) -> ! {
|
||||
fn span_unimpl(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
sess.span_unimpl(sp, msg);
|
||||
}
|
||||
fn span_bug(sp: span, msg: istr) -> ! {
|
||||
fn span_bug(sp: span, msg: str) -> ! {
|
||||
self.print_backtrace();
|
||||
sess.span_bug(sp, msg);
|
||||
}
|
||||
fn bug(msg: istr) -> ! {
|
||||
self.print_backtrace();
|
||||
sess.bug(msg);
|
||||
}
|
||||
fn bug(msg: str) -> ! { self.print_backtrace(); sess.bug(msg); }
|
||||
fn next_id() -> ast::node_id { ret sess.next_node_id(); }
|
||||
|
||||
}
|
||||
|
@ -96,11 +93,10 @@ fn mk_ctxt(sess: &session) -> ext_ctxt {
|
|||
// super-ugly and needs a better solution.
|
||||
let crate_file_name_hack = sess.get_codemap().files[0].name;
|
||||
|
||||
ret ext_ctxt(@sess, crate_file_name_hack,
|
||||
codemap::os_none);
|
||||
ret ext_ctxt(@sess, crate_file_name_hack, codemap::os_none);
|
||||
}
|
||||
|
||||
fn expr_to_str(cx: &ext_ctxt, expr: @ast::expr, error: &istr) -> istr {
|
||||
fn expr_to_str(cx: &ext_ctxt, expr: @ast::expr, error: &str) -> str {
|
||||
alt expr.node {
|
||||
ast::expr_lit(l) {
|
||||
alt l.node {
|
||||
|
@ -112,8 +108,7 @@ fn expr_to_str(cx: &ext_ctxt, expr: @ast::expr, error: &istr) -> istr {
|
|||
}
|
||||
}
|
||||
|
||||
fn expr_to_ident(cx: &ext_ctxt, expr: @ast::expr,
|
||||
error: &istr) -> ast::ident {
|
||||
fn expr_to_ident(cx: &ext_ctxt, expr: @ast::expr, error: &str) -> ast::ident {
|
||||
alt expr.node {
|
||||
ast::expr_path(p) {
|
||||
if vec::len(p.node.types) > 0u || vec::len(p.node.idents) != 1u {
|
||||
|
|
|
@ -3,17 +3,17 @@ import base::*;
|
|||
import syntax::ast;
|
||||
|
||||
fn expand_syntax_ext(cx: &ext_ctxt, sp: codemap::span, arg: @ast::expr,
|
||||
_body: &option::t<istr>) -> @ast::expr {
|
||||
_body: &option::t<str>) -> @ast::expr {
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp, ~"#concat_idents requires a vector argument .")
|
||||
cx.span_fatal(sp, "#concat_idents requires a vector argument .")
|
||||
}
|
||||
};
|
||||
let res: ast::ident = ~"";
|
||||
let res: ast::ident = "";
|
||||
for e: @ast::expr in args {
|
||||
res += expr_to_ident(cx, e, ~"expected an ident");
|
||||
res += expr_to_ident(cx, e, "expected an ident");
|
||||
}
|
||||
|
||||
ret @{id: cx.next_id(),
|
||||
|
|
|
@ -12,30 +12,28 @@ import base::*;
|
|||
export expand_syntax_ext;
|
||||
|
||||
fn expand_syntax_ext(cx: &ext_ctxt, sp: codemap::span, arg: @ast::expr,
|
||||
_body: &option::t<istr>) -> @ast::expr {
|
||||
_body: &option::t<str>) -> @ast::expr {
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp, ~"#env requires arguments of the form `[...]`.")
|
||||
cx.span_fatal(sp, "#env requires arguments of the form `[...]`.")
|
||||
}
|
||||
};
|
||||
if vec::len::<@ast::expr>(args) != 1u {
|
||||
cx.span_fatal(sp, ~"malformed #env call");
|
||||
cx.span_fatal(sp, "malformed #env call");
|
||||
}
|
||||
// FIXME: if this was more thorough it would manufacture an
|
||||
// option::t<str> rather than just an maybe-empty string.
|
||||
|
||||
let var = expr_to_str(cx, args[0], ~"#env requires a string");
|
||||
let var = expr_to_str(cx, args[0], "#env requires a string");
|
||||
alt generic_os::getenv(var) {
|
||||
option::none. { ret make_new_str(cx, sp, ~""); }
|
||||
option::some(s) {
|
||||
ret make_new_str(cx, sp, s);
|
||||
}
|
||||
option::none. { ret make_new_str(cx, sp, ""); }
|
||||
option::some(s) { ret make_new_str(cx, sp, s); }
|
||||
}
|
||||
}
|
||||
|
||||
fn make_new_str(cx: &ext_ctxt, sp: codemap::span, s: &istr) -> @ast::expr {
|
||||
fn make_new_str(cx: &ext_ctxt, sp: codemap::span, s: &str) -> @ast::expr {
|
||||
ret make_new_lit(cx, sp, ast::lit_str(s));
|
||||
}
|
||||
//
|
||||
|
|
|
@ -15,7 +15,7 @@ import syntax::fold::*;
|
|||
import syntax::ext::base::*;
|
||||
|
||||
|
||||
fn expand_expr(exts: &hashmap<istr, syntax_extension>, cx: &ext_ctxt,
|
||||
fn expand_expr(exts: &hashmap<str, syntax_extension>, cx: &ext_ctxt,
|
||||
e: &expr_, fld: ast_fold, orig: &fn(&expr_, ast_fold) -> expr_)
|
||||
-> expr_ {
|
||||
ret alt e {
|
||||
|
@ -27,8 +27,7 @@ fn expand_expr(exts: &hashmap<istr, syntax_extension>, cx: &ext_ctxt,
|
|||
alt exts.find(extname) {
|
||||
none. {
|
||||
cx.span_fatal(pth.span,
|
||||
#fmt["macro undefined: '%s'",
|
||||
extname])
|
||||
#fmt["macro undefined: '%s'", extname])
|
||||
}
|
||||
some(normal(ext)) {
|
||||
let expanded = ext(cx, pth.span, args, body);
|
||||
|
@ -42,14 +41,12 @@ fn expand_expr(exts: &hashmap<istr, syntax_extension>, cx: &ext_ctxt,
|
|||
}
|
||||
some(macro_defining(ext)) {
|
||||
let named_extension = ext(cx, pth.span, args, body);
|
||||
exts.insert(
|
||||
named_extension.ident,
|
||||
named_extension.ext);
|
||||
exts.insert(named_extension.ident, named_extension.ext);
|
||||
ast::expr_rec([], none)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ { cx.span_bug(mac.span, ~"naked syntactic bit") }
|
||||
_ { cx.span_bug(mac.span, "naked syntactic bit") }
|
||||
}
|
||||
}
|
||||
_ { orig(e, fld) }
|
||||
|
|
|
@ -16,26 +16,24 @@ import codemap::span;
|
|||
export expand_syntax_ext;
|
||||
|
||||
fn expand_syntax_ext(cx: &ext_ctxt, sp: span, arg: @ast::expr,
|
||||
_body: &option::t<istr>) -> @ast::expr {
|
||||
_body: &option::t<str>) -> @ast::expr {
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(
|
||||
sp, ~"#fmt requires arguments of the form `[...]`.")
|
||||
cx.span_fatal(sp, "#fmt requires arguments of the form `[...]`.")
|
||||
}
|
||||
};
|
||||
if vec::len::<@ast::expr>(args) == 0u {
|
||||
cx.span_fatal(sp, ~"#fmt requires a format string");
|
||||
cx.span_fatal(sp, "#fmt requires a format string");
|
||||
}
|
||||
let fmt =
|
||||
expr_to_str(cx, args[0],
|
||||
~"first argument to #fmt must be a "
|
||||
+ ~"string literal.");
|
||||
"first argument to #fmt must be a " + "string literal.");
|
||||
let fmtspan = args[0].span;
|
||||
log "Format string:";
|
||||
log fmt;
|
||||
fn parse_fmt_err_(cx: &ext_ctxt, sp: span, msg: &istr) -> ! {
|
||||
fn parse_fmt_err_(cx: &ext_ctxt, sp: span, msg: &str) -> ! {
|
||||
cx.span_fatal(sp, msg);
|
||||
}
|
||||
let parse_fmt_err = bind parse_fmt_err_(cx, fmtspan, _);
|
||||
|
@ -52,7 +50,7 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
let sp_lit = @{node: lit, span: sp};
|
||||
ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
|
||||
}
|
||||
fn make_new_str(cx: &ext_ctxt, sp: span, s: &istr) -> @ast::expr {
|
||||
fn make_new_str(cx: &ext_ctxt, sp: span, s: &str) -> @ast::expr {
|
||||
let lit = ast::lit_str(s);
|
||||
ret make_new_lit(cx, sp, lit);
|
||||
}
|
||||
|
@ -103,14 +101,13 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
}
|
||||
fn make_path_vec(cx: &ext_ctxt, ident: &ast::ident) -> [ast::ident] {
|
||||
fn compiling_std(cx: &ext_ctxt) -> bool {
|
||||
ret str::find(cx.crate_file_name(), ~"std.rc") >= 0;
|
||||
ret str::find(cx.crate_file_name(), "std.rc") >= 0;
|
||||
}
|
||||
if compiling_std(cx) {
|
||||
ret [~"extfmt", ~"rt", ident];
|
||||
} else { ret [~"std", ~"extfmt", ~"rt", ident]; }
|
||||
ret ["extfmt", "rt", ident];
|
||||
} else { ret ["std", "extfmt", "rt", ident]; }
|
||||
}
|
||||
fn make_rt_path_expr(cx: &ext_ctxt, sp: span,
|
||||
ident: &istr) -> @ast::expr {
|
||||
fn make_rt_path_expr(cx: &ext_ctxt, sp: span, ident: &str) -> @ast::expr {
|
||||
let path = make_path_vec(cx, ident);
|
||||
ret make_path_expr(cx, sp, path);
|
||||
}
|
||||
|
@ -123,11 +120,11 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
for f: flag in flags {
|
||||
let fstr;
|
||||
alt f {
|
||||
flag_left_justify. { fstr = ~"flag_left_justify"; }
|
||||
flag_left_zero_pad. { fstr = ~"flag_left_zero_pad"; }
|
||||
flag_space_for_sign. { fstr = ~"flag_space_for_sign"; }
|
||||
flag_sign_always. { fstr = ~"flag_sign_always"; }
|
||||
flag_alternate. { fstr = ~"flag_alternate"; }
|
||||
flag_left_justify. { fstr = "flag_left_justify"; }
|
||||
flag_left_zero_pad. { fstr = "flag_left_zero_pad"; }
|
||||
flag_space_for_sign. { fstr = "flag_space_for_sign"; }
|
||||
flag_sign_always. { fstr = "flag_sign_always"; }
|
||||
flag_alternate. { fstr = "flag_alternate"; }
|
||||
}
|
||||
flagexprs += [make_rt_path_expr(cx, sp, fstr)];
|
||||
}
|
||||
|
@ -136,22 +133,22 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
// this is a hack placeholder flag
|
||||
|
||||
if vec::len::<@ast::expr>(flagexprs) == 0u {
|
||||
flagexprs += [make_rt_path_expr(cx, sp, ~"flag_none")];
|
||||
flagexprs += [make_rt_path_expr(cx, sp, "flag_none")];
|
||||
}
|
||||
ret make_vec_expr(cx, sp, flagexprs);
|
||||
}
|
||||
fn make_count(cx: &ext_ctxt, sp: span, cnt: &count) -> @ast::expr {
|
||||
alt cnt {
|
||||
count_implied. {
|
||||
ret make_rt_path_expr(cx, sp, ~"count_implied");
|
||||
ret make_rt_path_expr(cx, sp, "count_implied");
|
||||
}
|
||||
count_is(c) {
|
||||
let count_lit = make_new_int(cx, sp, c);
|
||||
let count_is_path = make_path_vec(cx, ~"count_is");
|
||||
let count_is_path = make_path_vec(cx, "count_is");
|
||||
let count_is_args = [count_lit];
|
||||
ret make_call(cx, sp, count_is_path, count_is_args);
|
||||
}
|
||||
_ { cx.span_unimpl(sp, ~"unimplemented #fmt conversion"); }
|
||||
_ { cx.span_unimpl(sp, "unimplemented #fmt conversion"); }
|
||||
}
|
||||
}
|
||||
fn make_ty(cx: &ext_ctxt, sp: span, t: &ty) -> @ast::expr {
|
||||
|
@ -159,13 +156,13 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
alt t {
|
||||
ty_hex(c) {
|
||||
alt c {
|
||||
case_upper. { rt_type = ~"ty_hex_upper"; }
|
||||
case_lower. { rt_type = ~"ty_hex_lower"; }
|
||||
case_upper. { rt_type = "ty_hex_upper"; }
|
||||
case_lower. { rt_type = "ty_hex_lower"; }
|
||||
}
|
||||
}
|
||||
ty_bits. { rt_type = ~"ty_bits"; }
|
||||
ty_octal. { rt_type = ~"ty_octal"; }
|
||||
_ { rt_type = ~"ty_default"; }
|
||||
ty_bits. { rt_type = "ty_bits"; }
|
||||
ty_octal. { rt_type = "ty_octal"; }
|
||||
_ { rt_type = "ty_default"; }
|
||||
}
|
||||
ret make_rt_path_expr(cx, sp, rt_type);
|
||||
}
|
||||
|
@ -173,10 +170,10 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
width_expr: @ast::expr, precision_expr: @ast::expr,
|
||||
ty_expr: @ast::expr) -> @ast::expr {
|
||||
ret make_rec_expr(cx, sp,
|
||||
[{ident: ~"flags", ex: flags_expr},
|
||||
{ident: ~"width", ex: width_expr},
|
||||
{ident: ~"precision", ex: precision_expr},
|
||||
{ident: ~"ty", ex: ty_expr}]);
|
||||
[{ident: "flags", ex: flags_expr},
|
||||
{ident: "width", ex: width_expr},
|
||||
{ident: "precision", ex: precision_expr},
|
||||
{ident: "ty", ex: ty_expr}]);
|
||||
}
|
||||
let rt_conv_flags = make_flags(cx, sp, cnv.flags);
|
||||
let rt_conv_width = make_count(cx, sp, cnv.width);
|
||||
|
@ -185,9 +182,9 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
ret make_conv_rec(cx, sp, rt_conv_flags, rt_conv_width,
|
||||
rt_conv_precision, rt_conv_ty);
|
||||
}
|
||||
fn make_conv_call(cx: &ext_ctxt, sp: span, conv_type: &istr,
|
||||
cnv: &conv, arg: @ast::expr) -> @ast::expr {
|
||||
let fname = ~"conv_" + conv_type;
|
||||
fn make_conv_call(cx: &ext_ctxt, sp: span, conv_type: &str, cnv: &conv,
|
||||
arg: @ast::expr) -> @ast::expr {
|
||||
let fname = "conv_" + conv_type;
|
||||
let path = make_path_vec(cx, fname);
|
||||
let cnv_expr = make_rt_conv_expr(cx, sp, cnv);
|
||||
let args = [cnv_expr, arg];
|
||||
|
@ -205,7 +202,7 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
_ { ret false; }
|
||||
}
|
||||
}
|
||||
let unsupported = ~"conversion not supported in #fmt string";
|
||||
let unsupported = "conversion not supported in #fmt string";
|
||||
alt cnv.param {
|
||||
option::none. { }
|
||||
_ { cx.span_unimpl(sp, unsupported); }
|
||||
|
@ -216,15 +213,15 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
flag_sign_always. {
|
||||
if !is_signed_type(cnv) {
|
||||
cx.span_fatal(sp,
|
||||
~"+ flag only valid in " +
|
||||
~"signed #fmt conversion");
|
||||
"+ flag only valid in " +
|
||||
"signed #fmt conversion");
|
||||
}
|
||||
}
|
||||
flag_space_for_sign. {
|
||||
if !is_signed_type(cnv) {
|
||||
cx.span_fatal(sp,
|
||||
~"space flag only valid in " +
|
||||
~"signed #fmt conversions");
|
||||
"space flag only valid in " +
|
||||
"signed #fmt conversions");
|
||||
}
|
||||
}
|
||||
flag_left_zero_pad. { }
|
||||
|
@ -242,28 +239,26 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
_ { cx.span_unimpl(sp, unsupported); }
|
||||
}
|
||||
alt cnv.ty {
|
||||
ty_str. { ret make_conv_call(cx, arg.span, ~"str", cnv, arg); }
|
||||
ty_str. { ret make_conv_call(cx, arg.span, "str", cnv, arg); }
|
||||
ty_int(sign) {
|
||||
alt sign {
|
||||
signed. { ret make_conv_call(cx, arg.span, ~"int", cnv, arg); }
|
||||
signed. { ret make_conv_call(cx, arg.span, "int", cnv, arg); }
|
||||
unsigned. {
|
||||
ret make_conv_call(cx, arg.span, ~"uint", cnv, arg);
|
||||
ret make_conv_call(cx, arg.span, "uint", cnv, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
ty_bool. { ret make_conv_call(cx, arg.span, ~"bool", cnv, arg); }
|
||||
ty_char. { ret make_conv_call(cx, arg.span, ~"char", cnv, arg); }
|
||||
ty_hex(_) { ret make_conv_call(cx, arg.span, ~"uint", cnv, arg); }
|
||||
ty_bits. { ret make_conv_call(cx, arg.span, ~"uint", cnv, arg); }
|
||||
ty_octal. { ret make_conv_call(cx, arg.span, ~"uint", cnv, arg); }
|
||||
ty_bool. { ret make_conv_call(cx, arg.span, "bool", cnv, arg); }
|
||||
ty_char. { ret make_conv_call(cx, arg.span, "char", cnv, arg); }
|
||||
ty_hex(_) { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
|
||||
ty_bits. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
|
||||
ty_octal. { ret make_conv_call(cx, arg.span, "uint", cnv, arg); }
|
||||
_ { cx.span_unimpl(sp, unsupported); }
|
||||
}
|
||||
}
|
||||
fn log_conv(c: conv) {
|
||||
alt c.param {
|
||||
some(p) {
|
||||
log ~"param: " + std::int::to_str(p, 10u);
|
||||
}
|
||||
some(p) { log "param: " + std::int::to_str(p, 10u); }
|
||||
_ { log "param: none"; }
|
||||
}
|
||||
for f: flag in c.flags {
|
||||
|
@ -276,21 +271,17 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
}
|
||||
}
|
||||
alt c.width {
|
||||
count_is(i) { log ~"width: count is "
|
||||
+ std::int::to_str(i, 10u); }
|
||||
count_is(i) { log "width: count is " + std::int::to_str(i, 10u); }
|
||||
count_is_param(i) {
|
||||
log ~"width: count is param "
|
||||
+ std::int::to_str(i, 10u);
|
||||
log "width: count is param " + std::int::to_str(i, 10u);
|
||||
}
|
||||
count_is_next_param. { log "width: count is next param"; }
|
||||
count_implied. { log "width: count is implied"; }
|
||||
}
|
||||
alt c.precision {
|
||||
count_is(i) { log ~"prec: count is "
|
||||
+ std::int::to_str(i, 10u); }
|
||||
count_is(i) { log "prec: count is " + std::int::to_str(i, 10u); }
|
||||
count_is_param(i) {
|
||||
log ~"prec: count is param "
|
||||
+ std::int::to_str(i, 10u);
|
||||
log "prec: count is param " + std::int::to_str(i, 10u);
|
||||
}
|
||||
count_is_next_param. { log "prec: count is next param"; }
|
||||
count_implied. { log "prec: count is implied"; }
|
||||
|
@ -317,7 +308,7 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
}
|
||||
let fmt_sp = args[0].span;
|
||||
let n = 0u;
|
||||
let tmp_expr = make_new_str(cx, sp, ~"");
|
||||
let tmp_expr = make_new_str(cx, sp, "");
|
||||
let nargs = vec::len::<@ast::expr>(args);
|
||||
for pc: piece in pieces {
|
||||
alt pc {
|
||||
|
@ -329,8 +320,8 @@ fn pieces_to_expr(cx: &ext_ctxt, sp: span, pieces: &[piece],
|
|||
n += 1u;
|
||||
if n >= nargs {
|
||||
cx.span_fatal(sp,
|
||||
~"not enough arguments to #fmt " +
|
||||
~"for the given format string");
|
||||
"not enough arguments to #fmt " +
|
||||
"for the given format string");
|
||||
}
|
||||
log "Building conversion:";
|
||||
log_conv(conv);
|
||||
|
|
|
@ -5,20 +5,20 @@ import base::*;
|
|||
import syntax::ast;
|
||||
|
||||
fn expand_syntax_ext(cx: &ext_ctxt, sp: codemap::span, arg: @ast::expr,
|
||||
_body: &option::t<istr>) -> @ast::expr {
|
||||
_body: &option::t<str>) -> @ast::expr {
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp, ~"#ident_to_str requires a vector argument .")
|
||||
cx.span_fatal(sp, "#ident_to_str requires a vector argument .")
|
||||
}
|
||||
};
|
||||
if vec::len::<@ast::expr>(args) != 1u {
|
||||
cx.span_fatal(sp, ~"malformed #ident_to_str call");
|
||||
cx.span_fatal(sp, "malformed #ident_to_str call");
|
||||
}
|
||||
|
||||
ret make_new_lit(cx, sp,
|
||||
ast::lit_str(expr_to_ident(cx, args[0u],
|
||||
~"expected an ident")));
|
||||
"expected an ident")));
|
||||
|
||||
}
|
||||
|
|
|
@ -4,11 +4,10 @@ import syntax::ast;
|
|||
import std::str;
|
||||
|
||||
fn expand_syntax_ext(cx: &ext_ctxt, sp: codemap::span, arg: @ast::expr,
|
||||
_body: &option::t<istr>) -> @ast::expr {
|
||||
_body: &option::t<str>) -> @ast::expr {
|
||||
|
||||
cx.print_backtrace();
|
||||
std::io::stdout().write_line(
|
||||
print::pprust::expr_to_str(arg));
|
||||
std::io::stdout().write_line(print::pprust::expr_to_str(arg));
|
||||
|
||||
//trivial expression
|
||||
ret @{id: cx.next_id(), node: ast::expr_rec([], option::none), span: sp};
|
||||
|
|
|
@ -57,29 +57,29 @@ tag matchable {
|
|||
}
|
||||
|
||||
/* for when given an incompatible bit of AST */
|
||||
fn match_error(cx: &ext_ctxt, m: &matchable, expected: &istr) -> ! {
|
||||
fn match_error(cx: &ext_ctxt, m: &matchable, expected: &str) -> ! {
|
||||
alt m {
|
||||
match_expr(x) {
|
||||
cx.span_fatal(x.span,
|
||||
~"this argument is an expr, expected " + expected);
|
||||
"this argument is an expr, expected " + expected);
|
||||
}
|
||||
match_path(x) {
|
||||
cx.span_fatal(x.span,
|
||||
~"this argument is a path, expected " + expected);
|
||||
"this argument is a path, expected " + expected);
|
||||
}
|
||||
match_ident(x) {
|
||||
cx.span_fatal(x.span,
|
||||
~"this argument is an ident, expected " + expected);
|
||||
"this argument is an ident, expected " + expected);
|
||||
}
|
||||
match_ty(x) {
|
||||
cx.span_fatal(x.span,
|
||||
~"this argument is a type, expected " + expected);
|
||||
"this argument is a type, expected " + expected);
|
||||
}
|
||||
match_block(x) {
|
||||
cx.span_fatal(x.span,
|
||||
~"this argument is a block, expected " + expected);
|
||||
"this argument is a block, expected " + expected);
|
||||
}
|
||||
match_exact. { cx.bug(~"what is a match_exact doing in a bindings?"); }
|
||||
match_exact. { cx.bug("what is a match_exact doing in a bindings?"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ fn elts_to_ell(cx: &ext_ctxt, elts: &[@expr]) ->
|
|||
alt m.node {
|
||||
ast::mac_ellipsis. {
|
||||
if res != none {
|
||||
cx.span_fatal(m.span, ~"only one ellipsis allowed");
|
||||
cx.span_fatal(m.span, "only one ellipsis allowed");
|
||||
}
|
||||
res =
|
||||
some({pre: vec::slice(elts, 0u, idx - 1u),
|
||||
|
@ -190,8 +190,7 @@ fn use_selectors_to_bind(b: &binders, e: @expr) -> option::t<bindings> {
|
|||
alt sel(match_expr(e)) { none. { ret none; } _ { } }
|
||||
}
|
||||
let never_mind: bool = false;
|
||||
for each pair: @{key: ident,
|
||||
val: selector} in b.real_binders.items() {
|
||||
for each pair: @{key: ident, val: selector} in b.real_binders.items() {
|
||||
alt pair.val(match_expr(e)) {
|
||||
none. { never_mind = true; }
|
||||
some(mtc) { res.insert(pair.key, mtc); }
|
||||
|
@ -252,8 +251,8 @@ fn follow_for_trans(cx: &ext_ctxt, mmaybe: &option::t<arb_depth<matchable>>,
|
|||
ret alt follow(m, idx_path) {
|
||||
seq(_, sp) {
|
||||
cx.span_fatal(sp,
|
||||
~"syntax matched under ... but not " +
|
||||
~"used that way.")
|
||||
"syntax matched under ... but not " +
|
||||
"used that way.")
|
||||
}
|
||||
leaf(m) { ret some(m) }
|
||||
}
|
||||
|
@ -267,9 +266,7 @@ iter free_vars(b: &bindings, e: @expr) -> ident {
|
|||
let idents: hashmap<ident, ()> = new_str_hash::<()>();
|
||||
fn mark_ident(i: &ident, _fld: ast_fold, b: &bindings,
|
||||
idents: &hashmap<ident, ()>) -> ident {
|
||||
if b.contains_key(i) {
|
||||
idents.insert(i, ());
|
||||
}
|
||||
if b.contains_key(i) { idents.insert(i, ()); }
|
||||
ret i;
|
||||
}
|
||||
// using fold is a hack: we want visit, but it doesn't hit idents ) :
|
||||
|
@ -309,13 +306,10 @@ fn transcribe_exprs(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
|
|||
let len = vec::len(*ms);
|
||||
if old_len != len {
|
||||
let msg =
|
||||
#fmt["'%s' occurs %u times, but ",
|
||||
fv, len] +
|
||||
#fmt["'%s' occurs %u times",
|
||||
old_name,
|
||||
#fmt["'%s' occurs %u times, but ", fv, len] +
|
||||
#fmt["'%s' occurs %u times", old_name,
|
||||
old_len];
|
||||
cx.span_fatal(
|
||||
repeat_me.span, msg);
|
||||
cx.span_fatal(repeat_me.span, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,8 +319,8 @@ fn transcribe_exprs(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
|
|||
alt repeat {
|
||||
none. {
|
||||
cx.span_fatal(repeat_me.span,
|
||||
~"'...' surrounds an expression without any" +
|
||||
~" repeating syntax variables");
|
||||
"'...' surrounds an expression without any" +
|
||||
" repeating syntax variables");
|
||||
}
|
||||
some({rep_count: rc, _}) {
|
||||
/* Whew, we now know how how many times to repeat */
|
||||
|
@ -354,7 +348,7 @@ fn transcribe_ident(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
|
|||
i: &ident, _fld: ast_fold) -> ident {
|
||||
ret alt follow_for_trans(cx, b.find(i), idx_path) {
|
||||
some(match_ident(a_id)) { a_id.node }
|
||||
some(m) { match_error(cx, m, ~"an identifier") }
|
||||
some(m) { match_error(cx, m, "an identifier") }
|
||||
none. { i }
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +363,7 @@ fn transcribe_path(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
|
|||
{global: false, idents: [id.node], types: []}
|
||||
}
|
||||
some(match_path(a_pth)) { a_pth.node }
|
||||
some(m) { match_error(cx, m, ~"a path") }
|
||||
some(m) { match_error(cx, m, "a path") }
|
||||
none. { p }
|
||||
}
|
||||
}
|
||||
|
@ -394,7 +388,7 @@ fn transcribe_expr(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
|
|||
}
|
||||
some(match_path(a_pth)) { expr_path(a_pth) }
|
||||
some(match_expr(a_exp)) { a_exp.node }
|
||||
some(m) { match_error(cx, m, ~"an expression") }
|
||||
some(m) { match_error(cx, m, "an expression") }
|
||||
none. { orig(e, fld) }
|
||||
}
|
||||
}
|
||||
|
@ -411,7 +405,7 @@ fn transcribe_type(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
|
|||
some(id) {
|
||||
alt follow_for_trans(cx, b.find(id), idx_path) {
|
||||
some(match_ty(ty)) { ty.node }
|
||||
some(m) { match_error(cx, m, ~"a type") }
|
||||
some(m) { match_error(cx, m, "a type") }
|
||||
none. { orig(t, fld) }
|
||||
}
|
||||
}
|
||||
|
@ -431,14 +425,14 @@ fn transcribe_block(cx: &ext_ctxt, b: &bindings, idx_path: @mutable [uint],
|
|||
orig: fn(&blk_, ast_fold) -> blk_) -> blk_ {
|
||||
ret alt block_to_ident(blk) {
|
||||
some(id) {
|
||||
alt follow_for_trans(cx, b.find(
|
||||
id), idx_path) {
|
||||
alt follow_for_trans(cx, b.find(id), idx_path) {
|
||||
some(match_block(new_blk)) { new_blk.node }
|
||||
|
||||
|
||||
|
||||
// possibly allow promotion of ident/path/expr to blocks?
|
||||
some(m) {
|
||||
match_error(cx, m, ~"a block")
|
||||
match_error(cx, m, "a block")
|
||||
}
|
||||
none. { orig(blk, fld) }
|
||||
}
|
||||
|
@ -469,12 +463,12 @@ fn p_t_s_rec(cx: &ext_ctxt, m: &matchable, s: &selector, b: &binders) {
|
|||
|
||||
if vec::len(post) > 0u {
|
||||
cx.span_unimpl(e.span,
|
||||
~"matching after `...` not yet supported");
|
||||
"matching after `...` not yet supported");
|
||||
}
|
||||
}
|
||||
{pre: pre, rep: none., post: post} {
|
||||
if post != [] {
|
||||
cx.bug(~"elts_to_ell provided an invalid result");
|
||||
cx.bug("elts_to_ell provided an invalid result");
|
||||
}
|
||||
p_t_s_r_length(cx, vec::len(pre), false, s, b);
|
||||
p_t_s_r_actual_vector(cx, pre, false, s, b);
|
||||
|
@ -483,6 +477,7 @@ fn p_t_s_rec(cx: &ext_ctxt, m: &matchable, s: &selector, b: &binders) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* TODO: handle embedded types and blocks, at least */
|
||||
expr_mac(mac) {
|
||||
p_t_s_r_mac(cx, mac, s, b);
|
||||
|
@ -494,7 +489,7 @@ fn p_t_s_rec(cx: &ext_ctxt, m: &matchable, s: &selector, b: &binders) {
|
|||
match_expr(e) {
|
||||
if e == pat { some(leaf(match_exact)) } else { none }
|
||||
}
|
||||
_ { cx.bug(~"broken traversal in p_t_s_r") }
|
||||
_ { cx.bug("broken traversal in p_t_s_r") }
|
||||
}
|
||||
}
|
||||
b.literal_ast_matchers += [bind select(cx, _, e)];
|
||||
|
@ -530,14 +525,13 @@ fn p_t_s_r_path(cx: &ext_ctxt, p: &path, s: &selector, b: &binders) {
|
|||
fn select(cx: &ext_ctxt, m: &matchable) -> match_result {
|
||||
ret alt m {
|
||||
match_expr(e) { some(leaf(specialize_match(m))) }
|
||||
_ { cx.bug(~"broken traversal in p_t_s_r") }
|
||||
_ { cx.bug("broken traversal in p_t_s_r") }
|
||||
}
|
||||
}
|
||||
if b.real_binders.contains_key(p_id) {
|
||||
cx.span_fatal(p.span, ~"duplicate binding identifier");
|
||||
cx.span_fatal(p.span, "duplicate binding identifier");
|
||||
}
|
||||
b.real_binders.insert(p_id,
|
||||
compose_sels(s, bind select(cx, _)));
|
||||
b.real_binders.insert(p_id, compose_sels(s, bind select(cx, _)));
|
||||
}
|
||||
none. { }
|
||||
}
|
||||
|
@ -560,16 +554,15 @@ fn p_t_s_r_mac(cx: &ext_ctxt, mac: &ast::mac, s: &selector, b: &binders) {
|
|||
match_expr(e) {
|
||||
alt e.node { expr_mac(mac) { fn_m(mac) } _ { none } }
|
||||
}
|
||||
_ { cx.bug(~"broken traversal in p_t_s_r") }
|
||||
_ { cx.bug("broken traversal in p_t_s_r") }
|
||||
}
|
||||
}
|
||||
fn no_des(cx: &ext_ctxt, sp: &span, syn: &istr) -> ! {
|
||||
cx.span_fatal(sp, ~"destructuring "
|
||||
+ syn + ~" is not yet supported");
|
||||
fn no_des(cx: &ext_ctxt, sp: &span, syn: &str) -> ! {
|
||||
cx.span_fatal(sp, "destructuring " + syn + " is not yet supported");
|
||||
}
|
||||
alt mac.node {
|
||||
ast::mac_ellipsis. { cx.span_fatal(mac.span, ~"misused `...`"); }
|
||||
ast::mac_invoc(_, _, _) { no_des(cx, mac.span, ~"macro calls"); }
|
||||
ast::mac_ellipsis. { cx.span_fatal(mac.span, "misused `...`"); }
|
||||
ast::mac_invoc(_, _, _) { no_des(cx, mac.span, "macro calls"); }
|
||||
ast::mac_embed_type(ty) {
|
||||
alt ty.node {
|
||||
ast::ty_path(pth, _) {
|
||||
|
@ -583,13 +576,12 @@ fn p_t_s_r_mac(cx: &ext_ctxt, mac: &ast::mac, s: &selector, b: &binders) {
|
|||
}
|
||||
}
|
||||
let final_step = bind select_pt_1(cx, _, select_pt_2);
|
||||
b.real_binders.insert(
|
||||
id, compose_sels(s, final_step));
|
||||
b.real_binders.insert(id, compose_sels(s, final_step));
|
||||
}
|
||||
none. { no_des(cx, pth.span, ~"under `#<>`"); }
|
||||
none. { no_des(cx, pth.span, "under `#<>`"); }
|
||||
}
|
||||
}
|
||||
_ { no_des(cx, ty.span, ~"under `#<>`"); }
|
||||
_ { no_des(cx, ty.span, "under `#<>`"); }
|
||||
}
|
||||
}
|
||||
ast::mac_embed_block(blk) {
|
||||
|
@ -604,10 +596,9 @@ fn p_t_s_r_mac(cx: &ext_ctxt, mac: &ast::mac, s: &selector, b: &binders) {
|
|||
}
|
||||
}
|
||||
let final_step = bind select_pt_1(cx, _, select_pt_2);
|
||||
b.real_binders.insert(id,
|
||||
compose_sels(s, final_step));
|
||||
b.real_binders.insert(id, compose_sels(s, final_step));
|
||||
}
|
||||
none. { no_des(cx, blk.span, ~"under `#{}`"); }
|
||||
none. { no_des(cx, blk.span, "under `#{}`"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -635,7 +626,7 @@ fn p_t_s_r_ellipses(cx: &ext_ctxt, repeat_me: @expr, offset: uint,
|
|||
_ { none }
|
||||
}
|
||||
}
|
||||
_ { cx.bug(~"broken traversal in p_t_s_r") }
|
||||
_ { cx.bug("broken traversal in p_t_s_r") }
|
||||
}
|
||||
}
|
||||
p_t_s_rec(cx, match_expr(repeat_me),
|
||||
|
@ -680,7 +671,7 @@ fn p_t_s_r_actual_vector(cx: &ext_ctxt, elts: [@expr], _repeat_after: bool,
|
|||
_ { none }
|
||||
}
|
||||
}
|
||||
_ { cx.bug(~"broken traversal in p_t_s_r") }
|
||||
_ { cx.bug("broken traversal in p_t_s_r") }
|
||||
}
|
||||
}
|
||||
p_t_s_rec(cx, match_expr(elts[idx]),
|
||||
|
@ -690,25 +681,25 @@ fn p_t_s_r_actual_vector(cx: &ext_ctxt, elts: [@expr], _repeat_after: bool,
|
|||
}
|
||||
|
||||
fn add_new_extension(cx: &ext_ctxt, sp: span, arg: @expr,
|
||||
_body: &option::t<istr>) -> base::macro_def {
|
||||
_body: &option::t<str>) -> base::macro_def {
|
||||
let args: [@ast::expr] =
|
||||
alt arg.node {
|
||||
ast::expr_vec(elts, _) { elts }
|
||||
_ {
|
||||
cx.span_fatal(sp,
|
||||
~"#macro requires arguments of the form `[...]`.")
|
||||
"#macro requires arguments of the form `[...]`.")
|
||||
}
|
||||
};
|
||||
|
||||
let macro_name: option::t<istr> = none;
|
||||
let macro_name: option::t<str> = none;
|
||||
let clauses: [@clause] = [];
|
||||
for arg: @expr in args {
|
||||
alt arg.node {
|
||||
expr_vec(elts, mut) {
|
||||
if vec::len(elts) != 2u {
|
||||
cx.span_fatal((*arg).span,
|
||||
~"extension clause must consist of [" +
|
||||
~"macro invocation, expansion body]");
|
||||
"extension clause must consist of [" +
|
||||
"macro invocation, expansion body]");
|
||||
}
|
||||
|
||||
|
||||
|
@ -723,15 +714,15 @@ fn add_new_extension(cx: &ext_ctxt, sp: span, arg: @expr,
|
|||
some(other_id) {
|
||||
if id != other_id {
|
||||
cx.span_fatal(pth.span,
|
||||
~"macro name must be " +
|
||||
~"consistent");
|
||||
"macro name must be " +
|
||||
"consistent");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
none. {
|
||||
cx.span_fatal(pth.span,
|
||||
~"macro name must not be a path");
|
||||
"macro name must not be a path");
|
||||
}
|
||||
}
|
||||
clauses +=
|
||||
|
@ -744,14 +735,14 @@ fn add_new_extension(cx: &ext_ctxt, sp: span, arg: @expr,
|
|||
}
|
||||
_ {
|
||||
cx.span_fatal(elts[0u].span,
|
||||
~"extension clause must" +
|
||||
~" start with a macro invocation.");
|
||||
"extension clause must" +
|
||||
" start with a macro invocation.");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ {
|
||||
cx.span_fatal((*arg).span,
|
||||
~"extension must be [clause, " + ~" ...]");
|
||||
"extension must be [clause, " + " ...]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -763,22 +754,22 @@ fn add_new_extension(cx: &ext_ctxt, sp: span, arg: @expr,
|
|||
some(id) { id }
|
||||
none. {
|
||||
cx.span_fatal(sp,
|
||||
~"macro definition must have " +
|
||||
~"at least one clause")
|
||||
"macro definition must have " +
|
||||
"at least one clause")
|
||||
}
|
||||
},
|
||||
ext: normal(ext)};
|
||||
|
||||
fn generic_extension(cx: &ext_ctxt, sp: span, arg: @expr,
|
||||
_body: &option::t<istr>,
|
||||
clauses: [@clause]) -> @expr {
|
||||
_body: &option::t<str>, clauses: [@clause]) ->
|
||||
@expr {
|
||||
for c: @clause in clauses {
|
||||
alt use_selectors_to_bind(c.params, arg) {
|
||||
some(bindings) { ret transcribe(cx, bindings, c.body) }
|
||||
none. { cont; }
|
||||
}
|
||||
}
|
||||
cx.span_fatal(sp, ~"no clauses match macro invocation");
|
||||
cx.span_fatal(sp, "no clauses match macro invocation");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,15 +19,14 @@ tag eval_mode { mode_depend; mode_parse; }
|
|||
type ctx =
|
||||
@{p: parser,
|
||||
mode: eval_mode,
|
||||
mutable deps: [istr],
|
||||
mutable deps: [str],
|
||||
sess: parser::parse_sess,
|
||||
mutable chpos: uint,
|
||||
mutable byte_pos: uint,
|
||||
cfg: ast::crate_cfg};
|
||||
|
||||
fn eval_crate_directives(cx: ctx, cdirs: &[@ast::crate_directive],
|
||||
prefix: &istr,
|
||||
view_items: &mutable [@ast::view_item],
|
||||
prefix: &str, view_items: &mutable [@ast::view_item],
|
||||
items: &mutable [@ast::item]) {
|
||||
for sub_cdir: @ast::crate_directive in cdirs {
|
||||
eval_crate_directive(cx, sub_cdir, prefix, view_items, items);
|
||||
|
@ -35,34 +34,27 @@ fn eval_crate_directives(cx: ctx, cdirs: &[@ast::crate_directive],
|
|||
}
|
||||
|
||||
fn eval_crate_directives_to_mod(cx: ctx, cdirs: &[@ast::crate_directive],
|
||||
prefix: &istr) -> ast::_mod {
|
||||
prefix: &str) -> ast::_mod {
|
||||
let view_items: [@ast::view_item] = [];
|
||||
let items: [@ast::item] = [];
|
||||
eval_crate_directives(cx, cdirs, prefix, view_items, items);
|
||||
ret {view_items: view_items, items: items};
|
||||
}
|
||||
|
||||
fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &istr,
|
||||
fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &str,
|
||||
view_items: &mutable [@ast::view_item],
|
||||
items: &mutable [@ast::item]) {
|
||||
alt cdir.node {
|
||||
ast::cdir_src_mod(id, file_opt, attrs) {
|
||||
let file_path = id + ~".rs";
|
||||
alt file_opt {
|
||||
some(f) {
|
||||
file_path = f;
|
||||
}
|
||||
none. { }
|
||||
}
|
||||
let full_path = if std::fs::path_is_absolute(file_path) {
|
||||
file_path
|
||||
} else {
|
||||
prefix + std::fs::path_sep() + file_path
|
||||
};
|
||||
let file_path = id + ".rs";
|
||||
alt file_opt { some(f) { file_path = f; } none. { } }
|
||||
let full_path =
|
||||
if std::fs::path_is_absolute(file_path) {
|
||||
file_path
|
||||
} else { prefix + std::fs::path_sep() + file_path };
|
||||
if cx.mode == mode_depend { cx.deps += [full_path]; ret; }
|
||||
let p0 =
|
||||
new_parser_from_file(cx.sess, cx.cfg,
|
||||
full_path, cx.chpos,
|
||||
new_parser_from_file(cx.sess, cx.cfg, full_path, cx.chpos,
|
||||
cx.byte_pos, SOURCE_FILE);
|
||||
let inner_attrs = parse_inner_attrs_and_next(p0);
|
||||
let mod_attrs = attrs + inner_attrs.inner;
|
||||
|
@ -79,18 +71,11 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &istr,
|
|||
}
|
||||
ast::cdir_dir_mod(id, dir_opt, cdirs, attrs) {
|
||||
let path = id;
|
||||
alt dir_opt {
|
||||
some(d) {
|
||||
path = d;
|
||||
}
|
||||
none. { }
|
||||
}
|
||||
alt dir_opt { some(d) { path = d; } none. { } }
|
||||
let full_path =
|
||||
if std::fs::path_is_absolute(path) {
|
||||
path
|
||||
} else {
|
||||
prefix + std::fs::path_sep() + path
|
||||
};
|
||||
} else { prefix + std::fs::path_sep() + path };
|
||||
let m0 = eval_crate_directives_to_mod(cx, cdirs, full_path);
|
||||
let i =
|
||||
@{ident: id,
|
||||
|
|
|
@ -19,29 +19,29 @@ type reader =
|
|||
fn next() -> char;
|
||||
fn init();
|
||||
fn bump();
|
||||
fn get_str_from(uint) -> istr;
|
||||
fn get_interner() -> @interner::interner<istr>;
|
||||
fn get_str_from(uint) -> str;
|
||||
fn get_interner() -> @interner::interner<str>;
|
||||
fn get_chpos() -> uint;
|
||||
fn get_byte_pos() -> uint;
|
||||
fn get_col() -> uint;
|
||||
fn get_filemap() -> codemap::filemap;
|
||||
fn err(&istr);
|
||||
fn err(&str);
|
||||
};
|
||||
|
||||
fn new_reader(cm: &codemap::codemap, src: &istr, filemap: codemap::filemap,
|
||||
itr: @interner::interner<istr>) -> reader {
|
||||
fn new_reader(cm: &codemap::codemap, src: &str, filemap: codemap::filemap,
|
||||
itr: @interner::interner<str>) -> reader {
|
||||
obj reader(cm: codemap::codemap,
|
||||
src: istr,
|
||||
src: str,
|
||||
len: uint,
|
||||
mutable col: uint,
|
||||
mutable pos: uint,
|
||||
mutable ch: char,
|
||||
mutable chpos: uint,
|
||||
mutable strs: [istr],
|
||||
mutable strs: [str],
|
||||
fm: codemap::filemap,
|
||||
itr: @interner::interner<istr>) {
|
||||
itr: @interner::interner<str>) {
|
||||
fn is_eof() -> bool { ret ch == -1 as char; }
|
||||
fn get_str_from(start: uint) -> istr {
|
||||
fn get_str_from(start: uint) -> str {
|
||||
// I'm pretty skeptical about this subtraction. What if there's a
|
||||
// multi-byte character before the mark?
|
||||
ret str::slice(src, start - 1u, pos - 1u);
|
||||
|
@ -74,16 +74,14 @@ fn new_reader(cm: &codemap::codemap, src: &istr, filemap: codemap::filemap,
|
|||
ch = next.ch;
|
||||
} else { ch = -1 as char; }
|
||||
}
|
||||
fn get_interner() -> @interner::interner<istr> { ret itr; }
|
||||
fn get_interner() -> @interner::interner<str> { ret itr; }
|
||||
fn get_col() -> uint { ret col; }
|
||||
fn get_filemap() -> codemap::filemap { ret fm; }
|
||||
fn err(m: &istr) {
|
||||
codemap::emit_error(
|
||||
some(ast_util::mk_sp(chpos, chpos)),
|
||||
m, cm);
|
||||
fn err(m: &str) {
|
||||
codemap::emit_error(some(ast_util::mk_sp(chpos, chpos)), m, cm);
|
||||
}
|
||||
}
|
||||
let strs: [istr] = [];
|
||||
let strs: [str] = [];
|
||||
let rd =
|
||||
reader(cm, src, str::byte_len(src), 0u, 0u, -1 as char,
|
||||
filemap.start_pos.ch, strs, filemap, itr);
|
||||
|
@ -148,9 +146,7 @@ fn consume_any_line_comment(rdr: &reader) {
|
|||
fn consume_block_comment(rdr: &reader) {
|
||||
let level: int = 1;
|
||||
while level > 0 {
|
||||
if rdr.is_eof() {
|
||||
rdr.err(~"unterminated block comment"); fail;
|
||||
}
|
||||
if rdr.is_eof() { rdr.err("unterminated block comment"); fail; }
|
||||
if rdr.curr() == '/' && rdr.next() == '*' {
|
||||
rdr.bump();
|
||||
rdr.bump();
|
||||
|
@ -168,15 +164,15 @@ fn consume_block_comment(rdr: &reader) {
|
|||
be consume_whitespace_and_comments(rdr);
|
||||
}
|
||||
|
||||
fn digits_to_string(s: &istr) -> int {
|
||||
fn digits_to_string(s: &str) -> int {
|
||||
let accum_int: int = 0;
|
||||
for c: u8 in s { accum_int *= 10; accum_int += dec_digit_val(c as char); }
|
||||
ret accum_int;
|
||||
}
|
||||
|
||||
fn scan_exponent(rdr: &reader) -> option::t<istr> {
|
||||
fn scan_exponent(rdr: &reader) -> option::t<str> {
|
||||
let c = rdr.curr();
|
||||
let rslt = ~"";
|
||||
let rslt = "";
|
||||
if c == 'e' || c == 'E' {
|
||||
rslt += str::unsafe_from_bytes([c as u8]);
|
||||
rdr.bump();
|
||||
|
@ -188,13 +184,13 @@ fn scan_exponent(rdr: &reader) -> option::t<istr> {
|
|||
let exponent = scan_dec_digits(rdr);
|
||||
if str::byte_len(exponent) > 0u {
|
||||
ret some(rslt + exponent);
|
||||
} else { rdr.err(~"scan_exponent: bad fp literal"); fail; }
|
||||
} else { ret none::<istr>; }
|
||||
} else { rdr.err("scan_exponent: bad fp literal"); fail; }
|
||||
} else { ret none::<str>; }
|
||||
}
|
||||
|
||||
fn scan_dec_digits(rdr: &reader) -> istr {
|
||||
fn scan_dec_digits(rdr: &reader) -> str {
|
||||
let c = rdr.curr();
|
||||
let rslt: istr = ~"";
|
||||
let rslt: str = "";
|
||||
while is_dec_digit(c) || c == '_' {
|
||||
if c != '_' { rslt += str::unsafe_from_bytes([c as u8]); }
|
||||
rdr.bump();
|
||||
|
@ -205,7 +201,7 @@ fn scan_dec_digits(rdr: &reader) -> istr {
|
|||
|
||||
fn scan_number(c: char, rdr: &reader) -> token::token {
|
||||
let accum_int = 0;
|
||||
let dec_str: istr = ~"";
|
||||
let dec_str: str = "";
|
||||
let is_dec_integer: bool = false;
|
||||
let n = rdr.next();
|
||||
if c == '0' && n == 'x' {
|
||||
|
@ -276,7 +272,7 @@ fn scan_number(c: char, rdr: &reader) -> token::token {
|
|||
|
||||
rdr.bump();
|
||||
let dec_part = scan_dec_digits(rdr);
|
||||
let float_str = dec_str + ~"." + dec_part;
|
||||
let float_str = dec_str + "." + dec_part;
|
||||
c = rdr.curr();
|
||||
let exponent_str = scan_exponent(rdr);
|
||||
alt exponent_str { some(s) { float_str += s; } none. { } }
|
||||
|
@ -302,17 +298,15 @@ fn scan_number(c: char, rdr: &reader) -> token::token {
|
|||
|
||||
}
|
||||
} else {
|
||||
ret token::LIT_FLOAT(interner::intern::<istr>(
|
||||
*rdr.get_interner(),
|
||||
float_str));
|
||||
ret token::LIT_FLOAT(interner::intern::<str>(*rdr.get_interner(),
|
||||
float_str));
|
||||
}
|
||||
}
|
||||
let maybe_exponent = scan_exponent(rdr);
|
||||
alt maybe_exponent {
|
||||
some(s) {
|
||||
ret token::LIT_FLOAT(interner::intern::<istr>(
|
||||
*rdr.get_interner(),
|
||||
dec_str + s));
|
||||
ret token::LIT_FLOAT(interner::intern::<str>(*rdr.get_interner(),
|
||||
dec_str + s));
|
||||
}
|
||||
none. { ret token::LIT_INT(accum_int); }
|
||||
}
|
||||
|
@ -324,8 +318,7 @@ fn scan_numeric_escape(rdr: &reader, n_hex_digits: uint) -> char {
|
|||
let n = rdr.curr();
|
||||
rdr.bump();
|
||||
if !is_hex_digit(n) {
|
||||
rdr.err(
|
||||
#fmt["illegal numeric character escape: %d", n as int]);
|
||||
rdr.err(#fmt["illegal numeric character escape: %d", n as int]);
|
||||
fail;
|
||||
}
|
||||
accum_int *= 16;
|
||||
|
@ -344,7 +337,7 @@ fn next_token(rdr: &reader) -> {tok: token::token, chpos: uint, bpos: uint} {
|
|||
}
|
||||
|
||||
fn next_token_inner(rdr: &reader) -> token::token {
|
||||
let accum_str = ~"";
|
||||
let accum_str = "";
|
||||
let c = rdr.curr();
|
||||
if is_alpha(c) || c == '_' {
|
||||
while is_alnum(c) || c == '_' {
|
||||
|
@ -352,11 +345,10 @@ fn next_token_inner(rdr: &reader) -> token::token {
|
|||
rdr.bump();
|
||||
c = rdr.curr();
|
||||
}
|
||||
if str::eq(accum_str, ~"_") { ret token::UNDERSCORE; }
|
||||
if str::eq(accum_str, "_") { ret token::UNDERSCORE; }
|
||||
let is_mod_name = c == ':' && rdr.next() == ':';
|
||||
ret token::IDENT(interner::intern::<istr>(
|
||||
*rdr.get_interner(),
|
||||
accum_str), is_mod_name);
|
||||
ret token::IDENT(interner::intern::<str>(*rdr.get_interner(),
|
||||
accum_str), is_mod_name);
|
||||
}
|
||||
if is_dec_digit(c) { ret scan_number(c, rdr); }
|
||||
fn binop(rdr: &reader, op: token::binop) -> token::token {
|
||||
|
@ -369,6 +361,7 @@ fn next_token_inner(rdr: &reader) -> token::token {
|
|||
alt c {
|
||||
|
||||
|
||||
|
||||
// One-byte tokens.
|
||||
'?' {
|
||||
rdr.bump();
|
||||
|
@ -408,6 +401,7 @@ fn next_token_inner(rdr: &reader) -> token::token {
|
|||
}
|
||||
|
||||
|
||||
|
||||
// Multi-byte tokens.
|
||||
'=' {
|
||||
rdr.bump();
|
||||
|
@ -468,15 +462,13 @@ fn next_token_inner(rdr: &reader) -> token::token {
|
|||
'u' { c2 = scan_numeric_escape(rdr, 4u); }
|
||||
'U' { c2 = scan_numeric_escape(rdr, 8u); }
|
||||
c2 {
|
||||
rdr.err(
|
||||
#fmt["unknown character escape: %d",
|
||||
c2 as int]);
|
||||
rdr.err(#fmt["unknown character escape: %d", c2 as int]);
|
||||
fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
if rdr.curr() != '\'' {
|
||||
rdr.err(~"unterminated character constant");
|
||||
rdr.err("unterminated character constant");
|
||||
fail;
|
||||
}
|
||||
rdr.bump(); // advance curr past token
|
||||
|
@ -509,9 +501,7 @@ fn next_token_inner(rdr: &reader) -> token::token {
|
|||
str::push_char(accum_str, scan_numeric_escape(rdr, 8u));
|
||||
}
|
||||
c2 {
|
||||
rdr.err(
|
||||
#fmt["unknown string escape: %d",
|
||||
c2 as int]);
|
||||
rdr.err(#fmt["unknown string escape: %d", c2 as int]);
|
||||
fail;
|
||||
}
|
||||
}
|
||||
|
@ -520,9 +510,8 @@ fn next_token_inner(rdr: &reader) -> token::token {
|
|||
}
|
||||
}
|
||||
rdr.bump();
|
||||
ret token::LIT_STR(interner::intern::<istr>(
|
||||
*rdr.get_interner(),
|
||||
accum_str));
|
||||
ret token::LIT_STR(interner::intern::<str>(*rdr.get_interner(),
|
||||
accum_str));
|
||||
}
|
||||
'-' {
|
||||
if rdr.next() == '>' {
|
||||
|
@ -549,11 +538,7 @@ fn next_token_inner(rdr: &reader) -> token::token {
|
|||
'/' { ret binop(rdr, token::SLASH); }
|
||||
'^' { ret binop(rdr, token::CARET); }
|
||||
'%' { ret binop(rdr, token::PERCENT); }
|
||||
c {
|
||||
rdr.err(
|
||||
#fmt["unkown start of token: %d", c as int]);
|
||||
fail;
|
||||
}
|
||||
c { rdr.err(#fmt["unkown start of token: %d", c as int]); fail; }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,10 +549,10 @@ tag cmnt_style {
|
|||
blank_line; // Just a manual blank line "\n\n", for layout
|
||||
}
|
||||
|
||||
type cmnt = {style: cmnt_style, lines: [istr], pos: uint};
|
||||
type cmnt = {style: cmnt_style, lines: [str], pos: uint};
|
||||
|
||||
fn read_to_eol(rdr: &reader) -> istr {
|
||||
let val = ~"";
|
||||
fn read_to_eol(rdr: &reader) -> str {
|
||||
let val = "";
|
||||
while rdr.curr() != '\n' && !rdr.is_eof() {
|
||||
str::push_char(val, rdr.curr());
|
||||
rdr.bump();
|
||||
|
@ -576,7 +561,7 @@ fn read_to_eol(rdr: &reader) -> istr {
|
|||
ret val;
|
||||
}
|
||||
|
||||
fn read_one_line_comment(rdr: &reader) -> istr {
|
||||
fn read_one_line_comment(rdr: &reader) -> str {
|
||||
let val = read_to_eol(rdr);
|
||||
assert (val[0] == '/' as u8 && val[1] == '/' as u8);
|
||||
ret val;
|
||||
|
@ -594,7 +579,7 @@ fn consume_non_eol_whitespace(rdr: &reader) {
|
|||
|
||||
fn push_blank_line_comment(rdr: &reader, comments: &mutable [cmnt]) {
|
||||
log ">>> blank-line comment";
|
||||
let v: [istr] = [];
|
||||
let v: [str] = [];
|
||||
comments += [{style: blank_line, lines: v, pos: rdr.get_chpos()}];
|
||||
}
|
||||
|
||||
|
@ -611,7 +596,7 @@ fn consume_whitespace_counting_blank_lines(rdr: &reader,
|
|||
fn read_line_comments(rdr: &reader, code_to_the_left: bool) -> cmnt {
|
||||
log ">>> line comments";
|
||||
let p = rdr.get_chpos();
|
||||
let lines: [istr] = [];
|
||||
let lines: [str] = [];
|
||||
while rdr.curr() == '/' && rdr.next() == '/' {
|
||||
let line = read_one_line_comment(rdr);
|
||||
log line;
|
||||
|
@ -624,52 +609,52 @@ fn read_line_comments(rdr: &reader, code_to_the_left: bool) -> cmnt {
|
|||
pos: p};
|
||||
}
|
||||
|
||||
fn all_whitespace(s: &istr, begin: uint, end: uint) -> bool {
|
||||
fn all_whitespace(s: &str, begin: uint, end: uint) -> bool {
|
||||
let i: uint = begin;
|
||||
while i != end { if !is_whitespace(s[i] as char) { ret false; } i += 1u; }
|
||||
ret true;
|
||||
}
|
||||
|
||||
fn trim_whitespace_prefix_and_push_line(lines: &mutable [istr], s: &istr,
|
||||
fn trim_whitespace_prefix_and_push_line(lines: &mutable [str], s: &str,
|
||||
col: uint) {
|
||||
let s1;
|
||||
if all_whitespace(s, 0u, col) {
|
||||
if col < str::byte_len(s) {
|
||||
s1 = str::slice(s, col, str::byte_len(s));
|
||||
} else { s1 = ~""; }
|
||||
} else { s1 = ""; }
|
||||
} else { s1 = s; }
|
||||
log ~"pushing line: " + s1;
|
||||
log "pushing line: " + s1;
|
||||
lines += [s1];
|
||||
}
|
||||
|
||||
fn read_block_comment(rdr: &reader, code_to_the_left: bool) -> cmnt {
|
||||
log ">>> block comment";
|
||||
let p = rdr.get_chpos();
|
||||
let lines: [istr] = [];
|
||||
let lines: [str] = [];
|
||||
let col: uint = rdr.get_col();
|
||||
rdr.bump();
|
||||
rdr.bump();
|
||||
let curr_line = ~"/*";
|
||||
let curr_line = "/*";
|
||||
let level: int = 1;
|
||||
while level > 0 {
|
||||
log #fmt["=== block comment level %d", level];
|
||||
if rdr.is_eof() { rdr.err(~"unterminated block comment"); fail; }
|
||||
if rdr.is_eof() { rdr.err("unterminated block comment"); fail; }
|
||||
if rdr.curr() == '\n' {
|
||||
trim_whitespace_prefix_and_push_line(lines, curr_line, col);
|
||||
curr_line = ~"";
|
||||
curr_line = "";
|
||||
rdr.bump();
|
||||
} else {
|
||||
str::push_char(curr_line, rdr.curr());
|
||||
if rdr.curr() == '/' && rdr.next() == '*' {
|
||||
rdr.bump();
|
||||
rdr.bump();
|
||||
curr_line += ~"*";
|
||||
curr_line += "*";
|
||||
level += 1;
|
||||
} else {
|
||||
if rdr.curr() == '*' && rdr.next() == '/' {
|
||||
rdr.bump();
|
||||
rdr.bump();
|
||||
curr_line += ~"/";
|
||||
curr_line += "/";
|
||||
level -= 1;
|
||||
} else { rdr.bump(); }
|
||||
}
|
||||
|
@ -717,16 +702,14 @@ fn is_lit(t: &token::token) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
type lit = {lit: istr, pos: uint};
|
||||
type lit = {lit: str, pos: uint};
|
||||
|
||||
fn gather_comments_and_literals(cm: &codemap::codemap, path: &istr,
|
||||
fn gather_comments_and_literals(cm: &codemap::codemap, path: &str,
|
||||
srdr: io::reader) ->
|
||||
{cmnts: [cmnt], lits: [lit]} {
|
||||
let src = str::unsafe_from_bytes(srdr.read_whole_stream());
|
||||
let itr = @interner::mk::<istr>(str::hash, str::eq);
|
||||
let rdr = new_reader(cm, src,
|
||||
codemap::new_filemap(
|
||||
path, 0u, 0u), itr);
|
||||
let itr = @interner::mk::<str>(str::hash, str::eq);
|
||||
let rdr = new_reader(cm, src, codemap::new_filemap(path, 0u, 0u), itr);
|
||||
let comments: [cmnt] = [];
|
||||
let literals: [lit] = [];
|
||||
let first_read: bool = true;
|
||||
|
@ -748,7 +731,7 @@ fn gather_comments_and_literals(cm: &codemap::codemap, path: &istr,
|
|||
if is_lit(tok.tok) {
|
||||
literals += [{lit: rdr.get_str_from(tok.bpos), pos: tok.chpos}];
|
||||
}
|
||||
log ~"tok: " + token::to_str(rdr, tok.tok);
|
||||
log "tok: " + token::to_str(rdr, tok.tok);
|
||||
first_read = false;
|
||||
}
|
||||
ret {cmnts: comments, lits: literals};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -84,62 +84,64 @@ tag token {
|
|||
EOF;
|
||||
}
|
||||
|
||||
fn binop_to_str(o: binop) -> istr {
|
||||
fn binop_to_str(o: binop) -> str {
|
||||
alt o {
|
||||
PLUS. { ret ~"+"; }
|
||||
MINUS. { ret ~"-"; }
|
||||
STAR. { ret ~"*"; }
|
||||
SLASH. { ret ~"/"; }
|
||||
PERCENT. { ret ~"%"; }
|
||||
CARET. { ret ~"^"; }
|
||||
AND. { ret ~"&"; }
|
||||
OR. { ret ~"|"; }
|
||||
LSL. { ret ~"<<"; }
|
||||
LSR. { ret ~">>"; }
|
||||
ASR. { ret ~">>>"; }
|
||||
PLUS. { ret "+"; }
|
||||
MINUS. { ret "-"; }
|
||||
STAR. { ret "*"; }
|
||||
SLASH. { ret "/"; }
|
||||
PERCENT. { ret "%"; }
|
||||
CARET. { ret "^"; }
|
||||
AND. { ret "&"; }
|
||||
OR. { ret "|"; }
|
||||
LSL. { ret "<<"; }
|
||||
LSR. { ret ">>"; }
|
||||
ASR. { ret ">>>"; }
|
||||
}
|
||||
}
|
||||
|
||||
fn to_str(r: lexer::reader, t: token) -> istr {
|
||||
fn to_str(r: lexer::reader, t: token) -> str {
|
||||
alt t {
|
||||
EQ. { ret ~"="; }
|
||||
LT. { ret ~"<"; }
|
||||
LE. { ret ~"<="; }
|
||||
EQEQ. { ret ~"=="; }
|
||||
NE. { ret ~"!="; }
|
||||
GE. { ret ~">="; }
|
||||
GT. { ret ~">"; }
|
||||
NOT. { ret ~"!"; }
|
||||
TILDE. { ret ~"~"; }
|
||||
OROR. { ret ~"||"; }
|
||||
ANDAND. { ret ~"&&"; }
|
||||
EQ. { ret "="; }
|
||||
LT. { ret "<"; }
|
||||
LE. { ret "<="; }
|
||||
EQEQ. { ret "=="; }
|
||||
NE. { ret "!="; }
|
||||
GE. { ret ">="; }
|
||||
GT. { ret ">"; }
|
||||
NOT. { ret "!"; }
|
||||
TILDE. { ret "~"; }
|
||||
OROR. { ret "||"; }
|
||||
ANDAND. { ret "&&"; }
|
||||
BINOP(op) { ret binop_to_str(op); }
|
||||
BINOPEQ(op) { ret binop_to_str(op) + ~"="; }
|
||||
BINOPEQ(op) { ret binop_to_str(op) + "="; }
|
||||
|
||||
|
||||
|
||||
/* Structural symbols */
|
||||
AT. {
|
||||
ret ~"@";
|
||||
ret "@";
|
||||
}
|
||||
DOT. { ret ~"."; }
|
||||
ELLIPSIS. { ret ~"..."; }
|
||||
COMMA. { ret ~","; }
|
||||
SEMI. { ret ~";"; }
|
||||
COLON. { ret ~":"; }
|
||||
MOD_SEP. { ret ~"::"; }
|
||||
QUES. { ret ~"?"; }
|
||||
RARROW. { ret ~"->"; }
|
||||
LARROW. { ret ~"<-"; }
|
||||
DARROW. { ret ~"<->"; }
|
||||
LPAREN. { ret ~"("; }
|
||||
RPAREN. { ret ~")"; }
|
||||
LBRACKET. { ret ~"["; }
|
||||
RBRACKET. { ret ~"]"; }
|
||||
LBRACE. { ret ~"{"; }
|
||||
RBRACE. { ret ~"}"; }
|
||||
POUND. { ret ~"#"; }
|
||||
POUND_LBRACE. { ret ~"#{"; }
|
||||
POUND_LT. { ret ~"#<"; }
|
||||
DOT. { ret "."; }
|
||||
ELLIPSIS. { ret "..."; }
|
||||
COMMA. { ret ","; }
|
||||
SEMI. { ret ";"; }
|
||||
COLON. { ret ":"; }
|
||||
MOD_SEP. { ret "::"; }
|
||||
QUES. { ret "?"; }
|
||||
RARROW. { ret "->"; }
|
||||
LARROW. { ret "<-"; }
|
||||
DARROW. { ret "<->"; }
|
||||
LPAREN. { ret "("; }
|
||||
RPAREN. { ret ")"; }
|
||||
LBRACKET. { ret "["; }
|
||||
RBRACKET. { ret "]"; }
|
||||
LBRACE. { ret "{"; }
|
||||
RBRACE. { ret "}"; }
|
||||
POUND. { ret "#"; }
|
||||
POUND_LBRACE. { ret "#{"; }
|
||||
POUND_LT. { ret "#<"; }
|
||||
|
||||
|
||||
|
||||
/* Literals */
|
||||
|
@ -148,39 +150,35 @@ fn to_str(r: lexer::reader, t: token) -> istr {
|
|||
}
|
||||
LIT_UINT(u) { ret uint::to_str(u, 10u); }
|
||||
LIT_MACH_INT(tm, i) {
|
||||
ret int::to_str(i, 10u) + ~"_" + ty_mach_to_str(tm);
|
||||
ret int::to_str(i, 10u) + "_" + ty_mach_to_str(tm);
|
||||
}
|
||||
LIT_MACH_FLOAT(tm, s) {
|
||||
ret interner::get::<istr>(
|
||||
*r.get_interner(), s) + ~"_" +
|
||||
ty_mach_to_str(tm);
|
||||
}
|
||||
LIT_FLOAT(s) {
|
||||
ret interner::get::<istr>(*r.get_interner(), s);
|
||||
ret interner::get::<str>(*r.get_interner(), s) + "_" +
|
||||
ty_mach_to_str(tm);
|
||||
}
|
||||
LIT_FLOAT(s) { ret interner::get::<str>(*r.get_interner(), s); }
|
||||
LIT_STR(s) { // FIXME: escape.
|
||||
ret ~"\"" +
|
||||
interner::get::<istr>(*r.get_interner(), s)
|
||||
+ ~"\"";
|
||||
ret "\"" + interner::get::<str>(*r.get_interner(), s) + "\"";
|
||||
}
|
||||
LIT_CHAR(c) {
|
||||
// FIXME: escape.
|
||||
let tmp = ~"'";
|
||||
let tmp = "'";
|
||||
str::push_char(tmp, c);
|
||||
str::push_byte(tmp, '\'' as u8);
|
||||
ret tmp;
|
||||
}
|
||||
LIT_BOOL(b) { if b { ret ~"true"; } else { ret ~"false"; } }
|
||||
LIT_BOOL(b) { if b { ret "true"; } else { ret "false"; } }
|
||||
|
||||
|
||||
|
||||
/* Name components */
|
||||
IDENT(s, _) {
|
||||
ret interner::get::<istr>(*r.get_interner(), s);
|
||||
ret interner::get::<str>(*r.get_interner(), s);
|
||||
}
|
||||
IDX(i) { ret ~"_" + int::to_str(i, 10u); }
|
||||
UNDERSCORE. { ret ~"_"; }
|
||||
BRACEQUOTE(_) { ret ~"<bracequote>"; }
|
||||
EOF. { ret ~"<eof>"; }
|
||||
IDX(i) { ret "_" + int::to_str(i, 10u); }
|
||||
UNDERSCORE. { ret "_"; }
|
||||
BRACEQUOTE(_) { ret "<bracequote>"; }
|
||||
EOF. { ret "<eof>"; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,35 +61,33 @@ type break_t = {offset: int, blank_space: int};
|
|||
|
||||
type begin_t = {offset: int, breaks: breaks};
|
||||
|
||||
tag token { STRING(istr, int); BREAK(break_t); BEGIN(begin_t); END; EOF; }
|
||||
tag token { STRING(str, int); BREAK(break_t); BEGIN(begin_t); END; EOF; }
|
||||
|
||||
fn tok_str(t: token) -> istr {
|
||||
fn tok_str(t: token) -> str {
|
||||
alt t {
|
||||
STRING(s, len) {
|
||||
ret #fmt[~"STR(%s,%d)", s, len];
|
||||
}
|
||||
BREAK(_) { ret ~"BREAK"; }
|
||||
BEGIN(_) { ret ~"BEGIN"; }
|
||||
END. { ret ~"END"; }
|
||||
EOF. { ret ~"EOF"; }
|
||||
STRING(s, len) { ret #fmt["STR(%s,%d)", s, len]; }
|
||||
BREAK(_) { ret "BREAK"; }
|
||||
BEGIN(_) { ret "BEGIN"; }
|
||||
END. { ret "END"; }
|
||||
EOF. { ret "EOF"; }
|
||||
}
|
||||
}
|
||||
|
||||
fn buf_str(toks: &[mutable token], szs: &[mutable int], left: uint,
|
||||
right: uint, lim: uint) -> istr {
|
||||
right: uint, lim: uint) -> str {
|
||||
let n = vec::len(toks);
|
||||
assert (n == vec::len(szs));
|
||||
let i = left;
|
||||
let L = lim;
|
||||
let s = ~"[";
|
||||
let s = "[";
|
||||
while i != right && L != 0u {
|
||||
L -= 1u;
|
||||
if i != left { s += ~", "; }
|
||||
s += #fmt[~"%d=%s", szs[i], tok_str(toks[i])];
|
||||
if i != left { s += ", "; }
|
||||
s += #fmt["%d=%s", szs[i], tok_str(toks[i])];
|
||||
i += 1u;
|
||||
i %= n;
|
||||
}
|
||||
s += ~"]";
|
||||
s += "]";
|
||||
ret s;
|
||||
}
|
||||
|
||||
|
@ -104,7 +102,7 @@ fn mk_printer(out: io::writer, linewidth: uint) -> printer {
|
|||
// fall behind.
|
||||
|
||||
let n: uint = 3u * linewidth;
|
||||
log #fmt[~"mk_printer %u", linewidth];
|
||||
log #fmt["mk_printer %u", linewidth];
|
||||
let token: [mutable token] = vec::init_elt_mut(EOF, n);
|
||||
let size: [mutable int] = vec::init_elt_mut(0, n);
|
||||
let scan_stack: [mutable uint] = vec::init_elt_mut(0u, n);
|
||||
|
@ -244,7 +242,7 @@ obj printer(out: io::writer,
|
|||
fn replace_last_token(t: token) { token[right] = t; }
|
||||
|
||||
fn pretty_print(t: token) {
|
||||
log #fmt[~"pp [%u,%u]", left, right];
|
||||
log #fmt["pp [%u,%u]", left, right];
|
||||
alt t {
|
||||
EOF. {
|
||||
if !scan_stack_empty {
|
||||
|
@ -260,17 +258,17 @@ obj printer(out: io::writer,
|
|||
left = 0u;
|
||||
right = 0u;
|
||||
} else { self.advance_right(); }
|
||||
log #fmt[~"pp BEGIN/buffer [%u,%u]", left, right];
|
||||
log #fmt["pp BEGIN/buffer [%u,%u]", left, right];
|
||||
token[right] = t;
|
||||
size[right] = -right_total;
|
||||
self.scan_push(right);
|
||||
}
|
||||
END. {
|
||||
if scan_stack_empty {
|
||||
log #fmt[~"pp END/print [%u,%u]", left, right];
|
||||
log #fmt["pp END/print [%u,%u]", left, right];
|
||||
self.print(t, 0);
|
||||
} else {
|
||||
log #fmt[~"pp END/buffer [%u,%u]", left, right];
|
||||
log #fmt["pp END/buffer [%u,%u]", left, right];
|
||||
self.advance_right();
|
||||
token[right] = t;
|
||||
size[right] = -1;
|
||||
|
@ -284,7 +282,7 @@ obj printer(out: io::writer,
|
|||
left = 0u;
|
||||
right = 0u;
|
||||
} else { self.advance_right(); }
|
||||
log #fmt[~"pp BREAK/buffer [%u,%u]", left, right];
|
||||
log #fmt["pp BREAK/buffer [%u,%u]", left, right];
|
||||
self.check_stack(0);
|
||||
self.scan_push(right);
|
||||
token[right] = t;
|
||||
|
@ -293,10 +291,10 @@ obj printer(out: io::writer,
|
|||
}
|
||||
STRING(s, len) {
|
||||
if scan_stack_empty {
|
||||
log #fmt[~"pp STRING/print [%u,%u]", left, right];
|
||||
log #fmt["pp STRING/print [%u,%u]", left, right];
|
||||
self.print(t, len);
|
||||
} else {
|
||||
log #fmt[~"pp STRING/buffer [%u,%u]", left, right];
|
||||
log #fmt["pp STRING/buffer [%u,%u]", left, right];
|
||||
self.advance_right();
|
||||
token[right] = t;
|
||||
size[right] = len;
|
||||
|
@ -307,10 +305,10 @@ obj printer(out: io::writer,
|
|||
}
|
||||
}
|
||||
fn check_stream() {
|
||||
log #fmt[~"check_stream [%u, %u] with left_total=%d, right_total=%d",
|
||||
log #fmt["check_stream [%u, %u] with left_total=%d, right_total=%d",
|
||||
left, right, left_total, right_total];
|
||||
if right_total - left_total > space {
|
||||
log #fmt[~"scan window is %d, longer than space on line (%d)",
|
||||
log #fmt["scan window is %d, longer than space on line (%d)",
|
||||
right_total - left_total, space];
|
||||
if !scan_stack_empty {
|
||||
if left == scan_stack[bottom] {
|
||||
|
@ -392,7 +390,7 @@ obj printer(out: io::writer,
|
|||
}
|
||||
fn print_newline(amount: int) {
|
||||
log #fmt["NEWLINE %d", amount];
|
||||
out.write_str(~"\n");
|
||||
out.write_str("\n");
|
||||
pending_indentation = 0;
|
||||
self.indent(amount);
|
||||
}
|
||||
|
@ -406,16 +404,15 @@ obj printer(out: io::writer,
|
|||
if n != 0u { top = print_stack[n - 1u]; }
|
||||
ret top;
|
||||
}
|
||||
fn write_str(s: &istr) {
|
||||
fn write_str(s: &str) {
|
||||
while pending_indentation > 0 {
|
||||
out.write_str(~" ");
|
||||
out.write_str(" ");
|
||||
pending_indentation -= 1;
|
||||
}
|
||||
out.write_str(s);
|
||||
}
|
||||
fn print(x: token, L: int) {
|
||||
log #fmt["print %s %d (remaining line space=%d)",
|
||||
tok_str(x), L,
|
||||
log #fmt["print %s %d (remaining line space=%d)", tok_str(x), L,
|
||||
space];
|
||||
log buf_str(token, size, left, right, 6u);
|
||||
alt x {
|
||||
|
@ -495,15 +492,15 @@ fn end(p: printer) { p.pretty_print(END); }
|
|||
|
||||
fn eof(p: printer) { p.pretty_print(EOF); }
|
||||
|
||||
fn word(p: printer, wrd: &istr) {
|
||||
fn word(p: printer, wrd: &str) {
|
||||
p.pretty_print(STRING(wrd, str::char_len(wrd) as int));
|
||||
}
|
||||
|
||||
fn huge_word(p: printer, wrd: &istr) {
|
||||
fn huge_word(p: printer, wrd: &str) {
|
||||
p.pretty_print(STRING(wrd, size_infinity));
|
||||
}
|
||||
|
||||
fn zero_word(p: printer, wrd: &istr) { p.pretty_print(STRING(wrd, 0)); }
|
||||
fn zero_word(p: printer, wrd: &str) { p.pretty_print(STRING(wrd, 0)); }
|
||||
|
||||
fn spaces(p: printer, n: uint) { break_offset(p, n, 0); }
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -104,10 +104,7 @@ fn local_rhs_span(l: &@ast::local, def: &span) -> span {
|
|||
fn lit_eq(l: &@ast::lit, m: &@ast::lit) -> bool {
|
||||
alt l.node {
|
||||
ast::lit_str(s) {
|
||||
alt m.node {
|
||||
ast::lit_str(t) { ret s == t }
|
||||
_ { ret false; }
|
||||
}
|
||||
alt m.node { ast::lit_str(t) { ret s == t } _ { ret false; } }
|
||||
}
|
||||
ast::lit_char(c) {
|
||||
alt m.node { ast::lit_char(d) { ret c == d; } _ { ret false; } }
|
||||
|
@ -144,28 +141,28 @@ fn lit_eq(l: &@ast::lit, m: &@ast::lit) -> bool {
|
|||
|
||||
tag call_kind { kind_call; kind_spawn; kind_bind; kind_for_each; }
|
||||
|
||||
fn call_kind_str(c: call_kind) -> istr {
|
||||
fn call_kind_str(c: call_kind) -> str {
|
||||
alt c {
|
||||
kind_call. { ~"Call" }
|
||||
kind_spawn. { ~"Spawn" }
|
||||
kind_bind. { ~"Bind" }
|
||||
kind_for_each. { ~"For-Each" }
|
||||
kind_call. { "Call" }
|
||||
kind_spawn. { "Spawn" }
|
||||
kind_bind. { "Bind" }
|
||||
kind_for_each. { "For-Each" }
|
||||
}
|
||||
}
|
||||
|
||||
fn is_main_name(path: &[ast::ident]) -> bool {
|
||||
str::eq(option::get(std::vec::last(path)), ~"main")
|
||||
str::eq(option::get(std::vec::last(path)), "main")
|
||||
}
|
||||
|
||||
// FIXME mode this to std::float when editing the stdlib no longer
|
||||
// requires a snapshot
|
||||
fn float_to_str(num: float, digits: uint) -> istr {
|
||||
let accum = if num < 0.0 { num = -num; ~"-" } else { ~"" };
|
||||
fn float_to_str(num: float, digits: uint) -> str {
|
||||
let accum = if num < 0.0 { num = -num; "-" } else { "" };
|
||||
let trunc = num as uint;
|
||||
let frac = num - (trunc as float);
|
||||
accum += uint::str(trunc);
|
||||
if frac == 0.0 || digits == 0u { ret accum; }
|
||||
accum += ~".";
|
||||
accum += ".";
|
||||
while digits > 0u && frac > 0.0 {
|
||||
frac *= 10.0;
|
||||
let digit = frac as uint;
|
||||
|
|
|
@ -21,32 +21,31 @@ import syntax::ast;
|
|||
import middle::ast_map;
|
||||
import metadata::csearch;
|
||||
|
||||
fn mode_str(m: &ty::mode) -> istr {
|
||||
fn mode_str(m: &ty::mode) -> str {
|
||||
alt m {
|
||||
mo_val. { ~"" }
|
||||
mo_alias(false) { ~"&" }
|
||||
mo_alias(true) { ~"&mutable " }
|
||||
mo_move. { ~"-" }
|
||||
mo_val. { "" }
|
||||
mo_alias(false) { "&" }
|
||||
mo_alias(true) { "&mutable " }
|
||||
mo_move. { "-" }
|
||||
}
|
||||
}
|
||||
|
||||
fn mode_str_1(m: &ty::mode) -> istr {
|
||||
alt m { mo_val. { ~"val" } _ { mode_str(m) } }
|
||||
fn mode_str_1(m: &ty::mode) -> str {
|
||||
alt m { mo_val. { "val" } _ { mode_str(m) } }
|
||||
}
|
||||
|
||||
fn fn_ident_to_string(id: ast::node_id, i: &ast::fn_ident) -> istr {
|
||||
ret alt i {
|
||||
none. { ~"anon" + int::str(id) }
|
||||
some(s) { s }
|
||||
};
|
||||
fn fn_ident_to_string(id: ast::node_id, i: &ast::fn_ident) -> str {
|
||||
ret alt i { none. { "anon" + int::str(id) } some(s) { s } };
|
||||
}
|
||||
|
||||
fn get_id_ident(cx: &ctxt, id: ast::def_id) -> istr {
|
||||
fn get_id_ident(cx: &ctxt, id: ast::def_id) -> str {
|
||||
if id.crate != ast::local_crate {
|
||||
alt cx.ext_map.find(id) {
|
||||
some(j) { str::connect(j, ~"::") }
|
||||
_ { fail (~"get_id_ident: can't find item in ext_map, id.crate = "
|
||||
+ int::str(id.crate)) }
|
||||
some(j) { str::connect(j, "::") }
|
||||
_ {
|
||||
fail "get_id_ident: can't find item in ext_map, id.crate = " +
|
||||
int::str(id.crate)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
alt cx.items.find(id.node) {
|
||||
|
@ -56,90 +55,79 @@ fn get_id_ident(cx: &ctxt, id: ast::def_id) -> istr {
|
|||
}
|
||||
}
|
||||
|
||||
fn ty_to_str(cx: &ctxt, typ: &t) -> istr {
|
||||
fn ty_to_str(cx: &ctxt, typ: &t) -> str {
|
||||
fn fn_input_to_str(cx: &ctxt, input: &{mode: middle::ty::mode, ty: t}) ->
|
||||
istr {
|
||||
str {
|
||||
let s = mode_str(input.mode);
|
||||
ret s + ty_to_str(cx, input.ty);
|
||||
}
|
||||
fn fn_to_str(cx: &ctxt, proto: ast::proto, ident: option::t<ast::ident>,
|
||||
inputs: &[arg], output: t, cf: ast::controlflow,
|
||||
constrs: &[@constr]) -> istr {
|
||||
constrs: &[@constr]) -> str {
|
||||
let s = proto_to_str(proto);
|
||||
alt ident {
|
||||
some(i) {
|
||||
s += ~" ";
|
||||
s += i;
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
s += ~"(";
|
||||
alt ident { some(i) { s += " "; s += i; } _ { } }
|
||||
s += "(";
|
||||
let strs = [];
|
||||
for a: arg in inputs { strs += [fn_input_to_str(cx, a)]; }
|
||||
s += str::connect(strs, ~", ");
|
||||
s += ~")";
|
||||
s += str::connect(strs, ", ");
|
||||
s += ")";
|
||||
if struct(cx, output) != ty_nil {
|
||||
alt cf {
|
||||
ast::noreturn. { s += ~" -> !"; }
|
||||
ast::return. { s += ~" -> " + ty_to_str(cx, output); }
|
||||
ast::noreturn. { s += " -> !"; }
|
||||
ast::return. { s += " -> " + ty_to_str(cx, output); }
|
||||
}
|
||||
}
|
||||
s += constrs_str(constrs);
|
||||
ret s;
|
||||
}
|
||||
fn method_to_str(cx: &ctxt, m: &method) -> istr {
|
||||
fn method_to_str(cx: &ctxt, m: &method) -> str {
|
||||
ret fn_to_str(cx, m.proto, some::<ast::ident>(m.ident), m.inputs,
|
||||
m.output, m.cf, m.constrs) + ~";";
|
||||
m.output, m.cf, m.constrs) + ";";
|
||||
}
|
||||
fn field_to_str(cx: &ctxt, f: &field) -> istr {
|
||||
ret f.ident + ~": " + mt_to_str(cx, f.mt);
|
||||
fn field_to_str(cx: &ctxt, f: &field) -> str {
|
||||
ret f.ident + ": " + mt_to_str(cx, f.mt);
|
||||
}
|
||||
fn mt_to_str(cx: &ctxt, m: &mt) -> istr {
|
||||
fn mt_to_str(cx: &ctxt, m: &mt) -> str {
|
||||
let mstr;
|
||||
alt m.mut {
|
||||
ast::mut. { mstr = ~"mutable "; }
|
||||
ast::imm. { mstr = ~""; }
|
||||
ast::maybe_mut. { mstr = ~"mutable? "; }
|
||||
ast::mut. { mstr = "mutable "; }
|
||||
ast::imm. { mstr = ""; }
|
||||
ast::maybe_mut. { mstr = "mutable? "; }
|
||||
}
|
||||
ret mstr + ty_to_str(cx, m.ty);
|
||||
}
|
||||
alt cname(cx, typ) {
|
||||
some(cs) {
|
||||
ret cs;
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
alt cname(cx, typ) { some(cs) { ret cs; } _ { } }
|
||||
ret alt struct(cx, typ) {
|
||||
ty_native(_) { ~"native" }
|
||||
ty_nil. { ~"()" }
|
||||
ty_bot. { ~"_|_" }
|
||||
ty_bool. { ~"bool" }
|
||||
ty_int. { ~"int" }
|
||||
ty_float. { ~"float" }
|
||||
ty_uint. { ~"uint" }
|
||||
ty_native(_) { "native" }
|
||||
ty_nil. { "()" }
|
||||
ty_bot. { "_|_" }
|
||||
ty_bool. { "bool" }
|
||||
ty_int. { "int" }
|
||||
ty_float. { "float" }
|
||||
ty_uint. { "uint" }
|
||||
ty_machine(tm) { ty_mach_to_str(tm) }
|
||||
ty_char. { ~"char" }
|
||||
ty_istr. { ~"istr" }
|
||||
ty_box(tm) { ~"@" + mt_to_str(cx, tm) }
|
||||
ty_uniq(t) { ~"~" + ty_to_str(cx, t) }
|
||||
ty_vec(tm) { ~"[" + mt_to_str(cx, tm) + ~"]" }
|
||||
ty_type. { ~"type" }
|
||||
ty_char. { "char" }
|
||||
ty_istr. { "istr" }
|
||||
ty_box(tm) { "@" + mt_to_str(cx, tm) }
|
||||
ty_uniq(t) { "~" + ty_to_str(cx, t) }
|
||||
ty_vec(tm) { "[" + mt_to_str(cx, tm) + "]" }
|
||||
ty_type. { "type" }
|
||||
ty_rec(elems) {
|
||||
let strs: [istr] = [];
|
||||
let strs: [str] = [];
|
||||
for fld: field in elems { strs += [field_to_str(cx, fld)]; }
|
||||
~"{" + str::connect(strs, ~",") + ~"}"
|
||||
"{" + str::connect(strs, ",") + "}"
|
||||
}
|
||||
ty_tup(elems) {
|
||||
let strs = [];
|
||||
for elem in elems { strs += [ty_to_str(cx, elem)]; }
|
||||
~"(" + str::connect(strs, ~",") + ~")"
|
||||
"(" + str::connect(strs, ",") + ")"
|
||||
}
|
||||
ty_tag(id, tps) {
|
||||
let s = get_id_ident(cx, id);
|
||||
if vec::len::<t>(tps) > 0u {
|
||||
let strs: [istr] = [];
|
||||
let strs: [str] = [];
|
||||
for typ: t in tps { strs += [ty_to_str(cx, typ)]; }
|
||||
s += ~"[" + str::connect(strs, ~",") + ~"]";
|
||||
s += "[" + str::connect(strs, ",") + "]";
|
||||
}
|
||||
s
|
||||
}
|
||||
|
@ -153,42 +141,42 @@ fn ty_to_str(cx: &ctxt, typ: &t) -> istr {
|
|||
ty_obj(meths) {
|
||||
let strs = [];
|
||||
for m: method in meths { strs += [method_to_str(cx, m)]; }
|
||||
~"obj {\n\t" + str::connect(strs, ~"\n\t") + ~"\n}"
|
||||
"obj {\n\t" + str::connect(strs, "\n\t") + "\n}"
|
||||
}
|
||||
ty_res(id, _, _) { get_id_ident(cx, id) }
|
||||
ty_var(v) { ~"<T" + int::str(v) + ~">" }
|
||||
ty_var(v) { "<T" + int::str(v) + ">" }
|
||||
ty_param(id, _) {
|
||||
~"'" + str::unsafe_from_bytes([('a' as u8) + (id as u8)])
|
||||
"'" + str::unsafe_from_bytes([('a' as u8) + (id as u8)])
|
||||
}
|
||||
_ { ty_to_short_str(cx, typ) }
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_to_short_str(cx: &ctxt, typ: t) -> istr {
|
||||
fn ty_to_short_str(cx: &ctxt, typ: t) -> str {
|
||||
let s = encoder::encoded_ty(cx, typ);
|
||||
if str::byte_len(s) >= 32u { s = str::substr(s, 0u, 32u); }
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn constr_to_str(c: &@constr) -> istr {
|
||||
fn constr_to_str(c: &@constr) -> str {
|
||||
ret path_to_str(c.node.path) +
|
||||
pprust::constr_args_to_str(pprust::uint_to_str, c.node.args);
|
||||
pprust::constr_args_to_str(pprust::uint_to_str, c.node.args);
|
||||
}
|
||||
|
||||
fn constrs_str(constrs: &[@constr]) -> istr {
|
||||
let s = ~"";
|
||||
fn constrs_str(constrs: &[@constr]) -> str {
|
||||
let s = "";
|
||||
let colon = true;
|
||||
for c: @constr in constrs {
|
||||
if colon { s += ~" : "; colon = false; } else { s += ~", "; }
|
||||
if colon { s += " : "; colon = false; } else { s += ", "; }
|
||||
s += constr_to_str(c);
|
||||
}
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn ty_constr_to_str<Q>(c: &@ast::spanned<ast::constr_general_<ast::path, Q>>)
|
||||
-> istr {
|
||||
-> str {
|
||||
ret path_to_str(c.node.path) +
|
||||
constr_args_to_str::<ast::path>(path_to_str, c.node.args);
|
||||
constr_args_to_str::<ast::path>(path_to_str, c.node.args);
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -20,28 +20,28 @@ import rustc::syntax::codemap;
|
|||
import rustc::syntax::parse::parser;
|
||||
import rustc::syntax::print::pprust;
|
||||
|
||||
fn write_file(filename: &istr, content: &istr) {
|
||||
fn write_file(filename: &str, content: &str) {
|
||||
io::file_writer(filename, [io::create, io::truncate]).write_str(content);
|
||||
// Work around https://github.com/graydon/rust/issues/726
|
||||
std::run::run_program(~"chmod", [~"644", filename]);
|
||||
std::run::run_program("chmod", ["644", filename]);
|
||||
}
|
||||
|
||||
fn file_contains(filename: &istr, needle: &istr) -> bool {
|
||||
fn file_contains(filename: &str, needle: &str) -> bool {
|
||||
let contents = io::read_whole_file_str(filename);
|
||||
ret str::find(contents, needle) != -1;
|
||||
}
|
||||
|
||||
fn contains(haystack: &istr, needle: &istr) -> bool {
|
||||
fn contains(haystack: &str, needle: &str) -> bool {
|
||||
str::find(haystack, needle) != -1
|
||||
}
|
||||
|
||||
fn find_rust_files(files: &mutable [istr], path: &istr) {
|
||||
if str::ends_with(path, ~".rs") {
|
||||
if file_contains(path, ~"xfail-test") {
|
||||
fn find_rust_files(files: &mutable [str], path: &str) {
|
||||
if str::ends_with(path, ".rs") {
|
||||
if file_contains(path, "xfail-test") {
|
||||
//log_err "Skipping " + path + " because it is marked as xfail-test";
|
||||
} else { files += [path]; }
|
||||
} else if fs::file_is_dir(path)
|
||||
&& str::find(path, ~"compile-fail") == -1 {
|
||||
&& str::find(path, "compile-fail") == -1 {
|
||||
for p in fs::list_dir(path) {
|
||||
find_rust_files(files, p);
|
||||
}
|
||||
|
@ -150,28 +150,28 @@ iter under(n: uint) -> uint {
|
|||
|
||||
fn devnull() -> io::writer { std::io::string_writer().get_writer() }
|
||||
|
||||
fn as_str(f: fn(io::writer)) -> istr {
|
||||
fn as_str(f: fn(io::writer)) -> str {
|
||||
let w = std::io::string_writer();
|
||||
f(w.get_writer());
|
||||
ret w.get_str();
|
||||
}
|
||||
|
||||
fn check_variants_of_ast(crate: &ast::crate, codemap: &codemap::codemap,
|
||||
filename: &istr) {
|
||||
filename: &str) {
|
||||
let exprs = steal_exprs(crate);
|
||||
let exprsL = vec::len(exprs);
|
||||
if exprsL < 100u {
|
||||
for each i: uint in under(uint::min(exprsL, 20u)) {
|
||||
log_err ~"Replacing... " + pprust::expr_to_str(@exprs[i]);
|
||||
log_err "Replacing... " + pprust::expr_to_str(@exprs[i]);
|
||||
for each j: uint in under(uint::min(exprsL, 5u)) {
|
||||
log_err ~"With... " + pprust::expr_to_str(@exprs[j]);
|
||||
log_err "With... " + pprust::expr_to_str(@exprs[j]);
|
||||
let crate2 = @replace_expr_in_crate(crate, i, exprs[j].node);
|
||||
// It would be best to test the *crate* for stability, but testing the
|
||||
// string for stability is easier and ok for now.
|
||||
let str3 =
|
||||
as_str(bind pprust::print_crate(codemap, crate2,
|
||||
filename,
|
||||
io::string_reader(~""), _,
|
||||
io::string_reader(""), _,
|
||||
pprust::no_ann()));
|
||||
// 1u would be sane here, but the pretty-printer currently has lots of whitespace and paren issues,
|
||||
// and https://github.com/graydon/rust/issues/766 is hilarious.
|
||||
|
@ -186,61 +186,61 @@ fn check_variants_of_ast(crate: &ast::crate, codemap: &codemap::codemap,
|
|||
// - that would find many "false positives" or unimportant bugs
|
||||
// - that would be tricky, requiring use of tasks or serialization or randomness.
|
||||
// This seems to find plenty of bugs as it is :)
|
||||
fn check_whole_compiler(code: &istr) {
|
||||
let filename = ~"test.rs";
|
||||
fn check_whole_compiler(code: &str) {
|
||||
let filename = "test.rs";
|
||||
write_file(filename, code);
|
||||
let p =
|
||||
std::run::program_output(
|
||||
~"/Users/jruderman/code/rust/build/stage1/rustc",
|
||||
[~"-c", filename]);
|
||||
"/Users/jruderman/code/rust/build/stage1/rustc",
|
||||
["-c", filename]);
|
||||
|
||||
//log_err #fmt("Status: %d", p.status);
|
||||
//log_err "Output: " + p.out;
|
||||
if p.err != ~"" {
|
||||
if contains(p.err, ~"argument of incompatible type") {
|
||||
if p.err != "" {
|
||||
if contains(p.err, "argument of incompatible type") {
|
||||
log_err "https://github.com/graydon/rust/issues/769";
|
||||
} else if contains(p.err,
|
||||
~"Cannot create binary operator with two operands of differing type")
|
||||
"Cannot create binary operator with two operands of differing type")
|
||||
{
|
||||
log_err "https://github.com/graydon/rust/issues/770";
|
||||
} else if contains(p.err, ~"May only branch on boolean predicates!") {
|
||||
} else if contains(p.err, "May only branch on boolean predicates!") {
|
||||
log_err "https://github.com/graydon/rust/issues/770 or https://github.com/graydon/rust/issues/776";
|
||||
} else if contains(p.err, ~"Invalid constantexpr cast!") &&
|
||||
contains(code, ~"!") {
|
||||
} else if contains(p.err, "Invalid constantexpr cast!") &&
|
||||
contains(code, "!") {
|
||||
log_err "https://github.com/graydon/rust/issues/777";
|
||||
} else if contains(p.err,
|
||||
~"Both operands to ICmp instruction are not of the same type!")
|
||||
&& contains(code, ~"!") {
|
||||
"Both operands to ICmp instruction are not of the same type!")
|
||||
&& contains(code, "!") {
|
||||
log_err "https://github.com/graydon/rust/issues/777 #issuecomment-1678487";
|
||||
} else if contains(p.err, ~"Ptr must be a pointer to Val type!") &&
|
||||
contains(code, ~"!") {
|
||||
} else if contains(p.err, "Ptr must be a pointer to Val type!") &&
|
||||
contains(code, "!") {
|
||||
log_err "https://github.com/graydon/rust/issues/779";
|
||||
} else if contains(p.err, ~"Calling a function with bad signature!") &&
|
||||
(contains(code, ~"iter") || contains(code, ~"range")) {
|
||||
} else if contains(p.err, "Calling a function with bad signature!") &&
|
||||
(contains(code, "iter") || contains(code, "range")) {
|
||||
log_err "https://github.com/graydon/rust/issues/771 - calling an iter fails";
|
||||
} else if contains(p.err, ~"Calling a function with a bad signature!")
|
||||
&& contains(code, ~"empty") {
|
||||
} else if contains(p.err, "Calling a function with a bad signature!")
|
||||
&& contains(code, "empty") {
|
||||
log_err "https://github.com/graydon/rust/issues/775 - possibly a modification of run-pass/import-glob-crate.rs";
|
||||
} else if contains(p.err, ~"Invalid type for pointer element!") &&
|
||||
contains(code, ~"put") {
|
||||
} else if contains(p.err, "Invalid type for pointer element!") &&
|
||||
contains(code, "put") {
|
||||
log_err "https://github.com/graydon/rust/issues/773 - put put ()";
|
||||
} else if contains(p.err, ~"pointer being freed was not allocated") &&
|
||||
contains(p.out, ~"Out of stack space, sorry") {
|
||||
} else if contains(p.err, "pointer being freed was not allocated") &&
|
||||
contains(p.out, "Out of stack space, sorry") {
|
||||
log_err "https://github.com/graydon/rust/issues/768 + https://github.com/graydon/rust/issues/778"
|
||||
} else {
|
||||
log_err ~"Stderr: " + p.err;
|
||||
log_err "Stderr: " + p.err;
|
||||
fail "Unfamiliar error message";
|
||||
}
|
||||
} else if contains(p.out, ~"non-exhaustive match failure") &&
|
||||
contains(p.out, ~"alias.rs") {
|
||||
} else if contains(p.out, "non-exhaustive match failure") &&
|
||||
contains(p.out, "alias.rs") {
|
||||
log_err "https://github.com/graydon/rust/issues/772";
|
||||
} else if contains(p.out, ~"non-exhaustive match failure") &&
|
||||
contains(p.out, ~"trans.rs") && contains(code, ~"put") {
|
||||
} else if contains(p.out, "non-exhaustive match failure") &&
|
||||
contains(p.out, "trans.rs") && contains(code, "put") {
|
||||
log_err "https://github.com/graydon/rust/issues/774";
|
||||
} else if contains(p.out, ~"Out of stack space, sorry") {
|
||||
} else if contains(p.out, "Out of stack space, sorry") {
|
||||
log_err "Possibly a variant of https://github.com/graydon/rust/issues/768";
|
||||
} else if p.status == 256 {
|
||||
if !contains(p.out, ~"error:") {
|
||||
if !contains(p.out, "error:") {
|
||||
fail "Exited with status 256 without a span-error";
|
||||
}
|
||||
} else if p.status == 11 {
|
||||
|
@ -248,8 +248,8 @@ fn check_whole_compiler(code: &istr) {
|
|||
} else if p.status != 0 { fail "Unfamiliar status code"; }
|
||||
}
|
||||
|
||||
fn parse_and_print(code: &istr) -> istr {
|
||||
let filename = ~"tmp.rs";
|
||||
fn parse_and_print(code: &str) -> str {
|
||||
let filename = "tmp.rs";
|
||||
let sess = @{cm: codemap::new_codemap(), mutable next_id: 0};
|
||||
//write_file(filename, code);
|
||||
let crate = parser::parse_crate_from_source_str(
|
||||
|
@ -260,19 +260,19 @@ fn parse_and_print(code: &istr) -> istr {
|
|||
pprust::no_ann()));
|
||||
}
|
||||
|
||||
fn content_is_dangerous_to_modify(code: &istr) -> bool {
|
||||
fn content_is_dangerous_to_modify(code: &str) -> bool {
|
||||
let dangerous_patterns =
|
||||
[~"obj", // not safe to steal; https://github.com/graydon/rust/issues/761
|
||||
~"#macro", // not safe to steal things inside of it, because they have a special syntax
|
||||
~"#", // strange representation of the arguments to #fmt, for example
|
||||
~" be ", // don't want to replace its child with a non-call: "Non-call expression in tail call"
|
||||
~"@"]; // hangs when compiling: https://github.com/graydon/rust/issues/768
|
||||
["obj", // not safe to steal; https://github.com/graydon/rust/issues/761
|
||||
"#macro", // not safe to steal things inside of it, because they have a special syntax
|
||||
"#", // strange representation of the arguments to #fmt, for example
|
||||
" be ", // don't want to replace its child with a non-call: "Non-call expression in tail call"
|
||||
"@"]; // hangs when compiling: https://github.com/graydon/rust/issues/768
|
||||
|
||||
for p: istr in dangerous_patterns { if contains(code, p) { ret true; } }
|
||||
for p: str in dangerous_patterns { if contains(code, p) { ret true; } }
|
||||
ret false;
|
||||
}
|
||||
|
||||
fn content_is_confusing(code: &istr) ->
|
||||
fn content_is_confusing(code: &str) ->
|
||||
bool { // https://github.com/graydon/rust/issues/671
|
||||
// https://github.com/graydon/rust/issues/669
|
||||
// https://github.com/graydon/rust/issues/669
|
||||
|
@ -282,16 +282,16 @@ fn content_is_confusing(code: &istr) ->
|
|||
// more precedence issues?
|
||||
|
||||
let confusing_patterns =
|
||||
[~"#macro", ~"][]", ~"][mutable]", ~"][mutable ]", ~"self", ~"spawn",
|
||||
~"bind", ~"\n\n\n\n\n", // https://github.com/graydon/rust/issues/759
|
||||
~" : ", // https://github.com/graydon/rust/issues/760
|
||||
~"if ret", ~"alt ret", ~"if fail", ~"alt fail"];
|
||||
["#macro", "][]", "][mutable]", "][mutable ]", "self", "spawn",
|
||||
"bind", "\n\n\n\n\n", // https://github.com/graydon/rust/issues/759
|
||||
" : ", // https://github.com/graydon/rust/issues/760
|
||||
"if ret", "alt ret", "if fail", "alt fail"];
|
||||
|
||||
for p: istr in confusing_patterns { if contains(code, p) { ret true; } }
|
||||
for p: str in confusing_patterns { if contains(code, p) { ret true; } }
|
||||
ret false;
|
||||
}
|
||||
|
||||
fn file_is_confusing(filename: &istr) -> bool {
|
||||
fn file_is_confusing(filename: &str) -> bool {
|
||||
|
||||
// https://github.com/graydon/rust/issues/674
|
||||
|
||||
|
@ -302,16 +302,16 @@ fn file_is_confusing(filename: &istr) -> bool {
|
|||
// which i can't reproduce using "rustc
|
||||
// --pretty normal"???
|
||||
let confusing_files =
|
||||
[~"block-expr-precedence.rs", ~"nil-pattern.rs",
|
||||
~"syntax-extension-fmt.rs",
|
||||
~"newtype.rs"]; // modifying it hits something like https://github.com/graydon/rust/issues/670
|
||||
["block-expr-precedence.rs", "nil-pattern.rs",
|
||||
"syntax-extension-fmt.rs",
|
||||
"newtype.rs"]; // modifying it hits something like https://github.com/graydon/rust/issues/670
|
||||
|
||||
for f in confusing_files { if contains(filename, f) { ret true; } }
|
||||
|
||||
ret false;
|
||||
}
|
||||
|
||||
fn check_roundtrip_convergence(code: &istr, maxIters: uint) {
|
||||
fn check_roundtrip_convergence(code: &str, maxIters: uint) {
|
||||
|
||||
let i = 0u;
|
||||
let new = code;
|
||||
|
@ -329,16 +329,16 @@ fn check_roundtrip_convergence(code: &istr, maxIters: uint) {
|
|||
log_err #fmt["Converged after %u iterations", i];
|
||||
} else {
|
||||
log_err #fmt["Did not converge after %u iterations!", i];
|
||||
write_file(~"round-trip-a.rs", old);
|
||||
write_file(~"round-trip-b.rs", new);
|
||||
std::run::run_program(~"diff",
|
||||
[~"-w", ~"-u", ~"round-trip-a.rs",
|
||||
~"round-trip-b.rs"]);
|
||||
write_file("round-trip-a.rs", old);
|
||||
write_file("round-trip-b.rs", new);
|
||||
std::run::run_program("diff",
|
||||
["-w", "-u", "round-trip-a.rs",
|
||||
"round-trip-b.rs"]);
|
||||
fail "Mismatch";
|
||||
}
|
||||
}
|
||||
|
||||
fn check_convergence(files: &[istr]) {
|
||||
fn check_convergence(files: &[str]) {
|
||||
log_err #fmt["pp convergence tests: %u files", vec::len(files)];
|
||||
for file in files {
|
||||
if !file_is_confusing(file) {
|
||||
|
@ -352,14 +352,14 @@ fn check_convergence(files: &[istr]) {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_variants(files: &[istr]) {
|
||||
fn check_variants(files: &[str]) {
|
||||
for file in files {
|
||||
if !file_is_confusing(file) {
|
||||
let s = io::read_whole_file_str(file);
|
||||
if content_is_dangerous_to_modify(s) || content_is_confusing(s) {
|
||||
cont;
|
||||
}
|
||||
log_err ~"check_variants: " + file;
|
||||
log_err "check_variants: " + file;
|
||||
let sess = @{cm: codemap::new_codemap(), mutable next_id: 0};
|
||||
let crate =
|
||||
parser::parse_crate_from_source_str(
|
||||
|
@ -374,7 +374,7 @@ fn check_variants(files: &[istr]) {
|
|||
}
|
||||
}
|
||||
|
||||
fn main(args: [istr]) {
|
||||
fn main(args: [str]) {
|
||||
if vec::len(args) != 2u {
|
||||
log_err #fmt["usage: %s <testdir>", args[0]];
|
||||
ret;
|
||||
|
|
|
@ -64,6 +64,7 @@ fn vec_edits<T>(v: &[T], xs: &[T]) -> [[T]] {
|
|||
//if (Lv >= 3u) { edits += ~[vec_reverse(v)]; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
for each i: uint in ix(0u, 1u, Lv) { edits += [vec_omit(v, i)]; }
|
||||
for each i: uint in ix(0u, 1u, Lv) { edits += [vec_dup(v, i)]; }
|
||||
|
|
|
@ -45,6 +45,7 @@ tag request {
|
|||
type ctx = chan<request>;
|
||||
|
||||
fn ip_to_sbuf(ip: net::ip_addr) -> *u8 {
|
||||
|
||||
// FIXME: This is broken. We're creating a vector, getting a pointer
|
||||
// to its buffer, then dropping the vector. On top of that, the vector
|
||||
// created by str::bytes is not null-terminated.
|
||||
|
@ -97,8 +98,7 @@ fn accept_task(client: client, events: chan<server_event>) {
|
|||
fn server_task(ip: net::ip_addr, portnum: int, events: chan<server_event>,
|
||||
server: chan<server>) {
|
||||
let accepter = port();
|
||||
send(server,
|
||||
rustrt::aio_serve(ip_to_sbuf(ip), portnum, chan(accepter)));
|
||||
send(server, rustrt::aio_serve(ip_to_sbuf(ip), portnum, chan(accepter)));
|
||||
|
||||
let client: client;
|
||||
while true {
|
||||
|
|
|
@ -151,11 +151,9 @@ fn to_vec(v: &t) -> [uint] {
|
|||
ret vec::init_fn::<uint>(sub, v.nbits);
|
||||
}
|
||||
|
||||
fn to_str(v: &t) -> istr {
|
||||
let rs = ~"";
|
||||
for i: uint in to_vec(v) {
|
||||
if i == 1u { rs += ~"1"; } else { rs += ~"0"; }
|
||||
}
|
||||
fn to_str(v: &t) -> str {
|
||||
let rs = "";
|
||||
for i: uint in to_vec(v) { if i == 1u { rs += "1"; } else { rs += "0"; } }
|
||||
ret rs;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ native "rust" mod rustrt {
|
|||
type void;
|
||||
type rust_port;
|
||||
|
||||
fn chan_id_send<~T>(target_task: task::task,
|
||||
target_port: port_id, data: -T);
|
||||
fn chan_id_send<~T>(target_task: task::task, target_port: port_id,
|
||||
data: -T);
|
||||
|
||||
fn new_port(unit_sz: uint) -> *rust_port;
|
||||
fn del_port(po: *rust_port);
|
||||
|
|
|
@ -27,6 +27,7 @@ fn create<@T>() -> t<T> {
|
|||
|
||||
|
||||
|
||||
|
||||
fn grow<@T>(nelts: uint, lo: uint, elts: &[mutable cell<T>]) ->
|
||||
[mutable cell<T>] {
|
||||
assert (nelts == vec::len(elts));
|
||||
|
|
|
@ -67,7 +67,7 @@ fn get_doc(d: doc, tg: uint) -> doc {
|
|||
alt maybe_get_doc(d, tg) {
|
||||
some(d) { ret d; }
|
||||
none. {
|
||||
log_err ~"failed to find block with tag " + uint::to_str(tg, 10u);
|
||||
log_err "failed to find block with tag " + uint::to_str(tg, 10u);
|
||||
fail;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,30 +67,30 @@ mod ct {
|
|||
|
||||
|
||||
// A fragment of the output sequence
|
||||
tag piece { piece_string(istr); piece_conv(conv); }
|
||||
type error_fn = fn(&istr) -> ! ;
|
||||
tag piece { piece_string(str); piece_conv(conv); }
|
||||
type error_fn = fn(&str) -> ! ;
|
||||
|
||||
fn parse_fmt_string(s: &istr, error: error_fn) -> [piece] {
|
||||
fn parse_fmt_string(s: &str, error: error_fn) -> [piece] {
|
||||
let pieces: [piece] = [];
|
||||
let lim = str::byte_len(s);
|
||||
let buf = ~"";
|
||||
fn flush_buf(buf: &istr, pieces: &mutable [piece]) -> istr {
|
||||
let buf = "";
|
||||
fn flush_buf(buf: &str, pieces: &mutable [piece]) -> str {
|
||||
if str::byte_len(buf) > 0u {
|
||||
let piece = piece_string(buf);
|
||||
pieces += [piece];
|
||||
}
|
||||
ret ~"";
|
||||
ret "";
|
||||
}
|
||||
let i = 0u;
|
||||
while i < lim {
|
||||
let curr = str::substr(s, i, 1u);
|
||||
if str::eq(curr, ~"%") {
|
||||
if str::eq(curr, "%") {
|
||||
i += 1u;
|
||||
if i >= lim {
|
||||
error(~"unterminated conversion at end of string");
|
||||
error("unterminated conversion at end of string");
|
||||
}
|
||||
let curr2 = str::substr(s, i, 1u);
|
||||
if str::eq(curr2, ~"%") {
|
||||
if str::eq(curr2, "%") {
|
||||
i += 1u;
|
||||
} else {
|
||||
buf = flush_buf(buf, pieces);
|
||||
|
@ -103,7 +103,7 @@ mod ct {
|
|||
buf = flush_buf(buf, pieces);
|
||||
ret pieces;
|
||||
}
|
||||
fn peek_num(s: &istr, i: uint, lim: uint) ->
|
||||
fn peek_num(s: &str, i: uint, lim: uint) ->
|
||||
option::t<{num: uint, next: uint}> {
|
||||
if i >= lim { ret none; }
|
||||
let c = s[i];
|
||||
|
@ -118,7 +118,7 @@ mod ct {
|
|||
}
|
||||
};
|
||||
}
|
||||
fn parse_conversion(s: &istr, i: uint, lim: uint, error: error_fn) ->
|
||||
fn parse_conversion(s: &str, i: uint, lim: uint, error: error_fn) ->
|
||||
{piece: piece, next: uint} {
|
||||
let parm = parse_parameter(s, i, lim);
|
||||
let flags = parse_flags(s, parm.next, lim);
|
||||
|
@ -133,7 +133,7 @@ mod ct {
|
|||
ty: ty.ty}),
|
||||
next: ty.next};
|
||||
}
|
||||
fn parse_parameter(s: &istr, i: uint, lim: uint) ->
|
||||
fn parse_parameter(s: &str, i: uint, lim: uint) ->
|
||||
{param: option::t<int>, next: uint} {
|
||||
if i >= lim { ret {param: none, next: i}; }
|
||||
let num = peek_num(s, i, lim);
|
||||
|
@ -148,14 +148,14 @@ mod ct {
|
|||
}
|
||||
};
|
||||
}
|
||||
fn parse_flags(s: &istr, i: uint, lim: uint) ->
|
||||
fn parse_flags(s: &str, i: uint, lim: uint) ->
|
||||
{flags: [flag], next: uint} {
|
||||
let noflags: [flag] = [];
|
||||
if i >= lim { ret {flags: noflags, next: i}; }
|
||||
|
||||
// FIXME: This recursion generates illegal instructions if the return
|
||||
// value isn't boxed. Only started happening after the ivec conversion
|
||||
fn more_(f: flag, s: &istr, i: uint, lim: uint) ->
|
||||
fn more_(f: flag, s: &str, i: uint, lim: uint) ->
|
||||
@{flags: [flag], next: uint} {
|
||||
let next = parse_flags(s, i + 1u, lim);
|
||||
let rest = next.flags;
|
||||
|
@ -177,8 +177,8 @@ mod ct {
|
|||
*more(flag_alternate)
|
||||
} else { {flags: noflags, next: i} };
|
||||
}
|
||||
fn parse_count(s: &istr, i: uint,
|
||||
lim: uint) -> {count: count, next: uint} {
|
||||
fn parse_count(s: &str, i: uint, lim: uint) ->
|
||||
{count: count, next: uint} {
|
||||
ret if i >= lim {
|
||||
{count: count_implied, next: i}
|
||||
} else if s[i] == '*' as u8 {
|
||||
|
@ -198,7 +198,7 @@ mod ct {
|
|||
}
|
||||
};
|
||||
}
|
||||
fn parse_precision(s: &istr, i: uint, lim: uint) ->
|
||||
fn parse_precision(s: &str, i: uint, lim: uint) ->
|
||||
{count: count, next: uint} {
|
||||
ret if i >= lim {
|
||||
{count: count_implied, next: i}
|
||||
|
@ -214,32 +214,32 @@ mod ct {
|
|||
}
|
||||
} else { {count: count_implied, next: i} };
|
||||
}
|
||||
fn parse_type(s: &istr, i: uint, lim: uint, error: error_fn) ->
|
||||
fn parse_type(s: &str, i: uint, lim: uint, error: error_fn) ->
|
||||
{ty: ty, next: uint} {
|
||||
if i >= lim { error(~"missing type in conversion"); }
|
||||
if i >= lim { error("missing type in conversion"); }
|
||||
let tstr = str::substr(s, i, 1u);
|
||||
// TODO: Do we really want two signed types here?
|
||||
// How important is it to be printf compatible?
|
||||
let t =
|
||||
if str::eq(tstr, ~"b") {
|
||||
if str::eq(tstr, "b") {
|
||||
ty_bool
|
||||
} else if str::eq(tstr, ~"s") {
|
||||
} else if str::eq(tstr, "s") {
|
||||
ty_str
|
||||
} else if str::eq(tstr, ~"c") {
|
||||
} else if str::eq(tstr, "c") {
|
||||
ty_char
|
||||
} else if str::eq(tstr, ~"d") || str::eq(tstr, ~"i") {
|
||||
} else if str::eq(tstr, "d") || str::eq(tstr, "i") {
|
||||
ty_int(signed)
|
||||
} else if str::eq(tstr, ~"u") {
|
||||
} else if str::eq(tstr, "u") {
|
||||
ty_int(unsigned)
|
||||
} else if str::eq(tstr, ~"x") {
|
||||
} else if str::eq(tstr, "x") {
|
||||
ty_hex(case_lower)
|
||||
} else if str::eq(tstr, ~"X") {
|
||||
} else if str::eq(tstr, "X") {
|
||||
ty_hex(case_upper)
|
||||
} else if str::eq(tstr, ~"t") {
|
||||
} else if str::eq(tstr, "t") {
|
||||
ty_bits
|
||||
} else if str::eq(tstr, ~"o") {
|
||||
} else if str::eq(tstr, "o") {
|
||||
ty_octal
|
||||
} else { error(~"unknown type in conversion: " + tstr) };
|
||||
} else { error("unknown type in conversion: " + tstr) };
|
||||
ret {ty: t, next: i + 1u};
|
||||
}
|
||||
}
|
||||
|
@ -270,20 +270,20 @@ mod rt {
|
|||
// instead just use a bool per flag
|
||||
type conv = {flags: [flag], width: count, precision: count, ty: ty};
|
||||
|
||||
fn conv_int(cv: &conv, i: int) -> istr {
|
||||
fn conv_int(cv: &conv, i: int) -> str {
|
||||
let radix = 10u;
|
||||
let prec = get_int_precision(cv);
|
||||
let s = int_to_str_prec(i, radix, prec);
|
||||
if 0 <= i {
|
||||
if have_flag(cv.flags, flag_sign_always) {
|
||||
s = ~"+" + s;
|
||||
s = "+" + s;
|
||||
} else if have_flag(cv.flags, flag_space_for_sign) {
|
||||
s = ~" " + s;
|
||||
s = " " + s;
|
||||
}
|
||||
}
|
||||
ret pad(cv, s, pad_signed);
|
||||
}
|
||||
fn conv_uint(cv: &conv, u: uint) -> istr {
|
||||
fn conv_uint(cv: &conv, u: uint) -> str {
|
||||
let prec = get_int_precision(cv);
|
||||
let rs =
|
||||
alt cv.ty {
|
||||
|
@ -295,17 +295,17 @@ mod rt {
|
|||
};
|
||||
ret pad(cv, rs, pad_unsigned);
|
||||
}
|
||||
fn conv_bool(cv: &conv, b: bool) -> istr {
|
||||
let s = if b { ~"true" } else { ~"false" };
|
||||
fn conv_bool(cv: &conv, b: bool) -> str {
|
||||
let s = if b { "true" } else { "false" };
|
||||
// run the boolean conversion through the string conversion logic,
|
||||
// giving it the same rules for precision, etc.
|
||||
|
||||
ret conv_str(cv, s);
|
||||
}
|
||||
fn conv_char(cv: &conv, c: char) -> istr {
|
||||
fn conv_char(cv: &conv, c: char) -> str {
|
||||
ret pad(cv, str::from_char(c), pad_nozero);
|
||||
}
|
||||
fn conv_str(cv: &conv, s: &istr) -> istr {
|
||||
fn conv_str(cv: &conv, s: &str) -> str {
|
||||
// For strings, precision is the maximum characters
|
||||
// displayed
|
||||
|
||||
|
@ -324,18 +324,18 @@ mod rt {
|
|||
|
||||
// Convert an int to string with minimum number of digits. If precision is
|
||||
// 0 and num is 0 then the result is the empty string.
|
||||
fn int_to_str_prec(num: int, radix: uint, prec: uint) -> istr {
|
||||
fn int_to_str_prec(num: int, radix: uint, prec: uint) -> str {
|
||||
ret if num < 0 {
|
||||
~"-" + uint_to_str_prec(-num as uint, radix, prec)
|
||||
"-" + uint_to_str_prec(-num as uint, radix, prec)
|
||||
} else { uint_to_str_prec(num as uint, radix, prec) };
|
||||
}
|
||||
|
||||
// Convert a uint to string with a minimum number of digits. If precision
|
||||
// is 0 and num is 0 then the result is the empty string. Could move this
|
||||
// to uint: but it doesn't seem all that useful.
|
||||
fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> istr {
|
||||
fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> str {
|
||||
ret if prec == 0u && num == 0u {
|
||||
~""
|
||||
""
|
||||
} else {
|
||||
let s = uint::to_str(num, radix);
|
||||
let len = str::char_len(s);
|
||||
|
@ -354,13 +354,13 @@ mod rt {
|
|||
}
|
||||
|
||||
// FIXME: This might be useful in str: but needs to be utf8 safe first
|
||||
fn str_init_elt(c: char, n_elts: uint) -> istr {
|
||||
fn str_init_elt(c: char, n_elts: uint) -> str {
|
||||
let svec = vec::init_elt::<u8>(c as u8, n_elts);
|
||||
|
||||
ret str::unsafe_from_bytes(svec);
|
||||
}
|
||||
tag pad_mode { pad_signed; pad_unsigned; pad_nozero; }
|
||||
fn pad(cv: &conv, s: &istr, mode: pad_mode) -> istr {
|
||||
fn pad(cv: &conv, s: &str, mode: pad_mode) -> str {
|
||||
let uwidth;
|
||||
alt cv.width {
|
||||
count_implied. { ret s; }
|
||||
|
|
|
@ -6,15 +6,15 @@ native "rust" mod rustrt {
|
|||
fn rust_file_is_dir(path: str::sbuf) -> int;
|
||||
}
|
||||
|
||||
fn path_sep() -> istr { ret str::from_char(os_fs::path_sep); }
|
||||
fn path_sep() -> str { ret str::from_char(os_fs::path_sep); }
|
||||
|
||||
type path = istr;
|
||||
type path = str;
|
||||
|
||||
fn dirname(p: &path) -> path {
|
||||
let i: int = str::rindex(p, os_fs::path_sep as u8);
|
||||
if i == -1 {
|
||||
i = str::rindex(p, os_fs::alt_path_sep as u8);
|
||||
if i == -1 { ret ~"."; }
|
||||
if i == -1 { ret "."; }
|
||||
}
|
||||
ret str::substr(p, 0u, i as uint);
|
||||
}
|
||||
|
@ -42,36 +42,28 @@ fn connect(pre: &path, post: &path) -> path {
|
|||
}
|
||||
|
||||
fn file_is_dir(p: &path) -> bool {
|
||||
ret str::as_buf(p, { |buf|
|
||||
rustrt::rust_file_is_dir(buf) != 0
|
||||
});
|
||||
ret str::as_buf(p, {|buf| rustrt::rust_file_is_dir(buf) != 0 });
|
||||
}
|
||||
|
||||
fn list_dir(p: &path) -> [istr] {
|
||||
fn list_dir(p: &path) -> [str] {
|
||||
let p = p;
|
||||
let pl = str::byte_len(p);
|
||||
if pl == 0u || p[pl - 1u] as char != os_fs::path_sep { p += path_sep(); }
|
||||
let full_paths: [istr] = [];
|
||||
for filename: istr in os_fs::list_dir(p) {
|
||||
if !str::eq(filename, ~".") {
|
||||
if !str::eq(filename, ~"..") { full_paths += [p + filename]; }
|
||||
let full_paths: [str] = [];
|
||||
for filename: str in os_fs::list_dir(p) {
|
||||
if !str::eq(filename, ".") {
|
||||
if !str::eq(filename, "..") { full_paths += [p + filename]; }
|
||||
}
|
||||
}
|
||||
ret full_paths;
|
||||
}
|
||||
|
||||
fn path_is_absolute(p: &path) -> bool {
|
||||
ret os_fs::path_is_absolute(p);
|
||||
}
|
||||
fn path_is_absolute(p: &path) -> bool { ret os_fs::path_is_absolute(p); }
|
||||
|
||||
// FIXME: under Windows, we should prepend the current drive letter to paths
|
||||
// that start with a slash.
|
||||
fn make_absolute(p: &path) -> path {
|
||||
if path_is_absolute(p) {
|
||||
ret p;
|
||||
} else {
|
||||
ret connect(getcwd(), p);
|
||||
}
|
||||
if path_is_absolute(p) { ret p; } else { ret connect(getcwd(), p); }
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -29,53 +29,41 @@ type treemap<@K, @V> = @tree_node<K, V>;
|
|||
|
||||
fn init<@K, @V>() -> treemap<K, V> { @empty }
|
||||
|
||||
fn insert<@K, @V>(m : &treemap<K, V>, k : &K, v : &V) -> treemap<K,V> {
|
||||
fn insert<@K, @V>(m: &treemap<K, V>, k: &K, v: &V) -> treemap<K, V> {
|
||||
@alt m {
|
||||
@empty. {
|
||||
node(@k, @v, @empty, @empty)
|
||||
}
|
||||
@node(@kk, vv, left, right) {
|
||||
if k < kk {
|
||||
node(@kk, vv, insert(left, k, v), right)
|
||||
} else if k == kk {
|
||||
node(@kk, @v, left, right)
|
||||
} else {
|
||||
node(@kk, vv, left, insert(right, k, v))
|
||||
}
|
||||
}
|
||||
}
|
||||
@empty. { node(@k, @v, @empty, @empty) }
|
||||
@node(@kk, vv, left, right) {
|
||||
if k < kk {
|
||||
node(@kk, vv, insert(left, k, v), right)
|
||||
} else if k == kk {
|
||||
node(@kk, @v, left, right)
|
||||
} else { node(@kk, vv, left, insert(right, k, v)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find<@K, @V>(m : &treemap<K, V>, k : &K) -> option<V> {
|
||||
alt *m {
|
||||
empty. { none }
|
||||
node(@kk, @v, left, right) {
|
||||
if k == kk { some(v) }
|
||||
else if k < kk { find(left, k) }
|
||||
else { find(right, k) }
|
||||
fn find<@K, @V>(m: &treemap<K, V>, k: &K) -> option<V> {
|
||||
alt *m {
|
||||
empty. { none }
|
||||
node(@kk, @v, left, right) {
|
||||
if k == kk {
|
||||
some(v)
|
||||
} else if k < kk { find(left, k) } else { find(right, k) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Performs an in-order traversal
|
||||
fn traverse<@K, @V>(m : &treemap<K, V>, f : fn(&K, &V)) {
|
||||
alt *m {
|
||||
empty. { }
|
||||
node(@k, @v, _, _) {
|
||||
// copy v to make aliases work out
|
||||
let v1 = v;
|
||||
alt *m {
|
||||
node(_, _, left, _) {
|
||||
traverse(left, f);
|
||||
}
|
||||
}
|
||||
f(k, v1);
|
||||
alt *m {
|
||||
node(_, _, _, right) {
|
||||
traverse(right, f);
|
||||
}
|
||||
fn traverse<@K, @V>(m: &treemap<K, V>, f: fn(&K, &V)) {
|
||||
alt *m {
|
||||
empty. { }
|
||||
node(@k, @v, _, _) {
|
||||
// copy v to make aliases work out
|
||||
let v1 = v;
|
||||
alt *m { node(_, _, left, _) { traverse(left, f); } }
|
||||
f(k, v1);
|
||||
alt *m { node(_, _, _, right) { traverse(right, f); } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,40 +3,45 @@ import str::sbuf;
|
|||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "macos")]
|
||||
fn getenv(n: &istr) -> option::t<istr> {
|
||||
let s = str::as_buf(n, { |buf|
|
||||
os::libc::getenv(buf)
|
||||
});
|
||||
fn getenv(n: &str) -> option::t<str> {
|
||||
let s = str::as_buf(n, {|buf| os::libc::getenv(buf) });
|
||||
ret if unsafe::reinterpret_cast(s) == 0 {
|
||||
option::none::<istr>
|
||||
} else {
|
||||
let s = unsafe::reinterpret_cast(s);
|
||||
option::some::<istr>(str::str_from_cstr(s))
|
||||
};
|
||||
option::none::<str>
|
||||
} else {
|
||||
let s = unsafe::reinterpret_cast(s);
|
||||
option::some::<str>(str::str_from_cstr(s))
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "macos")]
|
||||
fn setenv(n: &istr, v: &istr) {
|
||||
fn setenv(n: &str, v: &str) {
|
||||
// FIXME (868)
|
||||
let _: () = str::as_buf(n, { |nbuf|
|
||||
// FIXME (868)
|
||||
let _: () = str::as_buf(v, { |vbuf|
|
||||
os::libc::setenv(nbuf, vbuf, 1);
|
||||
});
|
||||
});
|
||||
let _: () =
|
||||
str::as_buf(n,
|
||||
// FIXME (868)
|
||||
{|nbuf|
|
||||
let _: () =
|
||||
str::as_buf(v,
|
||||
{|vbuf|
|
||||
os::libc::setenv(nbuf, vbuf, 1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(target_os = "win32")]
|
||||
fn getenv(n: &istr) -> option::t<istr> {
|
||||
fn getenv(n: &str) -> option::t<str> {
|
||||
let nsize = 256u;
|
||||
while true {
|
||||
let v: [u8] = [];
|
||||
vec::reserve(v, nsize);
|
||||
let res = str::as_buf(n, { |nbuf|
|
||||
let vbuf = vec::to_ptr(v);
|
||||
os::kernel32::GetEnvironmentVariableA(nbuf, vbuf, nsize)
|
||||
});
|
||||
let res =
|
||||
str::as_buf(n,
|
||||
{|nbuf|
|
||||
let vbuf = vec::to_ptr(v);
|
||||
os::kernel32::GetEnvironmentVariableA(nbuf, vbuf,
|
||||
nsize)
|
||||
});
|
||||
if res == 0u {
|
||||
ret option::none;
|
||||
} else if res < nsize {
|
||||
|
@ -48,10 +53,10 @@ fn getenv(n: &istr) -> option::t<istr> {
|
|||
}
|
||||
|
||||
#[cfg(target_os = "win32")]
|
||||
fn setenv(n: &istr, v: &istr) {
|
||||
fn setenv(n: &str, v: &str) {
|
||||
// FIXME (868)
|
||||
let _: () = str::as_buf(n, { |nbuf|
|
||||
let _: () = str::as_buf(v, { |vbuf|
|
||||
let _: () = str::as_buf(n, {|nbuf|
|
||||
let _: () = str::as_buf(v, {|vbuf|
|
||||
os::kernel32::SetEnvironmentVariableA(nbuf, vbuf);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -29,7 +29,7 @@ export opt_strs;
|
|||
export opt_maybe_str;
|
||||
export opt_default;
|
||||
|
||||
tag name { long(istr); short(char); }
|
||||
tag name { long(str); short(char); }
|
||||
|
||||
tag hasarg { yes; no; maybe; }
|
||||
|
||||
|
@ -37,41 +37,41 @@ tag occur { req; optional; multi; }
|
|||
|
||||
type opt = {name: name, hasarg: hasarg, occur: occur};
|
||||
|
||||
fn mkname(nm: &istr) -> name {
|
||||
fn mkname(nm: &str) -> name {
|
||||
ret if str::char_len(nm) == 1u {
|
||||
short(str::char_at(nm, 0u))
|
||||
} else { long(nm) };
|
||||
}
|
||||
|
||||
fn reqopt(name: &istr) -> opt {
|
||||
fn reqopt(name: &str) -> opt {
|
||||
ret {name: mkname(name), hasarg: yes, occur: req};
|
||||
}
|
||||
|
||||
fn optopt(name: &istr) -> opt {
|
||||
fn optopt(name: &str) -> opt {
|
||||
ret {name: mkname(name), hasarg: yes, occur: optional};
|
||||
}
|
||||
|
||||
fn optflag(name: &istr) -> opt {
|
||||
fn optflag(name: &str) -> opt {
|
||||
ret {name: mkname(name), hasarg: no, occur: optional};
|
||||
}
|
||||
|
||||
fn optflagopt(name: &istr) -> opt {
|
||||
fn optflagopt(name: &str) -> opt {
|
||||
ret {name: mkname(name), hasarg: maybe, occur: optional};
|
||||
}
|
||||
|
||||
fn optmulti(name: &istr) -> opt {
|
||||
fn optmulti(name: &str) -> opt {
|
||||
ret {name: mkname(name), hasarg: yes, occur: multi};
|
||||
}
|
||||
|
||||
tag optval { val(istr); given; }
|
||||
tag optval { val(str); given; }
|
||||
|
||||
type match = {opts: [opt], vals: [mutable [optval]], free: [istr]};
|
||||
type match = {opts: [opt], vals: [mutable [optval]], free: [str]};
|
||||
|
||||
fn is_arg(arg: &istr) -> bool {
|
||||
fn is_arg(arg: &str) -> bool {
|
||||
ret str::byte_len(arg) > 1u && arg[0] == '-' as u8;
|
||||
}
|
||||
|
||||
fn name_str(nm: &name) -> istr {
|
||||
fn name_str(nm: &name) -> str {
|
||||
ret alt nm { short(ch) { str::from_char(ch) } long(s) { s } };
|
||||
}
|
||||
|
||||
|
@ -83,36 +83,34 @@ fn find_opt(opts: &[opt], nm: &name) -> option::t<uint> {
|
|||
}
|
||||
|
||||
tag fail_ {
|
||||
argument_missing(istr);
|
||||
unrecognized_option(istr);
|
||||
option_missing(istr);
|
||||
option_duplicated(istr);
|
||||
unexpected_argument(istr);
|
||||
argument_missing(str);
|
||||
unrecognized_option(str);
|
||||
option_missing(str);
|
||||
option_duplicated(str);
|
||||
unexpected_argument(str);
|
||||
}
|
||||
|
||||
fn fail_str(f: &fail_) -> istr {
|
||||
fn fail_str(f: &fail_) -> str {
|
||||
ret alt f {
|
||||
argument_missing(nm) {
|
||||
~"Argument to option '" + nm + ~"' missing." }
|
||||
unrecognized_option(nm) {
|
||||
~"Unrecognized option: '" + nm + ~"'." }
|
||||
option_missing(nm) { ~"Required option '" + nm + ~"' missing." }
|
||||
argument_missing(nm) { "Argument to option '" + nm + "' missing." }
|
||||
unrecognized_option(nm) { "Unrecognized option: '" + nm + "'." }
|
||||
option_missing(nm) { "Required option '" + nm + "' missing." }
|
||||
option_duplicated(nm) {
|
||||
~"Option '" + nm + ~"' given more than once."
|
||||
"Option '" + nm + "' given more than once."
|
||||
}
|
||||
unexpected_argument(nm) {
|
||||
~"Option " + nm + ~" does not take an argument."
|
||||
"Option " + nm + " does not take an argument."
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
tag result { success(match); failure(fail_); }
|
||||
|
||||
fn getopts(args: &[istr], opts: &[opt]) -> result {
|
||||
fn getopts(args: &[str], opts: &[opt]) -> result {
|
||||
let n_opts = vec::len::<opt>(opts);
|
||||
fn f(_x: uint) -> [optval] { ret []; }
|
||||
let vals = vec::init_fn_mut::<[optval]>(f, n_opts);
|
||||
let free: [istr] = [];
|
||||
let free: [str] = [];
|
||||
let l = vec::len(args);
|
||||
let i = 0u;
|
||||
while i < l {
|
||||
|
@ -120,13 +118,13 @@ fn getopts(args: &[istr], opts: &[opt]) -> result {
|
|||
let curlen = str::byte_len(cur);
|
||||
if !is_arg(cur) {
|
||||
free += [cur];
|
||||
} else if str::eq(cur, ~"--") {
|
||||
} else if str::eq(cur, "--") {
|
||||
let j = i + 1u;
|
||||
while j < l { free += [args[j]]; j += 1u; }
|
||||
break;
|
||||
} else {
|
||||
let names;
|
||||
let i_arg = option::none::<istr>;
|
||||
let i_arg = option::none::<str>;
|
||||
if cur[1] == '-' as u8 {
|
||||
let tail = str::slice(cur, 2u, curlen);
|
||||
let eq = str::index(tail, '=' as u8);
|
||||
|
@ -135,9 +133,9 @@ fn getopts(args: &[istr], opts: &[opt]) -> result {
|
|||
} else {
|
||||
names = [long(str::slice(tail, 0u, eq as uint))];
|
||||
i_arg =
|
||||
option::some::<istr>(str::slice(tail,
|
||||
(eq as uint) + 1u,
|
||||
curlen - 2u));
|
||||
option::some::<str>(str::slice(tail,
|
||||
(eq as uint) + 1u,
|
||||
curlen - 2u));
|
||||
}
|
||||
} else {
|
||||
let j = 1u;
|
||||
|
@ -158,13 +156,13 @@ fn getopts(args: &[istr], opts: &[opt]) -> result {
|
|||
}
|
||||
alt opts[optid].hasarg {
|
||||
no. {
|
||||
if !option::is_none::<istr>(i_arg) {
|
||||
if !option::is_none::<str>(i_arg) {
|
||||
ret failure(unexpected_argument(name_str(nm)));
|
||||
}
|
||||
vals[optid] += [given];
|
||||
}
|
||||
maybe. {
|
||||
if !option::is_none::<istr>(i_arg) {
|
||||
if !option::is_none::<str>(i_arg) {
|
||||
vals[optid] += [val(option::get(i_arg))];
|
||||
} else if name_pos < vec::len::<name>(names) ||
|
||||
i + 1u == l || is_arg(args[i + 1u]) {
|
||||
|
@ -172,8 +170,8 @@ fn getopts(args: &[istr], opts: &[opt]) -> result {
|
|||
} else { i += 1u; vals[optid] += [val(args[i])]; }
|
||||
}
|
||||
yes. {
|
||||
if !option::is_none::<istr>(i_arg) {
|
||||
vals[optid] += [val(option::get::<istr>(i_arg))];
|
||||
if !option::is_none::<str>(i_arg) {
|
||||
vals[optid] += [val(option::get::<str>(i_arg))];
|
||||
} else if i + 1u == l {
|
||||
ret failure(argument_missing(name_str(nm)));
|
||||
} else { i += 1u; vals[optid] += [val(args[i])]; }
|
||||
|
@ -202,45 +200,45 @@ fn getopts(args: &[istr], opts: &[opt]) -> result {
|
|||
ret success({opts: opts, vals: vals, free: free});
|
||||
}
|
||||
|
||||
fn opt_vals(m: &match, nm: &istr) -> [optval] {
|
||||
fn opt_vals(m: &match, nm: &str) -> [optval] {
|
||||
ret alt find_opt(m.opts, mkname(nm)) {
|
||||
some(id) { m.vals[id] }
|
||||
none. { log_err ~"No option '" + nm + ~"' defined."; fail }
|
||||
none. { log_err "No option '" + nm + "' defined."; fail }
|
||||
};
|
||||
}
|
||||
|
||||
fn opt_val(m: &match, nm: &istr) -> optval { ret opt_vals(m, nm)[0]; }
|
||||
fn opt_val(m: &match, nm: &str) -> optval { ret opt_vals(m, nm)[0]; }
|
||||
|
||||
fn opt_present(m: &match, nm: &istr) -> bool {
|
||||
fn opt_present(m: &match, nm: &str) -> bool {
|
||||
ret vec::len::<optval>(opt_vals(m, nm)) > 0u;
|
||||
}
|
||||
|
||||
fn opt_str(m: &match, nm: &istr) -> istr {
|
||||
fn opt_str(m: &match, nm: &str) -> str {
|
||||
ret alt opt_val(m, nm) { val(s) { s } _ { fail } };
|
||||
}
|
||||
|
||||
fn opt_strs(m: &match, nm: &istr) -> [istr] {
|
||||
let acc: [istr] = [];
|
||||
fn opt_strs(m: &match, nm: &str) -> [str] {
|
||||
let acc: [str] = [];
|
||||
for v: optval in opt_vals(m, nm) {
|
||||
alt v { val(s) { acc += [s]; } _ { } }
|
||||
}
|
||||
ret acc;
|
||||
}
|
||||
|
||||
fn opt_maybe_str(m: &match, nm: &istr) -> option::t<istr> {
|
||||
fn opt_maybe_str(m: &match, nm: &str) -> option::t<str> {
|
||||
let vals = opt_vals(m, nm);
|
||||
if vec::len::<optval>(vals) == 0u { ret none::<istr>; }
|
||||
ret alt vals[0] { val(s) { some::<istr>(s) } _ { none::<istr> } };
|
||||
if vec::len::<optval>(vals) == 0u { ret none::<str>; }
|
||||
ret alt vals[0] { val(s) { some::<str>(s) } _ { none::<str> } };
|
||||
}
|
||||
|
||||
|
||||
/// Returns none if the option was not present, `def` if the option was
|
||||
/// present but no argument was provided, and the argument if the option was
|
||||
/// present and an argument was provided.
|
||||
fn opt_default(m: &match, nm: &istr, def: &istr) -> option::t<istr> {
|
||||
fn opt_default(m: &match, nm: &str, def: &str) -> option::t<str> {
|
||||
let vals = opt_vals(m, nm);
|
||||
if vec::len::<optval>(vals) == 0u { ret none::<istr>; }
|
||||
ret alt vals[0] { val(s) { some::<istr>(s) } _ { some::<istr>(def) } }
|
||||
if vec::len::<optval>(vals) == 0u { ret none::<str>; }
|
||||
ret alt vals[0] { val(s) { some::<str>(s) } _ { some::<str>(def) } }
|
||||
}
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
|
|
|
@ -41,13 +41,13 @@ iter range(lo: int, hi: int) -> int {
|
|||
while lo_ < hi { put lo_; lo_ += 1; }
|
||||
}
|
||||
|
||||
fn to_str(n: int, radix: uint) -> istr {
|
||||
fn to_str(n: int, radix: uint) -> str {
|
||||
assert (0u < radix && radix <= 16u);
|
||||
ret if n < 0 {
|
||||
~"-" + uint::to_str(-n as uint, radix)
|
||||
"-" + uint::to_str(-n as uint, radix)
|
||||
} else { uint::to_str(n as uint, radix) };
|
||||
}
|
||||
fn str(i: int) -> istr { ret to_str(i, 10u); }
|
||||
fn str(i: int) -> str { ret to_str(i, 10u); }
|
||||
|
||||
fn pow(base: int, exponent: uint) -> int {
|
||||
ret if exponent == 0u {
|
||||
|
|
|
@ -40,8 +40,8 @@ type reader =
|
|||
fn read_bytes(uint) -> [u8];
|
||||
fn read_char() -> char;
|
||||
fn eof() -> bool;
|
||||
fn read_line() -> istr;
|
||||
fn read_c_str() -> istr;
|
||||
fn read_line() -> str;
|
||||
fn read_c_str() -> str;
|
||||
fn read_le_uint(uint) -> uint;
|
||||
fn read_le_int(uint) -> int;
|
||||
fn read_be_uint(uint) -> uint;
|
||||
|
@ -60,8 +60,8 @@ obj FILE_buf_reader(f: os::libc::FILE, res: option::t<@FILE_res>) {
|
|||
fn read(len: uint) -> [u8] {
|
||||
let buf = [];
|
||||
vec::reserve::<u8>(buf, len);
|
||||
let read = os::libc::fread(vec::unsafe::to_ptr::<u8>(buf),
|
||||
1u, len, f);
|
||||
let read =
|
||||
os::libc::fread(vec::unsafe::to_ptr::<u8>(buf), 1u, len, f);
|
||||
vec::unsafe::set_len::<u8>(buf, read);
|
||||
ret buf;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ obj new_reader(rdr: buf_reader) {
|
|||
ret val as char;
|
||||
}
|
||||
fn eof() -> bool { ret rdr.eof(); }
|
||||
fn read_line() -> istr {
|
||||
fn read_line() -> str {
|
||||
let buf: [u8] = [];
|
||||
// No break yet in rustc
|
||||
|
||||
|
@ -119,7 +119,7 @@ obj new_reader(rdr: buf_reader) {
|
|||
}
|
||||
ret str::unsafe_from_bytes(buf);
|
||||
}
|
||||
fn read_c_str() -> istr {
|
||||
fn read_c_str() -> str {
|
||||
let buf: [u8] = [];
|
||||
let go_on = true;
|
||||
while go_on {
|
||||
|
@ -174,13 +174,16 @@ fn stdin() -> reader {
|
|||
ret new_reader(FILE_buf_reader(rustrt::rust_get_stdin(), option::none));
|
||||
}
|
||||
|
||||
fn file_reader(path: &istr) -> reader {
|
||||
let f = str::as_buf(path, { |pathbuf|
|
||||
str::as_buf(~"r", { |modebuf|
|
||||
os::libc::fopen(pathbuf, modebuf)
|
||||
})
|
||||
});
|
||||
if f as uint == 0u { log_err ~"error opening " + path; fail; }
|
||||
fn file_reader(path: &str) -> reader {
|
||||
let f =
|
||||
str::as_buf(path,
|
||||
{|pathbuf|
|
||||
str::as_buf("r",
|
||||
{|modebuf|
|
||||
os::libc::fopen(pathbuf, modebuf)
|
||||
})
|
||||
});
|
||||
if f as uint == 0u { log_err "error opening " + path; fail; }
|
||||
ret new_reader(FILE_buf_reader(f, option::some(@FILE_res(f))));
|
||||
}
|
||||
|
||||
|
@ -219,7 +222,7 @@ fn new_byte_buf_reader(buf: &[u8]) -> buf_reader {
|
|||
ret byte_buf_reader(@{buf: buf, mutable pos: 0u});
|
||||
}
|
||||
|
||||
fn string_reader(s: &istr) -> reader {
|
||||
fn string_reader(s: &str) -> reader {
|
||||
ret new_reader(new_byte_buf_reader(str::bytes(s)));
|
||||
}
|
||||
|
||||
|
@ -279,7 +282,7 @@ obj fd_buf_writer(fd: int, res: option::t<@fd_res>) {
|
|||
}
|
||||
}
|
||||
|
||||
fn file_buf_writer(path: &istr, flags: &[fileflag]) -> buf_writer {
|
||||
fn file_buf_writer(path: &str, flags: &[fileflag]) -> buf_writer {
|
||||
let fflags: int =
|
||||
os::libc_constants::O_WRONLY() | os::libc_constants::O_BINARY();
|
||||
for f: fileflag in flags {
|
||||
|
@ -290,11 +293,13 @@ fn file_buf_writer(path: &istr, flags: &[fileflag]) -> buf_writer {
|
|||
none. { }
|
||||
}
|
||||
}
|
||||
let fd = str::as_buf(path, { |pathbuf|
|
||||
os::libc::open(pathbuf, fflags,
|
||||
os::libc_constants::S_IRUSR() |
|
||||
os::libc_constants::S_IWUSR())
|
||||
});
|
||||
let fd =
|
||||
str::as_buf(path,
|
||||
{|pathbuf|
|
||||
os::libc::open(pathbuf, fflags,
|
||||
os::libc_constants::S_IRUSR() |
|
||||
os::libc_constants::S_IWUSR())
|
||||
});
|
||||
if fd < 0 {
|
||||
log_err "error opening file for writing";
|
||||
log_err sys::rustrt::last_os_error();
|
||||
|
@ -308,8 +313,8 @@ type writer =
|
|||
// function will be provided for general encoded string output
|
||||
obj {
|
||||
fn get_buf_writer() -> buf_writer;
|
||||
fn write_str(&istr);
|
||||
fn write_line(&istr);
|
||||
fn write_str(&str);
|
||||
fn write_line(&str);
|
||||
fn write_char(char);
|
||||
fn write_int(int);
|
||||
fn write_uint(uint);
|
||||
|
@ -334,20 +339,18 @@ fn uint_to_be_bytes(n: uint, size: uint) -> [u8] {
|
|||
|
||||
obj new_writer(out: buf_writer) {
|
||||
fn get_buf_writer() -> buf_writer { ret out; }
|
||||
fn write_str(s: &istr) { out.write(str::bytes(s)); }
|
||||
fn write_line(s: &istr) {
|
||||
fn write_str(s: &str) { out.write(str::bytes(s)); }
|
||||
fn write_line(s: &str) {
|
||||
out.write(str::bytes(s));
|
||||
out.write(str::bytes(~"\n"));
|
||||
out.write(str::bytes("\n"));
|
||||
}
|
||||
fn write_char(ch: char) {
|
||||
// FIXME needlessly consy
|
||||
|
||||
out.write(str::bytes(str::from_char(ch)));
|
||||
}
|
||||
fn write_int(n: int) { out.write(str::bytes(
|
||||
int::to_str(n, 10u))); }
|
||||
fn write_uint(n: uint) { out.write(str::bytes(
|
||||
uint::to_str(n, 10u))); }
|
||||
fn write_int(n: int) { out.write(str::bytes(int::to_str(n, 10u))); }
|
||||
fn write_uint(n: uint) { out.write(str::bytes(uint::to_str(n, 10u))); }
|
||||
fn write_bytes(bytes: &[u8]) { out.write(bytes); }
|
||||
fn write_le_uint(n: uint, size: uint) {
|
||||
out.write(uint_to_le_bytes(n, size));
|
||||
|
@ -360,19 +363,22 @@ obj new_writer(out: buf_writer) {
|
|||
}
|
||||
}
|
||||
|
||||
fn file_writer(path: &istr, flags: &[fileflag]) -> writer {
|
||||
fn file_writer(path: &str, flags: &[fileflag]) -> writer {
|
||||
ret new_writer(file_buf_writer(path, flags));
|
||||
}
|
||||
|
||||
|
||||
// FIXME: fileflags
|
||||
fn buffered_file_buf_writer(path: &istr) -> buf_writer {
|
||||
let f = str::as_buf(path, { |pathbuf|
|
||||
str::as_buf(~"w", { |modebuf|
|
||||
os::libc::fopen(pathbuf, modebuf)
|
||||
})
|
||||
});
|
||||
if f as uint == 0u { log_err ~"error opening " + path; fail; }
|
||||
fn buffered_file_buf_writer(path: &str) -> buf_writer {
|
||||
let f =
|
||||
str::as_buf(path,
|
||||
{|pathbuf|
|
||||
str::as_buf("w",
|
||||
{|modebuf|
|
||||
os::libc::fopen(pathbuf, modebuf)
|
||||
})
|
||||
});
|
||||
if f as uint == 0u { log_err "error opening " + path; fail; }
|
||||
ret FILE_writer(f, option::some(@FILE_res(f)));
|
||||
}
|
||||
|
||||
|
@ -384,7 +390,7 @@ fn stderr() -> writer { ret new_writer(fd_buf_writer(2, option::none)); }
|
|||
type str_writer =
|
||||
obj {
|
||||
fn get_writer() -> writer;
|
||||
fn get_str() -> istr;
|
||||
fn get_str() -> str;
|
||||
};
|
||||
|
||||
type mutable_byte_buf = @{mutable buf: [mutable u8], mutable pos: uint};
|
||||
|
@ -427,7 +433,7 @@ fn string_writer() -> str_writer {
|
|||
let buf: mutable_byte_buf = @{mutable buf: b, mutable pos: 0u};
|
||||
obj str_writer_wrap(wr: writer, buf: mutable_byte_buf) {
|
||||
fn get_writer() -> writer { ret wr; }
|
||||
fn get_str() -> istr { ret str::unsafe_from_bytes(buf.buf); }
|
||||
fn get_str() -> str { ret str::unsafe_from_bytes(buf.buf); }
|
||||
}
|
||||
ret str_writer_wrap(new_writer(byte_buf_writer(buf)), buf);
|
||||
}
|
||||
|
@ -447,11 +453,11 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) ->
|
|||
ret bpos as uint;
|
||||
}
|
||||
|
||||
fn read_whole_file_str(file: &istr) -> istr {
|
||||
fn read_whole_file_str(file: &str) -> str {
|
||||
str::unsafe_from_bytes(read_whole_file(file))
|
||||
}
|
||||
|
||||
fn read_whole_file(file: &istr) -> [u8] {
|
||||
fn read_whole_file(file: &str) -> [u8] {
|
||||
|
||||
// FIXME: There's a lot of copying here
|
||||
file_reader(file).read_whole_stream()
|
||||
|
|
|
@ -50,11 +50,11 @@ mod libc_constants {
|
|||
fn S_IWUSR() -> uint { ret 128u; }
|
||||
}
|
||||
|
||||
fn exec_suffix() -> istr { ret ~""; }
|
||||
fn exec_suffix() -> str { ret ""; }
|
||||
|
||||
fn target_os() -> istr { ret ~"linux"; }
|
||||
fn target_os() -> str { ret "linux"; }
|
||||
|
||||
fn dylib_filename(base: &istr) -> istr { ret ~"lib" + base + ~".so"; }
|
||||
fn dylib_filename(base: &str) -> str { ret "lib" + base + ".so"; }
|
||||
|
||||
fn pipe() -> {in: int, out: int} {
|
||||
let fds = {mutable in: 0, mutable out: 0};
|
||||
|
@ -63,9 +63,7 @@ fn pipe() -> {in: int, out: int} {
|
|||
}
|
||||
|
||||
fn fd_FILE(fd: int) -> libc::FILE {
|
||||
ret str::as_buf(~"r", { |modebuf|
|
||||
libc::fdopen(fd, modebuf)
|
||||
});
|
||||
ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) });
|
||||
}
|
||||
|
||||
fn waitpid(pid: int) -> int {
|
||||
|
@ -75,12 +73,10 @@ fn waitpid(pid: int) -> int {
|
|||
}
|
||||
|
||||
native "rust" mod rustrt {
|
||||
fn rust_getcwd() -> istr;
|
||||
fn rust_getcwd() -> str;
|
||||
}
|
||||
|
||||
fn getcwd() -> istr {
|
||||
ret rustrt::rust_getcwd();
|
||||
}
|
||||
fn getcwd() -> str { ret rustrt::rust_getcwd(); }
|
||||
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -47,11 +47,11 @@ mod libc_constants {
|
|||
fn S_IWUSR() -> uint { ret 512u; }
|
||||
}
|
||||
|
||||
fn exec_suffix() -> istr { ret ~""; }
|
||||
fn exec_suffix() -> str { ret ""; }
|
||||
|
||||
fn target_os() -> istr { ret ~"macos"; }
|
||||
fn target_os() -> str { ret "macos"; }
|
||||
|
||||
fn dylib_filename(base: &istr) -> istr { ret ~"lib" + base + ~".dylib"; }
|
||||
fn dylib_filename(base: &str) -> str { ret "lib" + base + ".dylib"; }
|
||||
|
||||
fn pipe() -> {in: int, out: int} {
|
||||
let fds = {mutable in: 0, mutable out: 0};
|
||||
|
@ -60,9 +60,7 @@ fn pipe() -> {in: int, out: int} {
|
|||
}
|
||||
|
||||
fn fd_FILE(fd: int) -> libc::FILE {
|
||||
ret str::as_buf(~"r", { |modebuf|
|
||||
libc::fdopen(fd, modebuf)
|
||||
});
|
||||
ret str::as_buf("r", {|modebuf| libc::fdopen(fd, modebuf) });
|
||||
}
|
||||
|
||||
fn waitpid(pid: int) -> int {
|
||||
|
@ -72,12 +70,10 @@ fn waitpid(pid: int) -> int {
|
|||
}
|
||||
|
||||
native "rust" mod rustrt {
|
||||
fn rust_getcwd() -> istr;
|
||||
fn rust_getcwd() -> str;
|
||||
}
|
||||
|
||||
fn getcwd() -> istr {
|
||||
ret rustrt::rust_getcwd();
|
||||
}
|
||||
fn getcwd() -> str { ret rustrt::rust_getcwd(); }
|
||||
|
||||
|
||||
// Local Variables:
|
||||
|
|
|
@ -194,7 +194,7 @@ fn mk_hashmap<@K, @V>(hasher: &hashfn<K>, eqer: &eqfn<K>) -> hashmap<K, V> {
|
|||
|
||||
// Hash map constructors for basic types
|
||||
|
||||
fn new_str_hash<@V>() -> hashmap<istr, V> {
|
||||
fn new_str_hash<@V>() -> hashmap<str, V> {
|
||||
ret mk_hashmap(str::hash, str::eq);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import uint;
|
|||
|
||||
tag ip_addr { ipv4(u8, u8, u8, u8); }
|
||||
|
||||
fn format_addr(ip: ip_addr) -> istr {
|
||||
fn format_addr(ip: ip_addr) -> str {
|
||||
alt ip {
|
||||
ipv4(a, b, c, d) {
|
||||
#fmt["%u.%u.%u.%u", a as uint, b as uint, c as uint, d as uint]
|
||||
|
@ -12,10 +12,8 @@ fn format_addr(ip: ip_addr) -> istr {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_addr(ip: &istr) -> ip_addr {
|
||||
let parts = vec::map(
|
||||
{ |&s| uint::from_str(s) },
|
||||
str::split(ip, ~"."[0]));
|
||||
fn parse_addr(ip: &str) -> ip_addr {
|
||||
let parts = vec::map({|&s| uint::from_str(s) }, str::split(ip, "."[0]));
|
||||
if vec::len(parts) != 4u { fail "Too many dots in IP address"; }
|
||||
for i in parts { if i > 255u { fail "Invalid IP Address part."; } }
|
||||
ipv4(parts[0] as u8, parts[1] as u8, parts[2] as u8, parts[3] as u8)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
native "rust" mod rustrt {
|
||||
fn rust_list_files(path: &istr) -> [istr];
|
||||
fn rust_list_files(path: &str) -> [str];
|
||||
}
|
||||
|
||||
fn list_dir(path: &istr) -> [istr] {
|
||||
fn list_dir(path: &str) -> [str] {
|
||||
ret rustrt::rust_list_files(path);
|
||||
|
||||
// FIXME: No idea why, but this appears to corrupt memory on OSX. I
|
||||
|
@ -30,7 +30,7 @@ fn list_dir(path: &istr) -> [istr] {
|
|||
|
||||
}
|
||||
|
||||
fn path_is_absolute(p: &istr) -> bool { ret str::char_at(p, 0u) == '/'; }
|
||||
fn path_is_absolute(p: &str) -> bool { ret str::char_at(p, 0u) == '/'; }
|
||||
|
||||
const path_sep: char = '/';
|
||||
|
||||
|
|
|
@ -12,29 +12,27 @@ native "rust" mod rustrt {
|
|||
int;
|
||||
}
|
||||
|
||||
fn arg_vec(prog: &istr, args: &[@istr]) -> [sbuf] {
|
||||
let argptrs = str::as_buf(prog, { |buf| [buf] });
|
||||
for arg in args {
|
||||
argptrs += str::as_buf(*arg, { |buf| [buf] });
|
||||
}
|
||||
fn arg_vec(prog: &str, args: &[@str]) -> [sbuf] {
|
||||
let argptrs = str::as_buf(prog, {|buf| [buf] });
|
||||
for arg in args { argptrs += str::as_buf(*arg, {|buf| [buf] }); }
|
||||
argptrs += [unsafe::reinterpret_cast(0)];
|
||||
ret argptrs;
|
||||
}
|
||||
|
||||
fn spawn_process(prog: &istr, args: &[istr], in_fd: int, out_fd: int,
|
||||
fn spawn_process(prog: &str, args: &[str], in_fd: int, out_fd: int,
|
||||
err_fd: int) -> int {
|
||||
// Note: we have to hold on to these vector references while we hold a
|
||||
// pointer to their buffers
|
||||
let prog = prog;
|
||||
let args = vec::map({ |&arg| @arg }, args);
|
||||
let args = vec::map({|&arg| @arg }, args);
|
||||
let argv = arg_vec(prog, args);
|
||||
let pid =
|
||||
rustrt::rust_run_program(vec::unsafe::to_ptr(argv),
|
||||
in_fd, out_fd, err_fd);
|
||||
rustrt::rust_run_program(vec::unsafe::to_ptr(argv), in_fd, out_fd,
|
||||
err_fd);
|
||||
ret pid;
|
||||
}
|
||||
|
||||
fn run_program(prog: &istr, args: &[istr]) -> int {
|
||||
fn run_program(prog: &str, args: &[str]) -> int {
|
||||
ret os::waitpid(spawn_process(prog, args, 0, 0, 0));
|
||||
}
|
||||
|
||||
|
@ -51,7 +49,7 @@ type program =
|
|||
|
||||
resource program_res(p: program) { p.destroy(); }
|
||||
|
||||
fn start_program(prog: &istr, args: &[istr]) -> @program_res {
|
||||
fn start_program(prog: &str, args: &[str]) -> @program_res {
|
||||
let pipe_input = os::pipe();
|
||||
let pipe_output = os::pipe();
|
||||
let pipe_err = os::pipe();
|
||||
|
@ -102,8 +100,8 @@ fn start_program(prog: &istr, args: &[istr]) -> @program_res {
|
|||
os::fd_FILE(pipe_err.in), false));
|
||||
}
|
||||
|
||||
fn read_all(rd: &io::reader) -> istr {
|
||||
let buf = ~"";
|
||||
fn read_all(rd: &io::reader) -> str {
|
||||
let buf = "";
|
||||
while !rd.eof() {
|
||||
let bytes = rd.read_bytes(4096u);
|
||||
buf += str::unsafe_from_bytes(bytes);
|
||||
|
@ -111,8 +109,8 @@ fn read_all(rd: &io::reader) -> istr {
|
|||
ret buf;
|
||||
}
|
||||
|
||||
fn program_output(prog: &istr, args: &[istr]) ->
|
||||
{status: int, out: istr, err: istr} {
|
||||
fn program_output(prog: &str, args: &[str]) ->
|
||||
{status: int, out: str, err: str} {
|
||||
let pr = start_program(prog, args);
|
||||
pr.close_input();
|
||||
ret {status: pr.finish(),
|
||||
|
|
|
@ -6,20 +6,21 @@
|
|||
export sha1;
|
||||
export mk_sha1;
|
||||
|
||||
type sha1 = obj {
|
||||
type sha1 =
|
||||
// Provide message input as bytes
|
||||
fn input(&[u8]);
|
||||
// Provide message input as string
|
||||
fn input_str(&istr);
|
||||
// Read the digest as a vector of 20 bytes. After calling this no further
|
||||
// input may provided until reset is called
|
||||
fn result() -> [u8];
|
||||
// Same as above, just a hex-string version.
|
||||
fn result_str() -> istr;
|
||||
// Reset the sha1 state for reuse. This is called
|
||||
// automatically during construction
|
||||
fn reset();
|
||||
};
|
||||
obj {
|
||||
fn input(&[u8]);
|
||||
fn input_str(&str);
|
||||
fn result() -> [u8];
|
||||
fn result_str() -> str;
|
||||
fn reset();
|
||||
};
|
||||
|
||||
|
||||
// Some unexported constants
|
||||
|
@ -215,14 +216,12 @@ fn mk_sha1() -> sha1 {
|
|||
st.computed = false;
|
||||
}
|
||||
fn input(msg: &[u8]) { add_input(st, msg); }
|
||||
fn input_str(msg: &istr) { add_input(st, str::bytes(msg)); }
|
||||
fn input_str(msg: &str) { add_input(st, str::bytes(msg)); }
|
||||
fn result() -> [u8] { ret mk_result(st); }
|
||||
fn result_str() -> istr {
|
||||
fn result_str() -> str {
|
||||
let r = mk_result(st);
|
||||
let s = ~"";
|
||||
for b: u8 in r {
|
||||
s += uint::to_str(b as uint, 16u);
|
||||
}
|
||||
let s = "";
|
||||
for b: u8 in r { s += uint::to_str(b as uint, 16u); }
|
||||
ret s;
|
||||
}
|
||||
}
|
||||
|
|
214
src/lib/str.rs
214
src/lib/str.rs
|
@ -1,20 +1,20 @@
|
|||
export eq, lteq, hash, is_empty, is_not_empty, is_whitespace, byte_len,
|
||||
index, rindex, find, starts_with, ends_with, substr, slice, split,
|
||||
concat, connect, to_upper, replace, char_slice, trim_left, trim_right, trim,
|
||||
unshift_char, shift_char, pop_char, push_char, is_utf8, from_chars, to_chars,
|
||||
char_len, char_at, bytes, is_ascii, shift_byte, pop_byte, unsafe_from_byte,
|
||||
unsafe_from_bytes, from_char, char_range_at, str_from_cstr, sbuf,
|
||||
as_buf, push_byte, utf8_char_width, safe_slice;
|
||||
export eq, lteq, hash, is_empty, is_not_empty, is_whitespace, byte_len, index,
|
||||
rindex, find, starts_with, ends_with, substr, slice, split, concat,
|
||||
connect, to_upper, replace, char_slice, trim_left, trim_right, trim,
|
||||
unshift_char, shift_char, pop_char, push_char, is_utf8, from_chars,
|
||||
to_chars, char_len, char_at, bytes, is_ascii, shift_byte, pop_byte,
|
||||
unsafe_from_byte, unsafe_from_bytes, from_char, char_range_at,
|
||||
str_from_cstr, sbuf, as_buf, push_byte, utf8_char_width, safe_slice;
|
||||
|
||||
native "rust" mod rustrt {
|
||||
fn rust_istr_push(s: &mutable istr, ch: u8);
|
||||
fn rust_istr_push(s: &mutable str, ch: u8);
|
||||
}
|
||||
|
||||
fn eq(a: &istr, b: &istr) -> bool { a == b }
|
||||
fn eq(a: &str, b: &str) -> bool { a == b }
|
||||
|
||||
fn lteq(a: &istr, b: &istr) -> bool { a <= b }
|
||||
fn lteq(a: &str, b: &str) -> bool { a <= b }
|
||||
|
||||
fn hash(s: &istr) -> uint {
|
||||
fn hash(s: &str) -> uint {
|
||||
// djb hash.
|
||||
// FIXME: replace with murmur.
|
||||
|
||||
|
@ -54,23 +54,19 @@ fn is_utf8(v: &[u8]) -> bool {
|
|||
ret true;
|
||||
}
|
||||
|
||||
fn is_ascii(s: &istr) -> bool {
|
||||
fn is_ascii(s: &str) -> bool {
|
||||
let i: uint = byte_len(s);
|
||||
while i > 0u { i -= 1u; if s[i] & 128u8 != 0u8 { ret false; } }
|
||||
ret true;
|
||||
}
|
||||
|
||||
/// Returns true if the string has length 0
|
||||
pure fn is_empty(s: &istr) -> bool {
|
||||
for c: u8 in s { ret false; } ret true;
|
||||
}
|
||||
pure fn is_empty(s: &str) -> bool { for c: u8 in s { ret false; } ret true; }
|
||||
|
||||
/// Returns true if the string has length greater than 0
|
||||
pure fn is_not_empty(s: &istr) -> bool {
|
||||
!is_empty(s)
|
||||
}
|
||||
pure fn is_not_empty(s: &str) -> bool { !is_empty(s) }
|
||||
|
||||
fn is_whitespace(s: &istr) -> bool {
|
||||
fn is_whitespace(s: &str) -> bool {
|
||||
let i = 0u;
|
||||
let len = char_len(s);
|
||||
while i < len {
|
||||
|
@ -80,74 +76,68 @@ fn is_whitespace(s: &istr) -> bool {
|
|||
ret true;
|
||||
}
|
||||
|
||||
fn byte_len(s: &istr) -> uint {
|
||||
fn byte_len(s: &str) -> uint {
|
||||
let v: [u8] = unsafe::reinterpret_cast(s);
|
||||
let vlen = vec::len(v);
|
||||
unsafe::leak(v);
|
||||
// There should always be a null terminator
|
||||
assert vlen > 0u;
|
||||
assert (vlen > 0u);
|
||||
ret vlen - 1u;
|
||||
}
|
||||
|
||||
fn bytes(s: &istr) -> [u8] {
|
||||
fn bytes(s: &str) -> [u8] {
|
||||
let v = unsafe::reinterpret_cast(s);
|
||||
let vcopy = vec::slice(v, 0u, vec::len(v) - 1u);
|
||||
unsafe::leak(v);
|
||||
ret vcopy;
|
||||
}
|
||||
|
||||
fn unsafe_from_bytes(v: &[mutable? u8]) -> istr {
|
||||
fn unsafe_from_bytes(v: &[mutable? u8]) -> str {
|
||||
let vcopy: [u8] = v + [0u8];
|
||||
let scopy: istr = unsafe::reinterpret_cast(vcopy);
|
||||
let scopy: str = unsafe::reinterpret_cast(vcopy);
|
||||
unsafe::leak(vcopy);
|
||||
ret scopy;
|
||||
}
|
||||
|
||||
fn unsafe_from_byte(u: u8) -> istr {
|
||||
unsafe_from_bytes([u])
|
||||
}
|
||||
fn unsafe_from_byte(u: u8) -> str { unsafe_from_bytes([u]) }
|
||||
|
||||
fn push_utf8_bytes(s: &mutable istr, ch: char) {
|
||||
fn push_utf8_bytes(s: &mutable str, ch: char) {
|
||||
let code = ch as uint;
|
||||
let bytes = if code < max_one_b {
|
||||
[code as u8]
|
||||
} else if code < max_two_b {
|
||||
[(code >> 6u & 31u | tag_two_b) as u8,
|
||||
(code & 63u | tag_cont) as u8]
|
||||
} else if code < max_three_b {
|
||||
[(code >> 12u & 15u | tag_three_b) as u8,
|
||||
(code >> 6u & 63u | tag_cont) as u8,
|
||||
(code & 63u | tag_cont) as u8]
|
||||
} else if code < max_four_b {
|
||||
[(code >> 18u & 7u | tag_four_b) as u8,
|
||||
(code >> 12u & 63u | tag_cont) as u8,
|
||||
(code >> 6u & 63u | tag_cont) as u8,
|
||||
(code & 63u | tag_cont) as u8]
|
||||
} else if code < max_five_b {
|
||||
[(code >> 24u & 3u | tag_five_b) as u8,
|
||||
(code >> 18u & 63u | tag_cont) as u8,
|
||||
(code >> 12u & 63u | tag_cont) as u8,
|
||||
(code >> 6u & 63u | tag_cont) as u8,
|
||||
(code & 63u | tag_cont) as u8]
|
||||
} else {
|
||||
[(code >> 30u & 1u | tag_six_b) as u8,
|
||||
(code >> 24u & 63u | tag_cont) as u8,
|
||||
(code >> 18u & 63u | tag_cont) as u8,
|
||||
(code >> 12u & 63u | tag_cont) as u8,
|
||||
(code >> 6u & 63u | tag_cont) as u8,
|
||||
(code & 63u | tag_cont) as u8]
|
||||
};
|
||||
let bytes =
|
||||
if code < max_one_b {
|
||||
[code as u8]
|
||||
} else if code < max_two_b {
|
||||
[code >> 6u & 31u | tag_two_b as u8, code & 63u | tag_cont as u8]
|
||||
} else if code < max_three_b {
|
||||
[code >> 12u & 15u | tag_three_b as u8,
|
||||
code >> 6u & 63u | tag_cont as u8, code & 63u | tag_cont as u8]
|
||||
} else if code < max_four_b {
|
||||
[code >> 18u & 7u | tag_four_b as u8,
|
||||
code >> 12u & 63u | tag_cont as u8,
|
||||
code >> 6u & 63u | tag_cont as u8, code & 63u | tag_cont as u8]
|
||||
} else if code < max_five_b {
|
||||
[code >> 24u & 3u | tag_five_b as u8,
|
||||
code >> 18u & 63u | tag_cont as u8,
|
||||
code >> 12u & 63u | tag_cont as u8,
|
||||
code >> 6u & 63u | tag_cont as u8, code & 63u | tag_cont as u8]
|
||||
} else {
|
||||
[code >> 30u & 1u | tag_six_b as u8,
|
||||
code >> 24u & 63u | tag_cont as u8,
|
||||
code >> 18u & 63u | tag_cont as u8,
|
||||
code >> 12u & 63u | tag_cont as u8,
|
||||
code >> 6u & 63u | tag_cont as u8, code & 63u | tag_cont as u8]
|
||||
};
|
||||
push_bytes(s, bytes);
|
||||
}
|
||||
|
||||
fn from_char(ch: char) -> istr {
|
||||
let buf = ~"";
|
||||
fn from_char(ch: char) -> str {
|
||||
let buf = "";
|
||||
push_utf8_bytes(buf, ch);
|
||||
ret buf;
|
||||
}
|
||||
|
||||
fn from_chars(chs: &[char]) -> istr {
|
||||
let buf = ~"";
|
||||
fn from_chars(chs: &[char]) -> str {
|
||||
let buf = "";
|
||||
for ch: char in chs { push_utf8_bytes(buf, ch); }
|
||||
ret buf;
|
||||
}
|
||||
|
@ -166,7 +156,7 @@ fn utf8_char_width(b: u8) -> uint {
|
|||
ret 6u;
|
||||
}
|
||||
|
||||
fn char_range_at(s: &istr, i: uint) -> {ch: char, next: uint} {
|
||||
fn char_range_at(s: &str, i: uint) -> {ch: char, next: uint} {
|
||||
let b0 = s[i];
|
||||
let w = utf8_char_width(b0);
|
||||
assert (w != 0u);
|
||||
|
@ -188,9 +178,9 @@ fn char_range_at(s: &istr, i: uint) -> {ch: char, next: uint} {
|
|||
ret {ch: val as char, next: i};
|
||||
}
|
||||
|
||||
fn char_at(s: &istr, i: uint) -> char { ret char_range_at(s, i).ch; }
|
||||
fn char_at(s: &str, i: uint) -> char { ret char_range_at(s, i).ch; }
|
||||
|
||||
fn char_len(s: &istr) -> uint {
|
||||
fn char_len(s: &str) -> uint {
|
||||
let i = 0u;
|
||||
let len = 0u;
|
||||
let total = byte_len(s);
|
||||
|
@ -204,7 +194,7 @@ fn char_len(s: &istr) -> uint {
|
|||
ret len;
|
||||
}
|
||||
|
||||
fn to_chars(s: &istr) -> [char] {
|
||||
fn to_chars(s: &str) -> [char] {
|
||||
let buf: [char] = [];
|
||||
let i = 0u;
|
||||
let len = byte_len(s);
|
||||
|
@ -216,9 +206,9 @@ fn to_chars(s: &istr) -> [char] {
|
|||
ret buf;
|
||||
}
|
||||
|
||||
fn push_char(s: &mutable istr, ch: char) { s += from_char(ch); }
|
||||
fn push_char(s: &mutable str, ch: char) { s += from_char(ch); }
|
||||
|
||||
fn pop_char(s: &mutable istr) -> char {
|
||||
fn pop_char(s: &mutable str) -> char {
|
||||
let end = byte_len(s);
|
||||
while end > 0u && s[end - 1u] & 192u8 == tag_cont_u8 { end -= 1u; }
|
||||
assert (end > 0u);
|
||||
|
@ -227,31 +217,31 @@ fn pop_char(s: &mutable istr) -> char {
|
|||
ret ch;
|
||||
}
|
||||
|
||||
fn shift_char(s: &mutable istr) -> char {
|
||||
fn shift_char(s: &mutable str) -> char {
|
||||
let r = char_range_at(s, 0u);
|
||||
s = substr(s, r.next, byte_len(s) - r.next);
|
||||
ret r.ch;
|
||||
}
|
||||
|
||||
fn unshift_char(s: &mutable istr, ch: char) { s = from_char(ch) + s; }
|
||||
fn unshift_char(s: &mutable str, ch: char) { s = from_char(ch) + s; }
|
||||
|
||||
fn index(s: &istr, c: u8) -> int {
|
||||
fn index(s: &str, c: u8) -> int {
|
||||
let i: int = 0;
|
||||
for k: u8 in s { if k == c { ret i; } i += 1; }
|
||||
ret -1;
|
||||
}
|
||||
|
||||
fn rindex(s: &istr, c: u8) -> int {
|
||||
fn rindex(s: &str, c: u8) -> int {
|
||||
let n: int = byte_len(s) as int;
|
||||
while n >= 0 { if s[n] == c { ret n; } n -= 1; }
|
||||
ret n;
|
||||
}
|
||||
|
||||
fn find(haystack: &istr, needle: &istr) -> int {
|
||||
fn find(haystack: &str, needle: &str) -> int {
|
||||
let haystack_len: int = byte_len(haystack) as int;
|
||||
let needle_len: int = byte_len(needle) as int;
|
||||
if needle_len == 0 { ret 0; }
|
||||
fn match_at(haystack: &istr, needle: &istr, i: int) -> bool {
|
||||
fn match_at(haystack: &str, needle: &str, i: int) -> bool {
|
||||
let j: int = i;
|
||||
for c: u8 in needle { if haystack[j] != c { ret false; } j += 1; }
|
||||
ret true;
|
||||
|
@ -264,7 +254,7 @@ fn find(haystack: &istr, needle: &istr) -> int {
|
|||
ret -1;
|
||||
}
|
||||
|
||||
fn starts_with(haystack: &istr, needle: &istr) -> bool {
|
||||
fn starts_with(haystack: &str, needle: &str) -> bool {
|
||||
let haystack_len: uint = byte_len(haystack);
|
||||
let needle_len: uint = byte_len(needle);
|
||||
if needle_len == 0u { ret true; }
|
||||
|
@ -272,7 +262,7 @@ fn starts_with(haystack: &istr, needle: &istr) -> bool {
|
|||
ret eq(substr(haystack, 0u, needle_len), needle);
|
||||
}
|
||||
|
||||
fn ends_with(haystack: &istr, needle: &istr) -> bool {
|
||||
fn ends_with(haystack: &str, needle: &str) -> bool {
|
||||
let haystack_len: uint = byte_len(haystack);
|
||||
let needle_len: uint = byte_len(needle);
|
||||
ret if needle_len == 0u {
|
||||
|
@ -285,11 +275,11 @@ fn ends_with(haystack: &istr, needle: &istr) -> bool {
|
|||
};
|
||||
}
|
||||
|
||||
fn substr(s: &istr, begin: uint, len: uint) -> istr {
|
||||
fn substr(s: &str, begin: uint, len: uint) -> str {
|
||||
ret slice(s, begin, begin + len);
|
||||
}
|
||||
|
||||
fn slice(s: &istr, begin: uint, end: uint) -> istr {
|
||||
fn slice(s: &str, begin: uint, end: uint) -> str {
|
||||
// FIXME: Typestate precondition
|
||||
assert (begin <= end);
|
||||
assert (end <= byte_len(s));
|
||||
|
@ -298,19 +288,18 @@ fn slice(s: &istr, begin: uint, end: uint) -> istr {
|
|||
let v2 = vec::slice(v, begin, end);
|
||||
unsafe::leak(v);
|
||||
v2 += [0u8];
|
||||
let s2: istr = unsafe::reinterpret_cast(v2);
|
||||
let s2: str = unsafe::reinterpret_cast(v2);
|
||||
unsafe::leak(v2);
|
||||
ret s2;
|
||||
}
|
||||
|
||||
fn safe_slice(s: &istr, begin: uint, end: uint)
|
||||
: uint::le(begin, end) -> istr {
|
||||
fn safe_slice(s: &str, begin: uint, end: uint) : uint::le(begin, end) -> str {
|
||||
// would need some magic to make this a precondition
|
||||
assert (end <= byte_len(s));
|
||||
ret slice(s, begin, end);
|
||||
}
|
||||
|
||||
fn shift_byte(s: &mutable istr) -> u8 {
|
||||
fn shift_byte(s: &mutable str) -> u8 {
|
||||
let len = byte_len(s);
|
||||
assert (len > 0u);
|
||||
let b = s[0];
|
||||
|
@ -318,7 +307,7 @@ fn shift_byte(s: &mutable istr) -> u8 {
|
|||
ret b;
|
||||
}
|
||||
|
||||
fn pop_byte(s: &mutable istr) -> u8 {
|
||||
fn pop_byte(s: &mutable str) -> u8 {
|
||||
let len = byte_len(s);
|
||||
assert (len > 0u);
|
||||
let b = s[len - 1u];
|
||||
|
@ -326,24 +315,20 @@ fn pop_byte(s: &mutable istr) -> u8 {
|
|||
ret b;
|
||||
}
|
||||
|
||||
fn push_byte(s: &mutable istr, b: u8) {
|
||||
rustrt::rust_istr_push(s, b);
|
||||
fn push_byte(s: &mutable str, b: u8) { rustrt::rust_istr_push(s, b); }
|
||||
|
||||
fn push_bytes(s: &mutable str, bytes: &[u8]) {
|
||||
for byte in bytes { rustrt::rust_istr_push(s, byte); }
|
||||
}
|
||||
|
||||
fn push_bytes(s: &mutable istr, bytes: &[u8]) {
|
||||
for byte in bytes {
|
||||
rustrt::rust_istr_push(s, byte);
|
||||
}
|
||||
}
|
||||
|
||||
fn split(s: &istr, sep: u8) -> [istr] {
|
||||
let v: [istr] = [];
|
||||
let accum: istr = ~"";
|
||||
fn split(s: &str, sep: u8) -> [str] {
|
||||
let v: [str] = [];
|
||||
let accum: str = "";
|
||||
let ends_with_sep: bool = false;
|
||||
for c: u8 in s {
|
||||
if c == sep {
|
||||
v += [accum];
|
||||
accum = ~"";
|
||||
accum = "";
|
||||
ends_with_sep = true;
|
||||
} else { accum += unsafe_from_byte(c); ends_with_sep = false; }
|
||||
}
|
||||
|
@ -351,16 +336,16 @@ fn split(s: &istr, sep: u8) -> [istr] {
|
|||
ret v;
|
||||
}
|
||||
|
||||
fn concat(v: &[istr]) -> istr {
|
||||
let s: istr = ~"";
|
||||
for ss: istr in v { s += ss; }
|
||||
fn concat(v: &[str]) -> str {
|
||||
let s: str = "";
|
||||
for ss: str in v { s += ss; }
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn connect(v: &[istr], sep: &istr) -> istr {
|
||||
let s: istr = ~"";
|
||||
fn connect(v: &[str], sep: &str) -> str {
|
||||
let s: str = "";
|
||||
let first: bool = true;
|
||||
for ss: istr in v {
|
||||
for ss: str in v {
|
||||
if first { first = false; } else { s += sep; }
|
||||
s += ss;
|
||||
}
|
||||
|
@ -368,8 +353,8 @@ fn connect(v: &[istr], sep: &istr) -> istr {
|
|||
}
|
||||
|
||||
// FIXME: This only handles ASCII
|
||||
fn to_upper(s: &istr) -> istr {
|
||||
let outstr = ~"";
|
||||
fn to_upper(s: &str) -> str {
|
||||
let outstr = "";
|
||||
let ascii_a = 'a' as u8;
|
||||
let ascii_z = 'z' as u8;
|
||||
let diff = 32u8;
|
||||
|
@ -384,11 +369,11 @@ fn to_upper(s: &istr) -> istr {
|
|||
}
|
||||
|
||||
// FIXME: This is super-inefficient
|
||||
fn replace(s: &istr, from: &istr, to: &istr) : is_not_empty(from) -> istr {
|
||||
fn replace(s: &str, from: &str, to: &str) : is_not_empty(from) -> str {
|
||||
// FIXME (694): Shouldn't have to check this
|
||||
check (is_not_empty(from));
|
||||
if byte_len(s) == 0u {
|
||||
ret ~"";
|
||||
ret "";
|
||||
} else if starts_with(s, from) {
|
||||
ret to + replace(slice(s, byte_len(from), byte_len(s)), from, to);
|
||||
} else {
|
||||
|
@ -398,11 +383,11 @@ fn replace(s: &istr, from: &istr, to: &istr) : is_not_empty(from) -> istr {
|
|||
}
|
||||
|
||||
// FIXME: Also not efficient
|
||||
fn char_slice(s: &istr, begin: uint, end: uint) -> istr {
|
||||
fn char_slice(s: &str, begin: uint, end: uint) -> str {
|
||||
from_chars(vec::slice(to_chars(s), begin, end))
|
||||
}
|
||||
|
||||
fn trim_left(s: &istr) -> istr {
|
||||
fn trim_left(s: &str) -> str {
|
||||
fn count_whities(s: &[char]) -> uint {
|
||||
let i = 0u;
|
||||
while i < vec::len(s) {
|
||||
|
@ -416,7 +401,7 @@ fn trim_left(s: &istr) -> istr {
|
|||
ret from_chars(vec::slice(chars, whities, vec::len(chars)));
|
||||
}
|
||||
|
||||
fn trim_right(s: &istr) -> istr {
|
||||
fn trim_right(s: &str) -> str {
|
||||
fn count_whities(s: &[char]) -> uint {
|
||||
let i = vec::len(s);
|
||||
while 0u < i {
|
||||
|
@ -430,26 +415,21 @@ fn trim_right(s: &istr) -> istr {
|
|||
ret from_chars(vec::slice(chars, 0u, whities));
|
||||
}
|
||||
|
||||
fn trim(s: &istr) -> istr {
|
||||
trim_left(trim_right(s))
|
||||
}
|
||||
fn trim(s: &str) -> str { trim_left(trim_right(s)) }
|
||||
|
||||
type sbuf = *u8;
|
||||
|
||||
fn buf(s: &istr) -> sbuf {
|
||||
fn buf(s: &str) -> sbuf {
|
||||
let saddr = ptr::addr_of(s);
|
||||
let vaddr: *[u8] = unsafe::reinterpret_cast(saddr);
|
||||
let buf = vec::to_ptr(*vaddr);
|
||||
ret buf;
|
||||
}
|
||||
|
||||
fn as_buf<T>(s: &istr, f: &block(sbuf) -> T) -> T {
|
||||
let buf = buf(s);
|
||||
f(buf)
|
||||
}
|
||||
fn as_buf<T>(s: &str, f: &block(sbuf) -> T) -> T { let buf = buf(s); f(buf) }
|
||||
|
||||
fn str_from_cstr(cstr: sbuf) -> istr {
|
||||
let res = ~"";
|
||||
fn str_from_cstr(cstr: sbuf) -> str {
|
||||
let res = "";
|
||||
let start = cstr;
|
||||
let curr = start;
|
||||
let i = 0u;
|
||||
|
@ -459,4 +439,4 @@ fn str_from_cstr(cstr: sbuf) -> istr {
|
|||
curr = ptr::offset(start, i);
|
||||
}
|
||||
ret res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ fn spawn_inner(thunk: -fn(), notify: option<comm::chan<task_notification>>) ->
|
|||
// set up the task pointer
|
||||
let task_ptr = rust_task_ptr(rustrt::get_task_pointer(id));
|
||||
let regs = ptr::addr_of((**task_ptr).ctx.regs);
|
||||
(*regs).edx = cast(*task_ptr);
|
||||
(*regs).edx = cast(*task_ptr);;
|
||||
(*regs).esp = cast((**task_ptr).stack_ptr);
|
||||
|
||||
assert (ptr::null() != (**task_ptr).stack_ptr);
|
||||
|
|
|
@ -48,10 +48,10 @@ fn reset(writer: io::buf_writer) {
|
|||
}
|
||||
|
||||
fn color_supported() -> bool {
|
||||
let supported_terms = [~"xterm-color", ~"xterm", ~"screen-bce"];
|
||||
ret alt generic_os::getenv(~"TERM") {
|
||||
let supported_terms = ["xterm-color", "xterm", "screen-bce"];
|
||||
ret alt generic_os::getenv("TERM") {
|
||||
option::some(env) {
|
||||
for term: istr in supported_terms {
|
||||
for term: str in supported_terms {
|
||||
if str::eq(term, env) { ret true; }
|
||||
}
|
||||
false
|
||||
|
|
|
@ -35,7 +35,7 @@ native "rust" mod rustrt {
|
|||
// paths, i.e it should be a series of identifiers seperated by double
|
||||
// colons. This way if some test runner wants to arrange the tests
|
||||
// heirarchically it may.
|
||||
type test_name = istr;
|
||||
type test_name = str;
|
||||
|
||||
// A function that runs a test. If the function returns successfully,
|
||||
// the test succeeds; if the function fails then the test fails. We
|
||||
|
@ -49,7 +49,7 @@ type test_desc = {name: test_name, fn: test_fn, ignore: bool};
|
|||
|
||||
// The default console test runner. It accepts the command line
|
||||
// arguments and a vector of test_descs (generated at compile time).
|
||||
fn test_main(args: &[istr], tests: &[test_desc]) {
|
||||
fn test_main(args: &[str], tests: &[test_desc]) {
|
||||
check (vec::is_not_empty(args));
|
||||
let opts =
|
||||
alt parse_opts(args) {
|
||||
|
@ -59,21 +59,19 @@ fn test_main(args: &[istr], tests: &[test_desc]) {
|
|||
if !run_tests_console(opts, tests) { fail "Some tests failed"; }
|
||||
}
|
||||
|
||||
type test_opts = {filter: option::t<istr>, run_ignored: bool};
|
||||
type test_opts = {filter: option::t<str>, run_ignored: bool};
|
||||
|
||||
type opt_res = either::t<test_opts, istr>;
|
||||
type opt_res = either::t<test_opts, str>;
|
||||
|
||||
// Parses command line arguments into test options
|
||||
fn parse_opts(args: &[istr]) : vec::is_not_empty(args) -> opt_res {
|
||||
fn parse_opts(args: &[str]) : vec::is_not_empty(args) -> opt_res {
|
||||
|
||||
let args_ = vec::tail(args);
|
||||
let opts = [getopts::optflag(~"ignored")];
|
||||
let opts = [getopts::optflag("ignored")];
|
||||
let match =
|
||||
alt getopts::getopts(args_, opts) {
|
||||
getopts::success(m) { m }
|
||||
getopts::failure(f) {
|
||||
ret either::right(getopts::fail_str(f))
|
||||
}
|
||||
getopts::failure(f) { ret either::right(getopts::fail_str(f)) }
|
||||
};
|
||||
|
||||
let filter =
|
||||
|
@ -81,7 +79,7 @@ fn parse_opts(args: &[istr]) : vec::is_not_empty(args) -> opt_res {
|
|||
option::some(match.free[0])
|
||||
} else { option::none };
|
||||
|
||||
let run_ignored = getopts::opt_present(match, ~"ignored");
|
||||
let run_ignored = getopts::opt_present(match, "ignored");
|
||||
|
||||
let test_opts = {filter: filter, run_ignored: run_ignored};
|
||||
|
||||
|
@ -119,30 +117,26 @@ fn run_tests_console_(opts: &test_opts, tests: &[test_desc],
|
|||
alt event {
|
||||
te_filtered(filtered_tests) {
|
||||
st.total = vec::len(filtered_tests);
|
||||
st.out.write_line(
|
||||
#fmt["\nrunning %u tests", st.total]);
|
||||
}
|
||||
te_wait(test) {
|
||||
st.out.write_str(
|
||||
#fmt["test %s ... ", test.name]);
|
||||
st.out.write_line(#fmt["\nrunning %u tests", st.total]);
|
||||
}
|
||||
te_wait(test) { st.out.write_str(#fmt["test %s ... ", test.name]); }
|
||||
te_result(test, result) {
|
||||
alt result {
|
||||
tr_ok. {
|
||||
st.passed += 1u;
|
||||
write_ok(st.out, st.use_color);
|
||||
st.out.write_line(~"");
|
||||
st.out.write_line("");
|
||||
}
|
||||
tr_failed. {
|
||||
st.failed += 1u;
|
||||
write_failed(st.out, st.use_color);
|
||||
st.out.write_line(~"");
|
||||
st.out.write_line("");
|
||||
st.failures += [test];
|
||||
}
|
||||
tr_ignored. {
|
||||
st.ignored += 1u;
|
||||
write_ignored(st.out, st.use_color);
|
||||
st.out.write_line(~"");
|
||||
st.out.write_line("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +158,7 @@ fn run_tests_console_(opts: &test_opts, tests: &[test_desc],
|
|||
let success = st.failed == 0u;
|
||||
|
||||
if !success {
|
||||
st.out.write_line(~"\nfailures:");
|
||||
st.out.write_line("\nfailures:");
|
||||
for test: test_desc in st.failures {
|
||||
let testname = test.name; // Satisfy alias analysis
|
||||
st.out.write_line(#fmt[" %s", testname]);
|
||||
|
@ -176,25 +170,24 @@ fn run_tests_console_(opts: &test_opts, tests: &[test_desc],
|
|||
// There's no parallelism at this point so it's safe to use color
|
||||
write_ok(st.out, true);
|
||||
} else { write_failed(st.out, true); }
|
||||
st.out.write_str(
|
||||
#fmt[". %u passed; %u failed; %u ignored\n\n", st.passed,
|
||||
st.out.write_str(#fmt[". %u passed; %u failed; %u ignored\n\n", st.passed,
|
||||
st.failed, st.ignored]);
|
||||
|
||||
ret success;
|
||||
|
||||
fn write_ok(out: &io::writer, use_color: bool) {
|
||||
write_pretty(out, ~"ok", term::color_green, use_color);
|
||||
write_pretty(out, "ok", term::color_green, use_color);
|
||||
}
|
||||
|
||||
fn write_failed(out: &io::writer, use_color: bool) {
|
||||
write_pretty(out, ~"FAILED", term::color_red, use_color);
|
||||
write_pretty(out, "FAILED", term::color_red, use_color);
|
||||
}
|
||||
|
||||
fn write_ignored(out: &io::writer, use_color: bool) {
|
||||
write_pretty(out, ~"ignored", term::color_yellow, use_color);
|
||||
write_pretty(out, "ignored", term::color_yellow, use_color);
|
||||
}
|
||||
|
||||
fn write_pretty(out: &io::writer, word: &istr, color: u8,
|
||||
fn write_pretty(out: &io::writer, word: &str, color: u8,
|
||||
use_color: bool) {
|
||||
if use_color && term::color_supported() {
|
||||
term::fg(out.get_buf_writer(), color);
|
||||
|
@ -259,11 +252,11 @@ fn filter_tests(opts: &test_opts, tests: &[test_desc]) -> [test_desc] {
|
|||
let filter_str =
|
||||
alt opts.filter {
|
||||
option::some(f) { f }
|
||||
option::none. { ~"" }
|
||||
option::none. { "" }
|
||||
};
|
||||
|
||||
let filter =
|
||||
bind fn (test: &test_desc, filter_str: &istr) ->
|
||||
bind fn (test: &test_desc, filter_str: &str) ->
|
||||
option::t<test_desc> {
|
||||
if str::find(test.name, filter_str) >= 0 {
|
||||
ret option::some(test);
|
||||
|
|
|
@ -17,82 +17,49 @@ export insert;
|
|||
export find;
|
||||
export traverse;
|
||||
|
||||
tag tree_node<@K, @V> {
|
||||
empty;
|
||||
node(@K, @V, treemap<K, V>, treemap<K, V>);
|
||||
}
|
||||
tag tree_node<@K, @V> { empty; node(@K, @V, treemap<K, V>, treemap<K, V>); }
|
||||
|
||||
type treemap<@K, @V> = @mutable tree_node<K, V>;
|
||||
|
||||
fn init<@K, @V>() -> treemap<K,V> { @mutable empty }
|
||||
fn init<@K, @V>() -> treemap<K, V> { @mutable empty }
|
||||
|
||||
fn insert<@K, @V>(m : &treemap<K, V>, k : &K, v : &V) {
|
||||
fn insert<@K, @V>(m: &treemap<K, V>, k: &K, v: &V) {
|
||||
alt m {
|
||||
@empty. {
|
||||
*m = node(@k, @v, @mutable empty, @mutable empty);
|
||||
}
|
||||
@empty. { *m = node(@k, @v, @mutable empty, @mutable empty); }
|
||||
@node(@kk, _, _, _) {
|
||||
|
||||
// We have to name left and right individually, because
|
||||
// otherwise the alias checker complains.
|
||||
if k < kk {
|
||||
alt m {
|
||||
@node(_, _, left, _) {
|
||||
insert(left, k, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
alt m {
|
||||
@node(_, _, _, right) {
|
||||
insert(right, k, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
alt m { @node(_, _, left, _) { insert(left, k, v); } }
|
||||
} else { alt m { @node(_, _, _, right) { insert(right, k, v); } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find<@K, @V>(m : &treemap<K, V>, k : &K) -> option<V> {
|
||||
alt *m {
|
||||
empty. { none }
|
||||
node(@kk, @v, _, _) {
|
||||
if k == kk { some(v) }
|
||||
// Again, ugliness to unpack left and right individually.
|
||||
else if k < kk {
|
||||
alt *m {
|
||||
node(_, _, left, _) {
|
||||
find(left, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
alt *m {
|
||||
node(_, _, _, right) {
|
||||
find(right, k)
|
||||
}
|
||||
}
|
||||
fn find<@K, @V>(m: &treemap<K, V>, k: &K) -> option<V> {
|
||||
alt *m {
|
||||
empty. { none }
|
||||
node(@kk, @v, _, _) {
|
||||
if k == kk {
|
||||
some(v)
|
||||
} else if k < kk {
|
||||
// Again, ugliness to unpack left and right individually.
|
||||
alt *m { node(_, _, left, _) { find(left, k) } }
|
||||
} else { alt *m { node(_, _, _, right) { find(right, k) } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Performs an in-order traversal
|
||||
fn traverse<@K, @V>(m : &treemap<K, V>, f : fn(&K, &V)) {
|
||||
alt *m {
|
||||
empty. { }
|
||||
node(k, v, _, _) {
|
||||
let k1 = k, v1 = v;
|
||||
alt *m {
|
||||
node(_, _, left, _) {
|
||||
traverse(left, f);
|
||||
}
|
||||
}
|
||||
f(*k1, *v1);
|
||||
alt *m {
|
||||
node(_, _, _, right) {
|
||||
traverse(right, f);
|
||||
}
|
||||
fn traverse<@K, @V>(m: &treemap<K, V>, f: fn(&K, &V)) {
|
||||
alt *m {
|
||||
empty. { }
|
||||
node(k, v, _, _) {
|
||||
let k1 = k, v1 = v;
|
||||
alt *m { node(_, _, left, _) { traverse(left, f); } }
|
||||
f(*k1, *v1);
|
||||
alt *m { node(_, _, _, right) { traverse(right, f); } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
fn to_str(n: u64, radix: uint) -> istr {
|
||||
fn to_str(n: u64, radix: uint) -> str {
|
||||
assert (0u < radix && radix <= 16u);
|
||||
|
||||
let r64 = radix as u64;
|
||||
|
||||
fn digit(n: u64) -> istr {
|
||||
fn digit(n: u64) -> str {
|
||||
ret alt n {
|
||||
0u64 { ~"0" }
|
||||
1u64 { ~"1" }
|
||||
2u64 { ~"2" }
|
||||
3u64 { ~"3" }
|
||||
4u64 { ~"4" }
|
||||
5u64 { ~"5" }
|
||||
6u64 { ~"6" }
|
||||
7u64 { ~"7" }
|
||||
8u64 { ~"8" }
|
||||
9u64 { ~"9" }
|
||||
10u64 { ~"a" }
|
||||
11u64 { ~"b" }
|
||||
12u64 { ~"c" }
|
||||
13u64 { ~"d" }
|
||||
14u64 { ~"e" }
|
||||
15u64 { ~"f" }
|
||||
0u64 { "0" }
|
||||
1u64 { "1" }
|
||||
2u64 { "2" }
|
||||
3u64 { "3" }
|
||||
4u64 { "4" }
|
||||
5u64 { "5" }
|
||||
6u64 { "6" }
|
||||
7u64 { "7" }
|
||||
8u64 { "8" }
|
||||
9u64 { "9" }
|
||||
10u64 { "a" }
|
||||
11u64 { "b" }
|
||||
12u64 { "c" }
|
||||
13u64 { "d" }
|
||||
14u64 { "e" }
|
||||
15u64 { "f" }
|
||||
_ { fail }
|
||||
};
|
||||
}
|
||||
|
||||
if n == 0u64 { ret ~"0"; }
|
||||
if n == 0u64 { ret "0"; }
|
||||
|
||||
let s = ~"";
|
||||
let s = "";
|
||||
|
||||
while n > 0u64 { s = digit(n % r64) + s; n /= r64; }
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn str(n: u64) -> istr { ret to_str(n, 10u); }
|
||||
fn str(n: u64) -> str { ret to_str(n, 10u); }
|
||||
|
|
|
@ -56,9 +56,9 @@ fn parse_buf(buf: &[u8], radix: uint) -> uint {
|
|||
fail;
|
||||
}
|
||||
|
||||
fn from_str(s: &istr) -> uint { parse_buf(str::bytes(s), 10u) }
|
||||
fn from_str(s: &str) -> uint { parse_buf(str::bytes(s), 10u) }
|
||||
|
||||
fn to_str(num: uint, radix: uint) -> istr {
|
||||
fn to_str(num: uint, radix: uint) -> str {
|
||||
let n = num;
|
||||
assert (0u < radix && radix <= 16u);
|
||||
fn digit(n: uint) -> char {
|
||||
|
@ -82,18 +82,18 @@ fn to_str(num: uint, radix: uint) -> istr {
|
|||
_ { fail }
|
||||
};
|
||||
}
|
||||
if n == 0u { ret ~"0"; }
|
||||
let s: istr = ~"";
|
||||
if n == 0u { ret "0"; }
|
||||
let s: str = "";
|
||||
while n != 0u {
|
||||
s += str::unsafe_from_byte(digit(n % radix) as u8);
|
||||
n /= radix;
|
||||
}
|
||||
let s1: istr = ~"";
|
||||
let s1: str = "";
|
||||
let len: uint = str::byte_len(s);
|
||||
while len != 0u { len -= 1u; s1 += str::unsafe_from_byte(s[len]); }
|
||||
ret s1;
|
||||
}
|
||||
fn str(i: uint) -> istr { ret to_str(i, 10u); }
|
||||
fn str(i: uint) -> str { ret to_str(i, 10u); }
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
|
|
|
@ -11,6 +11,4 @@ native "rust" mod rustrt {
|
|||
// Casts the value at `src` to U. The two types must have the same length.
|
||||
fn reinterpret_cast<T, @U>(src: &T) -> U { ret rusti::cast(src); }
|
||||
|
||||
fn leak<@T>(thing: -T) {
|
||||
rustrt::leak(thing);
|
||||
}
|
||||
fn leak<@T>(thing: -T) { rustrt::leak(thing); }
|
||||
|
|
|
@ -262,8 +262,8 @@ fn position_pred<T>(f: fn(&T) -> bool, v: &[T]) -> option::t<uint> {
|
|||
}
|
||||
|
||||
pure fn same_length<T, U>(xs: &[T], ys: &[U]) -> bool {
|
||||
let xlen = unchecked { vec::len(xs) };
|
||||
let ylen = unchecked { vec::len(ys) };
|
||||
let xlen = unchecked{ vec::len(xs) };
|
||||
let ylen = unchecked{ vec::len(ys) };
|
||||
xlen == ylen
|
||||
}
|
||||
|
||||
|
@ -311,39 +311,28 @@ fn reversed<@T>(v: &[T]) -> [T] {
|
|||
}
|
||||
|
||||
// Generating vecs.
|
||||
fn enum_chars(start:u8, end:u8) : u8::le(start, end) -> [char] {
|
||||
fn enum_chars(start: u8, end: u8) : u8::le(start, end) -> [char] {
|
||||
let i = start;
|
||||
let r = [];
|
||||
while (i <= end) {
|
||||
r += [i as char];
|
||||
i += (1u as u8);
|
||||
}
|
||||
while i <= end { r += [i as char]; i += 1u as u8; }
|
||||
ret r;
|
||||
}
|
||||
|
||||
fn enum_uints(start:uint, end:uint) : uint::le(start, end) -> [uint] {
|
||||
fn enum_uints(start: uint, end: uint) : uint::le(start, end) -> [uint] {
|
||||
let i = start;
|
||||
let r = [];
|
||||
while (i <= end) {
|
||||
r += [i];
|
||||
i += 1u;
|
||||
}
|
||||
while i <= end { r += [i]; i += 1u; }
|
||||
ret r;
|
||||
}
|
||||
|
||||
// Iterate over a list with with the indexes
|
||||
iter iter2<@T>(v: &[T]) -> (uint, T) {
|
||||
let i = 0u;
|
||||
for x in v {
|
||||
put (i, x);
|
||||
i += 1u;
|
||||
}
|
||||
for x in v { put (i, x); i += 1u; }
|
||||
}
|
||||
|
||||
mod unsafe {
|
||||
type vec_repr = {mutable fill: uint,
|
||||
mutable alloc: uint,
|
||||
data: u8};
|
||||
type vec_repr = {mutable fill: uint, mutable alloc: uint, data: u8};
|
||||
|
||||
fn from_buf<T>(ptr: *T, elts: uint) -> [T] {
|
||||
ret rustrt::vec_from_buf_shared(ptr, elts);
|
||||
|
@ -360,9 +349,7 @@ mod unsafe {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_ptr<T>(v: &[T]) -> *T {
|
||||
ret unsafe::to_ptr(v);
|
||||
}
|
||||
fn to_ptr<T>(v: &[T]) -> *T { ret unsafe::to_ptr(v); }
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
|
||||
native "rust" mod rustrt {
|
||||
fn rust_list_files(path: &istr) -> [istr];
|
||||
fn rust_list_files(path: &str) -> [str];
|
||||
fn rust_file_is_dir(path: str) -> int;
|
||||
}
|
||||
|
||||
fn list_dir(path: &istr) -> [istr] {
|
||||
let path = path + ~"*";
|
||||
fn list_dir(path: &str) -> [str] {
|
||||
let path = path + "*";
|
||||
ret rustrt::rust_list_files(path);
|
||||
}
|
||||
|
||||
fn path_is_absolute(p: &istr) -> bool {
|
||||
fn path_is_absolute(p: &str) -> bool {
|
||||
ret str::char_at(p, 0u) == '/' ||
|
||||
str::char_at(p, 1u) == ':' && str::char_at(p, 2u) == '\\';
|
||||
}
|
||||
|
|
|
@ -40,16 +40,16 @@ mod libc_constants {
|
|||
}
|
||||
|
||||
native "x86stdcall" mod kernel32 {
|
||||
fn GetEnvironmentVariableA(n: str::sbuf, v: str::sbuf,
|
||||
nsize: uint) -> uint;
|
||||
fn GetEnvironmentVariableA(n: str::sbuf, v: str::sbuf, nsize: uint) ->
|
||||
uint;
|
||||
fn SetEnvironmentVariableA(n: str::sbuf, v: str::sbuf) -> int;
|
||||
}
|
||||
|
||||
fn exec_suffix() -> istr { ret ~".exe"; }
|
||||
fn exec_suffix() -> str { ret ".exe"; }
|
||||
|
||||
fn target_os() -> istr { ret ~"win32"; }
|
||||
fn target_os() -> str { ret "win32"; }
|
||||
|
||||
fn dylib_filename(base: &istr) -> istr { ret base + ~".dll"; }
|
||||
fn dylib_filename(base: &str) -> str { ret base + ".dll"; }
|
||||
|
||||
fn pipe() -> {in: int, out: int} {
|
||||
// Windows pipes work subtly differently than unix pipes, and their
|
||||
|
@ -69,21 +69,17 @@ fn pipe() -> {in: int, out: int} {
|
|||
}
|
||||
|
||||
fn fd_FILE(fd: int) -> libc::FILE {
|
||||
ret str::as_buf(~"r", { |modebuf|
|
||||
libc::_fdopen(fd, modebuf)
|
||||
});
|
||||
ret str::as_buf("r", {|modebuf| libc::_fdopen(fd, modebuf) });
|
||||
}
|
||||
|
||||
native "rust" mod rustrt {
|
||||
fn rust_process_wait(handle: int) -> int;
|
||||
fn rust_getcwd() -> istr;
|
||||
fn rust_getcwd() -> str;
|
||||
}
|
||||
|
||||
fn waitpid(pid: int) -> int { ret rustrt::rust_process_wait(pid); }
|
||||
|
||||
fn getcwd() -> istr {
|
||||
ret rustrt::rust_getcwd();
|
||||
}
|
||||
fn getcwd() -> str { ret rustrt::rust_getcwd(); }
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
|
|
|
@ -8,28 +8,28 @@ use std;
|
|||
import std::int;
|
||||
import std::str;
|
||||
|
||||
fn b1() -> istr { ret ~"# of beer on the wall, # of beer."; }
|
||||
fn b1() -> str { ret "# of beer on the wall, # of beer."; }
|
||||
|
||||
fn b2() -> istr {
|
||||
ret ~"Take one down and pass it around, # of beer on the wall.";
|
||||
fn b2() -> str {
|
||||
ret "Take one down and pass it around, # of beer on the wall.";
|
||||
}
|
||||
|
||||
fn b7() -> istr {
|
||||
ret ~"No more bottles of beer on the wall, no more bottles of beer.";
|
||||
fn b7() -> str {
|
||||
ret "No more bottles of beer on the wall, no more bottles of beer.";
|
||||
}
|
||||
|
||||
fn b8() -> istr {
|
||||
ret ~"Go to the store and buy some more, # of beer on the wall.";
|
||||
fn b8() -> str {
|
||||
ret "Go to the store and buy some more, # of beer on the wall.";
|
||||
}
|
||||
|
||||
fn sub(t: &istr, n: int) -> istr {
|
||||
let b: istr = ~"";
|
||||
fn sub(t: &str, n: int) -> str {
|
||||
let b: str = "";
|
||||
let i: uint = 0u;
|
||||
let ns: istr;
|
||||
let ns: str;
|
||||
alt n {
|
||||
0 { ns = ~"no more bottles"; }
|
||||
1 { ns = ~"1 bottle"; }
|
||||
_ { ns = int::to_str(n, 10u) + ~" bottles"; }
|
||||
0 { ns = "no more bottles"; }
|
||||
1 { ns = "1 bottle"; }
|
||||
_ { ns = int::to_str(n, 10u) + " bottles"; }
|
||||
}
|
||||
while i < str::byte_len(t) {
|
||||
if t[i] == '#' as u8 { b += ns; } else { str::push_byte(b, t[i]); }
|
||||
|
|
|
@ -29,12 +29,11 @@ fn show(b: bottle) {
|
|||
"1 bottle of beer on the wall.";
|
||||
}
|
||||
multiple(n) {
|
||||
let nb: istr = int::to_str(n, 10u);
|
||||
let mb: istr = int::to_str(n - 1, 10u);
|
||||
log nb + ~" bottles of beer on the wall, " + nb +
|
||||
~" bottles of beer,";
|
||||
log ~"Take one down and pass it around, " + mb +
|
||||
~" bottles of beer on the wall.";
|
||||
let nb: str = int::to_str(n, 10u);
|
||||
let mb: str = int::to_str(n - 1, 10u);
|
||||
log nb + " bottles of beer on the wall, " + nb + " bottles of beer,";
|
||||
log "Take one down and pass it around, " + mb +
|
||||
" bottles of beer on the wall.";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,28 +8,28 @@ use std;
|
|||
import std::int;
|
||||
import std::str;
|
||||
|
||||
fn b1() -> istr { ret ~"# of beer on the wall, # of beer."; }
|
||||
fn b1() -> str { ret "# of beer on the wall, # of beer."; }
|
||||
|
||||
fn b2() -> istr {
|
||||
ret ~"Take one down and pass it around, # of beer on the wall.";
|
||||
fn b2() -> str {
|
||||
ret "Take one down and pass it around, # of beer on the wall.";
|
||||
}
|
||||
|
||||
fn b7() -> istr {
|
||||
ret ~"No more bottles of beer on the wall, no more bottles of beer.";
|
||||
fn b7() -> str {
|
||||
ret "No more bottles of beer on the wall, no more bottles of beer.";
|
||||
}
|
||||
|
||||
fn b8() -> istr {
|
||||
ret ~"Go to the store and buy some more, # of beer on the wall.";
|
||||
fn b8() -> str {
|
||||
ret "Go to the store and buy some more, # of beer on the wall.";
|
||||
}
|
||||
|
||||
fn sub(t: &istr, n: int) -> istr {
|
||||
let b: istr = ~"";
|
||||
fn sub(t: &str, n: int) -> str {
|
||||
let b: str = "";
|
||||
let i: uint = 0u;
|
||||
let ns: istr;
|
||||
let ns: str;
|
||||
alt n {
|
||||
0 { ns = ~"no more bottles"; }
|
||||
1 { ns = ~"1 bottle"; }
|
||||
_ { ns = int::to_str(n, 10u) + ~" bottles"; }
|
||||
0 { ns = "no more bottles"; }
|
||||
1 { ns = "1 bottle"; }
|
||||
_ { ns = int::to_str(n, 10u) + " bottles"; }
|
||||
}
|
||||
while i < str::byte_len(t) {
|
||||
if t[i] == '#' as u8 { b += ns; } else { str::push_byte(b, t[i]); }
|
||||
|
|
|
@ -8,12 +8,11 @@ import std::str;
|
|||
|
||||
fn main() {
|
||||
fn multiple(n: int) {
|
||||
let nb: istr = int::to_str(n, 10u);
|
||||
let mb: istr = int::to_str(n - 1, 10u);
|
||||
log nb + ~" bottles of beer on the wall, " + nb +
|
||||
~" bottles of beer,";
|
||||
log ~"Take one down and pass it around, " + mb +
|
||||
~" bottles of beer on the wall.";
|
||||
let nb: str = int::to_str(n, 10u);
|
||||
let mb: str = int::to_str(n - 1, 10u);
|
||||
log nb + " bottles of beer on the wall, " + nb + " bottles of beer,";
|
||||
log "Take one down and pass it around, " + mb +
|
||||
" bottles of beer on the wall.";
|
||||
log "";
|
||||
if n > 3 { be multiple(n - 1); } else { be dual(); }
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ fn fannkuch(n: int) -> int {
|
|||
ret flips;
|
||||
}
|
||||
|
||||
fn main(args: [istr]) {
|
||||
fn main(args: [str]) {
|
||||
let n = 7;
|
||||
log #fmt["Pfannkuchen(%d) = %d", n, fannkuch(n)];
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue