From 9750e83a17a8f9f865eae757dcdccf374b1c82b7 Mon Sep 17 00:00:00 2001 From: Kevin Cantu Date: Tue, 24 Jan 2012 23:47:32 -0800 Subject: Replace uses of str::unsafe_from_byte --- src/comp/metadata/tydecode.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/comp') diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index 2e4e5cdc66d..cbd11c1c1b9 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)}]; -- cgit 1.4.1-3-g733a5 From eaa4befd6df4a26be0776d6aab0a7925232d76a7 Mon Sep 17 00:00:00 2001 From: Kevin Cantu Date: Wed, 25 Jan 2012 01:07:05 -0800 Subject: Replacing str::unsafe_from_bytes with str::from_bytes (part 3) --- src/comp/middle/trans.rs | 2 +- src/comp/util/ppaux.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/comp') diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 8de5d7257e2..e0dddd7057b 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -274,7 +274,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); } } } diff --git a/src/comp/util/ppaux.rs b/src/comp/util/ppaux.rs index 11ccd1cc71f..37e5a5f5101 100644 --- a/src/comp/util/ppaux.rs +++ b/src/comp/util/ppaux.rs @@ -122,7 +122,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { } ty_var(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) } } -- cgit 1.4.1-3-g733a5 From 87320a9f2768e5e011a6c8edaceb3d3b7ddc2747 Mon Sep 17 00:00:00 2001 From: Kevin Cantu Date: Wed, 25 Jan 2012 01:20:55 -0800 Subject: Replacing str::unsafe_from_bytes with str::from_bytes (part 4) --- src/comp/driver/driver.rs | 2 +- src/comp/metadata/decoder.rs | 20 ++++++++++---------- src/comp/syntax/parse/lexer.rs | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/comp') diff --git a/src/comp/driver/driver.rs b/src/comp/driver/driver.rs index 9d8d9ac03b7..de622ad8251 100644 --- a/src/comp/driver/driver.rs +++ b/src/comp/driver/driver.rs @@ -96,7 +96,7 @@ fn get_input_str(sess: session, infile: str) -> str { } } } else { io::stdin() }; - str::unsafe_from_bytes(stream.read_whole_stream()) + str::from_bytes(stream.read_whole_stream()) } fn time(do_it: bool, what: str, thunk: fn@() -> T) -> T { diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index bdd4623bbea..7711c819b06 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_tag_id(d: ebml::doc) -> ast::def_id { @@ -161,7 +161,7 @@ fn tag_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); @@ -177,7 +177,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 { @@ -326,7 +326,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::(desc, 4u, vec::len::(desc)); - let path = str::unsafe_from_bytes(pathbytes); + let path = str::from_bytes(pathbytes); ret {path: path, pos: pos}; } @@ -359,21 +359,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)]; }; @@ -428,7 +428,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; }; @@ -448,7 +448,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/syntax/parse/lexer.rs b/src/comp/syntax/parse/lexer.rs index 3dc1666b11e..f6a25ea61a7 100644 --- a/src/comp/syntax/parse/lexer.rs +++ b/src/comp/syntax/parse/lexer.rs @@ -671,7 +671,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::hash, str::eq); let rdr = new_reader(cm, diagnostic, src, codemap::new_filemap(path, 0u, 0u), itr); -- cgit 1.4.1-3-g733a5 From 4d7c297beaa4326d8c7dda029aeec264616cfca6 Mon Sep 17 00:00:00 2001 From: Kevin Cantu Date: Wed, 25 Jan 2012 22:27:29 -0800 Subject: (FIX) Change encoder::encode_metadata to return a [u8] (which will become an LLVM string) --- src/comp/metadata/encoder.rs | 4 ++-- src/comp/middle/trans.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/comp') diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index cc79e6a2bf0..66da9f7c36d 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -662,7 +662,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}; @@ -695,7 +695,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/middle/trans.rs b/src/comp/middle/trans.rs index e0dddd7057b..41fe5f8e19a 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5419,7 +5419,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 = trans_common::C_struct([llmeta]); let llglobal = str::as_buf("rust_metadata", -- cgit 1.4.1-3-g733a5 From dc55c06aa30a09f54e96e4049659fb1e3b85c486 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 27 Jan 2012 16:01:04 +0100 Subject: Properly check enum types for recursion Closes #742 --- src/comp/middle/ty.rs | 1 + src/comp/middle/typeck.rs | 25 +++++++++++++++++++------ src/test/compile-fail/recursive-enum.rs | 5 +++++ 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 src/test/compile-fail/recursive-enum.rs (limited to 'src/comp') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 160bb832f13..944614ad03e 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; diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 1d54ec2befc..c1079466e73 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 */ @@ -2490,7 +2489,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 +2511,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 +2536,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/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 { cons(T, list), nil } + +fn main() {} -- cgit 1.4.1-3-g733a5 From 362625008ab9e3479f7e34212e1887a3ad6d93b8 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 27 Jan 2012 17:15:31 +0100 Subject: Allow moving out of mutable unsafe pointers This makes it possible to de-initialize values anywhere in memory, which is needed, for example, for a fast imlementation of vec::pop. --- src/comp/middle/mut.rs | 22 ++++++++++++---------- src/libcore/vec.rs | 8 ++++++++ 2 files changed, 20 insertions(+), 10 deletions(-) (limited to 'src/comp') 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/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(&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 +*/ } /* -- cgit 1.4.1-3-g733a5 From e48bf6f3f4d1ca07f0c2820c6cfaad275bc106ac Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 27 Jan 2012 18:58:52 +0100 Subject: Make occurs check in ty::fixup_vars more reliable It wouldn't detect cycles that went through several type vars before. Closes #1464 --- src/comp/middle/ty.rs | 30 +++++++++++++++++++----------- src/libstd/list.rs | 2 +- src/test/compile-fail/occurs-check.rs | 2 +- 3 files changed, 21 insertions(+), 13 deletions(-) (limited to 'src/comp') diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 944614ad03e..502510063df 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -2421,7 +2421,8 @@ mod unify { fn fixup_vars(tcx: ty_ctxt, sp: option::t, vb: @var_bindings, typ: t) -> fixup_result { fn subst_vars(tcx: ty_ctxt, sp: option::t, vb: @var_bindings, - unresolved: @mutable option::t, vid: int) -> t { + unresolved: @mutable option::t, + vars_seen: std::list::list, 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) { @@ -2432,21 +2433,28 @@ mod unify { alt smallintmap::find::(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::; - 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/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(ls: list) : is_not_empty(ls) -> list { +pure fn tail(ls: list) -> list { alt ls { cons(_, tl) { ret *tl; } nil { fail "list empty" } 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; } -- cgit 1.4.1-3-g733a5 From 53dbde6cc2aabbf44bf75aea1eecad5729396081 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Fri, 27 Jan 2012 16:38:57 -0800 Subject: rustc: Make 'attempted access of field' error non-fatal --- src/comp/middle/typeck.rs | 4 +++- src/test/compile-fail/attempted-access-non-fatal.rs | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/attempted-access-non-fatal.rs (limited to 'src/comp') diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index c1079466e73..8a06314a96b 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -2297,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)); } } } 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 -- cgit 1.4.1-3-g733a5