From 43cae880790b532e5b3e2fb99c64a4ec78030652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Fri, 7 Jun 2013 20:00:37 +0200 Subject: [PATCH 1/8] Lexer: Fix offset handling in get_str_from() As the comment said, the subtraction is bogus for multibyte characters. Fortunately, we can just use last_pos instead of pos to get the correct position without any subtraction hackery. --- src/libsyntax/parse/comments.rs | 2 +- src/libsyntax/parse/lexer.rs | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index dab8dd3b4b6a3..54fba29a19ad4 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -347,7 +347,7 @@ pub fn gather_comments_and_literals(span_diagnostic: } - let bstart = rdr.pos; + let bstart = rdr.last_pos; rdr.next_token(); //discard, and look ahead; we're working with internal state let TokenAndSpan {tok: tok, sp: sp} = rdr.peek(); diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 84700f052c9c4..172e7f1545876 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -161,22 +161,20 @@ fn string_advance_token(r: @mut StringReader) { } } -fn byte_offset(rdr: &StringReader) -> BytePos { - (rdr.pos - rdr.filemap.start_pos) +fn byte_offset(rdr: &StringReader, pos: BytePos) -> BytePos { + (pos - rdr.filemap.start_pos) } pub fn get_str_from(rdr: @mut StringReader, start: BytePos) -> ~str { - // I'm pretty skeptical about this subtraction. What if there's a - // multi-byte character before the mark? - return str::slice(*rdr.src, start.to_uint() - 1u, - byte_offset(rdr).to_uint() - 1u).to_owned(); + return str::slice(*rdr.src, start.to_uint(), + byte_offset(rdr, rdr.last_pos).to_uint()).to_owned(); } // EFFECT: advance the StringReader by one character. If a newline is // discovered, add it to the FileMap's list of line start offsets. pub fn bump(rdr: &mut StringReader) { rdr.last_pos = rdr.pos; - let current_byte_offset = byte_offset(rdr).to_uint();; + let current_byte_offset = byte_offset(rdr, rdr.pos).to_uint(); if current_byte_offset < (*rdr.src).len() { assert!(rdr.curr != -1 as char); let last_char = rdr.curr; @@ -202,7 +200,7 @@ pub fn is_eof(rdr: @mut StringReader) -> bool { rdr.curr == -1 as char } pub fn nextch(rdr: @mut StringReader) -> char { - let offset = byte_offset(rdr).to_uint(); + let offset = byte_offset(rdr, rdr.pos).to_uint(); if offset < (*rdr.src).len() { return str::char_at(*rdr.src, offset); } else { return -1 as char; } @@ -692,7 +690,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { return token::LIT_INT(c2 as i64, ast::ty_char); } '"' => { - let n = byte_offset(rdr); + let n = byte_offset(rdr, rdr.last_pos); bump(rdr); while rdr.curr != '"' { if is_eof(rdr) { From b87047789723ac140f471c56cebf3faa27e0c06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Fri, 7 Jun 2013 20:22:47 +0200 Subject: [PATCH 2/8] Avoid unnecessary (re-)allocations in the lexer --- src/libsyntax/parse/lexer.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 172e7f1545876..2634fa0b4db12 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -538,19 +538,19 @@ fn ident_continue(c: char) -> bool { // EFFECT: advances the input past that token // EFFECT: updates the interner fn next_token_inner(rdr: @mut StringReader) -> token::Token { - let mut accum_str = ~""; let mut c = rdr.curr; if ident_start(c) { - while ident_continue(c) { - str::push_char(&mut accum_str, c); + let start = byte_offset(rdr, rdr.last_pos); + while ident_continue(rdr.curr) { bump(rdr); - c = rdr.curr; } - if accum_str == ~"_" { return token::UNDERSCORE; } - let is_mod_name = c == ':' && nextch(rdr) == ':'; + let string = get_str_from(rdr, start); + + if "_" == string { return token::UNDERSCORE; } + let is_mod_name = rdr.curr == ':' && nextch(rdr) == ':'; // FIXME: perform NFKC normalization here. (Issue #2253) - return token::IDENT(str_to_ident(accum_str), is_mod_name); + return token::IDENT(str_to_ident(string), is_mod_name); } if is_dec_digit(c) { return scan_number(c, rdr); @@ -690,6 +690,7 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { return token::LIT_INT(c2 as i64, ast::ty_char); } '"' => { + let mut accum_str = ~""; let n = byte_offset(rdr, rdr.last_pos); bump(rdr); while rdr.curr != '"' { From 51e85f5e6e77b73619cee5db9761820ccee8cf0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 8 Jun 2013 02:01:30 +0200 Subject: [PATCH 3/8] Avoid unnecessary heap allocations in the metadata ty decoder --- src/librustc/metadata/tydecode.rs | 89 +++++++++++++++---------------- 1 file changed, 43 insertions(+), 46 deletions(-) diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 33e033ace4835..16b57493adfa2 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -62,17 +62,17 @@ pub struct PState { tcx: ty::ctxt } -fn peek(st: @mut PState) -> char { +fn peek(st: &PState) -> char { st.data[st.pos] as char } -fn next(st: @mut PState) -> char { +fn next(st: &mut PState) -> char { let ch = st.data[st.pos] as char; st.pos = st.pos + 1u; return ch; } -fn next_byte(st: @mut PState) -> u8 { +fn next_byte(st: &mut PState) -> u8 { let b = st.data[st.pos]; st.pos = st.pos + 1u; return b; @@ -92,20 +92,20 @@ fn scan(st: &mut PState, is_last: &fn(char) -> bool, return op(st.data.slice(start_pos, end_pos)); } -pub fn parse_ident(st: @mut PState, last: char) -> ast::ident { +pub fn parse_ident(st: &mut PState, last: char) -> ast::ident { fn is_last(b: char, c: char) -> bool { return c == b; } return parse_ident_(st, |a| is_last(last, a) ); } -fn parse_ident_(st: @mut PState, is_last: @fn(char) -> bool) -> +fn parse_ident_(st: &mut PState, is_last: @fn(char) -> bool) -> ast::ident { let rslt = scan(st, is_last, str::from_bytes); return st.tcx.sess.ident_of(rslt); } pub fn parse_state_from_data(data: @~[u8], crate_num: int, - pos: uint, tcx: ty::ctxt) -> @mut PState { - @mut PState { + pos: uint, tcx: ty::ctxt) -> PState { + PState { data: data, crate: crate_num, pos: pos, @@ -115,23 +115,23 @@ pub fn parse_state_from_data(data: @~[u8], crate_num: int, pub fn parse_ty_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt, conv: conv_did) -> ty::t { - let st = parse_state_from_data(data, crate_num, pos, tcx); - parse_ty(st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx); + parse_ty(&mut st, conv) } pub fn parse_bare_fn_ty_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt, conv: conv_did) -> ty::BareFnTy { - let st = parse_state_from_data(data, crate_num, pos, tcx); - parse_bare_fn_ty(st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx); + parse_bare_fn_ty(&mut st, conv) } pub fn parse_trait_ref_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt, conv: conv_did) -> ty::TraitRef { - let st = parse_state_from_data(data, crate_num, pos, tcx); - parse_trait_ref(st, conv) + let mut st = parse_state_from_data(data, crate_num, pos, tcx); + parse_trait_ref(&mut st, conv) } -fn parse_path(st: @mut PState) -> @ast::Path { +fn parse_path(st: &mut PState) -> @ast::Path { let mut idents: ~[ast::ident] = ~[]; fn is_last(c: char) -> bool { return c == '(' || c == ':'; } idents.push(parse_ident_(st, is_last)); @@ -151,7 +151,7 @@ fn parse_path(st: @mut PState) -> @ast::Path { }; } -fn parse_sigil(st: @mut PState) -> ast::Sigil { +fn parse_sigil(st: &mut PState) -> ast::Sigil { match next(st) { '@' => ast::ManagedSigil, '~' => ast::OwnedSigil, @@ -160,7 +160,7 @@ fn parse_sigil(st: @mut PState) -> ast::Sigil { } } -fn parse_vstore(st: @mut PState) -> ty::vstore { +fn parse_vstore(st: &mut PState) -> ty::vstore { assert_eq!(next(st), '/'); let c = peek(st); @@ -178,7 +178,7 @@ fn parse_vstore(st: @mut PState) -> ty::vstore { } } -fn parse_trait_store(st: @mut PState) -> ty::TraitStore { +fn parse_trait_store(st: &mut PState) -> ty::TraitStore { match next(st) { '~' => ty::UniqTraitStore, '@' => ty::BoxTraitStore, @@ -187,10 +187,10 @@ fn parse_trait_store(st: @mut PState) -> ty::TraitStore { } } -fn parse_substs(st: @mut PState, conv: conv_did) -> ty::substs { - let self_r = parse_opt(st, || parse_region(st) ); +fn parse_substs(st: &mut PState, conv: conv_did) -> ty::substs { + let self_r = parse_opt(st, |st| parse_region(st) ); - let self_ty = parse_opt(st, || parse_ty(st, conv) ); + let self_ty = parse_opt(st, |st| parse_ty(st, conv) ); assert_eq!(next(st), '['); let mut params: ~[ty::t] = ~[]; @@ -204,7 +204,7 @@ fn parse_substs(st: @mut PState, conv: conv_did) -> ty::substs { }; } -fn parse_bound_region(st: @mut PState) -> ty::bound_region { +fn parse_bound_region(st: &mut PState) -> ty::bound_region { match next(st) { 's' => ty::br_self, 'a' => { @@ -222,7 +222,7 @@ fn parse_bound_region(st: @mut PState) -> ty::bound_region { } } -fn parse_region(st: @mut PState) -> ty::Region { +fn parse_region(st: &mut PState) -> ty::Region { match next(st) { 'b' => { ty::re_bound(parse_bound_region(st)) @@ -251,15 +251,15 @@ fn parse_region(st: @mut PState) -> ty::Region { } } -fn parse_opt(st: @mut PState, f: &fn() -> T) -> Option { +fn parse_opt(st: &mut PState, f: &fn(&mut PState) -> T) -> Option { match next(st) { 'n' => None, - 's' => Some(f()), + 's' => Some(f(st)), _ => fail!("parse_opt: bad input") } } -fn parse_str(st: @mut PState, term: char) -> ~str { +fn parse_str(st: &mut PState, term: char) -> ~str { let mut result = ~""; while peek(st) != term { result += str::from_byte(next_byte(st)); @@ -268,13 +268,13 @@ fn parse_str(st: @mut PState, term: char) -> ~str { return result; } -fn parse_trait_ref(st: @mut PState, conv: conv_did) -> ty::TraitRef { +fn parse_trait_ref(st: &mut PState, conv: conv_did) -> ty::TraitRef { let def = parse_def(st, NominalType, conv); let substs = parse_substs(st, conv); ty::TraitRef {def_id: def, substs: substs} } -fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t { +fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { match next(st) { 'n' => return ty::mk_nil(), 'z' => return ty::mk_bot(), @@ -370,8 +370,8 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t { match st.tcx.rcache.find(&key) { Some(&tt) => return tt, None => { - let ps = @mut PState {pos: pos ,.. copy *st}; - let tt = parse_ty(ps, conv); + let mut ps = PState {pos: pos ,.. copy *st}; + let tt = parse_ty(&mut ps, conv); st.tcx.rcache.insert(key, tt); return tt; } @@ -394,7 +394,7 @@ fn parse_ty(st: @mut PState, conv: conv_did) -> ty::t { } } -fn parse_mutability(st: @mut PState) -> ast::mutability { +fn parse_mutability(st: &mut PState) -> ast::mutability { match peek(st) { 'm' => { next(st); ast::m_mutbl } '?' => { next(st); ast::m_const } @@ -402,20 +402,17 @@ fn parse_mutability(st: @mut PState) -> ast::mutability { } } -fn parse_mt(st: @mut PState, conv: conv_did) -> ty::mt { +fn parse_mt(st: &mut PState, conv: conv_did) -> ty::mt { let m = parse_mutability(st); ty::mt { ty: parse_ty(st, conv), mutbl: m } } -fn parse_def(st: @mut PState, source: DefIdSource, +fn parse_def(st: &mut PState, source: DefIdSource, conv: conv_did) -> ast::def_id { - let mut def = ~[]; - while peek(st) != '|' { def.push(next_byte(st)); } - st.pos = st.pos + 1u; - return conv(source, parse_def_id(def)); + return conv(source, scan(st, |c| { c == '|' }, parse_def_id)); } -fn parse_uint(st: @mut PState) -> uint { +fn parse_uint(st: &mut PState) -> uint { let mut n = 0; loop { let cur = peek(st); @@ -426,7 +423,7 @@ fn parse_uint(st: @mut PState) -> uint { }; } -fn parse_hex(st: @mut PState) -> uint { +fn parse_hex(st: &mut PState) -> uint { let mut n = 0u; loop { let cur = peek(st); @@ -449,7 +446,7 @@ fn parse_purity(c: char) -> purity { } } -fn parse_abi_set(st: @mut PState) -> AbiSet { +fn parse_abi_set(st: &mut PState) -> AbiSet { assert_eq!(next(st), '['); let mut abis = AbiSet::empty(); while peek(st) != ']' { @@ -470,7 +467,7 @@ fn parse_onceness(c: char) -> ast::Onceness { } } -fn parse_closure_ty(st: @mut PState, conv: conv_did) -> ty::ClosureTy { +fn parse_closure_ty(st: &mut PState, conv: conv_did) -> ty::ClosureTy { let sigil = parse_sigil(st); let purity = parse_purity(next(st)); let onceness = parse_onceness(next(st)); @@ -487,7 +484,7 @@ fn parse_closure_ty(st: @mut PState, conv: conv_did) -> ty::ClosureTy { } } -fn parse_bare_fn_ty(st: @mut PState, conv: conv_did) -> ty::BareFnTy { +fn parse_bare_fn_ty(st: &mut PState, conv: conv_did) -> ty::BareFnTy { let purity = parse_purity(next(st)); let abi = parse_abi_set(st); let sig = parse_sig(st, conv); @@ -498,7 +495,7 @@ fn parse_bare_fn_ty(st: @mut PState, conv: conv_did) -> ty::BareFnTy { } } -fn parse_sig(st: @mut PState, conv: conv_did) -> ty::FnSig { +fn parse_sig(st: &mut PState, conv: conv_did) -> ty::FnSig { assert_eq!(next(st), '['); let mut inputs = ~[]; while peek(st) != ']' { @@ -541,16 +538,16 @@ pub fn parse_type_param_def_data(data: @~[u8], start: uint, crate_num: int, tcx: ty::ctxt, conv: conv_did) -> ty::TypeParameterDef { - let st = parse_state_from_data(data, crate_num, start, tcx); - parse_type_param_def(st, conv) + let mut st = parse_state_from_data(data, crate_num, start, tcx); + parse_type_param_def(&mut st, conv) } -fn parse_type_param_def(st: @mut PState, conv: conv_did) -> ty::TypeParameterDef { +fn parse_type_param_def(st: &mut PState, conv: conv_did) -> ty::TypeParameterDef { ty::TypeParameterDef {def_id: parse_def(st, NominalType, conv), bounds: @parse_bounds(st, conv)} } -fn parse_bounds(st: @mut PState, conv: conv_did) -> ty::ParamBounds { +fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { let mut param_bounds = ty::ParamBounds { builtin_bounds: ty::EmptyBuiltinBounds(), trait_bounds: ~[] From 96798f5e050829b2fe4e43420c21ae3372f2b76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 8 Jun 2013 02:24:11 +0200 Subject: [PATCH 4/8] tydecode: Accept a plain borrowed pointer to the data --- src/librustc/metadata/decoder.rs | 22 ++++++++-------------- src/librustc/metadata/tydecode.rs | 16 ++++++++-------- src/librustc/middle/astencode.rs | 4 ++-- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 5fa678e6121bf..0c19b546d684c 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -216,13 +216,13 @@ fn variant_disr_val(d: ebml::Doc) -> Option { fn doc_type(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t { let tp = reader::get_doc(doc, tag_items_data_item_type); - parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, + parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx, |_, did| translate_def_id(cdata, did)) } fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::BareFnTy { let tp = reader::get_doc(doc, tag_item_method_fty); - parse_bare_fn_ty_data(tp.data, cdata.cnum, tp.start, tcx, + parse_bare_fn_ty_data(*tp.data, cdata.cnum, tp.start, tcx, |_, did| translate_def_id(cdata, did)) } @@ -231,7 +231,7 @@ fn doc_transformed_self_ty(doc: ebml::Doc, cdata: cmd) -> Option { do reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map |tp| { - parse_ty_data(tp.data, cdata.cnum, tp.start, tcx, + parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx, |_, did| translate_def_id(cdata, did)) } } @@ -242,7 +242,7 @@ pub fn item_type(_item_id: ast::def_id, item: ebml::Doc, } fn doc_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef { - parse_trait_ref_data(doc.data, cdata.cnum, doc.start, tcx, + parse_trait_ref_data(*doc.data, cdata.cnum, doc.start, tcx, |_, did| translate_def_id(cdata, did)) } @@ -257,7 +257,7 @@ fn item_ty_param_defs(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd, let mut bounds = ~[]; for reader::tagged_docs(item, tag) |p| { let bd = parse_type_param_def_data( - p.data, p.start, cdata.cnum, tcx, + *p.data, p.start, cdata.cnum, tcx, |_, did| translate_def_id(cdata, did)); bounds.push(bd); } @@ -413,15 +413,9 @@ pub fn get_impl_trait(cdata: cmd, tcx: ty::ctxt) -> Option<@ty::TraitRef> { let item_doc = lookup_item(id, cdata.data); - let mut result = None; - for reader::tagged_docs(item_doc, tag_item_trait_ref) |tp| { - let trait_ref = - @parse_trait_ref_data(tp.data, cdata.cnum, tp.start, tcx, - |_, did| translate_def_id(cdata, did)); - result = Some(trait_ref); - break; - }; - result + do reader::maybe_get_doc(item_doc, tag_item_trait_ref).map |&tp| { + @doc_trait_ref(tp, tcx, cdata) + } } pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 16b57493adfa2..cf2a92b291f28 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -55,8 +55,8 @@ pub enum DefIdSource { type conv_did<'self> = &'self fn(source: DefIdSource, ast::def_id) -> ast::def_id; -pub struct PState { - data: @~[u8], +pub struct PState<'self> { + data: &'self [u8], crate: int, pos: uint, tcx: ty::ctxt @@ -103,8 +103,8 @@ fn parse_ident_(st: &mut PState, is_last: @fn(char) -> bool) -> return st.tcx.sess.ident_of(rslt); } -pub fn parse_state_from_data(data: @~[u8], crate_num: int, - pos: uint, tcx: ty::ctxt) -> PState { +pub fn parse_state_from_data<'a>(data: &'a [u8], crate_num: int, + pos: uint, tcx: ty::ctxt) -> PState<'a> { PState { data: data, crate: crate_num, @@ -113,19 +113,19 @@ pub fn parse_state_from_data(data: @~[u8], crate_num: int, } } -pub fn parse_ty_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt, +pub fn parse_ty_data(data: &[u8], crate_num: int, pos: uint, tcx: ty::ctxt, conv: conv_did) -> ty::t { let mut st = parse_state_from_data(data, crate_num, pos, tcx); parse_ty(&mut st, conv) } -pub fn parse_bare_fn_ty_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt, +pub fn parse_bare_fn_ty_data(data: &[u8], crate_num: int, pos: uint, tcx: ty::ctxt, conv: conv_did) -> ty::BareFnTy { let mut st = parse_state_from_data(data, crate_num, pos, tcx); parse_bare_fn_ty(&mut st, conv) } -pub fn parse_trait_ref_data(data: @~[u8], crate_num: int, pos: uint, tcx: ty::ctxt, +pub fn parse_trait_ref_data(data: &[u8], crate_num: int, pos: uint, tcx: ty::ctxt, conv: conv_did) -> ty::TraitRef { let mut st = parse_state_from_data(data, crate_num, pos, tcx); parse_trait_ref(&mut st, conv) @@ -534,7 +534,7 @@ pub fn parse_def_id(buf: &[u8]) -> ast::def_id { ast::def_id { crate: crate_num, node: def_num } } -pub fn parse_type_param_def_data(data: @~[u8], start: uint, +pub fn parse_type_param_def_data(data: &[u8], start: uint, crate_num: int, tcx: ty::ctxt, conv: conv_did) -> ty::TypeParameterDef { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 8bde4e37d54d8..32a2bf22f2705 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -964,7 +964,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder { return do self.read_opaque |this, doc| { let ty = tydecode::parse_ty_data( - doc.data, + *doc.data, xcx.dcx.cdata.cnum, doc.start, xcx.dcx.tcx, @@ -994,7 +994,7 @@ impl ebml_decoder_decoder_helpers for reader::Decoder { -> ty::TypeParameterDef { do self.read_opaque |this, doc| { tydecode::parse_type_param_def_data( - doc.data, + *doc.data, doc.start, xcx.dcx.cdata.cnum, xcx.dcx.tcx, From de1df3608b5ece9e492cbda06c443249691b017a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 8 Jun 2013 02:26:52 +0200 Subject: [PATCH 5/8] Lexer: Avoid unnecessary allocations --- src/libsyntax/parse/comments.rs | 9 ++-- src/libsyntax/parse/lexer.rs | 90 +++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 54fba29a19ad4..4921fb459bc15 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -13,7 +13,7 @@ use core::prelude::*; use ast; use codemap::{BytePos, CharPos, CodeMap, Pos}; use diagnostic; -use parse::lexer::{is_whitespace, get_str_from, reader}; +use parse::lexer::{is_whitespace, with_str_from, reader}; use parse::lexer::{StringReader, bump, is_eof, nextch, TokenAndSpan}; use parse::lexer::{is_line_non_doc_comment, is_block_non_doc_comment}; use parse::lexer; @@ -352,9 +352,10 @@ pub fn gather_comments_and_literals(span_diagnostic: //discard, and look ahead; we're working with internal state let TokenAndSpan {tok: tok, sp: sp} = rdr.peek(); if token::is_lit(&tok) { - let s = get_str_from(rdr, bstart); - debug!("tok lit: %s", s); - literals.push(lit {lit: s, pos: sp.lo}); + do with_str_from(rdr, bstart) |s| { + debug!("tok lit: %s", s); + literals.push(lit {lit: s.to_owned(), pos: sp.lo}); + } } else { debug!("tok: %s", token::to_str(get_ident_interner(), &tok)); } diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 2634fa0b4db12..8ee0a976c8b9c 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -165,9 +165,10 @@ fn byte_offset(rdr: &StringReader, pos: BytePos) -> BytePos { (pos - rdr.filemap.start_pos) } -pub fn get_str_from(rdr: @mut StringReader, start: BytePos) -> ~str { - return str::slice(*rdr.src, start.to_uint(), - byte_offset(rdr, rdr.last_pos).to_uint()).to_owned(); +pub fn with_str_from(rdr: @mut StringReader, start: BytePos, f: &fn(s: &str) -> T) -> T { + f(rdr.src.slice( + byte_offset(rdr, start).to_uint(), + byte_offset(rdr, rdr.last_pos).to_uint())) } // EFFECT: advance the StringReader by one character. If a newline is @@ -259,18 +260,24 @@ fn consume_any_line_comment(rdr: @mut StringReader) bump(rdr); // line comments starting with "///" or "//!" are doc-comments if rdr.curr == '/' || rdr.curr == '!' { - let start_bpos = rdr.pos - BytePos(2u); - let mut acc = ~"//"; + let start_bpos = rdr.pos - BytePos(3u); while rdr.curr != '\n' && !is_eof(rdr) { - str::push_char(&mut acc, rdr.curr); bump(rdr); } - // but comments with only more "/"s are not - if !is_line_non_doc_comment(acc) { - return Some(TokenAndSpan{ - tok: token::DOC_COMMENT(str_to_ident(acc)), - sp: codemap::mk_sp(start_bpos, rdr.pos) - }); + let ret = do with_str_from(rdr, start_bpos) |string| { + // but comments with only more "/"s are not + if !is_line_non_doc_comment(string) { + Some(TokenAndSpan{ + tok: token::DOC_COMMENT(str_to_ident(string)), + sp: codemap::mk_sp(start_bpos, rdr.pos) + }) + } else { + None + } + }; + + if ret.is_some() { + return ret; } } else { while rdr.curr != '\n' && !is_eof(rdr) { bump(rdr); } @@ -306,25 +313,26 @@ pub fn is_block_non_doc_comment(s: &str) -> bool { fn consume_block_comment(rdr: @mut StringReader) -> Option { // block comments starting with "/**" or "/*!" are doc-comments - if rdr.curr == '*' || rdr.curr == '!' { - let start_bpos = rdr.pos - BytePos(2u); - let mut acc = ~"/*"; + let res = if rdr.curr == '*' || rdr.curr == '!' { + let start_bpos = rdr.pos - BytePos(3u); while !(rdr.curr == '*' && nextch(rdr) == '/') && !is_eof(rdr) { - str::push_char(&mut acc, rdr.curr); bump(rdr); } if is_eof(rdr) { rdr.fatal(~"unterminated block doc-comment"); } else { - acc += "*/"; bump(rdr); bump(rdr); - // but comments with only "*"s between two "/"s are not - if !is_block_non_doc_comment(acc) { - return Some(TokenAndSpan{ - tok: token::DOC_COMMENT(str_to_ident(acc)), - sp: codemap::mk_sp(start_bpos, rdr.pos) - }); + do with_str_from(rdr, start_bpos) |string| { + // but comments with only "*"s between two "/"s are not + if !is_block_non_doc_comment(string) { + Some(TokenAndSpan{ + tok: token::DOC_COMMENT(str_to_ident(string)), + sp: codemap::mk_sp(start_bpos, rdr.pos) + }) + } else { + None + } } } } else { @@ -338,10 +346,11 @@ fn consume_block_comment(rdr: @mut StringReader) bump(rdr); } } - } + None + }; // restart whitespace munch. - return consume_whitespace_and_comments(rdr); + if res.is_some() { res } else { consume_whitespace_and_comments(rdr) } } fn scan_exponent(rdr: @mut StringReader) -> Option<~str> { @@ -540,17 +549,21 @@ fn ident_continue(c: char) -> bool { fn next_token_inner(rdr: @mut StringReader) -> token::Token { let mut c = rdr.curr; if ident_start(c) { - let start = byte_offset(rdr, rdr.last_pos); + let start = rdr.last_pos; while ident_continue(rdr.curr) { bump(rdr); } - let string = get_str_from(rdr, start); - if "_" == string { return token::UNDERSCORE; } - let is_mod_name = rdr.curr == ':' && nextch(rdr) == ':'; + return do with_str_from(rdr, start) |string| { + if string == "_" { + token::UNDERSCORE + } else { + let is_mod_name = rdr.curr == ':' && nextch(rdr) == ':'; - // FIXME: perform NFKC normalization here. (Issue #2253) - return token::IDENT(str_to_ident(string), is_mod_name); + // FIXME: perform NFKC normalization here. (Issue #2253) + token::IDENT(str_to_ident(string), is_mod_name) + } + } } if is_dec_digit(c) { return scan_number(c, rdr); @@ -648,19 +661,19 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { '\'' => { // Either a character constant 'a' OR a lifetime name 'abc bump(rdr); + let start = rdr.last_pos; let mut c2 = rdr.curr; bump(rdr); // If the character is an ident start not followed by another single // quote, then this is a lifetime name: if ident_start(c2) && rdr.curr != '\'' { - let mut lifetime_name = ~""; - lifetime_name.push_char(c2); while ident_continue(rdr.curr) { - lifetime_name.push_char(rdr.curr); bump(rdr); } - return token::LIFETIME(str_to_ident(lifetime_name)); + return do with_str_from(rdr, start) |lifetime_name| { + token::LIFETIME(str_to_ident(lifetime_name)) + } } // Otherwise it is a character constant: @@ -691,12 +704,13 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { } '"' => { let mut accum_str = ~""; - let n = byte_offset(rdr, rdr.last_pos); + let n = rdr.last_pos; bump(rdr); while rdr.curr != '"' { if is_eof(rdr) { - rdr.fatal(fmt!("unterminated double quote string: %s", - get_str_from(rdr, n))); + do with_str_from(rdr, n) |s| { + rdr.fatal(fmt!("unterminated double quote string: %s", s)); + } } let ch = rdr.curr; From b65dc42b25c71a1f032a08a2d592a3687cbefe86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 8 Jun 2013 02:28:06 +0200 Subject: [PATCH 6/8] TypeChecker: Avoid unnecessary copies --- src/librustc/middle/typeck/infer/combine.rs | 66 ++++++++++----------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs index f0fe48918073e..7668167489209 100644 --- a/src/librustc/middle/typeck/infer/combine.rs +++ b/src/librustc/middle/typeck/infer/combine.rs @@ -434,12 +434,12 @@ pub fn super_fn_sigs( pub fn super_tys( this: &C, a: ty::t, b: ty::t) -> cres { let tcx = this.infcx().tcx; - return match (/*bad*/copy ty::get(a).sty, /*bad*/copy ty::get(b).sty) { + return match (&ty::get(a).sty, &ty::get(b).sty) { // The "subtype" ought to be handling cases involving bot or var: - (ty::ty_bot, _) | - (_, ty::ty_bot) | - (ty::ty_infer(TyVar(_)), _) | - (_, ty::ty_infer(TyVar(_))) => { + (&ty::ty_bot, _) | + (_, &ty::ty_bot) | + (&ty::ty_infer(TyVar(_)), _) | + (_, &ty::ty_infer(TyVar(_))) => { tcx.sess.bug( fmt!("%s: bot and var types should have been handled (%s,%s)", this.tag(), @@ -448,46 +448,46 @@ pub fn super_tys( } // Relate integral variables to other types - (ty::ty_infer(IntVar(a_id)), ty::ty_infer(IntVar(b_id))) => { + (&ty::ty_infer(IntVar(a_id)), &ty::ty_infer(IntVar(b_id))) => { if_ok!(this.infcx().simple_vars(this.a_is_expected(), a_id, b_id)); Ok(a) } - (ty::ty_infer(IntVar(v_id)), ty::ty_int(v)) => { + (&ty::ty_infer(IntVar(v_id)), &ty::ty_int(v)) => { unify_integral_variable(this, this.a_is_expected(), v_id, IntType(v)) } - (ty::ty_int(v), ty::ty_infer(IntVar(v_id))) => { + (&ty::ty_int(v), &ty::ty_infer(IntVar(v_id))) => { unify_integral_variable(this, !this.a_is_expected(), v_id, IntType(v)) } - (ty::ty_infer(IntVar(v_id)), ty::ty_uint(v)) => { + (&ty::ty_infer(IntVar(v_id)), &ty::ty_uint(v)) => { unify_integral_variable(this, this.a_is_expected(), v_id, UintType(v)) } - (ty::ty_uint(v), ty::ty_infer(IntVar(v_id))) => { + (&ty::ty_uint(v), &ty::ty_infer(IntVar(v_id))) => { unify_integral_variable(this, !this.a_is_expected(), v_id, UintType(v)) } // Relate floating-point variables to other types - (ty::ty_infer(FloatVar(a_id)), ty::ty_infer(FloatVar(b_id))) => { + (&ty::ty_infer(FloatVar(a_id)), &ty::ty_infer(FloatVar(b_id))) => { if_ok!(this.infcx().simple_vars(this.a_is_expected(), a_id, b_id)); Ok(a) } - (ty::ty_infer(FloatVar(v_id)), ty::ty_float(v)) => { + (&ty::ty_infer(FloatVar(v_id)), &ty::ty_float(v)) => { unify_float_variable(this, this.a_is_expected(), v_id, v) } - (ty::ty_float(v), ty::ty_infer(FloatVar(v_id))) => { + (&ty::ty_float(v), &ty::ty_infer(FloatVar(v_id))) => { unify_float_variable(this, !this.a_is_expected(), v_id, v) } - (ty::ty_nil, _) | - (ty::ty_bool, _) | - (ty::ty_int(_), _) | - (ty::ty_uint(_), _) | - (ty::ty_float(_), _) => { + (&ty::ty_nil, _) | + (&ty::ty_bool, _) | + (&ty::ty_int(_), _) | + (&ty::ty_uint(_), _) | + (&ty::ty_float(_), _) => { if ty::get(a).sty == ty::get(b).sty { Ok(a) } else { @@ -495,12 +495,12 @@ pub fn super_tys( } } - (ty::ty_param(ref a_p), ty::ty_param(ref b_p)) if a_p.idx == b_p.idx => { + (&ty::ty_param(ref a_p), &ty::ty_param(ref b_p)) if a_p.idx == b_p.idx => { Ok(a) } - (ty::ty_enum(a_id, ref a_substs), - ty::ty_enum(b_id, ref b_substs)) + (&ty::ty_enum(a_id, ref a_substs), + &ty::ty_enum(b_id, ref b_substs)) if a_id == b_id => { let type_def = ty::lookup_item_type(tcx, a_id); do this.substs(&type_def.generics, a_substs, b_substs).chain |substs| { @@ -508,8 +508,8 @@ pub fn super_tys( } } - (ty::ty_trait(a_id, ref a_substs, a_store, a_mutbl), - ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl)) + (&ty::ty_trait(a_id, ref a_substs, a_store, a_mutbl), + &ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl)) if a_id == b_id && a_mutbl == b_mutbl => { let trait_def = ty::lookup_trait_def(tcx, a_id); do this.substs(&trait_def.generics, a_substs, b_substs).chain |substs| { @@ -519,7 +519,7 @@ pub fn super_tys( } } - (ty::ty_struct(a_id, ref a_substs), ty::ty_struct(b_id, ref b_substs)) + (&ty::ty_struct(a_id, ref a_substs), &ty::ty_struct(b_id, ref b_substs)) if a_id == b_id => { let type_def = ty::lookup_item_type(tcx, a_id); do this.substs(&type_def.generics, a_substs, b_substs).chain |substs| { @@ -527,31 +527,31 @@ pub fn super_tys( } } - (ty::ty_box(ref a_mt), ty::ty_box(ref b_mt)) => { + (&ty::ty_box(ref a_mt), &ty::ty_box(ref b_mt)) => { do this.mts(a_mt, b_mt).chain |mt| { Ok(ty::mk_box(tcx, mt)) } } - (ty::ty_uniq(ref a_mt), ty::ty_uniq(ref b_mt)) => { + (&ty::ty_uniq(ref a_mt), &ty::ty_uniq(ref b_mt)) => { do this.mts(a_mt, b_mt).chain |mt| { Ok(ty::mk_uniq(tcx, mt)) } } - (ty::ty_ptr(ref a_mt), ty::ty_ptr(ref b_mt)) => { + (&ty::ty_ptr(ref a_mt), &ty::ty_ptr(ref b_mt)) => { do this.mts(a_mt, b_mt).chain |mt| { Ok(ty::mk_ptr(tcx, mt)) } } - (ty::ty_rptr(a_r, ref a_mt), ty::ty_rptr(b_r, ref b_mt)) => { + (&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => { let r = if_ok!(this.contraregions(a_r, b_r)); let mt = if_ok!(this.mts(a_mt, b_mt)); Ok(ty::mk_rptr(tcx, r, mt)) } - (ty::ty_evec(ref a_mt, vs_a), ty::ty_evec(ref b_mt, vs_b)) => { + (&ty::ty_evec(ref a_mt, vs_a), &ty::ty_evec(ref b_mt, vs_b)) => { do this.mts(a_mt, b_mt).chain |mt| { do this.vstores(ty::terr_vec, vs_a, vs_b).chain |vs| { Ok(ty::mk_evec(tcx, mt, vs)) @@ -559,13 +559,13 @@ pub fn super_tys( } } - (ty::ty_estr(vs_a), ty::ty_estr(vs_b)) => { + (&ty::ty_estr(vs_a), &ty::ty_estr(vs_b)) => { do this.vstores(ty::terr_str, vs_a, vs_b).chain |vs| { Ok(ty::mk_estr(tcx,vs)) } } - (ty::ty_tup(ref as_), ty::ty_tup(ref bs)) => { + (&ty::ty_tup(ref as_), &ty::ty_tup(ref bs)) => { if as_.len() == bs.len() { map_vec2(*as_, *bs, |a, b| this.tys(*a, *b) ) .chain(|ts| Ok(ty::mk_tup(tcx, ts)) ) @@ -575,13 +575,13 @@ pub fn super_tys( } } - (ty::ty_bare_fn(ref a_fty), ty::ty_bare_fn(ref b_fty)) => { + (&ty::ty_bare_fn(ref a_fty), &ty::ty_bare_fn(ref b_fty)) => { do this.bare_fn_tys(a_fty, b_fty).chain |fty| { Ok(ty::mk_bare_fn(tcx, fty)) } } - (ty::ty_closure(ref a_fty), ty::ty_closure(ref b_fty)) => { + (&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => { do this.closure_tys(a_fty, b_fty).chain |fty| { Ok(ty::mk_closure(tcx, fty)) } From 29e5aa09427ce9f0c17e367f680d671268009ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 8 Jun 2013 02:32:25 +0200 Subject: [PATCH 7/8] Remove some unnecessary closures --- src/librustc/metadata/decoder.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 0c19b546d684c..b544b94d1c23e 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -174,7 +174,7 @@ fn item_symbol(item: ebml::Doc) -> ~str { fn item_parent_item(d: ebml::Doc) -> Option { for reader::tagged_docs(d, tag_items_data_parent_item) |did| { - return Some(reader::with_doc_data(did, |d| parse_def_id(d))); + return Some(reader::with_doc_data(did, parse_def_id)); } None } @@ -195,8 +195,7 @@ fn item_reqd_and_translated_parent_item(cnum: ast::crate_num, fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id { let tagdoc = reader::get_doc(d, tag_def_id); - return translate_def_id(cdata, reader::with_doc_data(tagdoc, - |d| parse_def_id(d))); + return translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id)); } fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool { @@ -282,7 +281,7 @@ fn enum_variant_ids(item: ebml::Doc, cdata: cmd) -> ~[ast::def_id] { let mut ids: ~[ast::def_id] = ~[]; let v = tag_items_data_item_variant; for reader::tagged_docs(item, v) |p| { - let ext = reader::with_doc_data(p, |d| parse_def_id(d)); + let ext = reader::with_doc_data(p, parse_def_id); ids.push(ast::def_id { crate: cdata.cnum, node: ext.node }); }; return ids; @@ -424,7 +423,7 @@ pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, let mut found = None; for reader::tagged_docs(find_item(id, items), tag_item_impl_method) |mid| { - let m_did = reader::with_doc_data(mid, |d| parse_def_id(d)); + let m_did = reader::with_doc_data(mid, parse_def_id); if item_name(intr, find_item(m_did.node, items)) == name { found = Some(translate_def_id(cdata, m_did)); } @@ -662,7 +661,7 @@ fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc, base_tps: uint) -> ~[@resolve::MethodInfo] { let mut rslt = ~[]; for reader::tagged_docs(item, tag_item_impl_method) |doc| { - let m_did = reader::with_doc_data(doc, |d| parse_def_id(d)); + let m_did = reader::with_doc_data(doc, parse_def_id); let mth_item = lookup_item(m_did.node, cdata.data); let explicit_self = get_explicit_self(mth_item); rslt.push(@resolve::MethodInfo { @@ -684,7 +683,7 @@ pub fn get_impls_for_mod(intr: @ident_interner, let mod_item = lookup_item(m_id, data); let mut result = ~[]; for reader::tagged_docs(mod_item, tag_mod_impl) |doc| { - let did = reader::with_doc_data(doc, |d| parse_def_id(d)); + let did = reader::with_doc_data(doc, parse_def_id); let local_did = translate_def_id(cdata, did); debug!("(get impls for mod) getting did %? for '%?'", local_did, name); From 2096d79626029bfbfd7d42668be4705390a2c4ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Sat, 8 Jun 2013 02:37:17 +0200 Subject: [PATCH 8/8] Avoid unnecessary allocations in the metadata decoder --- src/libextra/ebml.rs | 19 ++++++---- src/librustc/metadata/decoder.rs | 60 +++++++++++++++----------------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index 47b0b4f6c974b..09e6a849f98b5 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -93,6 +93,14 @@ pub mod reader { pub fn get(&self, tag: uint) -> Doc { get_doc(*self, tag) } + + pub fn as_str_slice<'a>(&'a self) -> &'a str { + str::from_bytes_slice(self.data.slice(self.start, self.end)) + } + + pub fn as_str(&self) -> ~str { + self.as_str_slice().to_owned() + } } struct Res { @@ -239,15 +247,10 @@ pub mod reader { return true; } - pub fn doc_data(d: Doc) -> ~[u8] { - vec::slice::(*d.data, d.start, d.end).to_vec() - } - pub fn with_doc_data(d: Doc, f: &fn(x: &[u8]) -> T) -> T { f(vec::slice(*d.data, d.start, d.end)) } - pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) } pub fn doc_as_u8(d: Doc) -> u8 { assert_eq!(d.end, d.start + 1u); @@ -294,7 +297,7 @@ pub mod reader { if r_tag == (EsLabel as uint) { self.pos = r_doc.end; - let str = doc_as_str(r_doc); + let str = r_doc.as_str_slice(); if lbl != str { fail!("Expected label %s but found %s", lbl, str); } @@ -415,7 +418,9 @@ pub mod reader { fn read_char(&mut self) -> char { doc_as_u32(self.next_doc(EsChar)) as char } - fn read_str(&mut self) -> ~str { doc_as_str(self.next_doc(EsStr)) } + fn read_str(&mut self) -> ~str { + self.next_doc(EsStr).as_str() + } // Compound types: fn read_enum(&mut self, diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index b544b94d1c23e..81c1560f18bd4 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -162,14 +162,13 @@ fn item_visibility(item: ebml::Doc) -> ast::visibility { fn item_method_sort(item: ebml::Doc) -> char { for reader::tagged_docs(item, tag_item_trait_method_sort) |doc| { - return str::from_bytes(reader::doc_data(doc))[0] as char; + return doc.as_str_slice()[0] as char; } return 'r'; } fn item_symbol(item: ebml::Doc) -> ~str { - let sym = reader::get_doc(item, tag_items_data_item_symbol); - return str::from_bytes(reader::doc_data(sym)); + reader::get_doc(item, tag_items_data_item_symbol).as_str() } fn item_parent_item(d: ebml::Doc) -> Option { @@ -209,7 +208,7 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool { fn variant_disr_val(d: ebml::Doc) -> Option { do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| { - int::parse_bytes(reader::doc_data(val_doc), 10u) + do reader::with_doc_data(val_doc) |data| { int::parse_bytes(data, 10u) } } } @@ -296,10 +295,10 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path { let mut result = vec::with_capacity(len); for reader::docs(path_doc) |tag, elt_doc| { if tag == tag_path_elt_mod { - let str = reader::doc_as_str(elt_doc); + let str = elt_doc.as_str_slice(); result.push(ast_map::path_mod(token::str_to_ident(str))); } else if tag == tag_path_elt_name { - let str = reader::doc_as_str(elt_doc); + let str = elt_doc.as_str_slice(); result.push(ast_map::path_name(token::str_to_ident(str))); } else { // ignore tag_path_len element @@ -311,12 +310,10 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path { fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident { let name = reader::get_doc(item, tag_paths_data_name); - do reader::with_doc_data(name) |data| { - let string = str::from_bytes_slice(data); - match intr.find_equiv(&StringRef(string)) { - None => token::str_to_ident(string), - Some(val) => ast::new_ident(val), - } + let string = name.as_str_slice(); + match intr.find_equiv(&StringRef(string)) { + None => token::str_to_ident(string), + Some(val) => ast::new_ident(val), } } @@ -506,19 +503,17 @@ pub fn each_path(intr: @ident_interner, let def_id_doc = reader::get_doc(reexport_doc, tag_items_data_item_reexport_def_id); - let def_id = - reader::with_doc_data(def_id_doc, - |d| parse_def_id(d)); + let def_id = reader::with_doc_data(def_id_doc, parse_def_id); let def_id = translate_def_id(cdata, def_id); let reexport_name_doc = reader::get_doc(reexport_doc, tag_items_data_item_reexport_name); - let reexport_name = reader::doc_as_str(reexport_name_doc); + let reexport_name = reexport_name_doc.as_str_slice(); let reexport_path; if path_is_empty { - reexport_path = reexport_name; + reexport_path = reexport_name.to_owned(); } else { reexport_path = path + "::" + reexport_name; } @@ -639,7 +634,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ { } let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self); - let string = reader::doc_as_str(explicit_self_doc); + let string = explicit_self_doc.as_str_slice(); let explicit_self_kind = string[0]; match explicit_self_kind as char { @@ -824,7 +819,7 @@ pub fn get_type_name_if_impl(cdata: cmd, } for reader::tagged_docs(item, tag_item_impl_type_basename) |doc| { - return Some(token::str_to_ident(str::from_bytes(reader::doc_data(doc)))); + return Some(token::str_to_ident(doc.as_str_slice())); } return None; @@ -846,7 +841,7 @@ pub fn get_static_methods_if_impl(intr: @ident_interner, let mut impl_method_ids = ~[]; for reader::tagged_docs(item, tag_item_impl_method) |impl_method_doc| { - impl_method_ids.push(parse_def_id(reader::doc_data(impl_method_doc))); + impl_method_ids.push(reader::with_doc_data(impl_method_doc, parse_def_id)); } let mut static_impl_methods = ~[]; @@ -943,12 +938,13 @@ fn family_names_type(fam: Family) -> bool { } fn read_path(d: ebml::Doc) -> (~str, uint) { - let desc = reader::doc_data(d); - let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint; - let pathbytes = vec::slice::(desc, 4u, vec::len::(desc)); - let path = str::from_bytes(pathbytes); + do reader::with_doc_data(d) |desc| { + let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint; + let pathbytes = desc.slice(4u, desc.len()); + let path = str::from_bytes(pathbytes); - (path, pos) + (path, pos) + } } fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str { @@ -989,21 +985,21 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { let mut items: ~[@ast::meta_item] = ~[]; for reader::tagged_docs(md, tag_meta_item_word) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); - let n = str::from_bytes(reader::doc_data(nd)); + let n = nd.as_str(); items.push(attr::mk_word_item(@n)); }; for reader::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); let vd = reader::get_doc(meta_item_doc, tag_meta_item_value); - let n = str::from_bytes(reader::doc_data(nd)); - let v = str::from_bytes(reader::doc_data(vd)); + let n = nd.as_str(); + let v = vd.as_str(); // FIXME (#623): Should be able to decode meta_name_value variants, // but currently the encoder just drops them items.push(attr::mk_name_value_item_str(@n, @v)); }; for reader::tagged_docs(md, tag_meta_item_list) |meta_item_doc| { let nd = reader::get_doc(meta_item_doc, tag_meta_item_name); - let n = str::from_bytes(reader::doc_data(nd)); + let n = nd.as_str(); let subitems = get_meta_items(meta_item_doc); items.push(attr::mk_list_item(@n, subitems)); }; @@ -1072,7 +1068,7 @@ pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] { let depsdoc = reader::get_doc(cratedoc, tag_crate_deps); let mut crate_num = 1; fn docstr(doc: ebml::Doc, tag_: uint) -> ~str { - str::from_bytes(reader::doc_data(reader::get_doc(doc, tag_))) + reader::get_doc(doc, tag_).as_str() } for reader::tagged_docs(depsdoc, tag_crate_dep) |depdoc| { deps.push(crate_dep {cnum: crate_num, @@ -1099,7 +1095,7 @@ fn list_crate_deps(data: @~[u8], out: @io::Writer) { pub fn get_crate_hash(data: @~[u8]) -> @~str { let cratedoc = reader::Doc(data); let hashdoc = reader::get_doc(cratedoc, tag_crate_hash); - @str::from_bytes(reader::doc_data(hashdoc)) + @hashdoc.as_str() } pub fn get_crate_vers(data: @~[u8]) -> @~str { @@ -1154,7 +1150,7 @@ pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] { let link_args = reader::get_doc(reader::Doc(cdata.data), tag_link_args); let mut result = ~[]; for reader::tagged_docs(link_args, tag_link_args_arg) |arg_doc| { - result.push(reader::doc_as_str(arg_doc)); + result.push(arg_doc.as_str()); } result }