diff options
| author | Josh Matthews <josh@joshmatthews.net> | 2012-01-28 11:50:48 -0500 |
|---|---|---|
| committer | Josh Matthews <josh@joshmatthews.net> | 2012-01-28 11:50:48 -0500 |
| commit | a831e7ce13aa19acf0f65e508097351f8dabca84 (patch) | |
| tree | e8b14ee2373337d3867ee573d61227387191c962 | |
| parent | fcb381410d59b89336a528103582a956334c9777 (diff) | |
| parent | 0794195fbdb6efa34388dfdf3dfc968bbbf06215 (diff) | |
| download | rust-a831e7ce13aa19acf0f65e508097351f8dabca84.tar.gz rust-a831e7ce13aa19acf0f65e508097351f8dabca84.zip | |
Merge remote-tracking branch 'mozilla/master'
32 files changed, 254 insertions, 100 deletions
diff --git a/AUTHORS.txt b/AUTHORS.txt index 1697ecd2fcb..3fd634894d5 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -5,6 +5,7 @@ Graydon Hoare <graydon@mozilla.com> Other authors: Adam Bozanich <adam.boz@gmail.com> +Aleksander Balicki <balicki.aleksander@gmail.com> Andreas Gal <gal@mozilla.com> Austin Seipp <mad.one@gmail.com> Ben Striegel <ben.striegel@gmail.com> diff --git a/mk/install.mk b/mk/install.mk index 244f4c05a59..9a5ad5a6c9f 100644 --- a/mk/install.mk +++ b/mk/install.mk @@ -5,12 +5,12 @@ # Installation macro. Call with source directory as arg 1, # destination directory as arg 2, and filename/libname-glob as arg 3 ifdef VERBOSE - INSTALL = cp $(1)/$(3) $(2)/$(3) - INSTALL_LIB = cp `ls -rt1 $(1)/$(3) | tail -1` $(2)/ + INSTALL = install -m755 -T $(1)/$(3) $(2)/$(3) + INSTALL_LIB = install -m644 `ls -rt1 $(1)/$(3) | tail -1` $(2)/ else - INSTALL = $(Q)$(call E, install: $(2)/$(3)) && cp $(1)/$(3) $(2)/$(3) + INSTALL = $(Q)$(call E, install: $(2)/$(3)) && install -m755 -T $(1)/$(3) $(2)/$(3) INSTALL_LIB = $(Q)$(call E, install_lib: $(2)/$(3)) && \ - cp `ls -rt1 $(1)/$(3) | tail -1` $(2)/ + install -m644 `ls -rt1 $(1)/$(3) | tail -1` $(2)/ endif # The stage we install from diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index 01466fbc52b..426263d654a 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -83,7 +83,7 @@ fn item_family(item: ebml::doc) -> u8 { 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)); + ret str::from_bytes(ebml::doc_data(sym)); } fn variant_enum_id(d: ebml::doc) -> ast::def_id { @@ -162,7 +162,7 @@ fn enum_variant_ids(item: ebml::doc, cdata: cmd) -> [ast::def_id] { // definition the path refers to. fn resolve_path(path: [ast::ident], data: @[u8]) -> [ast::def_id] { fn eq_item(data: [u8], s: str) -> bool { - ret str::eq(str::unsafe_from_bytes(data), s); + ret str::eq(str::from_bytes(data), s); } let s = str::connect(path, "::"); let md = ebml::new_doc(data); @@ -178,7 +178,7 @@ fn resolve_path(path: [ast::ident], data: @[u8]) -> [ast::def_id] { fn item_name(item: ebml::doc) -> ast::ident { let name = ebml::get_doc(item, tag_paths_data_name); - str::unsafe_from_bytes(ebml::doc_data(name)) + str::from_bytes(ebml::doc_data(name)) } fn lookup_item_name(data: @[u8], id: ast::node_id) -> ast::ident { @@ -325,7 +325,7 @@ 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)); - let path = str::unsafe_from_bytes(pathbytes); + let path = str::from_bytes(pathbytes); ret {path: path, pos: pos}; } @@ -358,21 +358,21 @@ fn get_meta_items(md: ebml::doc) -> [@ast::meta_item] { let items: [@ast::meta_item] = []; ebml::tagged_docs(md, tag_meta_item_word) {|meta_item_doc| let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); - let n = str::unsafe_from_bytes(ebml::doc_data(nd)); + let n = str::from_bytes(ebml::doc_data(nd)); items += [attr::mk_word_item(n)]; }; ebml::tagged_docs(md, tag_meta_item_name_value) {|meta_item_doc| let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); let vd = ebml::get_doc(meta_item_doc, tag_meta_item_value); - let n = str::unsafe_from_bytes(ebml::doc_data(nd)); - let v = str::unsafe_from_bytes(ebml::doc_data(vd)); + let n = str::from_bytes(ebml::doc_data(nd)); + let v = str::from_bytes(ebml::doc_data(vd)); // FIXME (#611): Should be able to decode meta_name_value variants, // but currently they can't be encoded items += [attr::mk_name_value_item_str(n, v)]; }; ebml::tagged_docs(md, tag_meta_item_list) {|meta_item_doc| let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); - let n = str::unsafe_from_bytes(ebml::doc_data(nd)); + let n = str::from_bytes(ebml::doc_data(nd)); let subitems = get_meta_items(meta_item_doc); items += [attr::mk_list_item(n, subitems)]; }; @@ -427,7 +427,7 @@ fn get_crate_deps(data: @[u8]) -> [crate_dep] { let depsdoc = ebml::get_doc(cratedoc, tag_crate_deps); let crate_num = 1; ebml::tagged_docs(depsdoc, tag_crate_dep) {|depdoc| - let depname = str::unsafe_from_bytes(ebml::doc_data(depdoc)); + let depname = str::from_bytes(ebml::doc_data(depdoc)); deps += [{cnum: crate_num, ident: depname}]; crate_num += 1; }; @@ -447,7 +447,7 @@ fn list_crate_deps(data: @[u8], out: io::writer) { fn get_crate_hash(data: @[u8]) -> str { let cratedoc = ebml::new_doc(data); let hashdoc = ebml::get_doc(cratedoc, tag_crate_hash); - ret str::unsafe_from_bytes(ebml::doc_data(hashdoc)); + ret str::from_bytes(ebml::doc_data(hashdoc)); } fn list_crate_items(bytes: @[u8], md: ebml::doc, out: io::writer) { diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index b7b4d97fc21..e74a2d62ced 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -661,7 +661,7 @@ fn encode_hash(ebml_w: ebml::writer, hash: str) { ebml::end_tag(ebml_w); } -fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str { +fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> [u8] { let abbrevs = ty::new_ty_hash(); let ecx = @{ccx: cx, type_abbrevs: abbrevs}; @@ -694,7 +694,7 @@ fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str { // Pad this, since something (LLVM, presumably) is cutting off the // remaining % 4 bytes. buf_w.write([0u8, 0u8, 0u8, 0u8]); - io::mem_buffer_str(buf) + io::mem_buffer_buf(buf) } // Get the encoded string for a type diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index d9087df05f8..b7adcfadf12 100644 --- a/src/comp/metadata/tydecode.rs +++ b/src/comp/metadata/tydecode.rs @@ -39,7 +39,7 @@ fn parse_ident_(st: @pstate, is_last: fn@(char) -> bool) -> ast::ident { let rslt = ""; while !is_last(peek(st) as char) { - rslt += str::unsafe_from_byte(next(st)); + rslt += str::from_byte(next(st)); } ret rslt; } @@ -226,7 +226,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { while peek(st) as char != ']' { let name = ""; while peek(st) as char != '=' { - name += str::unsafe_from_byte(next(st)); + name += str::from_byte(next(st)); } st.pos = st.pos + 1u; fields += [{ident: name, mt: parse_mt(st, conv)}]; diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs index 87a2c596fde..7ecdd8be8f1 100644 --- a/src/comp/middle/mut.rs +++ b/src/comp/middle/mut.rs @@ -5,7 +5,7 @@ import syntax::visit; import syntax::ast_util; import driver::session::session; -enum deref_t { unbox, field, index, } +enum deref_t { unbox(bool), field, index, } type deref = @{mut: bool, kind: deref_t, outer_t: ty::t}; @@ -20,15 +20,15 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) -> while true { alt ty::struct(tcx, t) { ty::ty_box(mt) { - ds += [@{mut: mt.mut == mut, kind: unbox, outer_t: t}]; + ds += [@{mut: mt.mut == mut, kind: unbox(false), outer_t: t}]; t = mt.ty; } ty::ty_uniq(mt) { - ds += [@{mut: mt.mut == mut, kind: unbox, outer_t: t}]; + ds += [@{mut: mt.mut == mut, kind: unbox(false), outer_t: t}]; t = mt.ty; } ty::ty_res(_, inner, tps) { - ds += [@{mut: false, kind: unbox, outer_t: t}]; + ds += [@{mut: false, kind: unbox(false), outer_t: t}]; t = ty::substitute_type_params(tcx, tps, inner); } ty::ty_enum(did, tps) { @@ -37,7 +37,7 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) -> vec::len(variants[0].args) != 1u { break; } - ds += [@{mut: false, kind: unbox, outer_t: t}]; + ds += [@{mut: false, kind: unbox(false), outer_t: t}]; t = ty::substitute_type_params(tcx, tps, variants[0].args[0]); } _ { break; } @@ -85,15 +85,16 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) -> expr_unary(op, base) { if op == deref { let base_t = ty::expr_ty(tcx, base); - let is_mut = false; + let is_mut = false, ptr = false; alt ty::struct(tcx, base_t) { ty::ty_box(mt) { is_mut = mt.mut == mut; } ty::ty_uniq(mt) { is_mut = mt.mut == mut; } ty::ty_res(_, _, _) { } ty::ty_enum(_, _) { } - ty::ty_ptr(mt) { is_mut = mt.mut == mut; } + ty::ty_ptr(mt) { is_mut = mt.mut == mut; ptr = true; } } - ds += [@{mut: is_mut, kind: unbox, outer_t: base_t}]; + ds += [@{mut: is_mut, kind: unbox(ptr && is_mut), + outer_t: base_t}]; ex = base; } else { break; } } @@ -187,7 +188,7 @@ fn check_lval(cx: @ctx, dest: @expr, msg: msg) { } else if !root.ds[0].mut { let name = alt root.ds[0].kind { - mut::unbox { "immutable box" } + mut::unbox(_) { "immutable box" } mut::field { "immutable field" } mut::index { "immutable vec content" } }; @@ -212,7 +213,8 @@ 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 { + if vec::len(*root.ds) != 0u && + root.ds[vec::len(*root.ds) - 1u].kind != unbox(true) { cx.tcx.sess.span_err(src.span, "moving out of a data structure"); } } diff --git a/src/comp/middle/trans/base.rs b/src/comp/middle/trans/base.rs index bcee44962ca..9b423be389e 100644 --- a/src/comp/middle/trans/base.rs +++ b/src/comp/middle/trans/base.rs @@ -268,7 +268,7 @@ fn sanitize(s: str) -> str { c != ' ' as u8 && c != '\t' as u8 && c != ';' as u8 { let v = [c]; - result += str::unsafe_from_bytes(v); + result += str::from_bytes(v); } } } @@ -5412,7 +5412,7 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) { fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) { if !cx.sess.building_library { ret; } - let llmeta = C_postr(metadata::encoder::encode_metadata(cx, crate)); + let llmeta = C_bytes(metadata::encoder::encode_metadata(cx, crate)); let llconst = C_struct([llmeta]); let llglobal = str::as_buf("rust_metadata", {|buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf) diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 160bb832f13..502510063df 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -172,6 +172,7 @@ export type_is_str; export type_is_unique; export type_is_enum; export type_is_c_like_enum; +export type_structurally_contains; export type_structurally_contains_uniques; export type_autoderef; export type_param; @@ -2420,7 +2421,8 @@ mod unify { fn fixup_vars(tcx: ty_ctxt, sp: option::t<span>, vb: @var_bindings, typ: t) -> fixup_result { fn subst_vars(tcx: ty_ctxt, sp: option::t<span>, vb: @var_bindings, - unresolved: @mutable option::t<int>, vid: int) -> t { + unresolved: @mutable option::t<int>, + vars_seen: std::list::list<int>, vid: int) -> t { // Should really return a fixup_result instead of a t, but fold_ty // doesn't allow returning anything but a t. if vid as uint >= ufind::set_count(vb.sets) { @@ -2431,21 +2433,28 @@ mod unify { alt smallintmap::find::<t>(vb.types, root_id) { none { *unresolved = some(vid); ret ty::mk_var(tcx, vid); } some(rt) { - if occurs_check_fails(tcx, sp, vid, rt) { - // Return the type unchanged, so we can error out - // downstream - ret rt; + let give_up = false; + std::list::iter(vars_seen) {|v| + if v == vid { + give_up = true; + option::may(sp) {|sp| + tcx.sess.span_fatal( + sp, "can not instantiate infinite type"); + } + } } - ret fold_ty(tcx, - fm_var(bind subst_vars(tcx, sp, vb, unresolved, - _)), rt); + // Return the type unchanged, so we can error out + // downstream + if give_up { ret rt; } + ret fold_ty(tcx, fm_var(bind subst_vars( + tcx, sp, vb, unresolved, std::list::cons(vid, @vars_seen), + _)), rt); } } } let unresolved = @mutable none::<int>; - let rty = - fold_ty(tcx, fm_var(bind subst_vars(tcx, sp, vb, unresolved, _)), - typ); + let rty = fold_ty(tcx, fm_var(bind subst_vars( + tcx, sp, vb, unresolved, std::list::nil, _)), typ); let ur = *unresolved; alt ur { none { ret fix_ok(rty); } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 1d54ec2befc..8a06314a96b 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -259,10 +259,9 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t { alt tcx.ast_ty_to_ty_cache.find(ast_ty) { some(some(ty)) { ret ty; } some(none) { - tcx.sess.span_fatal(ast_ty.span, - "illegal recursive type \ - insert a enum in the cycle, \ - if this is desired)"); + tcx.sess.span_fatal(ast_ty.span, "illegal recursive type. \ + insert a enum in the cycle, \ + if this is desired)"); } none { } } /* go on */ @@ -2298,7 +2297,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, let msg = #fmt["attempted access of field %s on type %s, but \ no method implementation was found", field, ty_to_str(tcx, t_err)]; - tcx.sess.span_fatal(expr.span, msg); + tcx.sess.span_err(expr.span, msg); + // NB: Adding a bogus type to allow typechecking to continue + write::ty_only_fixup(fcx, id, ty::mk_nil(tcx)); } } } @@ -2490,7 +2491,7 @@ fn check_const(ccx: @crate_ctxt, _sp: span, e: @ast::expr, id: ast::node_id) { demand::simple(fcx, e.span, declty, cty); } -fn check_enum_variants(ccx: @crate_ctxt, _sp: span, vs: [ast::variant], +fn check_enum_variants(ccx: @crate_ctxt, sp: span, vs: [ast::variant], id: ast::node_id) { // FIXME: this is kinda a kludge; we manufacture a fake function context // and statement context for checking the initializer expression. @@ -2512,7 +2513,7 @@ fn check_enum_variants(ccx: @crate_ctxt, _sp: span, vs: [ast::variant], some(e) { check_expr(fcx, e); let cty = expr_ty(fcx.ccx.tcx, e); - let declty =ty::mk_int(fcx.ccx.tcx); + let declty = ty::mk_int(fcx.ccx.tcx); demand::simple(fcx, e.span, declty, cty); // FIXME: issue #1417 // Also, check_expr (from check_const pass) doesn't guarantee that @@ -2537,6 +2538,20 @@ fn check_enum_variants(ccx: @crate_ctxt, _sp: span, vs: [ast::variant], disr_vals += [disr_val]; disr_val += 1; } + let outer = true, did = local_def(id); + if ty::type_structurally_contains(ccx.tcx, rty, {|sty| + alt sty { + ty::ty_enum(id, _) if id == did { + if outer { outer = false; false } + else { true } + } + _ { false } + } + }) { + ccx.tcx.sess.span_fatal(sp, "illegal recursive enum type. \ + wrap the inner value in a box to \ + make it represenable"); + } } // A generic function for checking the pred in a check diff --git a/src/comp/syntax/parse/lexer.rs b/src/comp/syntax/parse/lexer.rs index 66e0f87d982..d2fbe02d63a 100644 --- a/src/comp/syntax/parse/lexer.rs +++ b/src/comp/syntax/parse/lexer.rs @@ -672,7 +672,7 @@ 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 src = @str::from_bytes(srdr.read_whole_stream()); let itr = @interner::mk::<str>(str::hash, str::eq); let rdr = new_reader(cm, span_diagnostic, codemap::new_filemap(path, src, 0u, 0u), itr); diff --git a/src/comp/util/ppaux.rs b/src/comp/util/ppaux.rs index f2c342a2956..2ae8a860a27 100644 --- a/src/comp/util/ppaux.rs +++ b/src/comp/util/ppaux.rs @@ -118,7 +118,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { } ty_var(v) { "<T" + int::str(v) + ">" } ty_param(id, _) { - "'" + str::unsafe_from_bytes([('a' as u8) + (id as u8)]) + "'" + str::from_bytes([('a' as u8) + (id as u8)]) } _ { ty_to_short_str(cx, typ) } } diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index a758e9a21bb..6f3fd87466a 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -85,7 +85,7 @@ fn readclose(fd: fd_t) -> str { let buf = ""; while !reader.eof() { let bytes = reader.read_bytes(4096u); - buf += str::unsafe_from_bytes(bytes); + buf += str::from_bytes(bytes); } os::fclose(file); ret buf; @@ -114,8 +114,8 @@ fn worker(p: port<request>) { // the alt discriminant are wrong. alt recv(p) { exec(lib_path, prog, args, respchan) { - {lib_path: str::unsafe_from_bytes(lib_path), - prog: str::unsafe_from_bytes(prog), + {lib_path: str::from_bytes(lib_path), + prog: str::from_bytes(prog), args: clone_vecu8str(args), respchan: respchan} } @@ -189,7 +189,7 @@ fn clone_vecstr(v: [str]) -> [[u8]] { fn clone_vecu8str(v: [[u8]]) -> [str] { let r = []; for t in vec::slice(v, 0u, vec::len(v)) { - r += [str::unsafe_from_bytes(t)]; + r += [str::from_bytes(t)]; } ret r; } diff --git a/src/libcore/extfmt.rs b/src/libcore/extfmt.rs index 38b36f59d32..eb91c2cb5d5 100644 --- a/src/libcore/extfmt.rs +++ b/src/libcore/extfmt.rs @@ -390,7 +390,7 @@ mod rt { fn str_init_elt(n_elts: uint, c: char) -> str { let svec = vec::init_elt::<u8>(n_elts, c as u8); - ret str::unsafe_from_bytes(svec); + ret str::from_bytes(svec); } enum pad_mode { pad_signed, pad_unsigned, pad_nozero, } fn pad(cv: conv, s: str, mode: pad_mode) -> str { @@ -439,7 +439,8 @@ mod rt { if signed && zero_padding && str::byte_len(s) > 0u { let head = s[0]; if head == '+' as u8 || head == '-' as u8 || head == ' ' as u8 { - let headstr = str::unsafe_from_bytes([head]); + let headstr = str::from_bytes([head]); + // FIXME: not UTF-8 safe let bytelen = str::byte_len(s); let numpart = str::substr(s, 1u, bytelen - 1u); ret headstr + padstr + numpart; diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 823f7cc78c6..dad10eced7f 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -13,6 +13,7 @@ export // Creating a string from_bytes, unsafe_from_bytes, + from_byte, unsafe_from_byte, //push_utf8_bytes, from_char, @@ -117,14 +118,11 @@ Section: Creating a string /* Function: from_bytes -Safely convert a vector of bytes to a UTF-8 string, or error +Convert a vector of bytes to a UTF-8 string. Fails if invalid UTF-8. */ -fn from_bytes(vv: [u8]) -> result::t<str, str> { - if is_utf8(vv) { - ret result::ok(unsafe_from_bytes(vv)); - } else { - ret result::err("vector doesn't contain valid UTF-8"); - } +fn from_bytes(vv: [u8]) -> str { + assert is_utf8(vv); + ret unsafe_from_bytes(vv); } /* @@ -133,7 +131,7 @@ Function: unsafe_from_bytes Converts a vector of bytes to a string. Does not verify that the vector contains valid UTF-8. -// FIXME: remove? +FIXME: stop exporting */ fn unsafe_from_bytes(v: [const u8]) -> str unsafe { let vcopy: [u8] = v + [0u8]; @@ -148,10 +146,20 @@ Function: unsafe_from_byte Converts a byte to a string. Does not verify that the byte is valid UTF-8. -FIXME: rename to 'from_byte' +FIXME: stop exporting */ fn unsafe_from_byte(u: u8) -> str { unsafe_from_bytes([u]) } + +/* +Function: from_byte + +Convert a byte to a UTF-8 string. Fails if invalid UTF-8. +*/ +fn from_byte(uu: u8) -> str { + from_bytes([uu]) +} + fn push_utf8_bytes(&s: str, ch: char) { let code = ch as uint; let bytes = @@ -209,16 +217,16 @@ Function: from_cstr Create a Rust string from a null-terminated C string */ unsafe fn from_cstr(cstr: sbuf) -> str { - let res = ""; + let res = []; let start = cstr; let curr = start; let i = 0u; while *curr != 0u8 { - push_byte(res, *curr); + vec::push(res, *curr); i += 1u; curr = ptr::offset(start, i); } - ret res; + ret from_bytes(res); } /* @@ -526,7 +534,7 @@ fn split(s: str, sep: u8) -> [str] { v += [accum]; accum = ""; ends_with_sep = true; - } else { accum += unsafe_from_byte(c); ends_with_sep = false; } + } else { accum += from_byte(c); ends_with_sep = false; } } if byte_len(accum) != 0u || ends_with_sep { v += [accum]; } ret v; @@ -554,7 +562,7 @@ fn splitn(s: str, sep: u8, count: uint) -> [str] { v += [accum]; accum = ""; ends_with_sep = true; - } else { accum += unsafe_from_byte(c); ends_with_sep = false; } + } else { accum += from_byte(c); ends_with_sep = false; } } if byte_len(accum) != 0u || ends_with_sep { v += [accum]; } ret v; @@ -575,12 +583,12 @@ FIXME: should behave like split and split_char: */ fn split_str(s: str, sep: str) -> [str] { assert byte_len(sep) > 0u; - let v: [str] = [], accum = "", sep_match = 0u, leading = true; + let v: [str] = [], accum = [], sep_match = 0u, leading = true; for c: u8 in s { // Did we match the entire separator? if sep_match == byte_len(sep) { - if !leading { v += [accum]; } - accum = ""; + if !leading { vec::push(v, from_bytes(accum)); } + accum = []; sep_match = 0u; } @@ -588,13 +596,13 @@ fn split_str(s: str, sep: str) -> [str] { sep_match += 1u; } else { sep_match = 0u; - accum += unsafe_from_byte(c); + vec::push(accum, c); leading = false; } } - if byte_len(accum) > 0u { v += [accum]; } - if sep_match == byte_len(sep) { v += [""]; } + if vec::len(accum) > 0u { vec::push(v, from_bytes(accum)); } + if sep_match == byte_len(sep) { vec::push(v, ""); } ret v; } @@ -1783,7 +1791,24 @@ mod tests { 0x20_u8, 0x4e_u8, 0x61_u8, 0x6d_u8]; - assert ss == result::get(from_bytes(bb)); + assert ss == from_bytes(bb); + } + + #[test] + #[should_fail] + fn test_from_bytes_fail() { + let bb = [0xff_u8, 0xb8_u8, 0xa8_u8, + 0xe0_u8, 0xb9_u8, 0x84_u8, + 0xe0_u8, 0xb8_u8, 0x97_u8, + 0xe0_u8, 0xb8_u8, 0xa2_u8, + 0xe4_u8, 0xb8_u8, 0xad_u8, + 0xe5_u8, 0x8d_u8, 0x8e_u8, + 0x56_u8, 0x69_u8, 0xe1_u8, + 0xbb_u8, 0x87_u8, 0x74_u8, + 0x20_u8, 0x4e_u8, 0x61_u8, + 0x6d_u8]; + + let _x = from_bytes(bb); } #[test] @@ -1821,7 +1846,7 @@ mod tests { let s1: str = "All mimsy were the borogoves"; let v: [u8] = bytes(s1); - let s2: str = unsafe_from_bytes(v); + let s2: str = from_bytes(v); let i: uint = 0u; let n1: uint = byte_len(s1); let n2: uint = vec::len::<u8>(v); diff --git a/src/libcore/uint.rs b/src/libcore/uint.rs index 8d032610e17..2112399ba80 100644 --- a/src/libcore/uint.rs +++ b/src/libcore/uint.rs @@ -236,12 +236,12 @@ fn to_str(num: uint, radix: uint) -> str { if n == 0u { ret "0"; } let s: str = ""; while n != 0u { - s += str::unsafe_from_byte(digit(n % radix) as u8); + s += str::from_byte(digit(n % radix) as u8); n /= radix; } let s1: str = ""; let len: uint = str::byte_len(s); - while len != 0u { len -= 1u; s1 += str::unsafe_from_byte(s[len]); } + while len != 0u { len -= 1u; s1 += str::from_byte(s[len]); } ret s1; } diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 8b7ea91becd..4dabab99c23 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -307,6 +307,14 @@ fn pop<T: copy>(&v: [const T]) -> T { let e = v[ln]; v = slice(v, 0u, ln); ret e; +// FIXME use this implementation after the next snapshot (27.01.2012) +/* let new_ln = len(v) - 1u; + assert (new_ln > 0u); + let valptr = ptr::mut_addr_of(v[new_ln]); + let val <- *valptr; + unsafe::set_len(v, new_ln); + val +*/ } /* diff --git a/src/libstd/freebsd_os.rs b/src/libstd/freebsd_os.rs index 847262ca10c..89aad5d7777 100644 --- a/src/libstd/freebsd_os.rs +++ b/src/libstd/freebsd_os.rs @@ -129,7 +129,8 @@ fn dylib_filename(base: str) -> str { ret "lib" + base + ".so"; } /// followed by a path separator fn get_exe_path() -> option::t<fs::path> unsafe { let bufsize = 1023u; - let path = str::unsafe_from_bytes(vec::init_elt(bufsize, 0u8)); + // FIXME: path "strings" will likely need fixing... + let path = str::from_bytes(vec::init_elt(bufsize, 0u8)); let mib = [libc_constants::CTL_KERN, libc_constants::KERN_PROC, libc_constants::KERN_PROC_PATHNAME, -1i32]; diff --git a/src/libstd/generic_os.rs b/src/libstd/generic_os.rs index 750b333f1a6..934352e7788 100644 --- a/src/libstd/generic_os.rs +++ b/src/libstd/generic_os.rs @@ -75,7 +75,7 @@ fn getenv(n: str) -> option::t<str> { unsafe { vec::unsafe::set_len(v, res); } - ret option::some(str::unsafe_from_bytes(v)); + ret option::some(str::from_bytes(v)); // UTF-8 or fail } else { nsize = res; } } fail; diff --git a/src/libstd/io.rs b/src/libstd/io.rs index 1db355dd385..5cc08813d6a 100644 --- a/src/libstd/io.rs +++ b/src/libstd/io.rs @@ -109,7 +109,7 @@ impl reader_util for reader { if ch == -1 || ch == 10 { break; } buf += [ch as u8]; } - str::unsafe_from_bytes(buf) + str::from_bytes(buf) } fn read_c_str() -> str { @@ -118,7 +118,7 @@ impl reader_util for reader { let ch = self.read_byte(); if ch < 1 { break; } else { buf += [ch as u8]; } } - str::unsafe_from_bytes(buf) + str::from_bytes(buf) } // FIXME deal with eof? @@ -461,7 +461,10 @@ fn mk_mem_buffer() -> mem_buffer { } fn mem_buffer_writer(b: mem_buffer) -> writer { b as writer } fn mem_buffer_buf(b: mem_buffer) -> [u8] { vec::from_mut(b.buf) } -fn mem_buffer_str(b: mem_buffer) -> str { str::unsafe_from_bytes(b.buf) } +fn mem_buffer_str(b: mem_buffer) -> str { + let b_ = vec::from_mut(b.buf); + str::from_bytes(b_) +} // Utility functions fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) -> @@ -479,7 +482,7 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) -> fn read_whole_file_str(file: str) -> result::t<str, str> { result::chain(read_whole_file(file), { |bytes| - result::ok(str::unsafe_from_bytes(bytes)) + result::ok(str::from_bytes(bytes)) }) } diff --git a/src/libstd/linux_os.rs b/src/libstd/linux_os.rs index 7bc0212c1c2..82b1197a51f 100644 --- a/src/libstd/linux_os.rs +++ b/src/libstd/linux_os.rs @@ -125,7 +125,8 @@ fn dylib_filename(base: str) -> str { ret "lib" + base + ".so"; } /// followed by a path separator fn get_exe_path() -> option::t<fs::path> { let bufsize = 1023u; - let path = str::unsafe_from_bytes(vec::init_elt(bufsize, 0u8)); + // FIXME: path "strings" will likely need fixing... + let path = str::from_bytes(vec::init_elt(bufsize, 0u8)); ret str::as_buf("/proc/self/exe", { |proc_self_buf| str::as_buf(path, { |path_buf| if libc::readlink(proc_self_buf, path_buf, bufsize) != -1 { diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 2081a21de23..e393b42b9f2 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -128,7 +128,7 @@ Function: tail Returns all but the first element of a list */ -pure fn tail<T: copy>(ls: list<T>) : is_not_empty(ls) -> list<T> { +pure fn tail<T: copy>(ls: list<T>) -> list<T> { alt ls { cons(_, tl) { ret *tl; } nil { fail "list empty" } diff --git a/src/libstd/macos_os.rs b/src/libstd/macos_os.rs index b72fc732379..cd984870781 100644 --- a/src/libstd/macos_os.rs +++ b/src/libstd/macos_os.rs @@ -133,8 +133,9 @@ fn dylib_filename(base: str) -> str { ret "lib" + base + ".dylib"; } fn get_exe_path() -> option::t<fs::path> { // FIXME: This doesn't handle the case where the buffer is too small + // FIXME: path "strings" will likely need fixing... let bufsize = 1023u32; - let path = str::unsafe_from_bytes(vec::init_elt(bufsize as uint, 0u8)); + let path = str::from_bytes(vec::init_elt(bufsize as uint, 0u8)); ret str::as_buf(path, { |path_buf| if mac_libc::_NSGetExecutablePath(path_buf, ptr::mut_addr_of(bufsize)) == 0i32 { diff --git a/src/libstd/run_program.rs b/src/libstd/run_program.rs index e40526b5884..5b2de1e57d0 100644 --- a/src/libstd/run_program.rs +++ b/src/libstd/run_program.rs @@ -216,7 +216,7 @@ fn read_all(rd: io::reader) -> str { let buf = ""; while !rd.eof() { let bytes = rd.read_bytes(4096u); - buf += str::unsafe_from_bytes(bytes); + buf += str::from_bytes(bytes); } ret buf; } @@ -347,7 +347,7 @@ mod tests { let buf = ""; while !reader.eof() { let bytes = reader.read_bytes(4096u); - buf += str::unsafe_from_bytes(bytes); + buf += str::from_bytes(bytes); } os::fclose(file); ret buf; diff --git a/src/libstd/uvtmp.rs b/src/libstd/uvtmp.rs index fb9df4bfbd3..ae08cd5ed5e 100644 --- a/src/libstd/uvtmp.rs +++ b/src/libstd/uvtmp.rs @@ -27,6 +27,11 @@ native mod rustrt { thread: thread, req_id: u32, chan: comm::chan<iomsg>); + fn rust_uvtmp_timer( + thread: thread, + timeout: u32, + req_id: u32, + chan: comm::chan<iomsg>); fn rust_uvtmp_delete_buf(buf: *u8); fn rust_uvtmp_get_req_id(cd: connect_data) -> u32; } @@ -39,7 +44,9 @@ enum iomsg { whatever, connected(connect_data), wrote(connect_data), - read(connect_data, *u8, ctypes::ssize_t) + read(connect_data, *u8, ctypes::ssize_t), + timer(u32), + exit } fn create_thread() -> thread { @@ -80,6 +87,11 @@ fn read_start(thread: thread, req_id: u32, rustrt::rust_uvtmp_read_start(thread, req_id, chan); } +fn timer_start(thread: thread, timeout: u32, req_id: u32, + chan: comm::chan<iomsg>) { + rustrt::rust_uvtmp_timer(thread, timeout, req_id, chan); +} + fn delete_buf(buf: *u8) { rustrt::rust_uvtmp_delete_buf(buf); } @@ -138,7 +150,7 @@ fn test_http() { unsafe { log(error, len); let buf = vec::unsafe::from_buf(buf, len as uint); - let str = str::unsafe_from_bytes(buf); + let str = str::from_bytes(buf); #error("read something"); io::println(str); } @@ -153,4 +165,4 @@ fn test_http() { } join_thread(thread); delete_thread(thread); -} \ No newline at end of file +} diff --git a/src/libstd/win32_os.rs b/src/libstd/win32_os.rs index 949c818a7ed..83306c757a4 100644 --- a/src/libstd/win32_os.rs +++ b/src/libstd/win32_os.rs @@ -113,8 +113,9 @@ fn getcwd() -> str { ret rustrt::rust_getcwd(); } fn get_exe_path() -> option::t<fs::path> { // FIXME: This doesn't handle the case where the buffer is too small + // FIXME: path "strings" will likely need fixing... let bufsize = 1023u; - let path = str::unsafe_from_bytes(vec::init_elt(bufsize, 0u8)); + let path = str::from_bytes(vec::init_elt(bufsize, 0u8)); ret str::as_buf(path, { |path_buf| if kernel32::GetModuleFileNameA(0u, path_buf, bufsize as u32) != 0u32 { diff --git a/src/rt/rust_uvtmp.cpp b/src/rt/rust_uvtmp.cpp index 27e0021bc6c..7f4b425e5ec 100644 --- a/src/rt/rust_uvtmp.cpp +++ b/src/rt/rust_uvtmp.cpp @@ -15,9 +15,12 @@ struct connect_data { chan_handle chan; }; +const intptr_t whatever_tag = 0; const intptr_t connected_tag = 1; const intptr_t wrote_tag = 2; const intptr_t read_tag = 3; +const intptr_t timer_tag = 4; +const intptr_t exit_tag = 5; struct iomsg { intptr_t tag; @@ -29,6 +32,7 @@ struct iomsg { uint8_t *buf; ssize_t nread; } read_val; + uint32_t timer_req_id; } val; }; @@ -44,6 +48,13 @@ struct read_start_data { chan_handle chan; }; +struct timer_start_data { + rust_uvtmp_thread *thread; + uint32_t timeout; + uint32_t req_id; + chan_handle chan; +}; + // FIXME: Copied from rust_builtins.cpp. Could bitrot easily static void send(rust_task *task, chan_handle chan, void *data) { @@ -72,7 +83,7 @@ private: std::queue<connect_data*> close_connection_queue; std::queue<write_data*> write_queue; std::queue<read_start_data*> read_start_queue; - + std::queue<timer_start_data*> timer_start_queue; public: rust_uvtmp_thread() { @@ -139,6 +150,17 @@ public: read_start_queue.push(rd); } + void + timer(uint32_t timeout, uint32_t req_id, chan_handle chan) { + scoped_lock with(lock); + + timer_start_data *td = new timer_start_data(); + td->timeout = timeout; + td->req_id = req_id; + td->chan = chan; + timer_start_queue.push(td); + } + private: virtual void @@ -159,6 +181,7 @@ private: close_connections(); write_buffers(); start_reads(); + start_timers(); close_idle_if_stop(); } @@ -246,7 +269,7 @@ private: void on_write(uv_write_t *handle, write_data *wd) { iomsg msg; - msg.tag = wrote_tag; + msg.tag = timer_tag; msg.val.wrote_val = wd->cd; send(task, wd->chan, &msg); @@ -300,6 +323,40 @@ private: } void + start_timers() { + assert (lock.lock_held_by_current_thread()); + while (!timer_start_queue.empty()) { + timer_start_data *td = timer_start_queue.front(); + timer_start_queue.pop(); + + td->thread = this; + + uv_timer_t *timer = (uv_timer_t *)malloc(sizeof(uv_timer_t)); + timer->data = td; + uv_timer_init(loop, timer); + uv_timer_start(timer, timer_cb, td->timeout, 0); + } + } + + static void + timer_cb(uv_timer_t *handle, int what) { + timer_start_data *td = (timer_start_data*)handle->data; + rust_uvtmp_thread *self = td->thread; + self->on_timer(td); + free(handle); + } + + void + on_timer(timer_start_data *rd) { + iomsg msg; + msg.tag = timer_tag; + msg.val.timer_req_id = rd->req_id; + + send(task, rd->chan, &msg); + delete rd; + } + + void close_idle_if_stop() { assert(lock.lock_held_by_current_thread()); if (stop_flag) { @@ -354,6 +411,11 @@ rust_uvtmp_read_start(rust_uvtmp_thread *thread, uint32_t req_id, } extern "C" void +rust_uvtmp_timer(rust_uvtmp_thread *thread, uint32_t timeout, uint32_t req_id, chan_handle *chan) { + thread->timer(timeout, req_id, *chan); +} + +extern "C" void rust_uvtmp_delete_buf(uint8_t *buf) { delete [] buf; } diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 17a0274d96e..052f4a42779 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -96,6 +96,7 @@ rust_uvtmp_connect rust_uvtmp_close_connection rust_uvtmp_write rust_uvtmp_read_start +rust_uvtmp_timer rust_uvtmp_delete_buf rust_uvtmp_get_req_id diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs index 55fbc6705b6..8be28fabd79 100644 --- a/src/test/bench/task-perf-word-count-generic.rs +++ b/src/test/bench/task-perf-word-count-generic.rs @@ -32,7 +32,7 @@ import comm::recv; import comm::send; fn map(&&filename: [u8], emit: map_reduce::putter<[u8], int>) { - let f = io::file_reader(str::unsafe_from_bytes(filename)); + let f = io::file_reader(str::from_bytes(filename)); while true { alt read_word(f) { diff --git a/src/test/compile-fail/attempted-access-non-fatal.rs b/src/test/compile-fail/attempted-access-non-fatal.rs new file mode 100644 index 00000000000..7ead10b3f63 --- /dev/null +++ b/src/test/compile-fail/attempted-access-non-fatal.rs @@ -0,0 +1,6 @@ +// Check that bogus field access is non-fatal +fn main() { + let x = 0; + log(debug, x.foo); //! ERROR attempted access of field + log(debug, x.bar); //! ERROR attempted access of field +} \ No newline at end of file diff --git a/src/test/compile-fail/occurs-check.rs b/src/test/compile-fail/occurs-check.rs index aba5b5c5928..069bd0a5bbd 100644 --- a/src/test/compile-fail/occurs-check.rs +++ b/src/test/compile-fail/occurs-check.rs @@ -1,2 +1,2 @@ -// error-pattern: Type inference failed because I could not find +// error-pattern: can not instantiate infinite type fn main() { let f; f = @f; } diff --git a/src/test/compile-fail/recursive-enum.rs b/src/test/compile-fail/recursive-enum.rs new file mode 100644 index 00000000000..b3764036b99 --- /dev/null +++ b/src/test/compile-fail/recursive-enum.rs @@ -0,0 +1,5 @@ +// error-pattern: illegal recursive enum type + +enum list<T> { cons(T, list<T>), nil } + +fn main() {} diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index 777b56c7520..9301d93874e 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -81,7 +81,7 @@ mod map_reduce { mapper_done { num_mappers -= 1; } find_reducer(k, cc) { let c; - alt reducers.find(str::unsafe_from_bytes(k)) { + alt reducers.find(str::from_bytes(k)) { some(_c) { c = _c; } none { c = 0; } } |
