Accept prefix notation for writing the types of str/~ and friends.

This commit is contained in:
Michael Sullivan 2012-07-11 23:42:26 -07:00
parent acb86921a6
commit 2ea9c8df0f
37 changed files with 198 additions and 147 deletions

View File

@ -1347,7 +1347,7 @@ imply ownership. Pointers may be borrowed from any type, in which case
the pointer is guaranteed not to outlive the value it points to.
~~~~
# fn work_with_foo_by_pointer(f: &str) { }
# fn work_with_foo_by_pointer(f: &str/~) { }
let foo = "foo";
work_with_foo_by_pointer(&foo);
~~~~

View File

@ -418,7 +418,7 @@ fn check_compiling(filename: str) -> happiness {
}
fn parse_and_print(code: @str) -> str {
fn parse_and_print(code: @str/~) -> str {
let filename = "tmp.rs";
let sess = parse::new_parse_sess(option::none);
write_file(filename, *code);
@ -501,7 +501,7 @@ fn file_might_not_converge(filename: str) -> bool {
ret false;
}
fn check_roundtrip_convergence(code: @str, maxIters: uint) {
fn check_roundtrip_convergence(code: @str/~, maxIters: uint) {
let mut i = 0u;
let mut newv = code;

View File

@ -1300,7 +1300,7 @@ fn test_unkillable_nested() {
#[test]
fn test_tls_multitask() unsafe {
fn my_key(+_x: @str) { }
fn my_key(+_x: @str/~) { }
local_data_set(my_key, @"parent data");
do task::spawn {
assert local_data_get(my_key) == none; // TLS shouldn't carry over.
@ -1316,7 +1316,7 @@ fn test_tls_multitask() unsafe {
#[test]
fn test_tls_overwrite() unsafe {
fn my_key(+_x: @str) { }
fn my_key(+_x: @str/~) { }
local_data_set(my_key, @"first data");
local_data_set(my_key, @"next data"); // Shouldn't leak.
assert *(local_data_get(my_key).get()) == "next data";
@ -1324,7 +1324,7 @@ fn test_tls_overwrite() unsafe {
#[test]
fn test_tls_pop() unsafe {
fn my_key(+_x: @str) { }
fn my_key(+_x: @str/~) { }
local_data_set(my_key, @"weasel");
assert *(local_data_pop(my_key).get()) == "weasel";
// Pop must remove the data from the map.
@ -1333,7 +1333,7 @@ fn test_tls_pop() unsafe {
#[test]
fn test_tls_modify() unsafe {
fn my_key(+_x: @str) { }
fn my_key(+_x: @str/~) { }
local_data_modify(my_key, |data| {
alt data {
some(@val) { fail "unwelcome value: " + val }
@ -1357,7 +1357,7 @@ fn test_tls_crust_automorestack_memorial_bug() unsafe {
// jump over to the rust stack, which causes next_c_sp to get recorded as
// something within a rust stack segment. Then a subsequent upcall (esp.
// for logging, think vsnprintf) would run on a stack smaller than 1 MB.
fn my_key(+_x: @str) { }
fn my_key(+_x: @str/~) { }
do task::spawn {
unsafe { local_data_set(my_key, @"hax"); }
}
@ -1365,7 +1365,7 @@ fn test_tls_crust_automorestack_memorial_bug() unsafe {
#[test]
fn test_tls_multiple_types() unsafe {
fn str_key(+_x: @str) { }
fn str_key(+_x: @str/~) { }
fn box_key(+_x: @@()) { }
fn int_key(+_x: @int) { }
do task::spawn {
@ -1377,7 +1377,7 @@ fn test_tls_multiple_types() unsafe {
#[test]
fn test_tls_overwrite_multiple_types() unsafe {
fn str_key(+_x: @str) { }
fn str_key(+_x: @str/~) { }
fn box_key(+_x: @@()) { }
fn int_key(+_x: @int) { }
do task::spawn {
@ -1393,7 +1393,7 @@ fn test_tls_overwrite_multiple_types() unsafe {
#[should_fail]
#[ignore(cfg(windows))]
fn test_tls_cleanup_on_failure() unsafe {
fn str_key(+_x: @str) { }
fn str_key(+_x: @str/~) { }
fn box_key(+_x: @@()) { }
fn int_key(+_x: @int) { }
local_data_set(str_key, @"parent data");

View File

@ -14,6 +14,6 @@ impl of to_bytes for str {
fn to_bytes() -> ~[u8] { str::bytes(self) }
}
impl of to_bytes for @str {
impl of to_bytes for @(str/~) {
fn to_bytes() -> ~[u8] { str::bytes(*self) }
}

View File

@ -61,8 +61,8 @@ mod tests {
let box = @"box box box"; // refcount 1
bump_box_refcount(box); // refcount 2
let ptr: *int = transmute(box); // refcount 2
let _box1: @str = reinterpret_cast(ptr);
let _box2: @str = reinterpret_cast(ptr);
let _box1: @str/~ = reinterpret_cast(ptr);
let _box2: @str/~ = reinterpret_cast(ptr);
assert *_box1 == "box box box";
assert *_box2 == "box box box";
// Will destroy _box1 and _box2. Without the bump, this would

View File

@ -29,7 +29,7 @@ export null;
/// Represents a json value
enum json {
num(float),
string(@str),
string(@str/~),
boolean(bool),
list(@~[json]),
dict(map::hashmap<str, json>),
@ -39,7 +39,7 @@ enum json {
type error = {
line: uint,
col: uint,
msg: @str,
msg: @str/~,
};
/// Serializes a json value into a io::writer
@ -324,7 +324,7 @@ impl parser for parser {
ok(res)
}
fn parse_str() -> result<@str, error> {
fn parse_str() -> result<@str/~, error> {
let mut escape = false;
let mut res = "";
@ -579,7 +579,7 @@ impl of to_json for str {
fn to_json() -> json { string(@copy self) }
}
impl of to_json for @str {
impl of to_json for @str/~ {
fn to_json() -> json { string(self) }
}

View File

@ -310,8 +310,8 @@ fn str_hash<V: copy>() -> hashmap<str, V> {
}
/// Construct a hashmap for boxed string keys
fn box_str_hash<V: copy>() -> hashmap<@str, V> {
ret hashmap(|x: @str| str::hash(*x), |x,y| str::eq(*x,*y));
fn box_str_hash<V: copy>() -> hashmap<@str/~, V> {
ret hashmap(|x: @str/~| str::hash(*x), |x,y| str::eq(*x,*y));
}
/// Construct a hashmap for byte string keys

View File

@ -53,7 +53,7 @@ fn empty() -> rope {
* * this operation does not copy the string;
* * the function runs in linear time.
*/
fn of_str(str: @str) -> rope {
fn of_str(str: @str/~) -> rope {
ret of_substr(str, 0u, str::len(*str));
}
@ -79,7 +79,7 @@ fn of_str(str: @str) -> rope {
* * this function does _not_ check the validity of the substring;
* * this function fails if `byte_offset` or `byte_len` do not match `str`.
*/
fn of_substr(str: @str, byte_offset: uint, byte_len: uint) -> rope {
fn of_substr(str: @str/~, byte_offset: uint, byte_len: uint) -> rope {
if byte_len == 0u { ret node::empty; }
if byte_offset + byte_len > str::len(*str) { fail; }
ret node::content(node::of_substr(str, byte_offset, byte_len));
@ -107,7 +107,7 @@ fn append_char(rope: rope, char: char) -> rope {
*
* * this function executes in near-linear time
*/
fn append_str(rope: rope, str: @str) -> rope {
fn append_str(rope: rope, str: @str/~) -> rope {
ret append_rope(rope, of_str(str))
}
@ -127,7 +127,7 @@ fn prepend_char(rope: rope, char: char) -> rope {
* # Performance note
* * this function executes in near-linear time
*/
fn prepend_str(rope: rope, str: @str) -> rope {
fn prepend_str(rope: rope, str: @str/~) -> rope {
ret append_rope(of_str(str), rope)
}
@ -567,7 +567,7 @@ mod node {
byte_offset: uint,
byte_len: uint,
char_len: uint,
content: @str
content: @str/~
};
/**
@ -627,7 +627,7 @@ mod node {
* Performance note: The complexity of this function is linear in
* the length of `str`.
*/
fn of_str(str: @str) -> @node {
fn of_str(str: @str/~) -> @node {
ret of_substr(str, 0u, str::len(*str));
}
@ -648,7 +648,7 @@ mod node {
* Behavior is undefined if `byte_start` or `byte_len` do not represent
* valid positions in `str`
*/
fn of_substr(str: @str, byte_start: uint, byte_len: uint) -> @node {
fn of_substr(str: @str/~, byte_start: uint, byte_len: uint) -> @node {
ret of_substr_unsafer(str, byte_start, byte_len,
str::count_chars(*str, byte_start, byte_len));
}
@ -674,7 +674,7 @@ mod node {
* * Behavior is undefined if `char_len` does not accurately represent the
* number of chars between byte_start and byte_start+byte_len
*/
fn of_substr_unsafer(str: @str, byte_start: uint, byte_len: uint,
fn of_substr_unsafer(str: @str/~, byte_start: uint, byte_len: uint,
char_len: uint) -> @node {
assert(byte_start + byte_len <= str::len(*str));
let candidate = @leaf({

View File

@ -32,7 +32,7 @@ fn deserialize_span<D>(_d: D) -> span {
type spanned<T> = {node: T, span: span};
#[auto_serialize]
type ident = @str;
type ident = @str/~;
// Functions may or may not have names.
#[auto_serialize]
@ -427,11 +427,11 @@ type lit = spanned<lit_>;
#[auto_serialize]
enum lit_ {
lit_str(@str),
lit_str(@str/~),
lit_int(i64, int_ty),
lit_uint(u64, uint_ty),
lit_int_unsuffixed(i64),
lit_float(@str, float_ty),
lit_float(@str/~, float_ty),
lit_nil,
lit_bool(bool),
}

View File

@ -124,7 +124,7 @@ fn get_meta_item_name(meta: @ast::meta_item) -> ast::ident {
* Gets the string value if the meta_item is a meta_name_value variant
* containing a string, otherwise none
*/
fn get_meta_item_value_str(meta: @ast::meta_item) -> option<@str> {
fn get_meta_item_value_str(meta: @ast::meta_item) -> option<@str/~> {
alt meta.node {
ast::meta_name_value(_, v) {
alt v.node {
@ -154,7 +154,7 @@ fn get_meta_item_list(meta: @ast::meta_item) -> option<~[@ast::meta_item]> {
*/
fn get_name_value_str_pair(
item: @ast::meta_item
) -> option<(ast::ident, @str)> {
) -> option<(ast::ident, @str/~)> {
alt attr::get_meta_item_value_str(item) {
some(value) {
let name = attr::get_meta_item_name(item);
@ -239,7 +239,7 @@ fn attrs_contains_name(attrs: ~[ast::attribute], +name: str) -> bool {
}
fn first_attr_value_str_by_name(attrs: ~[ast::attribute], +name: str)
-> option<@str> {
-> option<@str/~> {
let mattrs = find_attrs_by_name(attrs, name);
if vec::len(mattrs) > 0u {
ret get_meta_item_value_str(attr_meta(mattrs[0]));
@ -258,7 +258,7 @@ fn last_meta_item_by_name(
fn last_meta_item_value_str_by_name(
items: ~[@ast::meta_item],
+name: str
) -> option<@str> {
) -> option<@str/~> {
alt last_meta_item_by_name(items, name) {
some(item) {
alt attr::get_meta_item_value_str(item) {

View File

@ -45,7 +45,7 @@ enum file_substr {
}
type filemap =
@{name: filename, substr: file_substr, src: @str,
@{name: filename, substr: file_substr, src: @str/~,
start_pos: file_pos, mut lines: ~[file_pos]};
type codemap = @{files: dvec<filemap>};
@ -55,7 +55,7 @@ type loc = {file: filemap, line: uint, col: uint};
fn new_codemap() -> codemap { @{files: dvec()} }
fn new_filemap_w_substr(+filename: filename, +substr: file_substr,
src: @str,
src: @str/~,
start_pos_ch: uint, start_pos_byte: uint)
-> filemap {
ret @{name: filename, substr: substr, src: src,
@ -63,7 +63,7 @@ fn new_filemap_w_substr(+filename: filename, +substr: file_substr,
mut lines: ~[{ch: start_pos_ch, byte: start_pos_byte}]};
}
fn new_filemap(+filename: filename, src: @str,
fn new_filemap(+filename: filename, src: @str/~,
start_pos_ch: uint, start_pos_byte: uint)
-> filemap {
ret new_filemap_w_substr(filename, fss_none, src,

View File

@ -218,7 +218,7 @@ impl helpers for ext_ctxt {
ast::expr_alt(v, arms, ast::alt_exhaustive)))
}
fn lit_str(span: span, s: @str) -> @ast::expr {
fn lit_str(span: span, s: @str/~) -> @ast::expr {
self.expr(
span,
ast::expr_lit(
@ -343,8 +343,19 @@ fn ser_lambda(cx: ext_ctxt, tps: ser_tps_map, ty: @ast::ty,
cx.lambda(cx.blk(ty.span, ser_ty(cx, tps, ty, s, v)))
}
fn is_vec_or_str(ty: @ast::ty) -> bool {
alt ty.node {
ast::ty_vec(_) { true }
// This may be wrong if the user has shadowed (!) str
ast::ty_path(@{span: _, global: _, idents: ids,
rp: none, types: _}, _)
if ids == ~[@"str"] { true }
_ { false }
}
}
fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
ty: @ast::ty, -s: @ast::expr, -v: @ast::expr)
ty: @ast::ty, -s: @ast::expr, -v: @ast::expr)
-> ~[@ast::stmt] {
let ext_cx = cx; // required for #ast{}
@ -365,6 +376,11 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
~[#ast(stmt){$(s).emit_box($(l));}]
}
// For unique evecs/estrs, just pass through to underlying vec or str
ast::ty_uniq(mt) if is_vec_or_str(mt.ty) {
ser_ty(cx, tps, mt.ty, s, v)
}
ast::ty_uniq(mt) {
let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) });
~[#ast(stmt){$(s).emit_uniq($(l));}]
@ -612,6 +628,11 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map,
#ast{ @$(d).read_box($(l)) }
}
// For unique evecs/estrs, just pass through to underlying vec or str
ast::ty_uniq(mt) if is_vec_or_str(mt.ty) {
deser_ty(cx, tps, mt.ty, d)
}
ast::ty_uniq(mt) {
let l = deser_lambda(cx, tps, mt.ty, cx.clone(d));
#ast{ ~$(d).read_uniq($(l)) }

View File

@ -679,7 +679,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
_body: ast::mac_body) -> base::macro_def {
let args = get_mac_args_no_max(cx, sp, arg, 0u, "macro");
let mut macro_name: option<@str> = none;
let mut macro_name: option<@str/~> = none;
let mut clauses: ~[@clause] = ~[];
for args.each |arg| {
alt arg.node {

View File

@ -24,7 +24,7 @@ type tt_frame = @{
type tt_reader = @{
sp_diag: span_handler,
interner: @interner<@str>,
interner: @interner<@str/~>,
mut cur: tt_frame,
/* for MBE-style macro transcription */
interpolations: std::map::hashmap<ident, @arb_depth>,
@ -38,7 +38,7 @@ type tt_reader = @{
/** This can do Macro-By-Example transcription. On the other hand, if
* `src` contains no `tt_dotdotdot`s and `tt_interpolate`s, `interp` can (and
* should) be none. */
fn new_tt_reader(sp_diag: span_handler, itr: @interner<@str>,
fn new_tt_reader(sp_diag: span_handler, itr: @interner<@str/~>,
interp: option<std::map::hashmap<ident,@arb_depth>>,
src: ~[ast::token_tree])
-> tt_reader {

View File

@ -25,7 +25,7 @@ type parse_sess = @{
cm: codemap::codemap,
mut next_id: node_id,
span_diagnostic: span_handler,
interner: @interner::interner<@str>,
interner: @interner::interner<@str/~>,
// these two must be kept up to date
mut chpos: uint,
mut byte_pos: uint
@ -36,7 +36,7 @@ fn new_parse_sess(demitter: option<emitter>) -> parse_sess {
ret @{cm: cm,
mut next_id: 1,
span_diagnostic: mk_span_handler(mk_handler(demitter), cm),
interner: @interner::mk::<@str>(|x| str::hash(*x),
interner: @interner::mk::<@str/~>(|x| str::hash(*x),
|x,y| str::eq(*x, *y)),
mut chpos: 0u, mut byte_pos: 0u};
}
@ -46,7 +46,7 @@ fn new_parse_sess_special_handler(sh: span_handler, cm: codemap::codemap)
ret @{cm: cm,
mut next_id: 1,
span_diagnostic: sh,
interner: @interner::mk::<@str>(|x| str::hash(*x),
interner: @interner::mk::<@str/~>(|x| str::hash(*x),
|x,y| str::eq(*x, *y)),
mut chpos: 0u, mut byte_pos: 0u};
}
@ -97,7 +97,7 @@ fn parse_crate_from_source_file(input: str, cfg: ast::crate_cfg,
ret r;
}
fn parse_crate_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
fn parse_crate_from_source_str(name: str, source: @str/~, cfg: ast::crate_cfg,
sess: parse_sess) -> @ast::crate {
let (p, rdr) = new_parser_etc_from_source_str(sess, cfg, name,
codemap::fss_none, source);
@ -107,7 +107,7 @@ fn parse_crate_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
ret r;
}
fn parse_expr_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
fn parse_expr_from_source_str(name: str, source: @str/~, cfg: ast::crate_cfg,
sess: parse_sess) -> @ast::expr {
let (p, rdr) = new_parser_etc_from_source_str(sess, cfg, name,
codemap::fss_none, source);
@ -117,7 +117,7 @@ fn parse_expr_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
ret r;
}
fn parse_item_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
fn parse_item_from_source_str(name: str, source: @str/~, cfg: ast::crate_cfg,
+attrs: ~[ast::attribute],
vis: ast::visibility,
sess: parse_sess) -> option<@ast::item> {
@ -131,7 +131,7 @@ fn parse_item_from_source_str(name: str, source: @str, cfg: ast::crate_cfg,
fn parse_from_source_str<T>(f: fn (p: parser) -> T,
name: str, ss: codemap::file_substr,
source: @str, cfg: ast::crate_cfg,
source: @str/~, cfg: ast::crate_cfg,
sess: parse_sess)
-> T
{
@ -156,7 +156,7 @@ fn next_node_id(sess: parse_sess) -> node_id {
fn new_parser_etc_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
+name: str, +ss: codemap::file_substr,
source: @str) -> (parser, string_reader) {
source: @str/~) -> (parser, string_reader) {
let ftype = parser::SOURCE_FILE;
let filemap = codemap::new_filemap_w_substr
(name, ss, source, sess.chpos, sess.byte_pos);
@ -168,7 +168,7 @@ fn new_parser_etc_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
fn new_parser_from_source_str(sess: parse_sess, cfg: ast::crate_cfg,
+name: str, +ss: codemap::file_substr,
source: @str) -> parser {
source: @str/~) -> parser {
let (p, _) = new_parser_etc_from_source_str(sess, cfg, name, ss, source);
ret p;
}

View File

@ -275,7 +275,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
srdr: io::reader) ->
{cmnts: ~[cmnt], lits: ~[lit]} {
let src = @str::from_bytes(srdr.read_whole_stream());
let itr = @interner::mk::<@str>(
let itr = @interner::mk::<@str/~>(
|x| str::hash(*x),
|x,y| str::eq(*x, *y)
);

View File

@ -78,7 +78,7 @@ fn parse_companion_mod(cx: ctx, prefix: str, suffix: option<str>)
}
}
fn cdir_path_opt(id: ast::ident, attrs: ~[ast::attribute]) -> @str {
fn cdir_path_opt(id: ast::ident, attrs: ~[ast::attribute]) -> @str/~ {
alt ::attr::first_attr_value_str_by_name(attrs, "path") {
some(d) {
ret d;

View File

@ -14,20 +14,20 @@ iface reader {
fn next_token() -> {tok: token::token, sp: span};
fn fatal(str) -> !;
fn span_diag() -> span_handler;
fn interner() -> @interner<@str>;
fn interner() -> @interner<@str/~>;
fn peek() -> {tok: token::token, sp: span};
fn dup() -> reader;
}
type string_reader = @{
span_diagnostic: span_handler,
src: @str,
src: @str/~,
mut col: uint,
mut pos: uint,
mut curr: char,
mut chpos: uint,
filemap: codemap::filemap,
interner: @interner<@str>,
interner: @interner<@str/~>,
/* cached: */
mut peek_tok: token::token,
mut peek_span: span
@ -35,7 +35,7 @@ type string_reader = @{
fn new_string_reader(span_diagnostic: span_handler,
filemap: codemap::filemap,
itr: @interner<@str>) -> string_reader {
itr: @interner<@str/~>) -> string_reader {
let r = new_low_level_string_reader(span_diagnostic, filemap, itr);
string_advance_token(r); /* fill in peek_* */
ret r;
@ -44,7 +44,7 @@ fn new_string_reader(span_diagnostic: span_handler,
/* For comments.rs, which hackily pokes into 'pos' and 'curr' */
fn new_low_level_string_reader(span_diagnostic: span_handler,
filemap: codemap::filemap,
itr: @interner<@str>)
itr: @interner<@str/~>)
-> string_reader {
let r = @{span_diagnostic: span_diagnostic, src: filemap.src,
mut col: 0u, mut pos: 0u, mut curr: -1 as char,
@ -79,7 +79,7 @@ impl string_reader_as_reader of reader for string_reader {
self.span_diagnostic.span_fatal(copy self.peek_span, m)
}
fn span_diag() -> span_handler { self.span_diagnostic }
fn interner() -> @interner<@str> { self.interner }
fn interner() -> @interner<@str/~> { self.interner }
fn peek() -> {tok: token::token, sp: span} {
{tok: self.peek_tok, sp: self.peek_span}
}
@ -101,7 +101,7 @@ impl tt_reader_as_reader of reader for tt_reader {
self.sp_diag.span_fatal(copy self.cur_span, m);
}
fn span_diag() -> span_handler { self.sp_diag }
fn interner() -> @interner<@str> { self.interner }
fn interner() -> @interner<@str/~> { self.interner }
fn peek() -> {tok: token::token, sp: span} {
{ tok: self.cur_tok, sp: self.cur_span }
}

View File

@ -230,7 +230,7 @@ class parser {
fn warn(m: str) {
self.sess.span_diagnostic.span_warn(copy self.span, m)
}
fn get_str(i: token::str_num) -> @str {
fn get_str(i: token::str_num) -> @str/~ {
interner::get(*self.reader.interner(), i)
}
fn get_id() -> node_id { next_node_id(self.sess) }
@ -394,7 +394,7 @@ class parser {
}
}
fn region_from_name(s: option<@str>) -> @region {
fn region_from_name(s: option<@str/~>) -> @region {
let r = alt s {
some (string) { re_named(string) }
none { re_anon }
@ -461,22 +461,10 @@ class parser {
}
} else if self.token == token::AT {
self.bump();
// HACK: turn @[...] into a @-evec
alt self.parse_mt() {
{ty: t @ @{node: ty_vec(_), _}, mutbl: m_imm} {
ty_vstore(t, vstore_box)
}
mt { ty_box(mt) }
}
ty_box(self.parse_mt())
} else if self.token == token::TILDE {
self.bump();
// HACK: turn ~[...] into a ~-evec
alt self.parse_mt() {
{ty: t @ @{node: ty_vec(_), _}, mutbl: m_imm} {
ty_vstore(t, vstore_uniq)
}
mt { ty_uniq(mt) }
}
ty_uniq(self.parse_mt())
} else if self.token == token::BINOP(token::STAR) {
self.bump();
ty_ptr(self.parse_mt())
@ -506,13 +494,8 @@ class parser {
} else if self.token == token::BINOP(token::AND) {
self.bump();
let region = self.parse_region_dot();
// HACK: turn &a.[...] into a &a-evec
alt self.parse_mt() {
{ty: t @ @{node: ty_vec(_), _}, mutbl: m_imm} {
ty_vstore(t, vstore_slice(region))
}
mt { ty_rptr(region, mt) }
}
let mt = self.parse_mt();
ty_rptr(region, mt)
} else if self.eat_keyword("pure") {
self.parse_ty_fn(ast::pure_fn)
} else if self.eat_keyword("unsafe") {
@ -2742,7 +2725,7 @@ class parser {
config: self.cfg});
}
fn parse_str() -> @str {
fn parse_str() -> @str/~ {
alt copy self.token {
token::LIT_STR(s) { self.bump(); self.get_str(s) }
_ {

View File

@ -115,7 +115,7 @@ fn binop_to_str(o: binop) -> str {
}
}
fn to_str(in: interner<@str>, t: token) -> str {
fn to_str(in: interner<@str/~>, t: token) -> str {
alt t {
EQ { "=" }
LT { "<" }

View File

@ -59,7 +59,7 @@ type break_t = {offset: int, blank_space: int};
type begin_t = {offset: int, breaks: breaks};
enum token { STRING(@str, int), BREAK(break_t), BEGIN(begin_t), END, EOF, }
enum token { STRING(@str/~, int), BREAK(break_t), BEGIN(begin_t), END, EOF, }
fn tok_str(++t: token) -> str {
alt t {

View File

@ -291,14 +291,14 @@ fn build_link_meta(sess: session, c: ast::crate, output: str,
sha: sha1) -> link_meta {
type provided_metas =
{name: option<@str>,
vers: option<@str>,
{name: option<@str/~>,
vers: option<@str/~>,
cmh_items: ~[@ast::meta_item]};
fn provided_link_metas(sess: session, c: ast::crate) ->
provided_metas {
let mut name: option<@str> = none;
let mut vers: option<@str> = none;
let mut name: option<@str/~> = none;
let mut vers: option<@str/~> = none;
let mut cmh_items: ~[@ast::meta_item] = ~[];
let linkage_metas = attr::find_linkage_metas(c.node.attrs);
attr::require_unique_names(sess.diagnostic(), linkage_metas);
@ -321,7 +321,7 @@ fn build_link_meta(sess: session, c: ast::crate, output: str,
// This calculates CMH as defined above
fn crate_meta_extras_hash(sha: sha1, _crate: ast::crate,
metas: provided_metas,
dep_hashes: ~[@str]) -> str {
dep_hashes: ~[@str/~]) -> str {
fn len_and_str(s: str) -> str {
ret #fmt["%u_%s", str::len(s), s];
}
@ -362,7 +362,7 @@ fn build_link_meta(sess: session, c: ast::crate, output: str,
}
fn crate_meta_name(sess: session, _crate: ast::crate,
output: str, metas: provided_metas) -> @str {
output: str, metas: provided_metas) -> @str/~ {
ret alt metas.name {
some(v) { v }
none {
@ -384,7 +384,7 @@ fn build_link_meta(sess: session, c: ast::crate, output: str,
}
fn crate_meta_vers(sess: session, _crate: ast::crate,
metas: provided_metas) -> @str {
metas: provided_metas) -> @str/~ {
ret alt metas.vers {
some(v) { v }
none {
@ -490,7 +490,7 @@ fn mangle(ss: path) -> str {
n
}
fn exported_name(path: path, hash: @str, vers: @str) -> str {
fn exported_name(path: path, hash: @str/~, vers: @str/~) -> str {
ret mangle(
vec::append_one(vec::append_one(path, path_name(hash)),
path_name(vers)));
@ -502,7 +502,7 @@ fn mangle_exported_name(ccx: @crate_ctxt, path: path, t: ty::t) -> str {
}
fn mangle_internal_name_by_type_only(ccx: @crate_ctxt,
t: ty::t, name: @str) ->
t: ty::t, name: @str/~) ->
str {
let s = @util::ppaux::ty_to_short_str(ccx.tcx, t);
let hash = get_symbol_hash(ccx, t);
@ -510,7 +510,7 @@ fn mangle_internal_name_by_type_only(ccx: @crate_ctxt,
}
fn mangle_internal_name_by_path_and_seq(ccx: @crate_ctxt, path: path,
flav: @str) -> str {
flav: @str/~) -> str {
ret mangle(vec::append_one(path, path_name(@ccx.names(*flav))));
}
@ -518,7 +518,7 @@ fn mangle_internal_name_by_path(_ccx: @crate_ctxt, path: path) -> str {
ret mangle(path);
}
fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: @str) -> str {
fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: @str/~) -> str {
ret ccx.names(*flav);
}

View File

@ -133,5 +133,5 @@ fn hash_path(&&s: str) -> uint {
ret h;
}
type link_meta = {name: @str, vers: @str, extras_hash: str};
type link_meta = {name: @str/~, vers: @str/~, extras_hash: str};

View File

@ -38,7 +38,7 @@ fn read_crates(diag: span_handler, crate: ast::crate,
type cache_entry = {
cnum: int,
span: span,
hash: @str,
hash: @str/~,
metas: @~[@ast::meta_item]
};

View File

@ -37,7 +37,7 @@ type cnum_map = map::hashmap<ast::crate_num, ast::crate_num>;
// Multiple items may have the same def_id in crate metadata. They may be
// renamed imports or reexports. This map keeps the "real" module path
// and def_id.
type mod_path_map = map::hashmap<ast::def_id, @str>;
type mod_path_map = map::hashmap<ast::def_id, @str/~>;
type crate_metadata = @{name: str,
data: @~[u8],
@ -83,12 +83,12 @@ fn get_crate_data(cstore: cstore, cnum: ast::crate_num) -> crate_metadata {
ret p(cstore).metas.get(cnum);
}
fn get_crate_hash(cstore: cstore, cnum: ast::crate_num) -> @str {
fn get_crate_hash(cstore: cstore, cnum: ast::crate_num) -> @str/~ {
let cdata = get_crate_data(cstore, cnum);
ret decoder::get_crate_hash(cdata.data);
}
fn get_crate_vers(cstore: cstore, cnum: ast::crate_num) -> @str {
fn get_crate_vers(cstore: cstore, cnum: ast::crate_num) -> @str/~ {
let cdata = get_crate_data(cstore, cnum);
ret decoder::get_crate_vers(cdata.data);
}
@ -153,8 +153,8 @@ fn find_use_stmt_cnum(cstore: cstore,
// returns hashes of crates directly used by this crate. Hashes are
// sorted by crate name.
fn get_dep_hashes(cstore: cstore) -> ~[@str] {
type crate_hash = {name: @str, hash: @str};
fn get_dep_hashes(cstore: cstore) -> ~[@str/~] {
type crate_hash = {name: @str/~, hash: @str/~};
let mut result = ~[];
for p(cstore).use_crate_map.each_value |cnum| {
@ -171,7 +171,7 @@ fn get_dep_hashes(cstore: cstore) -> ~[@str] {
for sorted.each |x| {
#debug(" hash[%s]: %s", *x.name, *x.hash);
}
fn mapper(ch: crate_hash) -> @str { ret ch.hash; }
fn mapper(ch: crate_hash) -> @str/~ { ret ch.hash; }
ret vec::map(sorted, mapper);
}

View File

@ -775,7 +775,7 @@ fn list_meta_items(meta_items: ebml::doc, out: io::writer) {
}
}
fn list_crate_attributes(md: ebml::doc, hash: @str, out: io::writer) {
fn list_crate_attributes(md: ebml::doc, hash: @str/~, out: io::writer) {
out.write_str(#fmt("=Crate Attributes (%s)=\n", *hash));
for get_attributes(md).each |attr| {
@ -790,7 +790,7 @@ fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] {
}
type crate_dep = {cnum: ast::crate_num, name: ast::ident,
vers: @str, hash: @str};
vers: @str/~, hash: @str/~};
fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
let mut deps: ~[crate_dep] = ~[];
@ -821,13 +821,13 @@ fn list_crate_deps(data: @~[u8], out: io::writer) {
out.write_str("\n");
}
fn get_crate_hash(data: @~[u8]) -> @str {
fn get_crate_hash(data: @~[u8]) -> @str/~ {
let cratedoc = ebml::doc(data);
let hashdoc = ebml::get_doc(cratedoc, tag_crate_hash);
ret @str::from_bytes(ebml::doc_data(hashdoc));
}
fn get_crate_vers(data: @~[u8]) -> @str {
fn get_crate_vers(data: @~[u8]) -> @str/~ {
let attrs = decoder::get_crate_attributes(data);
ret alt attr::last_meta_item_value_str_by_name(
attr::find_linkage_metas(attrs), "vers") {

View File

@ -116,7 +116,7 @@ fn find_library_crate_aux(cx: ctxt,
}
}
fn crate_name_from_metas(metas: ~[@ast::meta_item]) -> @str {
fn crate_name_from_metas(metas: ~[@ast::meta_item]) -> @str/~ {
let name_items = attr::find_meta_items_by_name(metas, "name");
alt vec::last_opt(name_items) {
some(i) {

View File

@ -29,7 +29,7 @@ type ctxt = {
// Compact string representation for ty.t values. API ty_str & parse_from_str.
// Extra parameters are for converting to/from def_ids in the string rep.
// Whatever format you choose should not contain pipe characters.
type ty_abbrev = {pos: uint, len: uint, s: @str};
type ty_abbrev = {pos: uint, len: uint, s: @str/~};
enum abbrev_ctxt { ac_no_abbrevs, ac_use_abbrevs(hashmap<ty::t, ty_abbrev>), }

View File

@ -462,7 +462,10 @@ fn check_item_old_vecs(cx: ty::ctxt, it: @ast::item) {
old_strs, t.id, it.id,
t.span, "deprecated str type");
}
ast::ty_vstore(inner, _) {
ast::ty_vstore(inner, _) |
ast::ty_box({ty: inner, _}) |
ast::ty_uniq({ty: inner, _}) |
ast::ty_rptr(_, {ty: inner, _}) {
uses_vstore.insert(inner.id, true);
}
_ { }

View File

@ -202,18 +202,18 @@ fn Atom(n: uint) -> Atom {
}
class AtomTable {
let atoms: hashmap<@str,Atom>;
let strings: dvec<@str>;
let atoms: hashmap<@str/~,Atom>;
let strings: dvec<@str/~>;
let mut atom_count: uint;
new() {
self.atoms = hashmap::<@str,Atom>(|x| str::hash(*x),
self.atoms = hashmap::<@str/~,Atom>(|x| str::hash(*x),
|x, y| str::eq(*x, *y));
self.strings = dvec();
self.atom_count = 0u;
}
fn intern(string: @str) -> Atom {
fn intern(string: @str/~) -> Atom {
alt self.atoms.find(string) {
none { /* fall through */ }
some(atom) { ret atom; }
@ -227,11 +227,11 @@ class AtomTable {
ret atom;
}
fn atom_to_str(atom: Atom) -> @str {
fn atom_to_str(atom: Atom) -> @str/~ {
ret self.strings.get_elt(atom);
}
fn atoms_to_strs(atoms: ~[Atom], f: fn(@str) -> bool) {
fn atoms_to_strs(atoms: ~[Atom], f: fn(@str/~) -> bool) {
for atoms.each |atom| {
if !f(self.atom_to_str(atom)) {
ret;
@ -239,7 +239,7 @@ class AtomTable {
}
}
fn atoms_to_str(atoms: ~[Atom]) -> @str {
fn atoms_to_str(atoms: ~[Atom]) -> @str/~ {
// XXX: str::connect should do this.
let mut result = "";
let mut first = true;
@ -577,7 +577,8 @@ class PrimitiveTypeTable {
self.intern(atom_table, @"u64", ty_uint(ty_u64));
}
fn intern(atom_table: @AtomTable, string: @str, primitive_type: prim_ty) {
fn intern(atom_table: @AtomTable, string: @str/~,
primitive_type: prim_ty) {
let atom = (*atom_table).intern(string);
self.primitive_types.insert(atom, primitive_type);
}

View File

@ -266,7 +266,7 @@ fn get_base_and_len(cx: block, v: ValueRef, e_ty: ty::t)
}
}
fn trans_estr(bcx: block, s: @str, vstore: ast::vstore,
fn trans_estr(bcx: block, s: @str/~, vstore: ast::vstore,
dest: dest) -> block {
let _icx = bcx.insn_ctxt("tvec::trans_estr");
let ccx = bcx.ccx();

View File

@ -253,7 +253,7 @@ type ctxt =
freevars: freevars::freevar_map,
tcache: type_cache,
rcache: creader_cache,
short_names_cache: hashmap<t, @str>,
short_names_cache: hashmap<t, @str/~>,
needs_drop_cache: hashmap<t, bool>,
needs_unwind_cleanup_cache: hashmap<t, bool>,
kind_cache: hashmap<t, kind>,

View File

@ -160,12 +160,17 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy>(
ret {ty: ast_ty_to_ty(self, rscope, mt.ty), mutbl: mt.mutbl};
}
fn mk_vstore<AC: ast_conv, RS: region_scope copy>(
self: AC, rscope: RS, a_seq_ty: @ast::ty, vst: ty::vstore) -> ty::t {
// Handle @, ~, and & being able to mean estrs and evecs.
// If a_seq_ty is a str or a vec, make it an estr/evec
fn mk_maybe_vstore<AC: ast_conv, RS: region_scope copy>(
self: AC, rscope: RS, a_seq_ty: ast::mt, vst: ty::vstore,
constr: fn(ty::mt) -> ty::t) -> ty::t {
let tcx = self.tcx();
alt a_seq_ty.node {
alt a_seq_ty.ty.node {
// to convert to an e{vec,str}, there can't be a mutability argument
_ if a_seq_ty.mutbl != ast::m_imm {}
ast::ty_vec(mt) {
ret ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, mt), vst);
}
@ -181,13 +186,8 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy>(
_ {}
}
// Get the type, just for the error message
let seq_ty = ast_ty_to_ty(self, rscope, a_seq_ty);
tcx.sess.span_err(
a_seq_ty.span,
#fmt["bound not allowed on a %s",
ty::ty_sort_str(tcx, seq_ty)]);
ret seq_ty;
let seq_ty = ast_mt_to_mt(self, rscope, a_seq_ty);
ret constr(seq_ty);
}
fn check_path_args(tcx: ty::ctxt,
@ -227,10 +227,12 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy>(
ast::ty_nil { ty::mk_nil(tcx) }
ast::ty_bot { ty::mk_bot(tcx) }
ast::ty_box(mt) {
ty::mk_box(tcx, ast_mt_to_mt(self, rscope, mt))
mk_maybe_vstore(self, rscope, mt, ty::vstore_box,
|tmt| ty::mk_box(tcx, tmt))
}
ast::ty_uniq(mt) {
ty::mk_uniq(tcx, ast_mt_to_mt(self, rscope, mt))
mk_maybe_vstore(self, rscope, mt, ty::vstore_uniq,
|tmt| ty::mk_uniq(tcx, tmt))
}
ast::ty_vec(mt) {
ty::mk_vec(tcx, ast_mt_to_mt(self, rscope, mt))
@ -240,8 +242,9 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy>(
}
ast::ty_rptr(region, mt) {
let r = ast_region_to_region(self, rscope, ast_ty.span, region);
let mt = ast_mt_to_mt(self, in_anon_rscope(rscope, r), mt);
ty::mk_rptr(tcx, r, mt)
mk_maybe_vstore(self, in_anon_rscope(rscope, r), mt,
ty::vstore_slice(r),
|tmt| ty::mk_rptr(tcx, r, tmt))
}
ast::ty_tup(fields) {
let flds = vec::map(fields, |t| ast_ty_to_ty(self, rscope, t));
@ -318,24 +321,64 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy>(
}
}
}
// This is awful and repetitive but will go away
ast::ty_vstore(a_t, ast::vstore_slice(a_r)) {
let r = ast_region_to_region(self, rscope, ast_ty.span, a_r);
mk_vstore(self, in_anon_rscope(rscope, r), a_t, ty::vstore_slice(r))
mk_maybe_vstore(self, in_anon_rscope(rscope, r),
{ty: a_t, mutbl: ast::m_imm},
ty::vstore_slice(r),
|ty| {
tcx.sess.span_err(
a_t.span,
#fmt["bound not allowed on a %s",
ty::ty_sort_str(tcx, ty.ty)]);
ty.ty
})
}
ast::ty_vstore(a_t, ast::vstore_uniq) {
mk_vstore(self, rscope, a_t, ty::vstore_uniq)
mk_maybe_vstore(self, rscope, {ty: a_t, mutbl: ast::m_imm},
ty::vstore_uniq,
|ty| {
tcx.sess.span_err(
a_t.span,
#fmt["bound not allowed on a %s",
ty::ty_sort_str(tcx, ty.ty)]);
ty.ty
})
}
ast::ty_vstore(a_t, ast::vstore_box) {
mk_vstore(self, rscope, a_t, ty::vstore_box)
mk_maybe_vstore(self, rscope, {ty: a_t, mutbl: ast::m_imm},
ty::vstore_box,
|ty| {
tcx.sess.span_err(
a_t.span,
#fmt["bound not allowed on a %s",
ty::ty_sort_str(tcx, ty.ty)]);
ty.ty
})
}
ast::ty_vstore(a_t, ast::vstore_fixed(some(u))) {
mk_vstore(self, rscope, a_t, ty::vstore_fixed(u))
mk_maybe_vstore(self, rscope, {ty: a_t, mutbl: ast::m_imm},
ty::vstore_fixed(u),
|ty| {
tcx.sess.span_err(
a_t.span,
#fmt["bound not allowed on a %s",
ty::ty_sort_str(tcx, ty.ty)]);
ty.ty
})
}
ast::ty_vstore(_, ast::vstore_fixed(none)) {
tcx.sess.span_bug(
ast_ty.span,
"implied fixed length for bound");
}
/*
ast::ty_vstore(_, _) {
tcx.sess.span_bug(ast_ty.span, "some BS");
}
*/
ast::ty_constr(t, cs) {
let mut out_cs = ~[];
for cs.each |constr| {

View File

@ -7,7 +7,7 @@ import dvec::*;
import dvec::dvec;
import std::map::hashmap;
type header_map = hashmap<str, @dvec<@str>>;
type header_map = hashmap<str, @dvec<@str/~>>;
// the unused ty param is necessary so this gets monomorphized
fn request<T: copy>(req: header_map) {

View File

@ -3,8 +3,8 @@
class foo {
let i: int;
let j: @str;
new(i:int, j: @str) { self.i = i; self.j = j; }
let j: @str/~;
new(i:int, j: @str/~) { self.i = i; self.j = j; }
}
fn main() {

View File

@ -4,7 +4,7 @@ fn main() {
let cheese = "roquefort";
let carrots = @"crunchy";
fn@(tasties: @str, macerate: fn(str)) {
fn@(tasties: @str/~, macerate: fn(str)) {
macerate(*tasties);
} (carrots, |food| {
let mush = food + cheese;

View File

@ -7,11 +7,11 @@ import uint;
fn main() {
let count = @mut 0u;
fn hash(&&s: ~[@str]) -> uint {
fn hash(&&s: ~[@str/~]) -> uint {
if (vec::len(s) > 0u && str::eq(*s[0], "boom")) { fail; }
ret 10u;
}
fn eq(&&s: ~[@str], &&t: ~[@str]) -> bool {
fn eq(&&s: ~[@str/~], &&t: ~[@str/~]) -> bool {
ret s == t;
}