about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2012-01-28 11:50:48 -0500
committerJosh Matthews <josh@joshmatthews.net>2012-01-28 11:50:48 -0500
commita831e7ce13aa19acf0f65e508097351f8dabca84 (patch)
treee8b14ee2373337d3867ee573d61227387191c962 /src/comp
parentfcb381410d59b89336a528103582a956334c9777 (diff)
parent0794195fbdb6efa34388dfdf3dfc968bbbf06215 (diff)
downloadrust-a831e7ce13aa19acf0f65e508097351f8dabca84.tar.gz
rust-a831e7ce13aa19acf0f65e508097351f8dabca84.zip
Merge remote-tracking branch 'mozilla/master'
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/metadata/decoder.rs20
-rw-r--r--src/comp/metadata/encoder.rs4
-rw-r--r--src/comp/metadata/tydecode.rs4
-rw-r--r--src/comp/middle/mut.rs22
-rw-r--r--src/comp/middle/trans/base.rs4
-rw-r--r--src/comp/middle/ty.rs31
-rw-r--r--src/comp/middle/typeck.rs29
-rw-r--r--src/comp/syntax/parse/lexer.rs2
-rw-r--r--src/comp/util/ppaux.rs2
9 files changed, 72 insertions, 46 deletions
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) }
     }