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. 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"; let foo = "foo";
work_with_foo_by_pointer(&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 filename = "tmp.rs";
let sess = parse::new_parse_sess(option::none); let sess = parse::new_parse_sess(option::none);
write_file(filename, *code); write_file(filename, *code);
@ -501,7 +501,7 @@ fn file_might_not_converge(filename: str) -> bool {
ret false; ret false;
} }
fn check_roundtrip_convergence(code: @str, maxIters: uint) { fn check_roundtrip_convergence(code: @str/~, maxIters: uint) {
let mut i = 0u; let mut i = 0u;
let mut newv = code; let mut newv = code;

View file

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

View file

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

View file

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

View file

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

View file

@ -32,7 +32,7 @@ fn deserialize_span<D>(_d: D) -> span {
type spanned<T> = {node: T, span: span}; type spanned<T> = {node: T, span: span};
#[auto_serialize] #[auto_serialize]
type ident = @str; type ident = @str/~;
// Functions may or may not have names. // Functions may or may not have names.
#[auto_serialize] #[auto_serialize]
@ -427,11 +427,11 @@ type lit = spanned<lit_>;
#[auto_serialize] #[auto_serialize]
enum lit_ { enum lit_ {
lit_str(@str), lit_str(@str/~),
lit_int(i64, int_ty), lit_int(i64, int_ty),
lit_uint(u64, uint_ty), lit_uint(u64, uint_ty),
lit_int_unsuffixed(i64), lit_int_unsuffixed(i64),
lit_float(@str, float_ty), lit_float(@str/~, float_ty),
lit_nil, lit_nil,
lit_bool(bool), 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 * Gets the string value if the meta_item is a meta_name_value variant
* containing a string, otherwise none * 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 { alt meta.node {
ast::meta_name_value(_, v) { ast::meta_name_value(_, v) {
alt v.node { 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( fn get_name_value_str_pair(
item: @ast::meta_item item: @ast::meta_item
) -> option<(ast::ident, @str)> { ) -> option<(ast::ident, @str/~)> {
alt attr::get_meta_item_value_str(item) { alt attr::get_meta_item_value_str(item) {
some(value) { some(value) {
let name = attr::get_meta_item_name(item); 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) fn first_attr_value_str_by_name(attrs: ~[ast::attribute], +name: str)
-> option<@str> { -> option<@str/~> {
let mattrs = find_attrs_by_name(attrs, name); let mattrs = find_attrs_by_name(attrs, name);
if vec::len(mattrs) > 0u { if vec::len(mattrs) > 0u {
ret get_meta_item_value_str(attr_meta(mattrs[0])); 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( fn last_meta_item_value_str_by_name(
items: ~[@ast::meta_item], items: ~[@ast::meta_item],
+name: str +name: str
) -> option<@str> { ) -> option<@str/~> {
alt last_meta_item_by_name(items, name) { alt last_meta_item_by_name(items, name) {
some(item) { some(item) {
alt attr::get_meta_item_value_str(item) { alt attr::get_meta_item_value_str(item) {

View file

@ -45,7 +45,7 @@ enum file_substr {
} }
type filemap = type filemap =
@{name: filename, substr: file_substr, src: @str, @{name: filename, substr: file_substr, src: @str/~,
start_pos: file_pos, mut lines: ~[file_pos]}; start_pos: file_pos, mut lines: ~[file_pos]};
type codemap = @{files: dvec<filemap>}; 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_codemap() -> codemap { @{files: dvec()} }
fn new_filemap_w_substr(+filename: filename, +substr: file_substr, fn new_filemap_w_substr(+filename: filename, +substr: file_substr,
src: @str, src: @str/~,
start_pos_ch: uint, start_pos_byte: uint) start_pos_ch: uint, start_pos_byte: uint)
-> filemap { -> filemap {
ret @{name: filename, substr: substr, src: src, 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}]}; 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) start_pos_ch: uint, start_pos_byte: uint)
-> filemap { -> filemap {
ret new_filemap_w_substr(filename, fss_none, src, 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))) 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( self.expr(
span, span,
ast::expr_lit( 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))) 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, 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] { -> ~[@ast::stmt] {
let ext_cx = cx; // required for #ast{} 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));}] ~[#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) { ast::ty_uniq(mt) {
let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) }); let l = ser_lambda(cx, tps, mt.ty, cx.clone(s), #ast{ *$(v) });
~[#ast(stmt){$(s).emit_uniq($(l));}] ~[#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)) } #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) { ast::ty_uniq(mt) {
let l = deser_lambda(cx, tps, mt.ty, cx.clone(d)); let l = deser_lambda(cx, tps, mt.ty, cx.clone(d));
#ast{ ~$(d).read_uniq($(l)) } #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 { _body: ast::mac_body) -> base::macro_def {
let args = get_mac_args_no_max(cx, sp, arg, 0u, "macro"); 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] = ~[]; let mut clauses: ~[@clause] = ~[];
for args.each |arg| { for args.each |arg| {
alt arg.node { alt arg.node {

View file

@ -24,7 +24,7 @@ type tt_frame = @{
type tt_reader = @{ type tt_reader = @{
sp_diag: span_handler, sp_diag: span_handler,
interner: @interner<@str>, interner: @interner<@str/~>,
mut cur: tt_frame, mut cur: tt_frame,
/* for MBE-style macro transcription */ /* for MBE-style macro transcription */
interpolations: std::map::hashmap<ident, @arb_depth>, 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 /** 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 * `src` contains no `tt_dotdotdot`s and `tt_interpolate`s, `interp` can (and
* should) be none. */ * 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>>, interp: option<std::map::hashmap<ident,@arb_depth>>,
src: ~[ast::token_tree]) src: ~[ast::token_tree])
-> tt_reader { -> tt_reader {

View file

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

View file

@ -275,7 +275,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
srdr: io::reader) -> srdr: io::reader) ->
{cmnts: ~[cmnt], lits: ~[lit]} { {cmnts: ~[cmnt], lits: ~[lit]} {
let src = @str::from_bytes(srdr.read_whole_stream()); let src = @str::from_bytes(srdr.read_whole_stream());
let itr = @interner::mk::<@str>( let itr = @interner::mk::<@str/~>(
|x| str::hash(*x), |x| str::hash(*x),
|x,y| str::eq(*x, *y) |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") { alt ::attr::first_attr_value_str_by_name(attrs, "path") {
some(d) { some(d) {
ret d; ret d;

View file

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

View file

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

View file

@ -59,7 +59,7 @@ type break_t = {offset: int, blank_space: int};
type begin_t = {offset: int, breaks: breaks}; 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 { fn tok_str(++t: token) -> str {
alt t { alt t {

View file

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

View file

@ -133,5 +133,5 @@ fn hash_path(&&s: str) -> uint {
ret h; 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 = { type cache_entry = {
cnum: int, cnum: int,
span: span, span: span,
hash: @str, hash: @str/~,
metas: @~[@ast::meta_item] 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 // 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 // renamed imports or reexports. This map keeps the "real" module path
// and def_id. // 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, type crate_metadata = @{name: str,
data: @~[u8], data: @~[u8],
@ -83,12 +83,12 @@ fn get_crate_data(cstore: cstore, cnum: ast::crate_num) -> crate_metadata {
ret p(cstore).metas.get(cnum); 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); let cdata = get_crate_data(cstore, cnum);
ret decoder::get_crate_hash(cdata.data); 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); let cdata = get_crate_data(cstore, cnum);
ret decoder::get_crate_vers(cdata.data); 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 // returns hashes of crates directly used by this crate. Hashes are
// sorted by crate name. // sorted by crate name.
fn get_dep_hashes(cstore: cstore) -> ~[@str] { fn get_dep_hashes(cstore: cstore) -> ~[@str/~] {
type crate_hash = {name: @str, hash: @str}; type crate_hash = {name: @str/~, hash: @str/~};
let mut result = ~[]; let mut result = ~[];
for p(cstore).use_crate_map.each_value |cnum| { for p(cstore).use_crate_map.each_value |cnum| {
@ -171,7 +171,7 @@ fn get_dep_hashes(cstore: cstore) -> ~[@str] {
for sorted.each |x| { for sorted.each |x| {
#debug(" hash[%s]: %s", *x.name, *x.hash); #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); 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)); out.write_str(#fmt("=Crate Attributes (%s)=\n", *hash));
for get_attributes(md).each |attr| { 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, 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] { fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
let mut deps: ~[crate_dep] = ~[]; let mut deps: ~[crate_dep] = ~[];
@ -821,13 +821,13 @@ fn list_crate_deps(data: @~[u8], out: io::writer) {
out.write_str("\n"); out.write_str("\n");
} }
fn get_crate_hash(data: @~[u8]) -> @str { fn get_crate_hash(data: @~[u8]) -> @str/~ {
let cratedoc = ebml::doc(data); let cratedoc = ebml::doc(data);
let hashdoc = ebml::get_doc(cratedoc, tag_crate_hash); let hashdoc = ebml::get_doc(cratedoc, tag_crate_hash);
ret @str::from_bytes(ebml::doc_data(hashdoc)); 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); let attrs = decoder::get_crate_attributes(data);
ret alt attr::last_meta_item_value_str_by_name( ret alt attr::last_meta_item_value_str_by_name(
attr::find_linkage_metas(attrs), "vers") { 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"); let name_items = attr::find_meta_items_by_name(metas, "name");
alt vec::last_opt(name_items) { alt vec::last_opt(name_items) {
some(i) { some(i) {

View file

@ -29,7 +29,7 @@ type ctxt = {
// Compact string representation for ty.t values. API ty_str & parse_from_str. // 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. // Extra parameters are for converting to/from def_ids in the string rep.
// Whatever format you choose should not contain pipe characters. // 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>), } 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, old_strs, t.id, it.id,
t.span, "deprecated str type"); 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); uses_vstore.insert(inner.id, true);
} }
_ { } _ { }

View file

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

View file

@ -253,7 +253,7 @@ type ctxt =
freevars: freevars::freevar_map, freevars: freevars::freevar_map,
tcache: type_cache, tcache: type_cache,
rcache: creader_cache, rcache: creader_cache,
short_names_cache: hashmap<t, @str>, short_names_cache: hashmap<t, @str/~>,
needs_drop_cache: hashmap<t, bool>, needs_drop_cache: hashmap<t, bool>,
needs_unwind_cleanup_cache: hashmap<t, bool>, needs_unwind_cleanup_cache: hashmap<t, bool>,
kind_cache: hashmap<t, kind>, 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}; ret {ty: ast_ty_to_ty(self, rscope, mt.ty), mutbl: mt.mutbl};
} }
fn mk_vstore<AC: ast_conv, RS: region_scope copy>( // Handle @, ~, and & being able to mean estrs and evecs.
self: AC, rscope: RS, a_seq_ty: @ast::ty, vst: ty::vstore) -> ty::t { // 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(); 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) { ast::ty_vec(mt) {
ret ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, mt), vst); 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_mt_to_mt(self, rscope, a_seq_ty);
let seq_ty = ast_ty_to_ty(self, rscope, a_seq_ty); ret constr(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;
} }
fn check_path_args(tcx: ty::ctxt, 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_nil { ty::mk_nil(tcx) }
ast::ty_bot { ty::mk_bot(tcx) } ast::ty_bot { ty::mk_bot(tcx) }
ast::ty_box(mt) { 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) { 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) { ast::ty_vec(mt) {
ty::mk_vec(tcx, ast_mt_to_mt(self, rscope, 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) { ast::ty_rptr(region, mt) {
let r = ast_region_to_region(self, rscope, ast_ty.span, region); 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); mk_maybe_vstore(self, in_anon_rscope(rscope, r), mt,
ty::mk_rptr(tcx, r, mt) ty::vstore_slice(r),
|tmt| ty::mk_rptr(tcx, r, tmt))
} }
ast::ty_tup(fields) { ast::ty_tup(fields) {
let flds = vec::map(fields, |t| ast_ty_to_ty(self, rscope, t)); 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)) { ast::ty_vstore(a_t, ast::vstore_slice(a_r)) {
let r = ast_region_to_region(self, rscope, ast_ty.span, 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) { 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) { 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))) { 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)) { ast::ty_vstore(_, ast::vstore_fixed(none)) {
tcx.sess.span_bug( tcx.sess.span_bug(
ast_ty.span, ast_ty.span,
"implied fixed length for bound"); "implied fixed length for bound");
} }
/*
ast::ty_vstore(_, _) {
tcx.sess.span_bug(ast_ty.span, "some BS");
}
*/
ast::ty_constr(t, cs) { ast::ty_constr(t, cs) {
let mut out_cs = ~[]; let mut out_cs = ~[];
for cs.each |constr| { for cs.each |constr| {

View file

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

View file

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

View file

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

View file

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