Merge branch 'incoming' into reg-snap
This commit is contained in:
commit
5de57e278d
106 changed files with 1552 additions and 900 deletions
|
|
@ -8,7 +8,7 @@ import rustc::metadata::filesearch::{get_cargo_root, get_cargo_root_nearest,
|
|||
import syntax::diagnostic;
|
||||
|
||||
import result::{ok, err};
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import std::{map, json, tempfile, term, sort, getopts};
|
||||
import map::hashmap;
|
||||
import to_str::to_str;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import run::spawn_process;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import libc::{c_int, pid_t};
|
||||
|
||||
import pipes::chan;
|
||||
|
|
@ -45,8 +45,8 @@ fn run(lib_path: ~str,
|
|||
let pipe_out = os::pipe();
|
||||
let pipe_err = os::pipe();
|
||||
let pid = spawn_process(prog, args,
|
||||
some(env + target_env(lib_path, prog)),
|
||||
none, pipe_in.in, pipe_out.out, pipe_err.out);
|
||||
&some(env + target_env(lib_path, prog)),
|
||||
&none, pipe_in.in, pipe_out.out, pipe_err.out);
|
||||
|
||||
os::close(pipe_in.in);
|
||||
os::close(pipe_out.out);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
import common::mode_run_pass;
|
||||
import common::mode_run_fail;
|
||||
|
|
@ -339,7 +339,7 @@ fn compose_and_run_compiler(
|
|||
config.compile_lib_path, input)
|
||||
}
|
||||
|
||||
fn ensure_dir(path: path) {
|
||||
fn ensure_dir(path: Path) {
|
||||
if os::path_is_dir(path) { return; }
|
||||
if !os::make_dir(path, 0x1c0i32) {
|
||||
fail fmt!{"can't make dir %s", path};
|
||||
|
|
@ -455,7 +455,7 @@ fn dump_output_file(config: config, testfile: ~str,
|
|||
out: ~str, extension: ~str) {
|
||||
let outfile = make_out_name(config, testfile, extension);
|
||||
let writer = result::get(
|
||||
io::file_writer(outfile, ~[io::create, io::truncate]));
|
||||
io::file_writer(outfile, ~[io::Create, io::Truncate]));
|
||||
writer.write_str(out);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ d.write("// AUTO-GENERATED FILE: DO NOT EDIT\n")
|
|||
d.write("use std;\n")
|
||||
d.write("use run_pass_stage2;\n")
|
||||
d.write("import run_pass_stage2::*;\n")
|
||||
d.write("import io::writer_util;\n");
|
||||
d.write("import io::WriterUtil;\n");
|
||||
d.write("fn main() {\n");
|
||||
d.write(" let out = io::stdout();\n");
|
||||
i = 0
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ rust-mode: A major emacs mode for editing Rust source code
|
|||
`rust-mode` makes editing [Rust](http://rust-lang.org) code with emacs
|
||||
enjoyable.
|
||||
|
||||
To install, check out this repository and add this to your .emacs
|
||||
|
||||
### Manual Installation
|
||||
|
||||
To install manually, check out this repository and add this to your .emacs
|
||||
file:
|
||||
|
||||
(add-to-list 'load-path "/path/to/rust-mode/")
|
||||
|
|
@ -25,3 +28,60 @@ it, and pressing `C-j`:
|
|||
|
||||
Rust mode will automatically be associated with .rs and .rc files. To
|
||||
enable it explicitly, do `M-x rust-mode`.
|
||||
|
||||
### package.el installation via Marmalade
|
||||
|
||||
It can be more convenient to use Emacs's package manager to handle
|
||||
installation for you if you use many elisp libraries. If you have
|
||||
package.el but haven't added Marmalade, the community package source,
|
||||
yet, add this to ~/.emacs.d/init.el:
|
||||
|
||||
```lisp
|
||||
(require 'package)
|
||||
(add-to-list 'package-archives
|
||||
'("marmalade" . "http://marmalade-repo.org/packages/"))
|
||||
(package-initialize)
|
||||
```
|
||||
|
||||
Then do this to load the package listing:
|
||||
|
||||
* <kbd>M-x eval-buffer</kbd>
|
||||
* <kbd>M-x package-refresh-contents</kbd>
|
||||
|
||||
If you use a version of Emacs prior to 24 that doesn't include
|
||||
package.el, you can get it from http://bit.ly/pkg-el23.
|
||||
|
||||
If you have an older ELPA package.el installed from tromey.com, you
|
||||
should upgrade in order to support installation from multiple sources.
|
||||
The ELPA archive is deprecated and no longer accepting new packages,
|
||||
so the version there (1.7.1) is very outdated.
|
||||
|
||||
From there you can install rust-mode or any other modes by choosing
|
||||
them from a list:
|
||||
|
||||
* <kbd>M-x package-list-packages</kbd>
|
||||
|
||||
Now, to install packages, move your cursor to them and press i. This
|
||||
will mark the packages for installation. When you're done with
|
||||
marking, press x, and ELPA will install the packages for you (under
|
||||
~/.emacs.d/elpa/).
|
||||
|
||||
* or using <kbd>M-x package-install rust-mode
|
||||
|
||||
#### Important
|
||||
|
||||
In order to have cm-mode properly initialized after compilation prior
|
||||
to rust-mode.el compilation you will need to add these `advices` to
|
||||
your init file or if you are a melpa user install the `melpa` package.
|
||||
|
||||
```lisp
|
||||
(defadvice package-download-tar
|
||||
(after package-download-tar-initialize activate compile)
|
||||
"initialize the package after compilation"
|
||||
(package-initialize))
|
||||
|
||||
(defadvice package-download-single
|
||||
(after package-download-single-initialize activate compile)
|
||||
"initialize the package after compilation"
|
||||
(package-initialize))
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
;;; cm-mode.el --- Wrapper for CodeMirror-style Emacs modes
|
||||
|
||||
;; Version: 0.1.0
|
||||
;; Author: Mozilla
|
||||
;; Url: https://github.com/mozilla/rust
|
||||
|
||||
;; Highlighting is done by running a stateful parser (with first-class
|
||||
;; state object) over the buffer, line by line, using the output to
|
||||
;; add 'face properties, and storing the parser state at the end of
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
;;; rust-mode.el --- A major emacs mode for editing Rust source code
|
||||
|
||||
;; Version: 0.1.0
|
||||
;; Author: Mozilla
|
||||
;; Package-Requires: ((cm-mode "0.1.0"))
|
||||
;; Url: https://github.com/mozilla/rust
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
import syntax::{ast, ast_util, fold, visit, codemap};
|
||||
import syntax::parse;
|
||||
|
|
@ -10,7 +10,7 @@ type context = { mode: test_mode }; // + rng
|
|||
|
||||
fn write_file(filename: ~str, content: ~str) {
|
||||
result::get(
|
||||
io::file_writer(filename, ~[io::create, io::truncate]))
|
||||
io::file_writer(filename, ~[io::Create, io::Truncate]))
|
||||
.write_str(content);
|
||||
}
|
||||
|
||||
|
|
@ -216,9 +216,9 @@ fn under(n: uint, it: fn(uint)) {
|
|||
while i < n { it(i); i += 1u; }
|
||||
}
|
||||
|
||||
fn devnull() -> io::writer { io::mem_buffer_writer(io::mem_buffer()) }
|
||||
fn devnull() -> io::Writer { io::mem_buffer_writer(io::mem_buffer()) }
|
||||
|
||||
fn as_str(f: fn@(io::writer)) -> ~str {
|
||||
fn as_str(f: fn@(io::Writer)) -> ~str {
|
||||
let buf = io::mem_buffer();
|
||||
f(io::mem_buffer_writer(buf));
|
||||
io::mem_buffer_str(buf)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
/*!
|
||||
* Communication between tasks
|
||||
*
|
||||
|
|
@ -162,7 +165,7 @@ fn chan<T: send>(p: port<T>) -> chan<T> {
|
|||
* Sends data over a channel. The sent data is moved into the channel,
|
||||
* whereupon the caller loses access to it.
|
||||
*/
|
||||
fn send<T: send>(ch: chan<T>, -data: T) {
|
||||
fn send<T: send>(ch: chan<T>, +data: T) {
|
||||
let chan_t(p) = ch;
|
||||
let data_ptr = ptr::addr_of(data) as *();
|
||||
let res = rustrt::rust_port_id_send(p, data_ptr);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ export send_map;
|
|||
export hash;
|
||||
export cmp;
|
||||
export num;
|
||||
export path;
|
||||
|
||||
// NDM seems to be necessary for resolve to work
|
||||
export option_iter;
|
||||
|
|
@ -214,11 +215,16 @@ mod pipes;
|
|||
|
||||
// Runtime and language-primitive support
|
||||
|
||||
#[warn(non_camel_case_types)]
|
||||
mod io;
|
||||
mod libc;
|
||||
#[warn(non_camel_case_types)]
|
||||
mod os;
|
||||
#[warn(non_camel_case_types)]
|
||||
mod path;
|
||||
#[warn(non_camel_case_types)]
|
||||
mod rand;
|
||||
#[warn(non_camel_case_types)]
|
||||
mod run;
|
||||
#[warn(non_camel_case_types)]
|
||||
mod sys;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
import option::{some, none};
|
||||
import option = option::option;
|
||||
import path = path::path;
|
||||
import Path = path::Path;
|
||||
import tuple::{TupleOps, ExtendedTupleOps};
|
||||
import str::{str_slice, unique_str};
|
||||
import vec::{const_vector, copyable_vector, immutable_vector};
|
||||
|
|
@ -14,7 +14,7 @@ import num::Num;
|
|||
import ptr::ptr;
|
||||
import to_str::ToStr;
|
||||
|
||||
export path, option, some, none, unreachable;
|
||||
export Path, option, some, none, unreachable;
|
||||
export extensions;
|
||||
// The following exports are the extension impls for numeric types
|
||||
export Num, times, timesi;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
/*!
|
||||
* Implementation of SipHash 2-4
|
||||
*
|
||||
|
|
@ -9,8 +13,8 @@
|
|||
* CPRNG like rand::rng.
|
||||
*/
|
||||
|
||||
import io::writer;
|
||||
import io::writer_util;
|
||||
import io::Writer;
|
||||
import io::WriterUtil;
|
||||
|
||||
export Streaming, State;
|
||||
export default_state;
|
||||
|
|
@ -122,7 +126,7 @@ fn SipState(key0: u64, key1: u64) -> SipState {
|
|||
}
|
||||
|
||||
|
||||
impl &SipState : io::writer {
|
||||
impl &SipState : io::Writer {
|
||||
|
||||
// Methods for io::writer
|
||||
fn write(msg: &[const u8]) {
|
||||
|
|
@ -205,7 +209,7 @@ impl &SipState : io::writer {
|
|||
self.ntail = left;
|
||||
}
|
||||
|
||||
fn seek(_x: int, _s: io::seek_style) {
|
||||
fn seek(_x: int, _s: io::SeekStyle) {
|
||||
fail;
|
||||
}
|
||||
fn tell() -> uint {
|
||||
|
|
@ -214,8 +218,8 @@ impl &SipState : io::writer {
|
|||
fn flush() -> int {
|
||||
0
|
||||
}
|
||||
fn get_type() -> io::writer_type {
|
||||
io::file
|
||||
fn get_type() -> io::WriterType {
|
||||
io::File
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -362,9 +366,9 @@ fn test_siphash() {
|
|||
let stream_inc = &State(k0,k1);
|
||||
let stream_full = &State(k0,k1);
|
||||
|
||||
fn to_hex_str(r:[u8]/8) -> ~str {
|
||||
fn to_hex_str(r: &[u8]/8) -> ~str {
|
||||
let mut s = ~"";
|
||||
for vec::each(r) |b| { s += uint::to_str(b as uint, 16u); }
|
||||
for vec::each(*r) |b| { s += uint::to_str(b as uint, 16u); }
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
@ -379,7 +383,7 @@ fn test_siphash() {
|
|||
stream_full.input(buf);
|
||||
let f = stream_full.result_str();
|
||||
let i = stream_inc.result_str();
|
||||
let v = to_hex_str(vecs[t]);
|
||||
let v = to_hex_str(&vecs[t]);
|
||||
debug!{"%d: (%s) => inc=%s full=%s", t, v, i, f};
|
||||
|
||||
assert f == i && f == v;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import libc::{c_int, c_long, c_uint, c_void, size_t, ssize_t};
|
|||
import libc::consts::os::posix88::*;
|
||||
import libc::consts::os::extra::*;
|
||||
|
||||
#[allow(non_camel_case_types)] // not sure what to do about this
|
||||
type fd_t = c_int;
|
||||
|
||||
#[abi = "cdecl"]
|
||||
|
|
@ -24,11 +25,11 @@ extern mod rustrt {
|
|||
|
||||
// FIXME (#2004): This is all buffered. We might need an unbuffered variant
|
||||
// as well
|
||||
enum seek_style { seek_set, seek_end, seek_cur, }
|
||||
enum SeekStyle { SeekSet, SeekEnd, SeekCur, }
|
||||
|
||||
|
||||
// The raw underlying reader trait. All readers must implement this.
|
||||
trait reader {
|
||||
trait Reader {
|
||||
// FIXME (#2004): Seekable really should be orthogonal.
|
||||
|
||||
// FIXME (#2982): This should probably return an error.
|
||||
|
|
@ -36,13 +37,13 @@ trait reader {
|
|||
fn read_byte() -> int;
|
||||
fn unread_byte(int);
|
||||
fn eof() -> bool;
|
||||
fn seek(int, seek_style);
|
||||
fn seek(int, SeekStyle);
|
||||
fn tell() -> uint;
|
||||
}
|
||||
|
||||
// Generic utility functions defined on readers
|
||||
|
||||
impl reader {
|
||||
impl Reader {
|
||||
fn read_bytes(len: uint) -> ~[u8] {
|
||||
let mut buf = ~[mut];
|
||||
vec::reserve(buf, len);
|
||||
|
|
@ -195,15 +196,15 @@ impl reader {
|
|||
|
||||
// Reader implementations
|
||||
|
||||
fn convert_whence(whence: seek_style) -> i32 {
|
||||
fn convert_whence(whence: SeekStyle) -> i32 {
|
||||
return match whence {
|
||||
seek_set => 0i32,
|
||||
seek_cur => 1i32,
|
||||
seek_end => 2i32
|
||||
SeekSet => 0i32,
|
||||
SeekCur => 1i32,
|
||||
SeekEnd => 2i32
|
||||
};
|
||||
}
|
||||
|
||||
impl *libc::FILE: reader {
|
||||
impl *libc::FILE: Reader {
|
||||
fn read(buf: &[mut u8], len: uint) -> uint {
|
||||
do vec::as_buf(buf) |buf_p, buf_len| {
|
||||
assert buf_len <= len;
|
||||
|
|
@ -217,7 +218,7 @@ impl *libc::FILE: reader {
|
|||
fn read_byte() -> int { return libc::fgetc(self) as int; }
|
||||
fn unread_byte(byte: int) { libc::ungetc(byte as c_int, self); }
|
||||
fn eof() -> bool { return libc::feof(self) != 0 as c_int; }
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
fn seek(offset: int, whence: SeekStyle) {
|
||||
assert libc::fseek(self, offset as c_long, convert_whence(whence))
|
||||
== 0 as c_int;
|
||||
}
|
||||
|
|
@ -227,26 +228,26 @@ impl *libc::FILE: reader {
|
|||
// A forwarding impl of reader that also holds on to a resource for the
|
||||
// duration of its lifetime.
|
||||
// FIXME there really should be a better way to do this // #2004
|
||||
impl<T: reader, C> {base: T, cleanup: C}: reader {
|
||||
impl<T: Reader, C> {base: T, cleanup: C}: Reader {
|
||||
fn read(buf: &[mut u8], len: uint) -> uint { self.base.read(buf, len) }
|
||||
fn read_byte() -> int { self.base.read_byte() }
|
||||
fn unread_byte(byte: int) { self.base.unread_byte(byte); }
|
||||
fn eof() -> bool { self.base.eof() }
|
||||
fn seek(off: int, whence: seek_style) { self.base.seek(off, whence) }
|
||||
fn seek(off: int, whence: SeekStyle) { self.base.seek(off, whence) }
|
||||
fn tell() -> uint { self.base.tell() }
|
||||
}
|
||||
|
||||
class FILE_res {
|
||||
class FILERes {
|
||||
let f: *libc::FILE;
|
||||
new(f: *libc::FILE) { self.f = f; }
|
||||
drop { libc::fclose(self.f); }
|
||||
}
|
||||
|
||||
fn FILE_reader(f: *libc::FILE, cleanup: bool) -> reader {
|
||||
fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader {
|
||||
if cleanup {
|
||||
{base: f, cleanup: FILE_res(f)} as reader
|
||||
{base: f, cleanup: FILERes(f)} as Reader
|
||||
} else {
|
||||
f as reader
|
||||
f as Reader
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,9 +255,9 @@ fn FILE_reader(f: *libc::FILE, cleanup: bool) -> reader {
|
|||
// top-level functions that take a reader, or a set of default methods on
|
||||
// reader (which can then be called reader)
|
||||
|
||||
fn stdin() -> reader { rustrt::rust_get_stdin() as reader }
|
||||
fn stdin() -> Reader { rustrt::rust_get_stdin() as Reader }
|
||||
|
||||
fn file_reader(path: ~str) -> result<reader, ~str> {
|
||||
fn file_reader(path: ~str) -> result<Reader, ~str> {
|
||||
let f = os::as_c_charp(path, |pathbuf| {
|
||||
os::as_c_charp(~"r", |modebuf|
|
||||
libc::fopen(pathbuf, modebuf)
|
||||
|
|
@ -271,9 +272,9 @@ fn file_reader(path: ~str) -> result<reader, ~str> {
|
|||
|
||||
// Byte buffer readers
|
||||
|
||||
type byte_buf = {buf: ~[const u8], mut pos: uint, len: uint};
|
||||
type ByteBuf = {buf: ~[const u8], mut pos: uint, len: uint};
|
||||
|
||||
impl byte_buf: reader {
|
||||
impl ByteBuf: Reader {
|
||||
fn read(buf: &[mut u8], len: uint) -> uint {
|
||||
let count = uint::min(len, self.len - self.pos);
|
||||
|
||||
|
|
@ -293,65 +294,65 @@ impl byte_buf: reader {
|
|||
// FIXME (#2738): implement this
|
||||
fn unread_byte(_byte: int) { error!{"Unimplemented: unread_byte"}; fail; }
|
||||
fn eof() -> bool { self.pos == self.len }
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
fn seek(offset: int, whence: SeekStyle) {
|
||||
let pos = self.pos;
|
||||
self.pos = seek_in_buf(offset, pos, self.len, whence);
|
||||
}
|
||||
fn tell() -> uint { self.pos }
|
||||
}
|
||||
|
||||
fn bytes_reader(bytes: ~[u8]) -> reader {
|
||||
fn bytes_reader(bytes: ~[u8]) -> Reader {
|
||||
bytes_reader_between(bytes, 0u, vec::len(bytes))
|
||||
}
|
||||
|
||||
fn bytes_reader_between(bytes: ~[u8], start: uint, end: uint) -> reader {
|
||||
{buf: bytes, mut pos: start, len: end} as reader
|
||||
fn bytes_reader_between(bytes: ~[u8], start: uint, end: uint) -> Reader {
|
||||
{buf: bytes, mut pos: start, len: end} as Reader
|
||||
}
|
||||
|
||||
fn with_bytes_reader<t>(bytes: ~[u8], f: fn(reader) -> t) -> t {
|
||||
fn with_bytes_reader<t>(bytes: ~[u8], f: fn(Reader) -> t) -> t {
|
||||
f(bytes_reader(bytes))
|
||||
}
|
||||
|
||||
fn with_bytes_reader_between<t>(bytes: ~[u8], start: uint, end: uint,
|
||||
f: fn(reader) -> t) -> t {
|
||||
f: fn(Reader) -> t) -> t {
|
||||
f(bytes_reader_between(bytes, start, end))
|
||||
}
|
||||
|
||||
fn str_reader(s: ~str) -> reader {
|
||||
fn str_reader(s: ~str) -> Reader {
|
||||
bytes_reader(str::bytes(s))
|
||||
}
|
||||
|
||||
fn with_str_reader<T>(s: ~str, f: fn(reader) -> T) -> T {
|
||||
fn with_str_reader<T>(s: ~str, f: fn(Reader) -> T) -> T {
|
||||
do str::as_bytes(s) |bytes| {
|
||||
with_bytes_reader_between(bytes, 0u, str::len(s), f)
|
||||
}
|
||||
}
|
||||
|
||||
// Writing
|
||||
enum fileflag { append, create, truncate, no_flag, }
|
||||
enum FileFlag { Append, Create, Truncate, NoFlag, }
|
||||
|
||||
// What type of writer are we?
|
||||
enum writer_type { screen, file }
|
||||
enum WriterType { Screen, File }
|
||||
|
||||
// FIXME (#2004): Seekable really should be orthogonal.
|
||||
// FIXME (#2004): eventually u64
|
||||
trait writer {
|
||||
trait Writer {
|
||||
fn write(v: &[const u8]);
|
||||
fn seek(int, seek_style);
|
||||
fn seek(int, SeekStyle);
|
||||
fn tell() -> uint;
|
||||
fn flush() -> int;
|
||||
fn get_type() -> writer_type;
|
||||
fn get_type() -> WriterType;
|
||||
}
|
||||
|
||||
impl<T: writer, C> {base: T, cleanup: C}: writer {
|
||||
impl<T: Writer, C> {base: T, cleanup: C}: Writer {
|
||||
fn write(bs: &[const u8]) { self.base.write(bs); }
|
||||
fn seek(off: int, style: seek_style) { self.base.seek(off, style); }
|
||||
fn seek(off: int, style: SeekStyle) { self.base.seek(off, style); }
|
||||
fn tell() -> uint { self.base.tell() }
|
||||
fn flush() -> int { self.base.flush() }
|
||||
fn get_type() -> writer_type { file }
|
||||
fn get_type() -> WriterType { File }
|
||||
}
|
||||
|
||||
impl *libc::FILE: writer {
|
||||
impl *libc::FILE: Writer {
|
||||
fn write(v: &[const u8]) {
|
||||
do vec::as_const_buf(v) |vbuf, len| {
|
||||
let nout = libc::fwrite(vbuf as *c_void, len as size_t,
|
||||
|
|
@ -363,28 +364,28 @@ impl *libc::FILE: writer {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
fn seek(offset: int, whence: SeekStyle) {
|
||||
assert libc::fseek(self, offset as c_long, convert_whence(whence))
|
||||
== 0 as c_int;
|
||||
}
|
||||
fn tell() -> uint { libc::ftell(self) as uint }
|
||||
fn flush() -> int { libc::fflush(self) as int }
|
||||
fn get_type() -> writer_type {
|
||||
fn get_type() -> WriterType {
|
||||
let fd = libc::fileno(self);
|
||||
if libc::isatty(fd) == 0 { file }
|
||||
else { screen }
|
||||
if libc::isatty(fd) == 0 { File }
|
||||
else { Screen }
|
||||
}
|
||||
}
|
||||
|
||||
fn FILE_writer(f: *libc::FILE, cleanup: bool) -> writer {
|
||||
fn FILE_writer(f: *libc::FILE, cleanup: bool) -> Writer {
|
||||
if cleanup {
|
||||
{base: f, cleanup: FILE_res(f)} as writer
|
||||
{base: f, cleanup: FILERes(f)} as Writer
|
||||
} else {
|
||||
f as writer
|
||||
f as Writer
|
||||
}
|
||||
}
|
||||
|
||||
impl fd_t: writer {
|
||||
impl fd_t: Writer {
|
||||
fn write(v: &[const u8]) {
|
||||
let mut count = 0u;
|
||||
do vec::as_const_buf(v) |vbuf, len| {
|
||||
|
|
@ -400,7 +401,7 @@ impl fd_t: writer {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn seek(_offset: int, _whence: seek_style) {
|
||||
fn seek(_offset: int, _whence: SeekStyle) {
|
||||
error!{"need 64-bit foreign calls for seek, sorry"};
|
||||
fail;
|
||||
}
|
||||
|
|
@ -409,28 +410,28 @@ impl fd_t: writer {
|
|||
fail;
|
||||
}
|
||||
fn flush() -> int { 0 }
|
||||
fn get_type() -> writer_type {
|
||||
if libc::isatty(self) == 0 { file } else { screen }
|
||||
fn get_type() -> WriterType {
|
||||
if libc::isatty(self) == 0 { File } else { Screen }
|
||||
}
|
||||
}
|
||||
|
||||
class fd_res {
|
||||
class FdRes {
|
||||
let fd: fd_t;
|
||||
new(fd: fd_t) { self.fd = fd; }
|
||||
drop { libc::close(self.fd); }
|
||||
}
|
||||
|
||||
fn fd_writer(fd: fd_t, cleanup: bool) -> writer {
|
||||
fn fd_writer(fd: fd_t, cleanup: bool) -> Writer {
|
||||
if cleanup {
|
||||
{base: fd, cleanup: fd_res(fd)} as writer
|
||||
{base: fd, cleanup: FdRes(fd)} as Writer
|
||||
} else {
|
||||
fd as writer
|
||||
fd as Writer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn mk_file_writer(path: ~str, flags: ~[fileflag])
|
||||
-> result<writer, ~str> {
|
||||
fn mk_file_writer(path: ~str, flags: ~[FileFlag])
|
||||
-> result<Writer, ~str> {
|
||||
|
||||
#[cfg(windows)]
|
||||
fn wb() -> c_int { (O_WRONLY | O_BINARY) as c_int }
|
||||
|
|
@ -441,10 +442,10 @@ fn mk_file_writer(path: ~str, flags: ~[fileflag])
|
|||
let mut fflags: c_int = wb();
|
||||
for vec::each(flags) |f| {
|
||||
match f {
|
||||
append => fflags |= O_APPEND as c_int,
|
||||
create => fflags |= O_CREAT as c_int,
|
||||
truncate => fflags |= O_TRUNC as c_int,
|
||||
no_flag => ()
|
||||
Append => fflags |= O_APPEND as c_int,
|
||||
Create => fflags |= O_CREAT as c_int,
|
||||
Truncate => fflags |= O_TRUNC as c_int,
|
||||
NoFlag => ()
|
||||
}
|
||||
}
|
||||
let fd = do os::as_c_charp(path) |pathbuf| {
|
||||
|
|
@ -535,7 +536,7 @@ fn u64_from_be_bytes(data: ~[u8], start: uint, size: uint) -> u64 {
|
|||
|
||||
// FIXME: #3048 combine trait+impl (or just move these to
|
||||
// default methods on writer)
|
||||
trait writer_util {
|
||||
trait WriterUtil {
|
||||
fn write_char(ch: char);
|
||||
fn write_str(s: &str);
|
||||
fn write_line(s: &str);
|
||||
|
|
@ -560,7 +561,7 @@ trait writer_util {
|
|||
fn write_u8(n: u8);
|
||||
}
|
||||
|
||||
impl<T:writer> T : writer_util {
|
||||
impl<T: Writer> T : WriterUtil {
|
||||
fn write_char(ch: char) {
|
||||
if ch as uint < 128u {
|
||||
self.write(&[ch as u8]);
|
||||
|
|
@ -631,13 +632,13 @@ impl<T:writer> T : writer_util {
|
|||
fn write_u8(n: u8) { self.write(&[n]) }
|
||||
}
|
||||
|
||||
fn file_writer(path: ~str, flags: ~[fileflag]) -> result<writer, ~str> {
|
||||
fn file_writer(path: ~str, flags: ~[FileFlag]) -> result<Writer, ~str> {
|
||||
result::chain(mk_file_writer(path, flags), |w| result::ok(w))
|
||||
}
|
||||
|
||||
|
||||
// FIXME: fileflags // #2004
|
||||
fn buffered_file_writer(path: ~str) -> result<writer, ~str> {
|
||||
fn buffered_file_writer(path: ~str) -> result<Writer, ~str> {
|
||||
let f = do os::as_c_charp(path) |pathbuf| {
|
||||
do os::as_c_charp(~"w") |modebuf| {
|
||||
libc::fopen(pathbuf, modebuf)
|
||||
|
|
@ -650,15 +651,15 @@ fn buffered_file_writer(path: ~str) -> result<writer, ~str> {
|
|||
// FIXME (#2004) it would be great if this could be a const
|
||||
// FIXME (#2004) why are these different from the way stdin() is
|
||||
// implemented?
|
||||
fn stdout() -> writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
|
||||
fn stderr() -> writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
|
||||
fn stdout() -> Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
|
||||
fn stderr() -> Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
|
||||
|
||||
fn print(s: &str) { stdout().write_str(s); }
|
||||
fn println(s: &str) { stdout().write_line(s); }
|
||||
|
||||
type mem_buffer = @{buf: dvec<u8>, mut pos: uint};
|
||||
type MemBuffer = @{buf: dvec<u8>, mut pos: uint};
|
||||
|
||||
impl mem_buffer: writer {
|
||||
impl MemBuffer: Writer {
|
||||
fn write(v: &[const u8]) {
|
||||
// Fast path.
|
||||
let vlen = vec::len(v);
|
||||
|
|
@ -679,33 +680,33 @@ impl mem_buffer: writer {
|
|||
self.buf.push_slice(v, vpos, vlen);
|
||||
self.pos += vlen;
|
||||
}
|
||||
fn seek(offset: int, whence: seek_style) {
|
||||
fn seek(offset: int, whence: SeekStyle) {
|
||||
let pos = self.pos;
|
||||
let len = self.buf.len();
|
||||
self.pos = seek_in_buf(offset, pos, len, whence);
|
||||
}
|
||||
fn tell() -> uint { self.pos }
|
||||
fn flush() -> int { 0 }
|
||||
fn get_type() -> writer_type { file }
|
||||
fn get_type() -> WriterType { File }
|
||||
}
|
||||
|
||||
fn mem_buffer() -> mem_buffer {
|
||||
fn mem_buffer() -> MemBuffer {
|
||||
@{buf: dvec(), mut pos: 0u}
|
||||
}
|
||||
fn mem_buffer_writer(b: mem_buffer) -> writer { b as writer }
|
||||
fn mem_buffer_buf(b: mem_buffer) -> ~[u8] { b.buf.get() }
|
||||
fn mem_buffer_str(b: mem_buffer) -> ~str {
|
||||
fn mem_buffer_writer(b: MemBuffer) -> Writer { b as Writer }
|
||||
fn mem_buffer_buf(b: MemBuffer) -> ~[u8] { b.buf.get() }
|
||||
fn mem_buffer_str(b: MemBuffer) -> ~str {
|
||||
str::from_bytes(b.buf.get())
|
||||
}
|
||||
|
||||
fn with_str_writer(f: fn(writer)) -> ~str {
|
||||
fn with_str_writer(f: fn(Writer)) -> ~str {
|
||||
let buf = mem_buffer();
|
||||
let wr = mem_buffer_writer(buf);
|
||||
f(wr);
|
||||
io::mem_buffer_str(buf)
|
||||
}
|
||||
|
||||
fn with_buf_writer(f: fn(writer)) -> ~[u8] {
|
||||
fn with_buf_writer(f: fn(Writer)) -> ~[u8] {
|
||||
let buf = mem_buffer();
|
||||
let wr = mem_buffer_writer(buf);
|
||||
f(wr);
|
||||
|
|
@ -713,14 +714,14 @@ fn with_buf_writer(f: fn(writer)) -> ~[u8] {
|
|||
}
|
||||
|
||||
// Utility functions
|
||||
fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) ->
|
||||
fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
|
||||
uint {
|
||||
let mut bpos = pos as int;
|
||||
let blen = len as int;
|
||||
match whence {
|
||||
seek_set => bpos = offset,
|
||||
seek_cur => bpos += offset,
|
||||
seek_end => bpos = blen + offset
|
||||
SeekSet => bpos = offset,
|
||||
SeekCur => bpos += offset,
|
||||
SeekEnd => bpos = blen + offset
|
||||
}
|
||||
if bpos < 0 { bpos = 0; } else if bpos > blen { bpos = blen; }
|
||||
return bpos as uint;
|
||||
|
|
@ -748,24 +749,24 @@ fn read_whole_file(file: ~str) -> result<~[u8], ~str> {
|
|||
|
||||
mod fsync {
|
||||
|
||||
enum level {
|
||||
enum Level {
|
||||
// whatever fsync does on that platform
|
||||
fsync,
|
||||
FSync,
|
||||
|
||||
// fdatasync on linux, similiar or more on other platforms
|
||||
fdatasync,
|
||||
FDataSync,
|
||||
|
||||
// full fsync
|
||||
//
|
||||
// You must additionally sync the parent directory as well!
|
||||
fullfsync,
|
||||
FullFSync,
|
||||
}
|
||||
|
||||
|
||||
// Artifacts that need to fsync on destruction
|
||||
class res<t> {
|
||||
let arg: arg<t>;
|
||||
new(-arg: arg<t>) { self.arg <- arg; }
|
||||
class Res<t> {
|
||||
let arg: Arg<t>;
|
||||
new(-arg: Arg<t>) { self.arg <- arg; }
|
||||
drop {
|
||||
match self.arg.opt_level {
|
||||
option::none => (),
|
||||
|
|
@ -777,44 +778,47 @@ mod fsync {
|
|||
}
|
||||
}
|
||||
|
||||
type arg<t> = {
|
||||
type Arg<t> = {
|
||||
val: t,
|
||||
opt_level: option<level>,
|
||||
fsync_fn: fn@(t, level) -> int
|
||||
opt_level: option<Level>,
|
||||
fsync_fn: fn@(t, Level) -> int
|
||||
};
|
||||
|
||||
// fsync file after executing blk
|
||||
// FIXME (#2004) find better way to create resources within lifetime of
|
||||
// outer res
|
||||
fn FILE_res_sync(&&file: FILE_res, opt_level: option<level>,
|
||||
blk: fn(&&res<*libc::FILE>)) {
|
||||
blk(res({
|
||||
fn FILE_res_sync(&&file: FILERes, opt_level: option<Level>,
|
||||
blk: fn(&&Res<*libc::FILE>)) {
|
||||
blk(Res({
|
||||
val: file.f, opt_level: opt_level,
|
||||
fsync_fn: fn@(&&file: *libc::FILE, l: level) -> int {
|
||||
fsync_fn: fn@(&&file: *libc::FILE, l: Level) -> int {
|
||||
return os::fsync_fd(libc::fileno(file), l) as int;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// fsync fd after executing blk
|
||||
fn fd_res_sync(&&fd: fd_res, opt_level: option<level>,
|
||||
blk: fn(&&res<fd_t>)) {
|
||||
blk(res({
|
||||
fn fd_res_sync(&&fd: FdRes, opt_level: option<Level>,
|
||||
blk: fn(&&Res<fd_t>)) {
|
||||
blk(Res({
|
||||
val: fd.fd, opt_level: opt_level,
|
||||
fsync_fn: fn@(&&fd: fd_t, l: level) -> int {
|
||||
fsync_fn: fn@(&&fd: fd_t, l: Level) -> int {
|
||||
return os::fsync_fd(fd, l) as int;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// Type of objects that may want to fsync
|
||||
trait t { fn fsync(l: level) -> int; }
|
||||
trait FSyncable { fn fsync(l: Level) -> int; }
|
||||
|
||||
// Call o.fsync after executing blk
|
||||
fn obj_sync(&&o: t, opt_level: option<level>, blk: fn(&&res<t>)) {
|
||||
blk(res({
|
||||
fn obj_sync(&&o: FSyncable, opt_level: option<Level>,
|
||||
blk: fn(&&Res<FSyncable>)) {
|
||||
blk(Res({
|
||||
val: o, opt_level: opt_level,
|
||||
fsync_fn: fn@(&&o: t, l: level) -> int { return o.fsync(l); }
|
||||
fsync_fn: fn@(&&o: FSyncable, l: Level) -> int {
|
||||
return o.fsync(l);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -830,12 +834,12 @@ mod tests {
|
|||
~"A hoopy frood who really knows where his towel is.";
|
||||
log(debug, frood);
|
||||
{
|
||||
let out: io::writer =
|
||||
let out: io::Writer =
|
||||
result::get(
|
||||
io::file_writer(tmpfile, ~[io::create, io::truncate]));
|
||||
io::file_writer(tmpfile, ~[io::Create, io::Truncate]));
|
||||
out.write_str(frood);
|
||||
}
|
||||
let inp: io::reader = result::get(io::file_reader(tmpfile));
|
||||
let inp: io::Reader = result::get(io::file_reader(tmpfile));
|
||||
let frood2: ~str = inp.read_c_str();
|
||||
log(debug, frood2);
|
||||
assert frood == frood2;
|
||||
|
|
@ -843,7 +847,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_readchars_empty() {
|
||||
let inp : io::reader = io::str_reader(~"");
|
||||
let inp : io::Reader = io::str_reader(~"");
|
||||
let res : ~[char] = inp.read_chars(128u);
|
||||
assert(vec::len(res) == 0u);
|
||||
}
|
||||
|
|
@ -858,7 +862,7 @@ mod tests {
|
|||
29983, 38152, 30340, 27748,
|
||||
21273, 20999, 32905, 27748];
|
||||
fn check_read_ln(len : uint, s: ~str, ivals: ~[int]) {
|
||||
let inp : io::reader = io::str_reader(s);
|
||||
let inp : io::Reader = io::str_reader(s);
|
||||
let res : ~[char] = inp.read_chars(len);
|
||||
if (len <= vec::len(ivals)) {
|
||||
assert(vec::len(res) == len);
|
||||
|
|
@ -877,14 +881,14 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_readchar() {
|
||||
let inp : io::reader = io::str_reader(~"生");
|
||||
let inp : io::Reader = io::str_reader(~"生");
|
||||
let res : char = inp.read_char();
|
||||
assert(res as int == 29983);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_readchar_empty() {
|
||||
let inp : io::reader = io::str_reader(~"");
|
||||
let inp : io::Reader = io::str_reader(~"");
|
||||
let res : char = inp.read_char();
|
||||
assert(res as int == -1);
|
||||
}
|
||||
|
|
@ -924,12 +928,12 @@ mod tests {
|
|||
let mbuf = mem_buffer();
|
||||
mbuf.write(~[0u8, 1u8, 2u8, 3u8]);
|
||||
assert mem_buffer_buf(mbuf) == ~[0u8, 1u8, 2u8, 3u8];
|
||||
mbuf.seek(-2, seek_cur);
|
||||
mbuf.seek(-2, SeekCur);
|
||||
mbuf.write(~[4u8, 5u8, 6u8, 7u8]);
|
||||
assert mem_buffer_buf(mbuf) == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8];
|
||||
mbuf.seek(-2, seek_end);
|
||||
mbuf.seek(-2, SeekEnd);
|
||||
mbuf.write(~[8u8]);
|
||||
mbuf.seek(1, seek_set);
|
||||
mbuf.seek(1, SeekSet);
|
||||
mbuf.write(~[9u8]);
|
||||
assert mem_buffer_buf(mbuf) == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
/*!
|
||||
* Bindings for libc.
|
||||
*
|
||||
|
|
@ -34,6 +37,8 @@
|
|||
* dissolved.
|
||||
*/
|
||||
|
||||
#[allow(non_camel_case_types)];
|
||||
|
||||
// Initial glob-exports mean that all the contents of all the modules
|
||||
// wind up exported, if you're interested in writing platform-specific code.
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,13 @@ pure fn map<T, U>(opt: option<T>, f: fn(T) -> U) -> option<U> {
|
|||
match opt { some(x) => some(f(x)), none => none }
|
||||
}
|
||||
|
||||
pure fn map_consume<T, U>(-opt: option<T>, f: fn(-T) -> U) -> option<U> {
|
||||
pure fn map_ref<T, U>(opt: &option<T>, f: fn(x: &T) -> U) -> option<U> {
|
||||
//! Maps a `some` value by reference from one type to another
|
||||
|
||||
match *opt { some(ref x) => some(f(x)), none => none }
|
||||
}
|
||||
|
||||
pure fn map_consume<T, U>(+opt: option<T>, f: fn(+T) -> U) -> option<U> {
|
||||
/*!
|
||||
* As `map`, but consumes the option and gives `f` ownership to avoid
|
||||
* copying.
|
||||
|
|
@ -63,6 +69,16 @@ pure fn chain<T, U>(opt: option<T>, f: fn(T) -> option<U>) -> option<U> {
|
|||
match opt { some(x) => f(x), none => none }
|
||||
}
|
||||
|
||||
pure fn chain_ref<T, U>(opt: &option<T>,
|
||||
f: fn(x: &T) -> option<U>) -> option<U> {
|
||||
/*!
|
||||
* Update an optional value by optionally running its content by reference
|
||||
* through a function that returns an option.
|
||||
*/
|
||||
|
||||
match *opt { some(ref x) => f(x), none => none }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn while_some<T>(+x: option<T>, blk: fn(+T) -> option<T>) {
|
||||
//! Applies a function zero or more times until the result is none.
|
||||
|
|
@ -97,14 +113,28 @@ pure fn map_default<T, U>(opt: option<T>, +def: U, f: fn(T) -> U) -> U {
|
|||
match opt { none => def, some(t) => f(t) }
|
||||
}
|
||||
|
||||
// This should replace map_default.
|
||||
pure fn map_default_ref<T, U>(opt: &option<T>, +def: U,
|
||||
f: fn(x: &T) -> U) -> U {
|
||||
//! Applies a function to the contained value or returns a default
|
||||
|
||||
match *opt { none => def, some(ref t) => f(t) }
|
||||
}
|
||||
|
||||
// This should change to by-copy mode; use iter_ref below for by reference
|
||||
pure fn iter<T>(opt: option<T>, f: fn(T)) {
|
||||
//! Performs an operation on the contained value or does nothing
|
||||
|
||||
match opt { none => (), some(t) => f(t) }
|
||||
}
|
||||
|
||||
pure fn iter_ref<T>(opt: &option<T>, f: fn(x: &T)) {
|
||||
//! Performs an operation on the contained value by reference
|
||||
match *opt { none => (), some(ref t) => f(t) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn unwrap<T>(-opt: option<T>) -> T {
|
||||
pure fn unwrap<T>(+opt: option<T>) -> T {
|
||||
/*!
|
||||
* Moves a value out of an option type and returns it.
|
||||
*
|
||||
|
|
@ -130,12 +160,13 @@ fn swap_unwrap<T>(opt: &mut option<T>) -> T {
|
|||
unwrap(util::replace(opt, none))
|
||||
}
|
||||
|
||||
pure fn unwrap_expect<T>(-opt: option<T>, reason: &str) -> T {
|
||||
pure fn unwrap_expect<T>(+opt: option<T>, reason: &str) -> T {
|
||||
//! As unwrap, but with a specified failure message.
|
||||
if opt.is_none() { fail reason.to_unique(); }
|
||||
unwrap(opt)
|
||||
}
|
||||
|
||||
// Some of these should change to be &option<T>, some should not. See below.
|
||||
impl<T> option<T> {
|
||||
/**
|
||||
* Update an optional value by optionally running its content through a
|
||||
|
|
@ -155,6 +186,23 @@ impl<T> option<T> {
|
|||
pure fn map<U>(f: fn(T) -> U) -> option<U> { map(self, f) }
|
||||
}
|
||||
|
||||
impl<T> &option<T> {
|
||||
/**
|
||||
* Update an optional value by optionally running its content by reference
|
||||
* through a function that returns an option.
|
||||
*/
|
||||
pure fn chain_ref<U>(f: fn(x: &T) -> option<U>) -> option<U> {
|
||||
chain_ref(self, f)
|
||||
}
|
||||
/// Applies a function to the contained value or returns a default
|
||||
pure fn map_default_ref<U>(+def: U, f: fn(x: &T) -> U) -> U
|
||||
{ map_default_ref(self, def, f) }
|
||||
/// Performs an operation on the contained value by reference
|
||||
pure fn iter_ref(f: fn(x: &T)) { iter_ref(self, f) }
|
||||
/// Maps a `some` value from one type to another by reference
|
||||
pure fn map_ref<U>(f: fn(x: &T) -> U) -> option<U> { map_ref(self, f) }
|
||||
}
|
||||
|
||||
impl<T: copy> option<T> {
|
||||
/**
|
||||
* Gets the value out of an option
|
||||
|
|
|
|||
|
|
@ -134,34 +134,34 @@ mod global_env {
|
|||
fn rust_global_env_chan_ptr() -> *libc::uintptr_t;
|
||||
}
|
||||
|
||||
enum msg {
|
||||
msg_getenv(~str, comm::chan<option<~str>>),
|
||||
msg_setenv(~str, ~str, comm::chan<()>),
|
||||
msg_env(comm::chan<~[(~str,~str)]>)
|
||||
enum Msg {
|
||||
MsgGetEnv(~str, comm::chan<option<~str>>),
|
||||
MsgSetEnv(~str, ~str, comm::chan<()>),
|
||||
MsgEnv(comm::chan<~[(~str,~str)]>)
|
||||
}
|
||||
|
||||
fn getenv(n: ~str) -> option<~str> {
|
||||
let env_ch = get_global_env_chan();
|
||||
let po = comm::port();
|
||||
comm::send(env_ch, msg_getenv(n, comm::chan(po)));
|
||||
comm::send(env_ch, MsgGetEnv(n, comm::chan(po)));
|
||||
comm::recv(po)
|
||||
}
|
||||
|
||||
fn setenv(n: ~str, v: ~str) {
|
||||
let env_ch = get_global_env_chan();
|
||||
let po = comm::port();
|
||||
comm::send(env_ch, msg_setenv(n, v, comm::chan(po)));
|
||||
comm::send(env_ch, MsgSetEnv(n, v, comm::chan(po)));
|
||||
comm::recv(po)
|
||||
}
|
||||
|
||||
fn env() -> ~[(~str,~str)] {
|
||||
let env_ch = get_global_env_chan();
|
||||
let po = comm::port();
|
||||
comm::send(env_ch, msg_env(comm::chan(po)));
|
||||
comm::send(env_ch, MsgEnv(comm::chan(po)));
|
||||
comm::recv(po)
|
||||
}
|
||||
|
||||
fn get_global_env_chan() -> comm::chan<msg> {
|
||||
fn get_global_env_chan() -> comm::chan<Msg> {
|
||||
let global_ptr = rustrt::rust_global_env_chan_ptr();
|
||||
unsafe {
|
||||
priv::chan_from_global_ptr(global_ptr, || {
|
||||
|
|
@ -172,18 +172,18 @@ mod global_env {
|
|||
}
|
||||
}
|
||||
|
||||
fn global_env_task(msg_po: comm::port<msg>) {
|
||||
fn global_env_task(msg_po: comm::port<Msg>) {
|
||||
unsafe {
|
||||
do priv::weaken_task |weak_po| {
|
||||
loop {
|
||||
match comm::select2(msg_po, weak_po) {
|
||||
either::left(msg_getenv(n, resp_ch)) => {
|
||||
either::left(MsgGetEnv(n, resp_ch)) => {
|
||||
comm::send(resp_ch, impl::getenv(n))
|
||||
}
|
||||
either::left(msg_setenv(n, v, resp_ch)) => {
|
||||
either::left(MsgSetEnv(n, v, resp_ch)) => {
|
||||
comm::send(resp_ch, impl::setenv(n, v))
|
||||
}
|
||||
either::left(msg_env(resp_ch)) => {
|
||||
either::left(MsgEnv(resp_ch)) => {
|
||||
comm::send(resp_ch, impl::env())
|
||||
}
|
||||
either::right(_) => break
|
||||
|
|
@ -272,28 +272,28 @@ fn fdopen(fd: c_int) -> *FILE {
|
|||
// fsync related
|
||||
|
||||
#[cfg(windows)]
|
||||
fn fsync_fd(fd: c_int, _level: io::fsync::level) -> c_int {
|
||||
fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int {
|
||||
import libc::funcs::extra::msvcrt::*;
|
||||
return commit(fd);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn fsync_fd(fd: c_int, level: io::fsync::level) -> c_int {
|
||||
fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
|
||||
import libc::funcs::posix01::unistd::*;
|
||||
match level {
|
||||
io::fsync::fsync
|
||||
| io::fsync::fullfsync => return fsync(fd),
|
||||
io::fsync::fdatasync => return fdatasync(fd)
|
||||
io::fsync::FSync
|
||||
| io::fsync::FullFSync => return fsync(fd),
|
||||
io::fsync::FDataSync => return fdatasync(fd)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn fsync_fd(fd: c_int, level: io::fsync::level) -> c_int {
|
||||
fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int {
|
||||
import libc::consts::os::extra::*;
|
||||
import libc::funcs::posix88::fcntl::*;
|
||||
import libc::funcs::posix01::unistd::*;
|
||||
match level {
|
||||
io::fsync::fsync => return fsync(fd),
|
||||
io::fsync::FSync => return fsync(fd),
|
||||
_ => {
|
||||
// According to man fnctl, the ok retval is only specified to be !=-1
|
||||
if (fcntl(F_FULLFSYNC as c_int, fd) == -1 as c_int)
|
||||
|
|
@ -305,7 +305,7 @@ fn fsync_fd(fd: c_int, level: io::fsync::level) -> c_int {
|
|||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn fsync_fd(fd: c_int, _l: io::fsync::level) -> c_int {
|
||||
fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int {
|
||||
import libc::funcs::posix01::unistd::*;
|
||||
return fsync(fd);
|
||||
}
|
||||
|
|
@ -369,10 +369,10 @@ fn dll_filename(base: ~str) -> ~str {
|
|||
}
|
||||
|
||||
|
||||
fn self_exe_path() -> option<path> {
|
||||
fn self_exe_path() -> option<Path> {
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn load_self() -> option<path> {
|
||||
fn load_self() -> option<Path> {
|
||||
unsafe {
|
||||
import libc::funcs::bsd44::*;
|
||||
import libc::consts::os::extra::*;
|
||||
|
|
@ -388,7 +388,7 @@ fn self_exe_path() -> option<path> {
|
|||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn load_self() -> option<path> {
|
||||
fn load_self() -> option<Path> {
|
||||
import libc::funcs::posix01::unistd::readlink;
|
||||
do fill_charp_buf() |buf, sz| {
|
||||
do as_c_charp(~"/proc/self/exe") |proc_self_buf| {
|
||||
|
|
@ -398,7 +398,7 @@ fn self_exe_path() -> option<path> {
|
|||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn load_self() -> option<path> {
|
||||
fn load_self() -> option<Path> {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::*;
|
||||
do fill_charp_buf() |buf, sz| {
|
||||
|
|
@ -408,7 +408,7 @@ fn self_exe_path() -> option<path> {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn load_self() -> option<path> {
|
||||
fn load_self() -> option<Path> {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::types::os::arch::extra::*;
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
|
|
@ -437,7 +437,7 @@ fn self_exe_path() -> option<path> {
|
|||
*
|
||||
* Otherwise, homedir returns option::none.
|
||||
*/
|
||||
fn homedir() -> option<path> {
|
||||
fn homedir() -> option<Path> {
|
||||
return match getenv(~"HOME") {
|
||||
some(p) => if !str::is_empty(p) {
|
||||
some(p)
|
||||
|
|
@ -448,12 +448,12 @@ fn homedir() -> option<path> {
|
|||
};
|
||||
|
||||
#[cfg(unix)]
|
||||
fn secondary() -> option<path> {
|
||||
fn secondary() -> option<Path> {
|
||||
none
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn secondary() -> option<path> {
|
||||
fn secondary() -> option<Path> {
|
||||
do option::chain(getenv(~"USERPROFILE")) |p| {
|
||||
if !str::is_empty(p) {
|
||||
some(p)
|
||||
|
|
@ -465,11 +465,11 @@ fn homedir() -> option<path> {
|
|||
}
|
||||
|
||||
/// Recursively walk a directory structure
|
||||
fn walk_dir(p: path, f: fn(path) -> bool) {
|
||||
fn walk_dir(p: Path, f: fn(Path) -> bool) {
|
||||
|
||||
walk_dir_(p, f);
|
||||
|
||||
fn walk_dir_(p: path, f: fn(path) -> bool) -> bool {
|
||||
fn walk_dir_(p: Path, f: fn(Path) -> bool) -> bool {
|
||||
let mut keepgoing = true;
|
||||
do list_dir(p).each |q| {
|
||||
let path = path::connect(p, q);
|
||||
|
|
@ -494,14 +494,14 @@ fn walk_dir(p: path, f: fn(path) -> bool) {
|
|||
}
|
||||
|
||||
/// Indicates whether a path represents a directory
|
||||
fn path_is_dir(p: path) -> bool {
|
||||
fn path_is_dir(p: Path) -> bool {
|
||||
do str::as_c_str(p) |buf| {
|
||||
rustrt::rust_path_is_dir(buf) != 0 as c_int
|
||||
}
|
||||
}
|
||||
|
||||
/// Indicates whether a path exists
|
||||
fn path_exists(p: path) -> bool {
|
||||
fn path_exists(p: Path) -> bool {
|
||||
do str::as_c_str(p) |buf| {
|
||||
rustrt::rust_path_exists(buf) != 0 as c_int
|
||||
}
|
||||
|
|
@ -519,7 +519,7 @@ fn path_exists(p: path) -> bool {
|
|||
// NB: this is here rather than in path because it is a form of environment
|
||||
// querying; what it does depends on the process working directory, not just
|
||||
// the input paths.
|
||||
fn make_absolute(p: path) -> path {
|
||||
fn make_absolute(p: Path) -> Path {
|
||||
if path::path_is_absolute(p) {
|
||||
p
|
||||
} else {
|
||||
|
|
@ -529,11 +529,11 @@ fn make_absolute(p: path) -> path {
|
|||
|
||||
|
||||
/// Creates a directory at the specified path
|
||||
fn make_dir(p: path, mode: c_int) -> bool {
|
||||
fn make_dir(p: Path, mode: c_int) -> bool {
|
||||
return mkdir(p, mode);
|
||||
|
||||
#[cfg(windows)]
|
||||
fn mkdir(p: path, _mode: c_int) -> bool {
|
||||
fn mkdir(p: Path, _mode: c_int) -> bool {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::types::os::arch::extra::*;
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
|
|
@ -546,7 +546,7 @@ fn make_dir(p: path, mode: c_int) -> bool {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn mkdir(p: path, mode: c_int) -> bool {
|
||||
fn mkdir(p: Path, mode: c_int) -> bool {
|
||||
do as_c_charp(p) |c| {
|
||||
libc::mkdir(c, mode as mode_t) == (0 as c_int)
|
||||
}
|
||||
|
|
@ -554,7 +554,7 @@ fn make_dir(p: path, mode: c_int) -> bool {
|
|||
}
|
||||
|
||||
/// Lists the contents of a directory
|
||||
fn list_dir(p: path) -> ~[~str] {
|
||||
fn list_dir(p: Path) -> ~[~str] {
|
||||
|
||||
#[cfg(unix)]
|
||||
fn star(p: ~str) -> ~str { p }
|
||||
|
|
@ -580,7 +580,7 @@ fn list_dir(p: path) -> ~[~str] {
|
|||
*
|
||||
* This version prepends each entry with the directory.
|
||||
*/
|
||||
fn list_dir_path(p: path) -> ~[~str] {
|
||||
fn list_dir_path(p: Path) -> ~[~str] {
|
||||
let mut p = p;
|
||||
let pl = str::len(p);
|
||||
if pl == 0u || (p[pl - 1u] as char != path::consts::path_sep
|
||||
|
|
@ -591,11 +591,11 @@ fn list_dir_path(p: path) -> ~[~str] {
|
|||
}
|
||||
|
||||
/// Removes a directory at the specified path
|
||||
fn remove_dir(p: path) -> bool {
|
||||
fn remove_dir(p: Path) -> bool {
|
||||
return rmdir(p);
|
||||
|
||||
#[cfg(windows)]
|
||||
fn rmdir(p: path) -> bool {
|
||||
fn rmdir(p: Path) -> bool {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import libc::types::os::arch::extra::*;
|
||||
|
|
@ -606,18 +606,18 @@ fn remove_dir(p: path) -> bool {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn rmdir(p: path) -> bool {
|
||||
fn rmdir(p: Path) -> bool {
|
||||
return do as_c_charp(p) |buf| {
|
||||
libc::rmdir(buf) == (0 as c_int)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn change_dir(p: path) -> bool {
|
||||
fn change_dir(p: Path) -> bool {
|
||||
return chdir(p);
|
||||
|
||||
#[cfg(windows)]
|
||||
fn chdir(p: path) -> bool {
|
||||
fn chdir(p: Path) -> bool {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import libc::types::os::arch::extra::*;
|
||||
|
|
@ -628,7 +628,7 @@ fn change_dir(p: path) -> bool {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn chdir(p: path) -> bool {
|
||||
fn chdir(p: Path) -> bool {
|
||||
return do as_c_charp(p) |buf| {
|
||||
libc::chdir(buf) == (0 as c_int)
|
||||
};
|
||||
|
|
@ -636,11 +636,11 @@ fn change_dir(p: path) -> bool {
|
|||
}
|
||||
|
||||
/// Copies a file from one location to another
|
||||
fn copy_file(from: path, to: path) -> bool {
|
||||
fn copy_file(from: Path, to: Path) -> bool {
|
||||
return do_copy_file(from, to);
|
||||
|
||||
#[cfg(windows)]
|
||||
fn do_copy_file(from: path, to: path) -> bool {
|
||||
fn do_copy_file(from: Path, to: Path) -> bool {
|
||||
// FIXME: remove imports when export globs work properly. #1238
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
import libc::types::os::arch::extra::*;
|
||||
|
|
@ -653,7 +653,7 @@ fn copy_file(from: path, to: path) -> bool {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn do_copy_file(from: path, to: path) -> bool {
|
||||
fn do_copy_file(from: Path, to: Path) -> bool {
|
||||
let istream = do as_c_charp(from) |fromp| {
|
||||
do as_c_charp(~"rb") |modebuf| {
|
||||
libc::fopen(fromp, modebuf)
|
||||
|
|
@ -699,11 +699,11 @@ fn copy_file(from: path, to: path) -> bool {
|
|||
}
|
||||
|
||||
/// Deletes an existing file
|
||||
fn remove_file(p: path) -> bool {
|
||||
fn remove_file(p: Path) -> bool {
|
||||
return unlink(p);
|
||||
|
||||
#[cfg(windows)]
|
||||
fn unlink(p: path) -> bool {
|
||||
fn unlink(p: Path) -> bool {
|
||||
// FIXME (similar to Issue #2006): remove imports when export globs
|
||||
// work properly.
|
||||
import libc::funcs::extra::kernel32::*;
|
||||
|
|
@ -715,7 +715,7 @@ fn remove_file(p: path) -> bool {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn unlink(p: path) -> bool {
|
||||
fn unlink(p: Path) -> bool {
|
||||
return do as_c_charp(p) |buf| {
|
||||
libc::unlink(buf) == (0 as c_int)
|
||||
};
|
||||
|
|
@ -792,7 +792,7 @@ mod tests {
|
|||
|
||||
fn make_rand_name() -> ~str {
|
||||
import rand;
|
||||
let rng: rand::rng = rand::rng();
|
||||
let rng: rand::Rng = rand::rng();
|
||||
let n = ~"TEST" + rng.gen_str(10u);
|
||||
assert option::is_none(getenv(n));
|
||||
n
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Path data type and helper functions
|
||||
|
||||
export path;
|
||||
export Path;
|
||||
export consts;
|
||||
export path_is_absolute;
|
||||
export path_sep;
|
||||
|
|
@ -14,7 +14,7 @@ export normalize;
|
|||
|
||||
// FIXME: This type should probably be constrained (#2624)
|
||||
/// A path or fragment of a filesystem path
|
||||
type path = ~str;
|
||||
type Path = ~str;
|
||||
|
||||
#[cfg(unix)]
|
||||
mod consts {
|
||||
|
|
@ -45,7 +45,7 @@ mod consts {
|
|||
* on Windows, begins with a drive letter.
|
||||
*/
|
||||
#[cfg(unix)]
|
||||
fn path_is_absolute(p: path) -> bool {
|
||||
fn path_is_absolute(p: Path) -> bool {
|
||||
str::char_at(p, 0u) == '/'
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ fn path_is_absolute(p: ~str) -> bool {
|
|||
/// Get the default path separator for the host platform
|
||||
fn path_sep() -> ~str { return str::from_char(consts::path_sep); }
|
||||
|
||||
fn split_dirname_basename (pp: path) -> {dirname: ~str, basename: ~str} {
|
||||
fn split_dirname_basename (pp: Path) -> {dirname: ~str, basename: ~str} {
|
||||
match str::rfind(pp, |ch|
|
||||
ch == consts::path_sep || ch == consts::alt_path_sep
|
||||
) {
|
||||
|
|
@ -81,7 +81,7 @@ fn split_dirname_basename (pp: path) -> {dirname: ~str, basename: ~str} {
|
|||
*
|
||||
* If the path is not prefixed with a directory, then "." is returned.
|
||||
*/
|
||||
fn dirname(pp: path) -> path {
|
||||
fn dirname(pp: Path) -> Path {
|
||||
return split_dirname_basename(pp).dirname;
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ fn dirname(pp: path) -> path {
|
|||
* the provided path. If an empty path is provided or the path ends
|
||||
* with a path separator then an empty path is returned.
|
||||
*/
|
||||
fn basename(pp: path) -> path {
|
||||
fn basename(pp: Path) -> Path {
|
||||
return split_dirname_basename(pp).basename;
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ fn basename(pp: path) -> path {
|
|||
* and any leading path separator on `post`, and returns the concatenation of
|
||||
* the two with a single path separator between them.
|
||||
*/
|
||||
fn connect(pre: path, post: path) -> path {
|
||||
fn connect(pre: Path, post: Path) -> Path {
|
||||
let mut pre_ = pre;
|
||||
let mut post_ = post;
|
||||
let sep = consts::path_sep as u8;
|
||||
|
|
@ -127,7 +127,7 @@ fn connect(pre: path, post: path) -> path {
|
|||
*
|
||||
* Inserts path separators as needed.
|
||||
*/
|
||||
fn connect_many(paths: ~[path]) -> path {
|
||||
fn connect_many(paths: ~[Path]) -> Path {
|
||||
return if vec::len(paths) == 1u {
|
||||
paths[0]
|
||||
} else {
|
||||
|
|
@ -144,7 +144,7 @@ fn connect_many(paths: ~[path]) -> path {
|
|||
* the first element of the returned vector will be the drive letter
|
||||
* followed by a colon.
|
||||
*/
|
||||
fn split(p: path) -> ~[path] {
|
||||
fn split(p: Path) -> ~[Path] {
|
||||
str::split_nonempty(p, |c| {
|
||||
c == consts::path_sep || c == consts::alt_path_sep
|
||||
})
|
||||
|
|
@ -159,7 +159,7 @@ fn split(p: path) -> ~[path] {
|
|||
* ignored. If the path includes directory components then they are included
|
||||
* in the filename part of the result pair.
|
||||
*/
|
||||
fn splitext(p: path) -> (~str, ~str) {
|
||||
fn splitext(p: Path) -> (~str, ~str) {
|
||||
if str::is_empty(p) { (~"", ~"") }
|
||||
else {
|
||||
let parts = str::split_char(p, '.');
|
||||
|
|
@ -212,7 +212,7 @@ fn splitext(p: path) -> (~str, ~str) {
|
|||
* * 'a/b/../../../' becomes '..'
|
||||
* * '/a/b/c/../d/./../../e/' becomes '/a/e/'
|
||||
*/
|
||||
fn normalize(p: path) -> path {
|
||||
fn normalize(p: Path) -> Path {
|
||||
let s = split(p);
|
||||
let s = strip_dots(s);
|
||||
let s = rollup_doubledots(s);
|
||||
|
|
@ -233,7 +233,7 @@ fn normalize(p: path) -> path {
|
|||
|
||||
return s;
|
||||
|
||||
fn strip_dots(s: ~[path]) -> ~[path] {
|
||||
fn strip_dots(s: ~[Path]) -> ~[Path] {
|
||||
vec::filter_map(s, |elem|
|
||||
if elem == ~"." {
|
||||
option::none
|
||||
|
|
@ -242,7 +242,7 @@ fn normalize(p: path) -> path {
|
|||
})
|
||||
}
|
||||
|
||||
fn rollup_doubledots(s: ~[path]) -> ~[path] {
|
||||
fn rollup_doubledots(s: ~[Path]) -> ~[Path] {
|
||||
if vec::is_empty(s) {
|
||||
return ~[];
|
||||
}
|
||||
|
|
@ -271,7 +271,7 @@ fn normalize(p: path) -> path {
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn reabsolute(orig: path, n: path) -> path {
|
||||
fn reabsolute(orig: Path, n: Path) -> Path {
|
||||
if path_is_absolute(orig) {
|
||||
path_sep() + n
|
||||
} else {
|
||||
|
|
@ -280,7 +280,7 @@ fn normalize(p: path) -> path {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn reabsolute(orig: path, newp: path) -> path {
|
||||
fn reabsolute(orig: Path, newp: Path) -> Path {
|
||||
if path_is_absolute(orig) && orig[0] == consts::path_sep as u8 {
|
||||
str::from_char(consts::path_sep) + newp
|
||||
} else {
|
||||
|
|
@ -288,7 +288,7 @@ fn normalize(p: path) -> path {
|
|||
}
|
||||
}
|
||||
|
||||
fn reterminate(orig: path, newp: path) -> path {
|
||||
fn reterminate(orig: Path, newp: Path) -> Path {
|
||||
let last = orig[str::len(orig) - 1u];
|
||||
if last == consts::path_sep as u8
|
||||
|| last == consts::path_sep as u8 {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
#[doc(hidden)];
|
||||
|
||||
export chan_from_global_ptr, weaken_task;
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ fn to_uint<T>(thing: &T) -> uint unsafe {
|
|||
|
||||
/// Determine if two borrowed pointers point to the same thing.
|
||||
#[inline(always)]
|
||||
fn ref_eq<T>(thing: &T, other: &T) -> bool {
|
||||
fn ref_eq<T>(thing: &a/T, other: &b/T) -> bool {
|
||||
to_uint(thing) == to_uint(other)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
//! Random number generation
|
||||
|
||||
export rng, seed, seeded_rng, weighted, extensions;
|
||||
export Rng, rng, seed, seeded_rng, Weighted, extensions;
|
||||
export xorshift, seeded_xorshift;
|
||||
|
||||
#[allow(non_camel_case_types)] // runtime type
|
||||
enum rctx {}
|
||||
|
||||
#[abi = "cdecl"]
|
||||
|
|
@ -15,16 +16,16 @@ extern mod rustrt {
|
|||
}
|
||||
|
||||
/// A random number generator
|
||||
trait rng {
|
||||
trait Rng {
|
||||
/// Return the next random integer
|
||||
fn next() -> u32;
|
||||
}
|
||||
|
||||
/// A value with a particular weight compared to other values
|
||||
type weighted<T> = { weight: uint, item: T };
|
||||
type Weighted<T> = { weight: uint, item: T };
|
||||
|
||||
/// Extension methods for random number generators
|
||||
impl rng {
|
||||
impl Rng {
|
||||
|
||||
/// Return a random int
|
||||
fn gen_int() -> int {
|
||||
|
|
@ -181,7 +182,7 @@ impl rng {
|
|||
* Choose an item respecting the relative weights, failing if the sum of
|
||||
* the weights is 0
|
||||
*/
|
||||
fn choose_weighted<T: copy>(v : ~[weighted<T>]) -> T {
|
||||
fn choose_weighted<T: copy>(v : ~[Weighted<T>]) -> T {
|
||||
self.choose_weighted_option(v).get()
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +190,7 @@ impl rng {
|
|||
* Choose some(item) respecting the relative weights, returning none if
|
||||
* the sum of the weights is 0
|
||||
*/
|
||||
fn choose_weighted_option<T:copy>(v: ~[weighted<T>]) -> option<T> {
|
||||
fn choose_weighted_option<T:copy>(v: ~[Weighted<T>]) -> option<T> {
|
||||
let mut total = 0u;
|
||||
for v.each |item| {
|
||||
total += item.weight;
|
||||
|
|
@ -212,7 +213,7 @@ impl rng {
|
|||
* Return a vec containing copies of the items, in order, where
|
||||
* the weight of the item determines how many copies there are
|
||||
*/
|
||||
fn weighted_vec<T:copy>(v: ~[weighted<T>]) -> ~[T] {
|
||||
fn weighted_vec<T:copy>(v: ~[Weighted<T>]) -> ~[T] {
|
||||
let mut r = ~[];
|
||||
for v.each |item| {
|
||||
for uint::range(0u, item.weight) |_i| {
|
||||
|
|
@ -242,13 +243,13 @@ impl rng {
|
|||
|
||||
}
|
||||
|
||||
class rand_res {
|
||||
class RandRes {
|
||||
let c: *rctx;
|
||||
new(c: *rctx) { self.c = c; }
|
||||
drop { rustrt::rand_free(self.c); }
|
||||
}
|
||||
|
||||
impl @rand_res: rng {
|
||||
impl @RandRes: Rng {
|
||||
fn next() -> u32 { return rustrt::rand_next((*self).c); }
|
||||
}
|
||||
|
||||
|
|
@ -258,8 +259,8 @@ fn seed() -> ~[u8] {
|
|||
}
|
||||
|
||||
/// Create a random number generator with a system specified seed
|
||||
fn rng() -> rng {
|
||||
@rand_res(rustrt::rand_new()) as rng
|
||||
fn rng() -> Rng {
|
||||
@RandRes(rustrt::rand_new()) as Rng
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -268,18 +269,18 @@ fn rng() -> rng {
|
|||
* all other generators constructed with the same seed. The seed may be any
|
||||
* length.
|
||||
*/
|
||||
fn seeded_rng(seed: ~[u8]) -> rng {
|
||||
@rand_res(rustrt::rand_new_seeded(seed)) as rng
|
||||
fn seeded_rng(seed: ~[u8]) -> Rng {
|
||||
@RandRes(rustrt::rand_new_seeded(seed)) as Rng
|
||||
}
|
||||
|
||||
type xorshift_state = {
|
||||
type XorShiftState = {
|
||||
mut x: u32,
|
||||
mut y: u32,
|
||||
mut z: u32,
|
||||
mut w: u32
|
||||
};
|
||||
|
||||
impl xorshift_state: rng {
|
||||
impl XorShiftState: Rng {
|
||||
fn next() -> u32 {
|
||||
let x = self.x;
|
||||
let mut t = x ^ (x << 11);
|
||||
|
|
@ -292,13 +293,13 @@ impl xorshift_state: rng {
|
|||
}
|
||||
}
|
||||
|
||||
fn xorshift() -> rng {
|
||||
fn xorshift() -> Rng {
|
||||
// constants taken from http://en.wikipedia.org/wiki/Xorshift
|
||||
seeded_xorshift(123456789u32, 362436069u32, 521288629u32, 88675123u32)
|
||||
}
|
||||
|
||||
fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> rng {
|
||||
{mut x: x, mut y: y, mut z: z, mut w: w} as rng
|
||||
fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng {
|
||||
{mut x: x, mut y: y, mut z: z, mut w: w} as Rng
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
//! Runtime calls emitted by the compiler.
|
||||
|
||||
import libc::c_char;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
//! Process spawning
|
||||
import option::{some, none};
|
||||
import libc::{pid_t, c_void, c_int};
|
||||
|
||||
export program;
|
||||
export Program;
|
||||
export run_program;
|
||||
export start_program;
|
||||
export program_output;
|
||||
|
|
@ -18,18 +22,18 @@ extern mod rustrt {
|
|||
}
|
||||
|
||||
/// A value representing a child process
|
||||
trait program {
|
||||
trait Program {
|
||||
/// Returns the process id of the program
|
||||
fn get_id() -> pid_t;
|
||||
|
||||
/// Returns an io::writer that can be used to write to stdin
|
||||
fn input() -> io::writer;
|
||||
fn input() -> io::Writer;
|
||||
|
||||
/// Returns an io::reader that can be used to read from stdout
|
||||
fn output() -> io::reader;
|
||||
fn output() -> io::Reader;
|
||||
|
||||
/// Returns an io::reader that can be used to read from stderr
|
||||
fn err() -> io::reader;
|
||||
fn err() -> io::Reader;
|
||||
|
||||
/// Closes the handle to the child processes standard input
|
||||
fn close_input();
|
||||
|
|
@ -62,9 +66,9 @@ trait program {
|
|||
*
|
||||
* The process id of the spawned process
|
||||
*/
|
||||
fn spawn_process(prog: ~str, args: ~[~str],
|
||||
env: option<~[(~str,~str)]>,
|
||||
dir: option<~str>,
|
||||
fn spawn_process(prog: &str, args: &[~str],
|
||||
env: &option<~[(~str,~str)]>,
|
||||
dir: &option<~str>,
|
||||
in_fd: c_int, out_fd: c_int, err_fd: c_int)
|
||||
-> pid_t {
|
||||
do with_argv(prog, args) |argv| {
|
||||
|
|
@ -77,7 +81,7 @@ fn spawn_process(prog: ~str, args: ~[~str],
|
|||
}
|
||||
}
|
||||
|
||||
fn with_argv<T>(prog: ~str, args: ~[~str],
|
||||
fn with_argv<T>(prog: &str, args: &[~str],
|
||||
cb: fn(**libc::c_char) -> T) -> T {
|
||||
let mut argptrs = str::as_c_str(prog, |b| ~[b]);
|
||||
let mut tmps = ~[];
|
||||
|
|
@ -91,11 +95,11 @@ fn with_argv<T>(prog: ~str, args: ~[~str],
|
|||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn with_envp<T>(env: option<~[(~str,~str)]>,
|
||||
fn with_envp<T>(env: &option<~[(~str,~str)]>,
|
||||
cb: fn(*c_void) -> T) -> T {
|
||||
// On posixy systems we can pass a char** for envp, which is
|
||||
// a null-terminated array of "k=v\n" strings.
|
||||
match env {
|
||||
match *env {
|
||||
some(es) if !vec::is_empty(es) => {
|
||||
let mut tmps = ~[];
|
||||
let mut ptrs = ~[];
|
||||
|
|
@ -116,13 +120,13 @@ fn with_envp<T>(env: option<~[(~str,~str)]>,
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn with_envp<T>(env: option<~[(~str,~str)]>,
|
||||
fn with_envp<T>(env: &option<~[(~str,~str)]>,
|
||||
cb: fn(*c_void) -> T) -> T {
|
||||
// On win32 we pass an "environment block" which is not a char**, but
|
||||
// rather a concatenation of null-terminated k=v\0 sequences, with a final
|
||||
// \0 to terminate.
|
||||
unsafe {
|
||||
match env {
|
||||
match *env {
|
||||
some(es) if !vec::is_empty(es) => {
|
||||
let mut blk : ~[u8] = ~[];
|
||||
for vec::each(es) |e| {
|
||||
|
|
@ -140,9 +144,9 @@ fn with_envp<T>(env: option<~[(~str,~str)]>,
|
|||
}
|
||||
}
|
||||
|
||||
fn with_dirp<T>(d: option<~str>,
|
||||
fn with_dirp<T>(d: &option<~str>,
|
||||
cb: fn(*libc::c_char) -> T) -> T {
|
||||
match d {
|
||||
match *d {
|
||||
some(dir) => str::as_c_str(dir, cb),
|
||||
none => cb(ptr::null())
|
||||
}
|
||||
|
|
@ -160,8 +164,8 @@ fn with_dirp<T>(d: option<~str>,
|
|||
*
|
||||
* The process id
|
||||
*/
|
||||
fn run_program(prog: ~str, args: ~[~str]) -> int {
|
||||
let pid = spawn_process(prog, args, none, none,
|
||||
fn run_program(prog: &str, args: &[~str]) -> int {
|
||||
let pid = spawn_process(prog, args, &none, &none,
|
||||
0i32, 0i32, 0i32);
|
||||
if pid == -1 as pid_t { fail; }
|
||||
return waitpid(pid);
|
||||
|
|
@ -183,12 +187,12 @@ fn run_program(prog: ~str, args: ~[~str]) -> int {
|
|||
*
|
||||
* A class with a <program> field
|
||||
*/
|
||||
fn start_program(prog: ~str, args: ~[~str]) -> program {
|
||||
fn start_program(prog: &str, args: &[~str]) -> Program {
|
||||
let pipe_input = os::pipe();
|
||||
let pipe_output = os::pipe();
|
||||
let pipe_err = os::pipe();
|
||||
let pid =
|
||||
spawn_process(prog, args, none, none,
|
||||
spawn_process(prog, args, &none, &none,
|
||||
pipe_input.in, pipe_output.out,
|
||||
pipe_err.out);
|
||||
|
||||
|
|
@ -197,54 +201,54 @@ fn start_program(prog: ~str, args: ~[~str]) -> program {
|
|||
libc::close(pipe_output.out);
|
||||
libc::close(pipe_err.out);
|
||||
|
||||
type prog_repr = {pid: pid_t,
|
||||
mut in_fd: c_int,
|
||||
out_file: *libc::FILE,
|
||||
err_file: *libc::FILE,
|
||||
mut finished: bool};
|
||||
type ProgRepr = {pid: pid_t,
|
||||
mut in_fd: c_int,
|
||||
out_file: *libc::FILE,
|
||||
err_file: *libc::FILE,
|
||||
mut finished: bool};
|
||||
|
||||
fn close_repr_input(r: prog_repr) {
|
||||
fn close_repr_input(r: &ProgRepr) {
|
||||
let invalid_fd = -1i32;
|
||||
if r.in_fd != invalid_fd {
|
||||
libc::close(r.in_fd);
|
||||
r.in_fd = invalid_fd;
|
||||
}
|
||||
}
|
||||
fn finish_repr(r: prog_repr) -> int {
|
||||
fn finish_repr(r: &ProgRepr) -> int {
|
||||
if r.finished { return 0; }
|
||||
r.finished = true;
|
||||
close_repr_input(r);
|
||||
return waitpid(r.pid);
|
||||
}
|
||||
fn destroy_repr(r: prog_repr) {
|
||||
fn destroy_repr(r: &ProgRepr) {
|
||||
finish_repr(r);
|
||||
libc::fclose(r.out_file);
|
||||
libc::fclose(r.err_file);
|
||||
}
|
||||
class prog_res {
|
||||
let r: prog_repr;
|
||||
new(-r: prog_repr) { self.r = r; }
|
||||
drop { destroy_repr(self.r); }
|
||||
class ProgRes {
|
||||
let r: ProgRepr;
|
||||
new(+r: ProgRepr) { self.r = r; }
|
||||
drop { destroy_repr(&self.r); }
|
||||
}
|
||||
|
||||
impl prog_res: program {
|
||||
impl ProgRes: Program {
|
||||
fn get_id() -> pid_t { return self.r.pid; }
|
||||
fn input() -> io::writer { io::fd_writer(self.r.in_fd, false) }
|
||||
fn output() -> io::reader { io::FILE_reader(self.r.out_file, false) }
|
||||
fn err() -> io::reader { io::FILE_reader(self.r.err_file, false) }
|
||||
fn close_input() { close_repr_input(self.r); }
|
||||
fn finish() -> int { finish_repr(self.r) }
|
||||
fn destroy() { destroy_repr(self.r); }
|
||||
fn input() -> io::Writer { io::fd_writer(self.r.in_fd, false) }
|
||||
fn output() -> io::Reader { io::FILE_reader(self.r.out_file, false) }
|
||||
fn err() -> io::Reader { io::FILE_reader(self.r.err_file, false) }
|
||||
fn close_input() { close_repr_input(&self.r); }
|
||||
fn finish() -> int { finish_repr(&self.r) }
|
||||
fn destroy() { destroy_repr(&self.r); }
|
||||
}
|
||||
let repr = {pid: pid,
|
||||
mut in_fd: pipe_input.out,
|
||||
out_file: os::fdopen(pipe_output.in),
|
||||
err_file: os::fdopen(pipe_err.in),
|
||||
mut finished: false};
|
||||
return prog_res(repr) as program;
|
||||
return ProgRes(move repr) as Program;
|
||||
}
|
||||
|
||||
fn read_all(rd: io::reader) -> ~str {
|
||||
fn read_all(rd: io::Reader) -> ~str {
|
||||
let mut buf = ~"";
|
||||
while !rd.eof() {
|
||||
let bytes = rd.read_bytes(4096u);
|
||||
|
|
@ -267,13 +271,13 @@ fn read_all(rd: io::reader) -> ~str {
|
|||
* A record, {status: int, out: str, err: str} containing the exit code,
|
||||
* the contents of stdout and the contents of stderr.
|
||||
*/
|
||||
fn program_output(prog: ~str, args: ~[~str]) ->
|
||||
fn program_output(prog: &str, args: &[~str]) ->
|
||||
{status: int, out: ~str, err: ~str} {
|
||||
|
||||
let pipe_in = os::pipe();
|
||||
let pipe_out = os::pipe();
|
||||
let pipe_err = os::pipe();
|
||||
let pid = spawn_process(prog, args, none, none,
|
||||
let pid = spawn_process(prog, args, &none, &none,
|
||||
pipe_in.in, pipe_out.out, pipe_err.out);
|
||||
|
||||
os::close(pipe_in.in);
|
||||
|
|
@ -321,8 +325,8 @@ fn program_output(prog: ~str, args: ~[~str]) ->
|
|||
return {status: status, out: outs, err: errs};
|
||||
}
|
||||
|
||||
fn writeclose(fd: c_int, s: ~str) {
|
||||
import io::writer_util;
|
||||
fn writeclose(fd: c_int, s: &str) {
|
||||
import io::WriterUtil;
|
||||
|
||||
error!{"writeclose %d, %s", fd as int, s};
|
||||
let writer = io::fd_writer(fd, false);
|
||||
|
|
@ -388,14 +392,14 @@ fn waitpid(pid: pid_t) -> int {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
// Regression test for memory leaks
|
||||
#[ignore(cfg(windows))] // FIXME (#2626)
|
||||
fn test_leaks() {
|
||||
run::run_program(~"echo", ~[]);
|
||||
run::start_program(~"echo", ~[]);
|
||||
run::program_output(~"echo", ~[]);
|
||||
run::run_program("echo", []);
|
||||
run::start_program("echo", []);
|
||||
run::program_output("echo", []);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -406,7 +410,7 @@ mod tests {
|
|||
|
||||
let pid =
|
||||
run::spawn_process(
|
||||
~"cat", ~[], none, none,
|
||||
"cat", [], &none, &none,
|
||||
pipe_in.in, pipe_out.out, pipe_err.out);
|
||||
os::close(pipe_in.in);
|
||||
os::close(pipe_out.out);
|
||||
|
|
@ -426,8 +430,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn waitpid() {
|
||||
let pid = run::spawn_process(~"false", ~[],
|
||||
none, none,
|
||||
let pid = run::spawn_process("false", [],
|
||||
&none, &none,
|
||||
0i32, 0i32, 0i32);
|
||||
let status = run::waitpid(pid);
|
||||
assert status == 1;
|
||||
|
|
|
|||
|
|
@ -237,11 +237,11 @@ mod linear {
|
|||
}
|
||||
|
||||
impl<K,V> &const linear_map<K,V> {
|
||||
fn len() -> uint {
|
||||
pure fn len() -> uint {
|
||||
self.size
|
||||
}
|
||||
|
||||
fn is_empty() -> bool {
|
||||
pure fn is_empty() -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
import libc::size_t;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
export
|
||||
// Creating a string
|
||||
|
|
@ -54,6 +54,7 @@ export
|
|||
|
||||
// Comparing strings
|
||||
eq,
|
||||
eq_slice,
|
||||
le,
|
||||
hash,
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
/*!
|
||||
* Task management.
|
||||
*
|
||||
|
|
@ -730,8 +734,8 @@ type taskgroup_arc = unsafe::Exclusive<option<taskgroup_data>>;
|
|||
type taskgroup_inner = &mut option<taskgroup_data>;
|
||||
|
||||
// A taskgroup is 'dead' when nothing can cause it to fail; only members can.
|
||||
fn taskgroup_is_dead(tg: taskgroup_data) -> bool {
|
||||
(&mut tg.members).is_empty()
|
||||
pure fn taskgroup_is_dead(tg: &taskgroup_data) -> bool {
|
||||
(&tg.members).is_empty()
|
||||
}
|
||||
|
||||
// A list-like structure by which taskgroups keep track of all ancestor groups
|
||||
|
|
@ -841,8 +845,11 @@ fn each_ancestor(list: &mut ancestor_list,
|
|||
do with_parent_tg(&mut nobe.parent_group) |tg_opt| {
|
||||
// Decide whether this group is dead. Note that the
|
||||
// group being *dead* is disjoint from it *failing*.
|
||||
do tg_opt.iter |tg| {
|
||||
nobe_is_dead = taskgroup_is_dead(tg);
|
||||
match *tg_opt {
|
||||
some(ref tg) => {
|
||||
nobe_is_dead = taskgroup_is_dead(tg);
|
||||
},
|
||||
none => { }
|
||||
}
|
||||
// Call iterator block. (If the group is dead, it's
|
||||
// safe to skip it. This will leave our *rust_task
|
||||
|
|
@ -1100,7 +1107,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
|
|||
}
|
||||
}
|
||||
|
||||
fn spawn_raw(opts: task_opts, +f: fn~()) {
|
||||
fn spawn_raw(+opts: task_opts, +f: fn~()) {
|
||||
let (child_tg, ancestors, is_main) =
|
||||
gen_child_taskgroup(opts.linked, opts.supervised);
|
||||
|
||||
|
|
@ -1138,10 +1145,10 @@ fn spawn_raw(opts: task_opts, +f: fn~()) {
|
|||
// (3a) If any of those fails, it leaves all groups, and does nothing.
|
||||
// (3b) Otherwise it builds a task control structure and puts it in TLS,
|
||||
// (4) ...and runs the provided body function.
|
||||
fn make_child_wrapper(child: *rust_task, -child_arc: taskgroup_arc,
|
||||
-ancestors: ancestor_list, is_main: bool,
|
||||
fn make_child_wrapper(child: *rust_task, +child_arc: taskgroup_arc,
|
||||
+ancestors: ancestor_list, is_main: bool,
|
||||
notify_chan: option<comm::chan<notification>>,
|
||||
-f: fn~()) -> fn~() {
|
||||
+f: fn~()) -> fn~() {
|
||||
let child_data = ~mut some((child_arc, ancestors));
|
||||
return fn~() {
|
||||
// Agh. Get move-mode items into the closure. FIXME (#2829)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
trait ToBytes {
|
||||
fn to_bytes() -> ~[u8];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
trait ToStr { fn to_str() -> ~str; }
|
||||
|
||||
impl int: ToStr {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
//! Operations on tuples
|
||||
|
||||
trait TupleOps<T,U> {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
mod general_category {
|
||||
pure fn Cc(c: char) -> bool {
|
||||
return match c {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! Unsafe operations
|
||||
|
||||
export reinterpret_cast, forget, bump_box_refcount, transmute;
|
||||
export transmute_mut, transmute_immut, transmute_region, transmute_mut_region;
|
||||
|
||||
export SharedMutableState, shared_mutable_state, clone_shared_mutable_state;
|
||||
export get_shared_mutable_state, get_shared_immutable_state;
|
||||
|
|
@ -53,6 +54,17 @@ unsafe fn transmute<L, G>(-thing: L) -> G {
|
|||
return newthing;
|
||||
}
|
||||
|
||||
/// Coerce an immutable reference to be mutable.
|
||||
unsafe fn transmute_mut<T>(+ptr: &T) -> &mut T { transmute(ptr) }
|
||||
/// Coerce a mutable reference to be immutable.
|
||||
unsafe fn transmute_immut<T>(+ptr: &mut T) -> &T { transmute(ptr) }
|
||||
/// Coerce a borrowed pointer to have an arbitrary associated region.
|
||||
unsafe fn transmute_region<T>(+ptr: &a/T) -> &b/T { transmute(ptr) }
|
||||
/// Coerce a borrowed mutable pointer to have an arbitrary associated region.
|
||||
unsafe fn transmute_mut_region<T>(+ptr: &a/mut T) -> &b/mut T {
|
||||
transmute(ptr)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Shared state & exclusive ARC
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
/**
|
||||
* Miscellaneous helpers for common patterns.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
/**
|
||||
* Concurrency-enabled mechanisms for sharing mutable and/or immutable state
|
||||
* between tasks.
|
||||
|
|
@ -10,7 +13,7 @@ import sync;
|
|||
import sync::{mutex, rwlock};
|
||||
|
||||
export arc, clone, get;
|
||||
export condvar, mutex_arc, rw_arc;
|
||||
export condvar, mutex_arc, rw_arc, rw_write_mode, rw_read_mode;
|
||||
|
||||
/// As sync::condvar, a mechanism for unlock-and-descheduling and signalling.
|
||||
struct condvar { is_mutex: bool; failed: &mut bool; cond: &sync::condvar; }
|
||||
|
|
@ -136,10 +139,11 @@ impl<T: send> &mutex_arc<T> {
|
|||
&condvar { is_mutex: true, failed: &mut state.failed,
|
||||
cond: cond })
|
||||
*/
|
||||
// XXX: Working around two seeming region bugs here
|
||||
let fref = unsafe { unsafe::reinterpret_cast(&mut state.failed) };
|
||||
// FIXME(#2282) region variance
|
||||
let fref =
|
||||
unsafe { unsafe::transmute_mut_region(&mut state.failed) };
|
||||
let cvar = condvar { is_mutex: true, failed: fref, cond: cond };
|
||||
blk(&mut state.data, unsafe { unsafe::reinterpret_cast(&cvar) } )
|
||||
blk(&mut state.data, unsafe { unsafe::transmute_region(&cvar) } )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -227,10 +231,12 @@ impl<T: const send> &rw_arc<T> {
|
|||
&condvar { is_mutex: false, failed: &mut state.failed,
|
||||
cond: cond })
|
||||
*/
|
||||
// XXX: Working around two seeming region bugs here
|
||||
let fref = unsafe { unsafe::reinterpret_cast(&mut state.failed) };
|
||||
// FIXME(#2282): Need region variance to use the commented-out
|
||||
// code above instead of this casting mess
|
||||
let fref =
|
||||
unsafe { unsafe::transmute_mut_region(&mut state.failed) };
|
||||
let cvar = condvar { is_mutex: false, failed: fref, cond: cond };
|
||||
blk(&mut state.data, unsafe { unsafe::reinterpret_cast(&cvar) } )
|
||||
blk(&mut state.data, unsafe { unsafe::transmute_region(&cvar) } )
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
|
@ -249,6 +255,52 @@ impl<T: const send> &rw_arc<T> {
|
|||
blk(&state.data)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* As write(), but with the ability to atomically 'downgrade' the lock.
|
||||
* See sync::rwlock.write_downgrade(). The rw_write_mode token must be
|
||||
* used to obtain the &mut T, and can be transformed into a rw_read_mode
|
||||
* token by calling downgrade(), after which a &T can be obtained instead.
|
||||
* ~~~
|
||||
* do arc.write_downgrade |write_mode| {
|
||||
* do (&write_mode).write_cond |state, condvar| {
|
||||
* ... exclusive access with mutable state ...
|
||||
* }
|
||||
* let read_mode = arc.downgrade(write_mode);
|
||||
* do (&read_mode).read |state| {
|
||||
* ... shared access with immutable state ...
|
||||
* }
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
fn write_downgrade<U>(blk: fn(+rw_write_mode<T>) -> U) -> U {
|
||||
let state = unsafe { get_shared_mutable_state(&self.x) };
|
||||
do borrow_rwlock(state).write_downgrade |write_mode| {
|
||||
check_poison(false, state.failed);
|
||||
// FIXME(#2282) need region variance to avoid having to cast here
|
||||
let (data,failed) =
|
||||
unsafe { (unsafe::transmute_mut_region(&mut state.data),
|
||||
unsafe::transmute_mut_region(&mut state.failed)) };
|
||||
blk(rw_write_mode((data, write_mode, poison_on_fail(failed))))
|
||||
}
|
||||
}
|
||||
|
||||
/// To be called inside of the write_downgrade block.
|
||||
fn downgrade(+token: rw_write_mode<T>) -> rw_read_mode<T> {
|
||||
// The rwlock should assert that the token belongs to us for us.
|
||||
let state = unsafe { get_shared_immutable_state(&self.x) };
|
||||
let rw_write_mode((data, t, _poison)) = token;
|
||||
// Let readers in
|
||||
let new_token = (&state.lock).downgrade(t);
|
||||
// Whatever region the input reference had, it will be safe to use
|
||||
// the same region for the output reference. (The only 'unsafe' part
|
||||
// of this cast is removing the mutability.)
|
||||
let new_data = unsafe { unsafe::transmute_immut(data) };
|
||||
// Downgrade ensured the token belonged to us. Just a sanity check.
|
||||
assert ptr::ref_eq(&state.data, new_data);
|
||||
// Produce new token
|
||||
rw_read_mode((new_data, new_token))
|
||||
}
|
||||
}
|
||||
|
||||
// Borrowck rightly complains about immutably aliasing the rwlock in order to
|
||||
|
|
@ -258,6 +310,58 @@ fn borrow_rwlock<T: const send>(state: &mut rw_arc_inner<T>) -> &rwlock {
|
|||
unsafe { unsafe::reinterpret_cast(&state.lock) }
|
||||
}
|
||||
|
||||
// FIXME (#3154) ice with struct/&<T> prevents these from being structs.
|
||||
|
||||
/// The "write permission" token used for rw_arc.write_downgrade().
|
||||
enum rw_write_mode<T: const send> =
|
||||
(&mut T, sync::rwlock_write_mode, poison_on_fail);
|
||||
/// The "read permission" token used for rw_arc.write_downgrade().
|
||||
enum rw_read_mode<T:const send> = (&T, sync::rwlock_read_mode);
|
||||
|
||||
impl<T: const send> &rw_write_mode<T> {
|
||||
/// Access the pre-downgrade rw_arc in write mode.
|
||||
fn write<U>(blk: fn(x: &mut T) -> U) -> U {
|
||||
match *self {
|
||||
rw_write_mode((data, ref token, _)) => {
|
||||
// FIXME(#2282) cast to avoid region invariance
|
||||
let mode = unsafe { unsafe::transmute_region(token) };
|
||||
do mode.write {
|
||||
blk(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Access the pre-downgrade rw_arc in write mode with a condvar.
|
||||
fn write_cond<U>(blk: fn(x: &x/mut T, c: &c/condvar) -> U) -> U {
|
||||
match *self {
|
||||
rw_write_mode((data, ref token, ref poison)) => {
|
||||
// FIXME(#2282) cast to avoid region invariance
|
||||
let mode = unsafe { unsafe::transmute_region(token) };
|
||||
do mode.write_cond |cond| {
|
||||
let cvar = condvar {
|
||||
is_mutex: false, failed: poison.failed,
|
||||
cond: unsafe { unsafe::reinterpret_cast(cond) } };
|
||||
// FIXME(#2282) region variance would avoid having to cast
|
||||
blk(data, &cvar)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: const send> &rw_read_mode<T> {
|
||||
/// Access the post-downgrade rwlock in read mode.
|
||||
fn read<U>(blk: fn(x: &T) -> U) -> U {
|
||||
match *self {
|
||||
rw_read_mode((data, ref token)) => {
|
||||
// FIXME(#2282) cast to avoid region invariance
|
||||
let mode = unsafe { unsafe::transmute_region(token) };
|
||||
do mode.read { blk(data) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Tests
|
||||
****************************************************************************/
|
||||
|
|
@ -374,6 +478,23 @@ mod tests {
|
|||
assert *one == 1;
|
||||
}
|
||||
}
|
||||
#[test] #[should_fail] #[ignore(cfg(windows))]
|
||||
fn test_rw_arc_poison_dw() {
|
||||
let arc = ~rw_arc(1);
|
||||
let arc2 = ~arc.clone();
|
||||
do task::try {
|
||||
do arc2.write_downgrade |write_mode| {
|
||||
// FIXME(#2282)
|
||||
let mode = unsafe { unsafe::transmute_region(&write_mode) };
|
||||
do mode.write |one| {
|
||||
assert *one == 2;
|
||||
}
|
||||
}
|
||||
};
|
||||
do arc.write |one| {
|
||||
assert *one == 1;
|
||||
}
|
||||
}
|
||||
#[test] #[ignore(cfg(windows))]
|
||||
fn test_rw_arc_no_poison_rr() {
|
||||
let arc = ~rw_arc(1);
|
||||
|
|
@ -400,7 +521,24 @@ mod tests {
|
|||
assert *one == 1;
|
||||
}
|
||||
}
|
||||
|
||||
#[test] #[ignore(cfg(windows))]
|
||||
fn test_rw_arc_no_poison_dr() {
|
||||
let arc = ~rw_arc(1);
|
||||
let arc2 = ~arc.clone();
|
||||
do task::try {
|
||||
do arc2.write_downgrade |write_mode| {
|
||||
let read_mode = arc2.downgrade(write_mode);
|
||||
// FIXME(#2282)
|
||||
let mode = unsafe { unsafe::transmute_region(&read_mode) };
|
||||
do mode.read |one| {
|
||||
assert *one == 2;
|
||||
}
|
||||
}
|
||||
};
|
||||
do arc.write |one| {
|
||||
assert *one == 1;
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn test_rw_arc() {
|
||||
let arc = ~rw_arc(0);
|
||||
|
|
@ -434,4 +572,84 @@ mod tests {
|
|||
p.recv();
|
||||
do arc.read |num| { assert *num == 10; }
|
||||
}
|
||||
#[test]
|
||||
fn test_rw_downgrade() {
|
||||
// (1) A downgrader gets in write mode and does cond.wait.
|
||||
// (2) A writer gets in write mode, sets state to 42, and does signal.
|
||||
// (3) Downgrader wakes, sets state to 31337.
|
||||
// (4) tells writer and all other readers to contend as it downgrades.
|
||||
// (5) Writer attempts to set state back to 42, while downgraded task
|
||||
// and all reader tasks assert that it's 31337.
|
||||
let arc = ~rw_arc(0);
|
||||
|
||||
// Reader tasks
|
||||
let mut reader_convos = ~[];
|
||||
for 10.times {
|
||||
let ((rc1,rp1),(rc2,rp2)) = (pipes::stream(),pipes::stream());
|
||||
vec::push(reader_convos, (rc1,rp2));
|
||||
let arcn = ~arc.clone();
|
||||
do task::spawn {
|
||||
rp1.recv(); // wait for downgrader to give go-ahead
|
||||
do arcn.read |state| {
|
||||
assert *state == 31337;
|
||||
rc2.send(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Writer task
|
||||
let arc2 = ~arc.clone();
|
||||
let ((wc1,wp1),(wc2,wp2)) = (pipes::stream(),pipes::stream());
|
||||
do task::spawn {
|
||||
wp1.recv();
|
||||
do arc2.write_cond |state, cond| {
|
||||
assert *state == 0;
|
||||
*state = 42;
|
||||
cond.signal();
|
||||
}
|
||||
wp1.recv();
|
||||
do arc2.write |state| {
|
||||
// This shouldn't happen until after the downgrade read
|
||||
// section, and all other readers, finish.
|
||||
assert *state == 31337;
|
||||
*state = 42;
|
||||
}
|
||||
wc2.send(());
|
||||
}
|
||||
|
||||
// Downgrader (us)
|
||||
do arc.write_downgrade |write_mode| {
|
||||
// FIXME(#2282)
|
||||
let mode = unsafe { unsafe::transmute_region(&write_mode) };
|
||||
do mode.write_cond |state, cond| {
|
||||
wc1.send(()); // send to another writer who will wake us up
|
||||
while *state == 0 {
|
||||
cond.wait();
|
||||
}
|
||||
assert *state == 42;
|
||||
*state = 31337;
|
||||
// send to other readers
|
||||
for vec::each(reader_convos) |x| {
|
||||
match x {
|
||||
(rc, _) => rc.send(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
let read_mode = arc.downgrade(write_mode);
|
||||
// FIXME(#2282)
|
||||
let mode = unsafe { unsafe::transmute_region(&read_mode) };
|
||||
do mode.read |state| {
|
||||
// complete handshake with other readers
|
||||
for vec::each(reader_convos) |x| {
|
||||
match x {
|
||||
(_, rp) => rp.recv(),
|
||||
}
|
||||
}
|
||||
wc1.send(()); // tell writer to try again
|
||||
assert *state == 31337;
|
||||
}
|
||||
}
|
||||
|
||||
wp2.recv(); // complete handshake with writer
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import io::reader;
|
||||
import io::Reader;
|
||||
|
||||
trait to_base64 {
|
||||
fn to_base64() -> ~str;
|
||||
|
|
|
|||
|
|
@ -172,13 +172,13 @@ fn doc_as_i32(d: doc) -> i32 { doc_as_u32(d) as i32 }
|
|||
fn doc_as_i64(d: doc) -> i64 { doc_as_u64(d) as i64 }
|
||||
|
||||
// ebml writing
|
||||
type writer_ = {writer: io::writer, mut size_positions: ~[uint]};
|
||||
type writer_ = {writer: io::Writer, mut size_positions: ~[uint]};
|
||||
|
||||
enum writer {
|
||||
writer_(writer_)
|
||||
}
|
||||
|
||||
fn write_sized_vuint(w: io::writer, n: uint, size: uint) {
|
||||
fn write_sized_vuint(w: io::Writer, n: uint, size: uint) {
|
||||
match size {
|
||||
1u => w.write(&[0x80u8 | (n as u8)]),
|
||||
2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
|
||||
|
|
@ -190,7 +190,7 @@ fn write_sized_vuint(w: io::writer, n: uint, size: uint) {
|
|||
};
|
||||
}
|
||||
|
||||
fn write_vuint(w: io::writer, n: uint) {
|
||||
fn write_vuint(w: io::Writer, n: uint) {
|
||||
if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
|
||||
if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
|
||||
if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
|
||||
|
|
@ -198,7 +198,7 @@ fn write_vuint(w: io::writer, n: uint) {
|
|||
fail fmt!{"vint to write too big: %?", n};
|
||||
}
|
||||
|
||||
fn writer(w: io::writer) -> writer {
|
||||
fn writer(w: io::Writer) -> writer {
|
||||
let size_positions: ~[uint] = ~[];
|
||||
return writer_({writer: w, mut size_positions: size_positions});
|
||||
}
|
||||
|
|
@ -220,10 +220,10 @@ impl writer {
|
|||
fn end_tag() {
|
||||
let last_size_pos = vec::pop::<uint>(self.size_positions);
|
||||
let cur_pos = self.writer.tell();
|
||||
self.writer.seek(last_size_pos as int, io::seek_set);
|
||||
self.writer.seek(last_size_pos as int, io::SeekSet);
|
||||
let size = (cur_pos - last_size_pos - 4u);
|
||||
write_sized_vuint(self.writer, size, 4u);
|
||||
self.writer.seek(cur_pos as int, io::seek_set);
|
||||
self.writer.seek(cur_pos as int, io::SeekSet);
|
||||
|
||||
debug!{"End tag (size = %u)", size};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import result::{result, ok, err};
|
||||
import io;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import map;
|
||||
import map::hashmap;
|
||||
import map::map;
|
||||
|
|
@ -43,7 +43,7 @@ type error = {
|
|||
};
|
||||
|
||||
/// Serializes a json value into a io::writer
|
||||
fn to_writer(wr: io::writer, j: json) {
|
||||
fn to_writer(wr: io::Writer, j: json) {
|
||||
match j {
|
||||
num(n) => wr.write_str(float::to_str(n, 6u)),
|
||||
string(s) => wr.write_str(escape_str(*s)),
|
||||
|
|
@ -109,7 +109,7 @@ fn to_str(j: json) -> ~str {
|
|||
}
|
||||
|
||||
type parser_ = {
|
||||
rdr: io::reader,
|
||||
rdr: io::Reader,
|
||||
mut ch: char,
|
||||
mut line: uint,
|
||||
mut col: uint,
|
||||
|
|
@ -458,7 +458,7 @@ impl parser {
|
|||
}
|
||||
|
||||
/// Deserializes a json value from an io::reader
|
||||
fn from_reader(rdr: io::reader) -> result<json, error> {
|
||||
fn from_reader(rdr: io::Reader) -> result<json, error> {
|
||||
let parser = parser_({
|
||||
rdr: rdr,
|
||||
mut ch: rdr.read_char(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#[warn(deprecated_mode)];
|
||||
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import to_str::ToStr;
|
||||
export hashmap, hashfn, eqfn, set, map, chained, hashmap, str_hash;
|
||||
export box_str_hash;
|
||||
|
|
@ -328,7 +328,7 @@ mod chained {
|
|||
}
|
||||
|
||||
impl<K: copy ToStr, V: ToStr copy> t<K, V>: ToStr {
|
||||
fn to_writer(wr: io::writer) {
|
||||
fn to_writer(wr: io::Writer) {
|
||||
if self.count == 0u {
|
||||
wr.write_str(~"{}");
|
||||
return;
|
||||
|
|
@ -389,6 +389,12 @@ fn hashmap<K: const, V: copy>(+hasher: hashfn<K>, +eqer: eqfn<K>)
|
|||
chained::mk(hasher, eqer)
|
||||
}
|
||||
|
||||
/// Construct a hashmap for string-slice keys
|
||||
fn str_slice_hash<V: copy>() -> hashmap<&str, V> {
|
||||
return hashmap(|s| hash::hash_str(*s) as uint,
|
||||
|a,b| str::eq_slice(*a, *b));
|
||||
}
|
||||
|
||||
/// Construct a hashmap for string keys
|
||||
fn str_hash<V: copy>() -> hashmap<~str, V> {
|
||||
return hashmap(str::hash, str::eq);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import future_spawn = future::spawn;
|
|||
// should be able to, but can't atm, replace w/ result::{result, extensions};
|
||||
import result::*;
|
||||
import libc::size_t;
|
||||
import io::{reader, writer};
|
||||
import io::{Reader, Writer};
|
||||
|
||||
// tcp interfaces
|
||||
export tcp_socket;
|
||||
|
|
@ -752,7 +752,7 @@ impl tcp_socket {
|
|||
}
|
||||
|
||||
/// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket`
|
||||
impl @tcp_socket_buf: io::reader {
|
||||
impl @tcp_socket_buf: io::Reader {
|
||||
fn read(buf: &[mut u8], len: uint) -> uint {
|
||||
// Loop until our buffer has enough data in it for us to read from.
|
||||
while self.data.buf.len() < len {
|
||||
|
|
@ -795,7 +795,7 @@ impl @tcp_socket_buf: io::reader {
|
|||
fn eof() -> bool {
|
||||
false // noop
|
||||
}
|
||||
fn seek(dist: int, seek: io::seek_style) {
|
||||
fn seek(dist: int, seek: io::SeekStyle) {
|
||||
log(debug, fmt!{"tcp_socket_buf seek stub %? %?", dist, seek});
|
||||
// noop
|
||||
}
|
||||
|
|
@ -805,7 +805,7 @@ impl @tcp_socket_buf: io::reader {
|
|||
}
|
||||
|
||||
/// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket`
|
||||
impl @tcp_socket_buf: io::writer {
|
||||
impl @tcp_socket_buf: io::Writer {
|
||||
fn write(data: &[const u8]) unsafe {
|
||||
let socket_data_ptr =
|
||||
ptr::addr_of(*((*(self.data)).sock).socket_data);
|
||||
|
|
@ -817,7 +817,7 @@ impl @tcp_socket_buf: io::writer {
|
|||
err_data.err_name, err_data.err_msg});
|
||||
}
|
||||
}
|
||||
fn seek(dist: int, seek: io::seek_style) {
|
||||
fn seek(dist: int, seek: io::SeekStyle) {
|
||||
log(debug, fmt!{"tcp_socket_buf seek stub %? %?", dist, seek});
|
||||
// noop
|
||||
}
|
||||
|
|
@ -827,8 +827,8 @@ impl @tcp_socket_buf: io::writer {
|
|||
fn flush() -> int {
|
||||
0
|
||||
}
|
||||
fn get_type() -> io::writer_type {
|
||||
io::file
|
||||
fn get_type() -> io::WriterType {
|
||||
io::File
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1441,11 +1441,11 @@ mod test {
|
|||
assert false;
|
||||
}
|
||||
let sock_buf = @socket_buf(result::unwrap(conn_result));
|
||||
buf_write(sock_buf as io::writer, expected_req);
|
||||
buf_write(sock_buf as io::Writer, expected_req);
|
||||
|
||||
// so contrived!
|
||||
let actual_resp = do str::as_bytes(expected_resp) |resp_buf| {
|
||||
buf_read(sock_buf as io::reader,
|
||||
buf_read(sock_buf as io::Reader,
|
||||
vec::len(resp_buf))
|
||||
};
|
||||
|
||||
|
|
@ -1458,7 +1458,7 @@ mod test {
|
|||
assert str::contains(actual_resp, expected_resp);
|
||||
}
|
||||
|
||||
fn buf_write(+w: io::writer, val: ~str) {
|
||||
fn buf_write(+w: io::Writer, val: ~str) {
|
||||
log(debug, fmt!{"BUF_WRITE: val len %?", str::len(val)});
|
||||
do str::byte_slice(val) |b_slice| {
|
||||
log(debug, fmt!{"BUF_WRITE: b_slice len %?",
|
||||
|
|
@ -1467,7 +1467,7 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
fn buf_read(+r: io::reader, len: uint) -> ~str {
|
||||
fn buf_read(+r: io::Reader, len: uint) -> ~str {
|
||||
let new_bytes = r.read_bytes(len);
|
||||
log(debug, fmt!{"in buf_read.. new_bytes len: %?",
|
||||
vec::len(new_bytes)});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import map;
|
||||
import map::{hashmap, str_hash};
|
||||
import io::reader;
|
||||
import io::Reader;
|
||||
import dvec::dvec;
|
||||
|
||||
export url, userinfo, query;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import io::writer;
|
||||
import io::writer_util;
|
||||
import io::Writer;
|
||||
import io::WriterUtil;
|
||||
import serialization::serializer;
|
||||
|
||||
impl writer: serializer {
|
||||
impl Writer: serializer {
|
||||
fn emit_nil() {
|
||||
self.write_str(~"()")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
/**
|
||||
* The concurrency primitives you know and love.
|
||||
*
|
||||
|
|
@ -5,7 +8,7 @@
|
|||
* in std.
|
||||
*/
|
||||
|
||||
export condvar, semaphore, mutex, rwlock;
|
||||
export condvar, semaphore, mutex, rwlock, rwlock_write_mode, rwlock_read_mode;
|
||||
|
||||
// FIXME (#3119) This shouldn't be a thing exported from core.
|
||||
import unsafe::{Exclusive, exclusive};
|
||||
|
|
@ -387,16 +390,17 @@ impl &rwlock {
|
|||
* the meantime (such as unlocking and then re-locking as a reader would
|
||||
* do). The block takes a "write mode token" argument, which can be
|
||||
* transformed into a "read mode token" by calling downgrade(). Example:
|
||||
*
|
||||
* do lock.write_downgrade |write_mode| {
|
||||
* do (&write_mode).write_cond |condvar| {
|
||||
* ... exclusive access ...
|
||||
* }
|
||||
* let read_mode = lock.downgrade(write_mode);
|
||||
* do (&read_mode).read {
|
||||
* ... shared access ...
|
||||
* }
|
||||
* ~~~
|
||||
* do lock.write_downgrade |write_mode| {
|
||||
* do (&write_mode).write_cond |condvar| {
|
||||
* ... exclusive access ...
|
||||
* }
|
||||
* let read_mode = lock.downgrade(write_mode);
|
||||
* do (&read_mode).read {
|
||||
* ... shared access ...
|
||||
* }
|
||||
* }
|
||||
* ~~~
|
||||
*/
|
||||
fn write_downgrade<U>(blk: fn(+rwlock_write_mode) -> U) -> U {
|
||||
// Implementation slightly different from the slicker 'write's above.
|
||||
|
|
@ -413,6 +417,7 @@ impl &rwlock {
|
|||
blk(rwlock_write_mode { lock: self })
|
||||
}
|
||||
|
||||
/// To be called inside of the write_downgrade block.
|
||||
fn downgrade(+token: rwlock_write_mode) -> rwlock_read_mode {
|
||||
if !ptr::ref_eq(self, token.lock) {
|
||||
fail ~"Can't downgrade() with a different rwlock's write_mode!";
|
||||
|
|
@ -498,8 +503,7 @@ struct rwlock_write_mode { lock: &rwlock; drop { } }
|
|||
/// The "read permission" token used for rwlock.write_downgrade().
|
||||
struct rwlock_read_mode { priv lock: &rwlock; drop { } }
|
||||
|
||||
// FIXME(#3145) XXX Region invariance forbids "mode.write(blk)"
|
||||
impl rwlock_write_mode {
|
||||
impl &rwlock_write_mode {
|
||||
/// Access the pre-downgrade rwlock in write mode.
|
||||
fn write<U>(blk: fn() -> U) -> U { blk() }
|
||||
/// Access the pre-downgrade rwlock in write mode with a condvar.
|
||||
|
|
@ -507,7 +511,7 @@ impl rwlock_write_mode {
|
|||
blk(&condvar { sem: &self.lock.access_lock })
|
||||
}
|
||||
}
|
||||
impl rwlock_read_mode {
|
||||
impl &rwlock_read_mode {
|
||||
/// Access the post-downgrade rwlock in read mode.
|
||||
fn read<U>(blk: fn() -> U) -> U { blk() }
|
||||
}
|
||||
|
|
@ -762,9 +766,51 @@ mod tests {
|
|||
assert result.is_err();
|
||||
// child task must have finished by the time try returns
|
||||
do m.lock_cond |cond| {
|
||||
let _woken = cond.signal();
|
||||
// FIXME(#3145) this doesn't work
|
||||
//assert !woken;
|
||||
let woken = cond.signal();
|
||||
assert !woken;
|
||||
}
|
||||
}
|
||||
#[test] #[ignore(cfg(windows))]
|
||||
fn test_mutex_killed_broadcast() {
|
||||
let m = ~mutex();
|
||||
let m2 = ~m.clone();
|
||||
let (c,p) = pipes::stream();
|
||||
|
||||
let result: result::result<(),()> = do task::try {
|
||||
let mut sibling_convos = ~[];
|
||||
for 2.times {
|
||||
let (c,p) = pipes::stream();
|
||||
let c = ~mut some(c);
|
||||
vec::push(sibling_convos, p);
|
||||
let mi = ~m2.clone();
|
||||
// spawn sibling task
|
||||
do task::spawn { // linked
|
||||
do mi.lock_cond |cond| {
|
||||
let c = option::swap_unwrap(c);
|
||||
c.send(()); // tell sibling to go ahead
|
||||
let _z = send_on_failure(c);
|
||||
cond.wait(); // block forever
|
||||
}
|
||||
}
|
||||
}
|
||||
for vec::each(sibling_convos) |p| {
|
||||
let _ = p.recv(); // wait for sibling to get in the mutex
|
||||
}
|
||||
do m2.lock { }
|
||||
c.send(sibling_convos); // let parent wait on all children
|
||||
fail;
|
||||
};
|
||||
assert result.is_err();
|
||||
// child task must have finished by the time try returns
|
||||
for vec::each(p.recv()) |p| { p.recv(); } // wait on all its siblings
|
||||
do m.lock_cond |cond| {
|
||||
let woken = cond.broadcast();
|
||||
assert woken == 0;
|
||||
}
|
||||
struct send_on_failure {
|
||||
c: pipes::chan<()>;
|
||||
new(+c: pipes::chan<()>) { self.c = c; }
|
||||
drop { self.c.send(()); }
|
||||
}
|
||||
}
|
||||
/************************************************************************
|
||||
|
|
@ -777,13 +823,23 @@ mod tests {
|
|||
match mode {
|
||||
read => x.read(blk),
|
||||
write => x.write(blk),
|
||||
downgrade => do x.write_downgrade |mode| { mode.write(blk); },
|
||||
downgrade =>
|
||||
do x.write_downgrade |mode| {
|
||||
// FIXME(#2282)
|
||||
let mode = unsafe { unsafe::transmute_region(&mode) };
|
||||
mode.write(blk);
|
||||
},
|
||||
downgrade_read =>
|
||||
do x.write_downgrade |mode| { x.downgrade(mode).read(blk); },
|
||||
do x.write_downgrade |mode| {
|
||||
let mode = x.downgrade(mode);
|
||||
// FIXME(#2282)
|
||||
let mode = unsafe { unsafe::transmute_region(&mode) };
|
||||
mode.read(blk);
|
||||
},
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
fn test_rwlock_exclusion(x: ~rwlock, mode1: rwlock_mode,
|
||||
fn test_rwlock_exclusion(+x: ~rwlock, mode1: rwlock_mode,
|
||||
mode2: rwlock_mode) {
|
||||
// Test mutual exclusion between readers and writers. Just like the
|
||||
// mutex mutual exclusion test, a ways above.
|
||||
|
|
@ -828,7 +884,7 @@ mod tests {
|
|||
test_rwlock_exclusion(~rwlock(), downgrade, downgrade);
|
||||
}
|
||||
#[cfg(test)]
|
||||
fn test_rwlock_handshake(x: ~rwlock, mode1: rwlock_mode,
|
||||
fn test_rwlock_handshake(+x: ~rwlock, mode1: rwlock_mode,
|
||||
mode2: rwlock_mode, make_mode2_go_first: bool) {
|
||||
// Much like sem_multi_resource.
|
||||
let x2 = ~x.clone();
|
||||
|
|
@ -922,7 +978,11 @@ mod tests {
|
|||
// Much like the mutex broadcast test. Downgrade-enabled.
|
||||
fn lock_cond(x: &rwlock, downgrade: bool, blk: fn(c: &condvar)) {
|
||||
if downgrade {
|
||||
do x.write_downgrade |mode| { mode.write_cond(blk) }
|
||||
do x.write_downgrade |mode| {
|
||||
// FIXME(#2282)
|
||||
let mode = unsafe { unsafe::transmute_region(&mode) };
|
||||
mode.write_cond(blk)
|
||||
}
|
||||
} else {
|
||||
x.write_cond(blk)
|
||||
}
|
||||
|
|
@ -1009,9 +1069,8 @@ mod tests {
|
|||
do x.write_downgrade |xwrite| {
|
||||
let mut xopt = some(xwrite);
|
||||
do y.write_downgrade |_ywrite| {
|
||||
do y.downgrade(option::swap_unwrap(&mut xopt)).read {
|
||||
error!("oops, y.downgrade(x) should have failed!");
|
||||
}
|
||||
y.downgrade(option::swap_unwrap(&mut xopt));
|
||||
error!("oops, y.downgrade(x) should have failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ const color_bright_magenta: u8 = 13u8;
|
|||
const color_bright_cyan: u8 = 14u8;
|
||||
const color_bright_white: u8 = 15u8;
|
||||
|
||||
fn esc(writer: io::writer) { writer.write(~[0x1bu8, '[' as u8]); }
|
||||
fn esc(writer: io::Writer) { writer.write(~[0x1bu8, '[' as u8]); }
|
||||
|
||||
/// Reset the foreground and background colors to default
|
||||
fn reset(writer: io::writer) {
|
||||
fn reset(writer: io::Writer) {
|
||||
esc(writer);
|
||||
writer.write(~['0' as u8, 'm' as u8]);
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ fn color_supported() -> bool {
|
|||
};
|
||||
}
|
||||
|
||||
fn set_color(writer: io::writer, first_char: u8, color: u8) {
|
||||
fn set_color(writer: io::Writer, first_char: u8, color: u8) {
|
||||
assert (color < 16u8);
|
||||
esc(writer);
|
||||
let mut color = color;
|
||||
|
|
@ -55,12 +55,12 @@ fn set_color(writer: io::writer, first_char: u8, color: u8) {
|
|||
}
|
||||
|
||||
/// Set the foreground color
|
||||
fn fg(writer: io::writer, color: u8) {
|
||||
fn fg(writer: io::Writer, color: u8) {
|
||||
return set_color(writer, '3' as u8, color);
|
||||
}
|
||||
|
||||
/// Set the background color
|
||||
fn bg(writer: io::writer, color: u8) {
|
||||
fn bg(writer: io::Writer, color: u8) {
|
||||
return set_color(writer, '4' as u8, color);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import either::either;
|
||||
import result::{ok, err};
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import libc::size_t;
|
||||
import task::task_builder;
|
||||
|
||||
|
|
@ -91,8 +91,8 @@ fn parse_opts(args: ~[~str]) -> opt_res {
|
|||
enum test_result { tr_ok, tr_failed, tr_ignored, }
|
||||
|
||||
type console_test_state =
|
||||
@{out: io::writer,
|
||||
log_out: option<io::writer>,
|
||||
@{out: io::Writer,
|
||||
log_out: option<io::Writer>,
|
||||
use_color: bool,
|
||||
mut total: uint,
|
||||
mut passed: uint,
|
||||
|
|
@ -141,7 +141,7 @@ fn run_tests_console(opts: test_opts,
|
|||
|
||||
let log_out = match opts.logfile {
|
||||
some(path) => match io::file_writer(path,
|
||||
~[io::create, io::truncate]) {
|
||||
~[io::Create, io::Truncate]) {
|
||||
result::ok(w) => some(w),
|
||||
result::err(s) => {
|
||||
fail(fmt!{"can't open output file: %s", s})
|
||||
|
|
@ -179,7 +179,7 @@ fn run_tests_console(opts: test_opts,
|
|||
|
||||
return success;
|
||||
|
||||
fn write_log(out: io::writer, result: test_result, test: test_desc) {
|
||||
fn write_log(out: io::Writer, result: test_result, test: test_desc) {
|
||||
out.write_line(fmt!{"%s %s",
|
||||
match result {
|
||||
tr_ok => ~"ok",
|
||||
|
|
@ -188,19 +188,19 @@ fn run_tests_console(opts: test_opts,
|
|||
}, test.name});
|
||||
}
|
||||
|
||||
fn write_ok(out: io::writer, use_color: bool) {
|
||||
fn write_ok(out: io::Writer, use_color: bool) {
|
||||
write_pretty(out, ~"ok", term::color_green, use_color);
|
||||
}
|
||||
|
||||
fn write_failed(out: io::writer, use_color: bool) {
|
||||
fn write_failed(out: io::Writer, use_color: bool) {
|
||||
write_pretty(out, ~"FAILED", term::color_red, use_color);
|
||||
}
|
||||
|
||||
fn write_ignored(out: io::writer, use_color: bool) {
|
||||
fn write_ignored(out: io::Writer, use_color: bool) {
|
||||
write_pretty(out, ~"ignored", term::color_yellow, use_color);
|
||||
}
|
||||
|
||||
fn write_pretty(out: io::writer, word: ~str, color: u8, use_color: bool) {
|
||||
fn write_pretty(out: io::Writer, word: ~str, color: u8, use_color: bool) {
|
||||
if use_color && term::color_supported() {
|
||||
term::fg(out, color);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import libc::{c_char, c_int, c_long, size_t, time_t};
|
||||
import io::reader;
|
||||
import io::Reader;
|
||||
import result::{result, ok, err};
|
||||
|
||||
export
|
||||
|
|
|
|||
|
|
@ -600,7 +600,7 @@ enum self_ty_ {
|
|||
sty_static, // no self: static method
|
||||
sty_by_ref, // old by-reference self: ``
|
||||
sty_value, // by-value self: `self`
|
||||
sty_region(@region, mutability), // by-region self: `&self`
|
||||
sty_region(mutability), // by-region self: `&self`
|
||||
sty_box(mutability), // by-managed-pointer self: `@self`
|
||||
sty_uniq(mutability) // by-unique-pointer self: `~self`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import std::term;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import codemap::span;
|
||||
|
||||
export emitter, emit;
|
||||
|
|
@ -166,7 +166,7 @@ fn diagnosticcolor(lvl: level) -> u8 {
|
|||
|
||||
fn print_diagnostic(topic: ~str, lvl: level, msg: ~str) {
|
||||
let use_color = term::color_supported() &&
|
||||
io::stderr().get_type() == io::screen;
|
||||
io::stderr().get_type() == io::Screen;
|
||||
if str::is_not_empty(topic) {
|
||||
io::stderr().write_str(fmt!{"%s ", topic});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import base::*;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, tt: ~[ast::token_tree])
|
||||
-> base::mac_result {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ fn expand_include_bin(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
|
|||
}
|
||||
}
|
||||
|
||||
fn res_rel_file(cx: ext_ctxt, sp: codemap::span, +arg: path) -> path {
|
||||
fn res_rel_file(cx: ext_ctxt, sp: codemap::span, +arg: Path) -> Path {
|
||||
// NB: relative paths are resolved relative to the compilation unit
|
||||
if !path::path_is_absolute(arg) {
|
||||
let cu = codemap::span_to_filename(sp, cx.codemap());
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
|
|||
};
|
||||
|
||||
// Given `lhses` and `rhses`, this is the new macro we create
|
||||
fn generic_extension(cx: ext_ctxt, sp: span, name: ident,
|
||||
fn generic_extension(cx: ext_ctxt, sp: span, _name: ident,
|
||||
arg: ~[ast::token_tree],
|
||||
lhses: ~[@named_match], rhses: ~[@named_match])
|
||||
-> mac_result {
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ type lit = {lit: ~str, pos: uint};
|
|||
|
||||
fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
|
||||
path: ~str,
|
||||
srdr: io::reader) ->
|
||||
srdr: io::Reader) ->
|
||||
{cmnts: ~[cmnt], lits: ~[lit]} {
|
||||
let src = @str::from_bytes(srdr.read_whole_stream());
|
||||
let itr = @interner::mk::<@~str>(
|
||||
|
|
|
|||
|
|
@ -111,6 +111,12 @@ enum item_or_view_item {
|
|||
iovi_view_item(@view_item)
|
||||
}
|
||||
|
||||
enum view_item_parse_mode {
|
||||
VIEW_ITEMS_AND_ITEMS_ALLOWED,
|
||||
VIEW_ITEMS_ALLOWED,
|
||||
IMPORTS_AND_ITEMS_ALLOWED
|
||||
}
|
||||
|
||||
/* The expr situation is not as complex as I thought it would be.
|
||||
The important thing is to make sure that lookahead doesn't balk
|
||||
at INTERPOLATED tokens */
|
||||
|
|
@ -2054,7 +2060,7 @@ class parser {
|
|||
|
||||
let item_attrs = vec::append(first_item_attrs, item_attrs);
|
||||
|
||||
match self.parse_item_or_view_item(item_attrs) {
|
||||
match self.parse_item_or_view_item(item_attrs, true) {
|
||||
iovi_item(i) => {
|
||||
let mut hi = i.span.hi;
|
||||
let decl = @spanned(lo, hi, decl_item(i));
|
||||
|
|
@ -2141,8 +2147,17 @@ class parser {
|
|||
+first_item_attrs: ~[attribute]) -> blk {
|
||||
let mut stmts = ~[];
|
||||
let mut expr = none;
|
||||
let {attrs_remaining, view_items} =
|
||||
self.parse_view(first_item_attrs, true);
|
||||
|
||||
let {attrs_remaining, view_items, items: items} =
|
||||
self.parse_items_and_view_items(first_item_attrs,
|
||||
IMPORTS_AND_ITEMS_ALLOWED);
|
||||
|
||||
for items.each |item| {
|
||||
let decl = @spanned(item.span.lo, item.span.hi, decl_item(item));
|
||||
push(stmts, @spanned(item.span.lo, item.span.hi,
|
||||
stmt_decl(decl, self.get_id())));
|
||||
}
|
||||
|
||||
let mut initial_attrs = attrs_remaining;
|
||||
|
||||
if self.token == token::RBRACE && !vec::is_empty(initial_attrs) {
|
||||
|
|
@ -2285,29 +2300,7 @@ class parser {
|
|||
self.bump();
|
||||
let mutability = self.parse_mutability();
|
||||
self.expect_self_ident();
|
||||
|
||||
// Parse an explicit region, if possible.
|
||||
let region_name;
|
||||
match copy self.token {
|
||||
token::BINOP(token::SLASH) => {
|
||||
self.bump();
|
||||
match copy self.token {
|
||||
token::IDENT(sid, false) => {
|
||||
self.bump();
|
||||
region_name = some(self.get_str(sid));
|
||||
}
|
||||
_ => {
|
||||
region_name = none;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
region_name = none;
|
||||
}
|
||||
}
|
||||
|
||||
let region = self.region_from_name(region_name);
|
||||
self_ty = sty_region(region, mutability);
|
||||
self_ty = sty_region(mutability);
|
||||
} else {
|
||||
self_ty = sty_by_ref;
|
||||
}
|
||||
|
|
@ -2709,9 +2702,11 @@ class parser {
|
|||
fn parse_mod_items(term: token::token,
|
||||
+first_item_attrs: ~[attribute]) -> _mod {
|
||||
// Shouldn't be any view items since we've already parsed an item attr
|
||||
let {attrs_remaining, view_items} =
|
||||
self.parse_view(first_item_attrs, false);
|
||||
let mut items: ~[@item] = ~[];
|
||||
let {attrs_remaining, view_items, items: starting_items} =
|
||||
self.parse_items_and_view_items(first_item_attrs,
|
||||
VIEW_ITEMS_AND_ITEMS_ALLOWED);
|
||||
let mut items: ~[@item] = move starting_items;
|
||||
|
||||
let mut first = true;
|
||||
while self.token != term {
|
||||
let mut attrs = self.parse_outer_attributes();
|
||||
|
|
@ -2721,7 +2716,7 @@ class parser {
|
|||
}
|
||||
debug!("parse_mod_items: parse_item_or_view_item(attrs=%?)",
|
||||
attrs);
|
||||
match self.parse_item_or_view_item(attrs) {
|
||||
match self.parse_item_or_view_item(attrs, true) {
|
||||
iovi_item(item) => vec::push(items, item),
|
||||
iovi_view_item(view_item) => {
|
||||
self.span_fatal(view_item.span, ~"view items must be \
|
||||
|
|
@ -2797,8 +2792,10 @@ class parser {
|
|||
fn parse_foreign_mod_items(+first_item_attrs: ~[attribute]) ->
|
||||
foreign_mod {
|
||||
// Shouldn't be any view items since we've already parsed an item attr
|
||||
let {attrs_remaining, view_items} =
|
||||
self.parse_view(first_item_attrs, false);
|
||||
let {attrs_remaining, view_items, items: _} =
|
||||
self.parse_items_and_view_items(first_item_attrs,
|
||||
VIEW_ITEMS_ALLOWED);
|
||||
|
||||
let mut items: ~[@foreign_item] = ~[];
|
||||
let mut initial_attrs = attrs_remaining;
|
||||
while self.token != token::RBRACE {
|
||||
|
|
@ -2813,7 +2810,8 @@ class parser {
|
|||
|
||||
fn parse_item_foreign_mod(lo: uint,
|
||||
visibility: visibility,
|
||||
attrs: ~[attribute])
|
||||
attrs: ~[attribute],
|
||||
items_allowed: bool)
|
||||
-> item_or_view_item {
|
||||
if self.is_keyword(~"mod") {
|
||||
self.expect_keyword(~"mod");
|
||||
|
|
@ -2823,7 +2821,7 @@ class parser {
|
|||
let ident = self.parse_ident();
|
||||
|
||||
// extern mod { ... }
|
||||
if self.eat(token::LBRACE) {
|
||||
if items_allowed && self.eat(token::LBRACE) {
|
||||
let extra_attrs = self.parse_inner_attrs_and_next();
|
||||
let m = self.parse_foreign_mod_items(extra_attrs.next);
|
||||
self.expect(token::RBRACE);
|
||||
|
|
@ -2836,6 +2834,7 @@ class parser {
|
|||
|
||||
// extern mod foo;
|
||||
let metadata = self.parse_optional_meta();
|
||||
self.expect(token::SEMI);
|
||||
return iovi_view_item(@{
|
||||
node: view_item_use(ident, metadata, self.get_id()),
|
||||
attrs: attrs,
|
||||
|
|
@ -3033,7 +3032,8 @@ class parser {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_item_or_view_item(+attrs: ~[attribute]) -> item_or_view_item {
|
||||
fn parse_item_or_view_item(+attrs: ~[attribute], items_allowed: bool)
|
||||
-> item_or_view_item {
|
||||
maybe_whole!{iovi self,nt_item};
|
||||
let lo = self.span.lo;
|
||||
|
||||
|
|
@ -3046,25 +3046,26 @@ class parser {
|
|||
visibility = inherited;
|
||||
}
|
||||
|
||||
if self.eat_keyword(~"const") {
|
||||
if items_allowed && self.eat_keyword(~"const") {
|
||||
let (ident, item_, extra_attrs) = self.parse_item_const();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.is_keyword(~"fn") &&
|
||||
} else if items_allowed &&
|
||||
self.is_keyword(~"fn") &&
|
||||
!self.fn_expr_lookahead(self.look_ahead(1u)) {
|
||||
self.bump();
|
||||
let (ident, item_, extra_attrs) = self.parse_item_fn(impure_fn);
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"pure") {
|
||||
} else if items_allowed && self.eat_keyword(~"pure") {
|
||||
self.expect_keyword(~"fn");
|
||||
let (ident, item_, extra_attrs) = self.parse_item_fn(pure_fn);
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.is_keyword(~"unsafe")
|
||||
} else if items_allowed && self.is_keyword(~"unsafe")
|
||||
&& self.look_ahead(1u) != token::LBRACE {
|
||||
self.bump();
|
||||
self.expect_keyword(~"fn");
|
||||
|
|
@ -3073,8 +3074,7 @@ class parser {
|
|||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"extern") {
|
||||
// XXX: "extern mod foo;" syntax as a "use" replacement.
|
||||
if self.eat_keyword(~"fn") {
|
||||
if items_allowed && self.eat_keyword(~"fn") {
|
||||
let (ident, item_, extra_attrs) =
|
||||
self.parse_item_fn(extern_fn);
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident,
|
||||
|
|
@ -3082,45 +3082,49 @@ class parser {
|
|||
maybe_append(attrs,
|
||||
extra_attrs)));
|
||||
}
|
||||
return self.parse_item_foreign_mod(lo, visibility, attrs);
|
||||
} else if self.eat_keyword(~"mod") || self.eat_keyword(~"module") {
|
||||
return self.parse_item_foreign_mod(lo, visibility, attrs,
|
||||
items_allowed);
|
||||
} else if items_allowed && (self.eat_keyword(~"mod") ||
|
||||
self.eat_keyword(~"module")) {
|
||||
let (ident, item_, extra_attrs) = self.parse_item_mod();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"type") {
|
||||
} else if items_allowed && self.eat_keyword(~"type") {
|
||||
let (ident, item_, extra_attrs) = self.parse_item_type();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"enum") {
|
||||
} else if items_allowed && self.eat_keyword(~"enum") {
|
||||
let (ident, item_, extra_attrs) = self.parse_item_enum();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"iface") {
|
||||
} else if items_allowed && self.eat_keyword(~"iface") {
|
||||
self.warn(~"`iface` is deprecated; use `trait`");
|
||||
let (ident, item_, extra_attrs) = self.parse_item_trait();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"trait") {
|
||||
} else if items_allowed && self.eat_keyword(~"trait") {
|
||||
let (ident, item_, extra_attrs) = self.parse_item_trait();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"impl") {
|
||||
} else if items_allowed && self.eat_keyword(~"impl") {
|
||||
let (ident, item_, extra_attrs) = self.parse_item_impl();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"class") || self.eat_keyword(~"struct") {
|
||||
} else if items_allowed &&
|
||||
(self.eat_keyword(~"class") || self.eat_keyword(~"struct")) {
|
||||
let (ident, item_, extra_attrs) = self.parse_item_class();
|
||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs)));
|
||||
} else if self.eat_keyword(~"use") {
|
||||
let view_item = self.parse_use();
|
||||
self.expect(token::SEMI);
|
||||
return iovi_view_item(@{
|
||||
node: view_item,
|
||||
attrs: attrs,
|
||||
|
|
@ -3129,6 +3133,7 @@ class parser {
|
|||
});
|
||||
} else if self.eat_keyword(~"import") {
|
||||
let view_paths = self.parse_view_paths();
|
||||
self.expect(token::SEMI);
|
||||
return iovi_view_item(@{
|
||||
node: view_item_import(view_paths),
|
||||
attrs: attrs,
|
||||
|
|
@ -3137,15 +3142,16 @@ class parser {
|
|||
});
|
||||
} else if self.eat_keyword(~"export") {
|
||||
let view_paths = self.parse_view_paths();
|
||||
self.expect(token::SEMI);
|
||||
return iovi_view_item(@{
|
||||
node: view_item_export(view_paths),
|
||||
attrs: attrs,
|
||||
vis: visibility,
|
||||
span: mk_sp(lo, self.last_span.hi)
|
||||
});
|
||||
} else if !self.is_any_keyword(copy self.token)
|
||||
} else if items_allowed && (!self.is_any_keyword(copy self.token)
|
||||
&& self.look_ahead(1) == token::NOT
|
||||
&& is_plain_ident(self.look_ahead(2)) {
|
||||
&& is_plain_ident(self.look_ahead(2))) {
|
||||
// item macro.
|
||||
let pth = self.parse_path_without_tps();
|
||||
self.expect(token::NOT);
|
||||
|
|
@ -3173,7 +3179,7 @@ class parser {
|
|||
}
|
||||
|
||||
fn parse_item(+attrs: ~[attribute]) -> option<@ast::item> {
|
||||
match self.parse_item_or_view_item(attrs) {
|
||||
match self.parse_item_or_view_item(attrs, true) {
|
||||
iovi_none =>
|
||||
none,
|
||||
iovi_view_item(_) =>
|
||||
|
|
@ -3296,18 +3302,53 @@ class parser {
|
|||
vis: vis, span: mk_sp(lo, self.last_span.hi)}
|
||||
}
|
||||
|
||||
fn parse_view(+first_item_attrs: ~[attribute],
|
||||
only_imports: bool) -> {attrs_remaining: ~[attribute],
|
||||
view_items: ~[@view_item]} {
|
||||
fn parse_items_and_view_items(+first_item_attrs: ~[attribute],
|
||||
mode: view_item_parse_mode)
|
||||
-> {attrs_remaining: ~[attribute],
|
||||
view_items: ~[@view_item],
|
||||
items: ~[@item]} {
|
||||
let mut attrs = vec::append(first_item_attrs,
|
||||
self.parse_outer_attributes());
|
||||
let mut items = ~[];
|
||||
while if only_imports { self.is_keyword(~"import") }
|
||||
else { self.is_view_item() } {
|
||||
vec::push(items, self.parse_view_item(attrs));
|
||||
|
||||
let items_allowed;
|
||||
match mode {
|
||||
VIEW_ITEMS_AND_ITEMS_ALLOWED | IMPORTS_AND_ITEMS_ALLOWED =>
|
||||
items_allowed = true,
|
||||
VIEW_ITEMS_ALLOWED =>
|
||||
items_allowed = false
|
||||
}
|
||||
|
||||
let (view_items, items) = (dvec(), dvec());
|
||||
loop {
|
||||
match self.parse_item_or_view_item(attrs, items_allowed) {
|
||||
iovi_none =>
|
||||
break,
|
||||
iovi_view_item(view_item) => {
|
||||
match mode {
|
||||
VIEW_ITEMS_AND_ITEMS_ALLOWED |
|
||||
VIEW_ITEMS_ALLOWED => {}
|
||||
IMPORTS_AND_ITEMS_ALLOWED =>
|
||||
match view_item.node {
|
||||
view_item_import(_) => {}
|
||||
view_item_export(_) | view_item_use(*) =>
|
||||
self.fatal(~"exports and \"extern mod\" \
|
||||
declarations are not \
|
||||
allowed here")
|
||||
}
|
||||
}
|
||||
view_items.push(view_item);
|
||||
}
|
||||
iovi_item(item) => {
|
||||
assert items_allowed;
|
||||
items.push(item)
|
||||
}
|
||||
}
|
||||
attrs = self.parse_outer_attributes();
|
||||
}
|
||||
{attrs_remaining: attrs, view_items: items}
|
||||
|
||||
{attrs_remaining: attrs,
|
||||
view_items: vec::from_mut(dvec::unwrap(view_items)),
|
||||
items: vec::from_mut(dvec::unwrap(items))}
|
||||
}
|
||||
|
||||
// Parses a source module as a crate
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import dvec::dvec;
|
||||
|
||||
/*
|
||||
|
|
@ -95,7 +95,7 @@ type print_stack_elt = {offset: int, pbreak: print_stack_break};
|
|||
|
||||
const size_infinity: int = 0xffff;
|
||||
|
||||
fn mk_printer(out: io::writer, linewidth: uint) -> printer {
|
||||
fn mk_printer(out: io::Writer, linewidth: uint) -> printer {
|
||||
// Yes 3, it makes the ring buffers big enough to never
|
||||
// fall behind.
|
||||
let n: uint = 3u * linewidth;
|
||||
|
|
@ -201,7 +201,7 @@ fn mk_printer(out: io::writer, linewidth: uint) -> printer {
|
|||
* called 'print'.
|
||||
*/
|
||||
type printer_ = {
|
||||
out: io::writer,
|
||||
out: io::Writer,
|
||||
buf_len: uint,
|
||||
mut margin: int, // width of lines we're constrained to
|
||||
mut space: int, // number of spaces left on line
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ fn end(s: ps) {
|
|||
pp::end(s.s);
|
||||
}
|
||||
|
||||
fn rust_printer(writer: io::writer) -> ps {
|
||||
fn rust_printer(writer: io::Writer) -> ps {
|
||||
return @{s: pp::mk_printer(writer, default_columns),
|
||||
cm: none::<codemap>,
|
||||
intr: @interner::mk::<@~str>(|x| str::hash(*x),
|
||||
|
|
@ -61,7 +61,7 @@ fn rust_printer(writer: io::writer) -> ps {
|
|||
ann: no_ann()};
|
||||
}
|
||||
|
||||
fn unexpanded_rust_printer(writer: io::writer, intr: ident_interner) -> ps {
|
||||
fn unexpanded_rust_printer(writer: io::Writer, intr: ident_interner) -> ps {
|
||||
return @{s: pp::mk_printer(writer, default_columns),
|
||||
cm: none::<codemap>,
|
||||
intr: intr,
|
||||
|
|
@ -83,8 +83,8 @@ const default_columns: uint = 78u;
|
|||
// copy forward.
|
||||
fn print_crate(cm: codemap, intr: @interner::interner<@~str>,
|
||||
span_diagnostic: diagnostic::span_handler,
|
||||
crate: @ast::crate, filename: ~str, in: io::reader,
|
||||
out: io::writer, ann: pp_ann, is_expanded: bool) {
|
||||
crate: @ast::crate, filename: ~str, in: io::Reader,
|
||||
out: io::Writer, ann: pp_ann, is_expanded: bool) {
|
||||
let r = comments::gather_comments_and_literals(span_diagnostic,
|
||||
filename, in);
|
||||
let s =
|
||||
|
|
@ -838,6 +838,11 @@ fn print_block_unclosed(s: ps, blk: ast::blk) {
|
|||
false);
|
||||
}
|
||||
|
||||
fn print_block_unclosed_indent(s: ps, blk: ast::blk, indented: uint) {
|
||||
print_possibly_embedded_block_(s, blk, block_normal, indented, ~[],
|
||||
false);
|
||||
}
|
||||
|
||||
fn print_block_with_attrs(s: ps, blk: ast::blk, attrs: ~[ast::attribute]) {
|
||||
print_possibly_embedded_block_(s, blk, block_normal, indent_unit, attrs,
|
||||
true);
|
||||
|
|
@ -1178,8 +1183,16 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
|
|||
assert arm.body.node.rules == ast::default_blk;
|
||||
match arm.body.node.expr {
|
||||
some(expr) => {
|
||||
end(s); // close the ibox for the pattern
|
||||
print_expr(s, expr);
|
||||
match expr.node {
|
||||
ast::expr_block(blk) => {
|
||||
// the block will close the pattern's ibox
|
||||
print_block_unclosed_indent(s, blk, alt_indent_unit);
|
||||
}
|
||||
_ => {
|
||||
end(s); // close the ibox for the pattern
|
||||
print_expr(s, expr);
|
||||
}
|
||||
}
|
||||
if !expr_is_simple_block(expr)
|
||||
&& i < len - 1 {
|
||||
word(s.s, ~",");
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import lib::llvm::{ModuleRef, mk_pass_manager, mk_target_data, True, False,
|
|||
FileType};
|
||||
import metadata::filesearch;
|
||||
import syntax::ast_map::{path, path_mod, path_name};
|
||||
import io::{writer, writer_util};
|
||||
import io::{Writer, WriterUtil};
|
||||
|
||||
enum output_type {
|
||||
output_type_none,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ fn get_rpath_flags(sess: session::session, out_filename: ~str) -> ~[~str] {
|
|||
rpaths_to_flags(rpaths)
|
||||
}
|
||||
|
||||
fn get_sysroot_absolute_rt_lib(sess: session::session) -> path::path {
|
||||
fn get_sysroot_absolute_rt_lib(sess: session::session) -> path::Path {
|
||||
let mut path = vec::append(~[sess.filesearch.sysroot()],
|
||||
filesearch::relative_target_lib_path(
|
||||
sess.opts.target_triple));
|
||||
|
|
@ -48,8 +48,8 @@ fn rpaths_to_flags(rpaths: ~[~str]) -> ~[~str] {
|
|||
vec::map(rpaths, |rpath| fmt!{"-Wl,-rpath,%s",rpath} )
|
||||
}
|
||||
|
||||
fn get_rpaths(os: session::os, cwd: path::path, sysroot: path::path,
|
||||
output: path::path, libs: ~[path::path],
|
||||
fn get_rpaths(os: session::os, cwd: path::Path, sysroot: path::Path,
|
||||
output: path::Path, libs: ~[path::Path],
|
||||
target_triple: ~str) -> ~[~str] {
|
||||
debug!{"cwd: %s", cwd};
|
||||
debug!{"sysroot: %s", sysroot};
|
||||
|
|
@ -93,18 +93,18 @@ fn get_rpaths(os: session::os, cwd: path::path, sysroot: path::path,
|
|||
}
|
||||
|
||||
fn get_rpaths_relative_to_output(os: session::os,
|
||||
cwd: path::path,
|
||||
output: path::path,
|
||||
libs: ~[path::path]) -> ~[~str] {
|
||||
cwd: path::Path,
|
||||
output: path::Path,
|
||||
libs: ~[path::Path]) -> ~[~str] {
|
||||
vec::map(libs, |a| {
|
||||
get_rpath_relative_to_output(os, cwd, output, a)
|
||||
})
|
||||
}
|
||||
|
||||
fn get_rpath_relative_to_output(os: session::os,
|
||||
cwd: path::path,
|
||||
output: path::path,
|
||||
&&lib: path::path) -> ~str {
|
||||
cwd: path::Path,
|
||||
output: path::Path,
|
||||
&&lib: path::Path) -> ~str {
|
||||
assert not_win32(os);
|
||||
|
||||
// Mac doesn't appear to support $ORIGIN
|
||||
|
|
@ -121,7 +121,7 @@ fn get_rpath_relative_to_output(os: session::os,
|
|||
}
|
||||
|
||||
// Find the relative path from one file to another
|
||||
fn get_relative_to(abs1: path::path, abs2: path::path) -> path::path {
|
||||
fn get_relative_to(abs1: path::Path, abs2: path::Path) -> path::Path {
|
||||
assert path::path_is_absolute(abs1);
|
||||
assert path::path_is_absolute(abs2);
|
||||
debug!{"finding relative path from %s to %s",
|
||||
|
|
@ -154,15 +154,15 @@ fn get_relative_to(abs1: path::path, abs2: path::path) -> path::path {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_absolute_rpaths(cwd: path::path, libs: ~[path::path]) -> ~[~str] {
|
||||
fn get_absolute_rpaths(cwd: path::Path, libs: ~[path::Path]) -> ~[~str] {
|
||||
vec::map(libs, |a| get_absolute_rpath(cwd, a) )
|
||||
}
|
||||
|
||||
fn get_absolute_rpath(cwd: path::path, &&lib: path::path) -> ~str {
|
||||
fn get_absolute_rpath(cwd: path::Path, &&lib: path::Path) -> ~str {
|
||||
path::dirname(get_absolute(cwd, lib))
|
||||
}
|
||||
|
||||
fn get_absolute(cwd: path::path, lib: path::path) -> path::path {
|
||||
fn get_absolute(cwd: path::Path, lib: path::Path) -> path::Path {
|
||||
if path::path_is_absolute(lib) {
|
||||
lib
|
||||
} else {
|
||||
|
|
@ -170,7 +170,7 @@ fn get_absolute(cwd: path::path, lib: path::path) -> path::path {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_install_prefix_rpath(cwd: path::path, target_triple: ~str) -> ~str {
|
||||
fn get_install_prefix_rpath(cwd: path::Path, target_triple: ~str) -> ~str {
|
||||
let install_prefix = env!{"CFG_PREFIX"};
|
||||
|
||||
if install_prefix == ~"" {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import util::ppaux;
|
|||
import back::link;
|
||||
import result::{ok, err};
|
||||
import std::getopts;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import getopts::{optopt, optmulti, optflag, optflagopt, opt_present};
|
||||
import back::{x86, x86_64};
|
||||
import std::map::hashmap;
|
||||
|
|
@ -701,7 +701,7 @@ fn early_error(emitter: diagnostic::emitter, msg: ~str) -> ! {
|
|||
fail;
|
||||
}
|
||||
|
||||
fn list_metadata(sess: session, path: ~str, out: io::writer) {
|
||||
fn list_metadata(sess: session, path: ~str, out: io::Writer) {
|
||||
metadata::loader::list_file_metadata(
|
||||
session::sess_os_to_meta_os(sess.targ_cfg.os), path, out);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
import std::{ebml, map};
|
||||
import std::map::{hashmap, str_hash};
|
||||
import dvec::dvec;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import syntax::{ast, ast_util};
|
||||
import syntax::attr;
|
||||
import middle::ty;
|
||||
|
|
@ -598,22 +598,7 @@ fn get_self_ty(item: ebml::doc) -> ast::self_ty_ {
|
|||
'v' => { return ast::sty_value; }
|
||||
'@' => { return ast::sty_box(get_mutability(string[1])); }
|
||||
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
|
||||
'&' => {
|
||||
let mutability = get_mutability(string[1]);
|
||||
|
||||
let region;
|
||||
let region_doc =
|
||||
ebml::get_doc(self_type_doc,
|
||||
tag_item_trait_method_self_ty_region);
|
||||
let region_string = str::from_bytes(ebml::doc_data(region_doc));
|
||||
if region_string == ~"" {
|
||||
region = ast::re_anon;
|
||||
} else {
|
||||
region = ast::re_named(@region_string);
|
||||
}
|
||||
|
||||
return ast::sty_region(@{ id: 0, node: region }, mutability);
|
||||
}
|
||||
'&' => { return ast::sty_region(get_mutability(string[1])); }
|
||||
_ => {
|
||||
fail fmt!{"unknown self type code: `%c`", self_ty_kind as char};
|
||||
}
|
||||
|
|
@ -861,13 +846,13 @@ fn get_attributes(md: ebml::doc) -> ~[ast::attribute] {
|
|||
return attrs;
|
||||
}
|
||||
|
||||
fn list_meta_items(meta_items: ebml::doc, out: io::writer) {
|
||||
fn list_meta_items(meta_items: ebml::doc, out: io::Writer) {
|
||||
for get_meta_items(meta_items).each |mi| {
|
||||
out.write_str(fmt!{"%s\n", pprust::meta_item_to_str(*mi)});
|
||||
}
|
||||
}
|
||||
|
||||
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| {
|
||||
|
|
@ -902,7 +887,7 @@ fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
|
|||
return deps;
|
||||
}
|
||||
|
||||
fn list_crate_deps(data: @~[u8], out: io::writer) {
|
||||
fn list_crate_deps(data: @~[u8], out: io::Writer) {
|
||||
out.write_str(~"=External Dependencies=\n");
|
||||
|
||||
for get_crate_deps(data).each |dep| {
|
||||
|
|
@ -928,7 +913,7 @@ fn get_crate_vers(data: @~[u8]) -> @~str {
|
|||
};
|
||||
}
|
||||
|
||||
fn list_crate_items(bytes: @~[u8], md: ebml::doc, out: io::writer) {
|
||||
fn list_crate_items(bytes: @~[u8], md: ebml::doc, out: io::Writer) {
|
||||
out.write_str(~"=Items=\n");
|
||||
let items = ebml::get_doc(md, tag_items);
|
||||
do iter_crate_items(bytes) |tag, path, did| {
|
||||
|
|
@ -984,7 +969,7 @@ fn get_crate_module_paths(bytes: @~[u8]) -> ~[(ast::def_id, ~str)] {
|
|||
}
|
||||
}
|
||||
|
||||
fn list_crate_metadata(bytes: @~[u8], out: io::writer) {
|
||||
fn list_crate_metadata(bytes: @~[u8], out: io::Writer) {
|
||||
let hash = get_crate_hash(bytes);
|
||||
let md = ebml::doc(bytes);
|
||||
list_crate_attributes(md, hash, out);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import util::ppaux::ty_to_str;
|
|||
|
||||
import std::{ebml, map};
|
||||
import std::map::hashmap;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import ebml::writer;
|
||||
import syntax::ast::*;
|
||||
import syntax::print::pprust;
|
||||
|
|
@ -500,7 +500,7 @@ fn encode_self_type(ebml_w: ebml::writer, self_type: ast::self_ty_) {
|
|||
sty_static => { ch = 's' as u8; }
|
||||
sty_by_ref => { ch = 'r' as u8; }
|
||||
sty_value => { ch = 'v' as u8; }
|
||||
sty_region(_, _) => { ch = '&' as u8; }
|
||||
sty_region(_) => { ch = '&' as u8; }
|
||||
sty_box(_) => { ch = '@' as u8; }
|
||||
sty_uniq(_) => { ch = '~' as u8; }
|
||||
}
|
||||
|
|
@ -509,27 +509,17 @@ fn encode_self_type(ebml_w: ebml::writer, self_type: ast::self_ty_) {
|
|||
// Encode mutability.
|
||||
match self_type {
|
||||
sty_static | sty_by_ref | sty_value => { /* No-op. */ }
|
||||
sty_region(_, m_imm) | sty_box(m_imm) | sty_uniq(m_imm) => {
|
||||
sty_region(m_imm) | sty_box(m_imm) | sty_uniq(m_imm) => {
|
||||
ebml_w.writer.write(&[ 'i' as u8 ]);
|
||||
}
|
||||
sty_region(_, m_mutbl) | sty_box(m_mutbl) | sty_uniq(m_mutbl) => {
|
||||
sty_region(m_mutbl) | sty_box(m_mutbl) | sty_uniq(m_mutbl) => {
|
||||
ebml_w.writer.write(&[ 'm' as u8 ]);
|
||||
}
|
||||
sty_region(_, m_const) | sty_box(m_const) | sty_uniq(m_const) => {
|
||||
sty_region(m_const) | sty_box(m_const) | sty_uniq(m_const) => {
|
||||
ebml_w.writer.write(&[ 'c' as u8 ]);
|
||||
}
|
||||
}
|
||||
|
||||
// Encode the region.
|
||||
match self_type {
|
||||
sty_region(region, _) => {
|
||||
encode_region(ebml_w, *region);
|
||||
}
|
||||
sty_static | sty_by_ref | sty_value | sty_box(*) | sty_uniq(*) => {
|
||||
// Nothing to do.
|
||||
}
|
||||
}
|
||||
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
|
|
@ -1015,7 +1005,7 @@ fn create_index<T: copy>(index: ~[entry<T>], hash_fn: fn@(T) -> uint) ->
|
|||
}
|
||||
|
||||
fn encode_index<T>(ebml_w: ebml::writer, buckets: ~[@~[entry<T>]],
|
||||
write_fn: fn(io::writer, T)) {
|
||||
write_fn: fn(io::Writer, T)) {
|
||||
let writer = ebml_w.writer;
|
||||
ebml_w.start_tag(tag_index);
|
||||
let mut bucket_locs: ~[uint] = ~[];
|
||||
|
|
@ -1042,9 +1032,9 @@ fn encode_index<T>(ebml_w: ebml::writer, buckets: ~[@~[entry<T>]],
|
|||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn write_str(writer: io::writer, &&s: ~str) { writer.write_str(s); }
|
||||
fn write_str(writer: io::Writer, &&s: ~str) { writer.write_str(s); }
|
||||
|
||||
fn write_int(writer: io::writer, &&n: int) {
|
||||
fn write_int(writer: io::Writer, &&n: int) {
|
||||
assert n < 0x7fff_ffff;
|
||||
writer.write_be_u32(n as u32);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,31 +14,31 @@ export get_cargo_root;
|
|||
export get_cargo_root_nearest;
|
||||
export libdir;
|
||||
|
||||
import path::path;
|
||||
import path::Path;
|
||||
|
||||
type pick<T> = fn(path: path) -> option<T>;
|
||||
type pick<T> = fn(path: Path) -> option<T>;
|
||||
|
||||
fn pick_file(file: path, path: path) -> option<path> {
|
||||
fn pick_file(file: Path, path: Path) -> option<Path> {
|
||||
if path::basename(path) == file { option::some(path) }
|
||||
else { option::none }
|
||||
}
|
||||
|
||||
trait filesearch {
|
||||
fn sysroot() -> path;
|
||||
fn lib_search_paths() -> ~[path];
|
||||
fn get_target_lib_path() -> path;
|
||||
fn get_target_lib_file_path(file: path) -> path;
|
||||
fn sysroot() -> Path;
|
||||
fn lib_search_paths() -> ~[Path];
|
||||
fn get_target_lib_path() -> Path;
|
||||
fn get_target_lib_file_path(file: Path) -> Path;
|
||||
}
|
||||
|
||||
fn mk_filesearch(maybe_sysroot: option<path>,
|
||||
fn mk_filesearch(maybe_sysroot: option<Path>,
|
||||
target_triple: ~str,
|
||||
addl_lib_search_paths: ~[path]) -> filesearch {
|
||||
type filesearch_impl = {sysroot: path,
|
||||
addl_lib_search_paths: ~[path],
|
||||
addl_lib_search_paths: ~[Path]) -> filesearch {
|
||||
type filesearch_impl = {sysroot: Path,
|
||||
addl_lib_search_paths: ~[Path],
|
||||
target_triple: ~str};
|
||||
impl filesearch_impl: filesearch {
|
||||
fn sysroot() -> path { self.sysroot }
|
||||
fn lib_search_paths() -> ~[path] {
|
||||
fn sysroot() -> Path { self.sysroot }
|
||||
fn lib_search_paths() -> ~[Path] {
|
||||
let mut paths = self.addl_lib_search_paths;
|
||||
|
||||
vec::push(paths,
|
||||
|
|
@ -53,10 +53,10 @@ fn mk_filesearch(maybe_sysroot: option<path>,
|
|||
}
|
||||
paths
|
||||
}
|
||||
fn get_target_lib_path() -> path {
|
||||
fn get_target_lib_path() -> Path {
|
||||
make_target_lib_path(self.sysroot, self.target_triple)
|
||||
}
|
||||
fn get_target_lib_file_path(file: path) -> path {
|
||||
fn get_target_lib_file_path(file: Path) -> Path {
|
||||
path::connect(self.get_target_lib_path(), file)
|
||||
}
|
||||
}
|
||||
|
|
@ -88,38 +88,38 @@ fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option<T> {
|
|||
return rslt;
|
||||
}
|
||||
|
||||
fn relative_target_lib_path(target_triple: ~str) -> ~[path] {
|
||||
fn relative_target_lib_path(target_triple: ~str) -> ~[Path] {
|
||||
~[libdir(), ~"rustc", target_triple, libdir()]
|
||||
}
|
||||
|
||||
fn make_target_lib_path(sysroot: path,
|
||||
target_triple: ~str) -> path {
|
||||
fn make_target_lib_path(sysroot: Path,
|
||||
target_triple: ~str) -> Path {
|
||||
let path = vec::append(~[sysroot],
|
||||
relative_target_lib_path(target_triple));
|
||||
let path = path::connect_many(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
fn get_default_sysroot() -> path {
|
||||
fn get_default_sysroot() -> Path {
|
||||
match os::self_exe_path() {
|
||||
option::some(p) => path::normalize(path::connect(p, ~"..")),
|
||||
option::none => fail ~"can't determine value for sysroot"
|
||||
}
|
||||
}
|
||||
|
||||
fn get_sysroot(maybe_sysroot: option<path>) -> path {
|
||||
fn get_sysroot(maybe_sysroot: option<Path>) -> Path {
|
||||
match maybe_sysroot {
|
||||
option::some(sr) => sr,
|
||||
option::none => get_default_sysroot()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_cargo_sysroot() -> result<path, ~str> {
|
||||
fn get_cargo_sysroot() -> result<Path, ~str> {
|
||||
let path = ~[get_default_sysroot(), libdir(), ~"cargo"];
|
||||
result::ok(path::connect_many(path))
|
||||
}
|
||||
|
||||
fn get_cargo_root() -> result<path, ~str> {
|
||||
fn get_cargo_root() -> result<Path, ~str> {
|
||||
match os::getenv(~"CARGO_ROOT") {
|
||||
some(_p) => result::ok(_p),
|
||||
none => match os::homedir() {
|
||||
|
|
@ -129,7 +129,7 @@ fn get_cargo_root() -> result<path, ~str> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_cargo_root_nearest() -> result<path, ~str> {
|
||||
fn get_cargo_root_nearest() -> result<Path, ~str> {
|
||||
do result::chain(get_cargo_root()) |p| {
|
||||
let cwd = os::getcwd();
|
||||
let mut dirname = path::dirname(cwd);
|
||||
|
|
@ -153,13 +153,13 @@ fn get_cargo_root_nearest() -> result<path, ~str> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_cargo_lib_path() -> result<path, ~str> {
|
||||
fn get_cargo_lib_path() -> result<Path, ~str> {
|
||||
do result::chain(get_cargo_root()) |p| {
|
||||
result::ok(path::connect(p, libdir()))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_cargo_lib_path_nearest() -> result<path, ~str> {
|
||||
fn get_cargo_lib_path_nearest() -> result<Path, ~str> {
|
||||
do result::chain(get_cargo_root_nearest()) |p| {
|
||||
result::ok(path::connect(p, libdir()))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import syntax::print::pprust;
|
|||
import syntax::codemap::span;
|
||||
import lib::llvm::{False, llvm, mk_object_file, mk_section_iter};
|
||||
import filesearch::filesearch;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
export os;
|
||||
export os_macos, os_win32, os_linux, os_freebsd;
|
||||
|
|
@ -206,7 +206,7 @@ fn meta_section_name(os: os) -> ~str {
|
|||
}
|
||||
|
||||
// A diagnostic function for dumping crate metadata to an output stream
|
||||
fn list_file_metadata(os: os, path: ~str, out: io::writer) {
|
||||
fn list_file_metadata(os: os, path: ~str, out: io::Writer) {
|
||||
match get_metadata_section(os, path) {
|
||||
option::some(bytes) => decoder::list_crate_metadata(bytes, out),
|
||||
option::none => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Type encoding
|
||||
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import std::map::hashmap;
|
||||
import syntax::ast::*;
|
||||
import syntax::diagnostic::span_handler;
|
||||
|
|
@ -40,7 +40,7 @@ fn cx_uses_abbrevs(cx: @ctxt) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_ty(w: io::writer, cx: @ctxt, t: ty::t) {
|
||||
fn enc_ty(w: io::Writer, cx: @ctxt, t: ty::t) {
|
||||
match cx.abbrevs {
|
||||
ac_no_abbrevs => {
|
||||
let result_str = match cx.tcx.short_names_cache.find(t) {
|
||||
|
|
@ -95,7 +95,7 @@ fn enc_ty(w: io::writer, cx: @ctxt, t: ty::t) {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn enc_mt(w: io::writer, cx: @ctxt, mt: ty::mt) {
|
||||
fn enc_mt(w: io::Writer, cx: @ctxt, mt: ty::mt) {
|
||||
match mt.mutbl {
|
||||
m_imm => (),
|
||||
m_mutbl => w.write_char('m'),
|
||||
|
|
@ -104,7 +104,7 @@ fn enc_mt(w: io::writer, cx: @ctxt, mt: ty::mt) {
|
|||
enc_ty(w, cx, mt.ty);
|
||||
}
|
||||
|
||||
fn enc_opt<T>(w: io::writer, t: option<T>, enc_f: fn(T)) {
|
||||
fn enc_opt<T>(w: io::Writer, t: option<T>, enc_f: fn(T)) {
|
||||
match t {
|
||||
none => w.write_char('n'),
|
||||
some(v) => {
|
||||
|
|
@ -114,7 +114,7 @@ fn enc_opt<T>(w: io::writer, t: option<T>, enc_f: fn(T)) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_substs(w: io::writer, cx: @ctxt, substs: ty::substs) {
|
||||
fn enc_substs(w: io::Writer, cx: @ctxt, substs: ty::substs) {
|
||||
do enc_opt(w, substs.self_r) |r| { enc_region(w, cx, r) }
|
||||
do enc_opt(w, substs.self_ty) |t| { enc_ty(w, cx, t) }
|
||||
w.write_char('[');
|
||||
|
|
@ -122,7 +122,7 @@ fn enc_substs(w: io::writer, cx: @ctxt, substs: ty::substs) {
|
|||
w.write_char(']');
|
||||
}
|
||||
|
||||
fn enc_region(w: io::writer, cx: @ctxt, r: ty::region) {
|
||||
fn enc_region(w: io::Writer, cx: @ctxt, r: ty::region) {
|
||||
match r {
|
||||
ty::re_bound(br) => {
|
||||
w.write_char('b');
|
||||
|
|
@ -151,7 +151,7 @@ fn enc_region(w: io::writer, cx: @ctxt, r: ty::region) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_bound_region(w: io::writer, br: ty::bound_region) {
|
||||
fn enc_bound_region(w: io::Writer, br: ty::bound_region) {
|
||||
match br {
|
||||
ty::br_self => w.write_char('s'),
|
||||
ty::br_anon => w.write_char('a'),
|
||||
|
|
@ -169,7 +169,7 @@ fn enc_bound_region(w: io::writer, br: ty::bound_region) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_vstore(w: io::writer, cx: @ctxt, v: ty::vstore) {
|
||||
fn enc_vstore(w: io::Writer, cx: @ctxt, v: ty::vstore) {
|
||||
w.write_char('/');
|
||||
match v {
|
||||
ty::vstore_fixed(u) => {
|
||||
|
|
@ -189,7 +189,7 @@ fn enc_vstore(w: io::writer, cx: @ctxt, v: ty::vstore) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
||||
fn enc_sty(w: io::Writer, cx: @ctxt, st: ty::sty) {
|
||||
match st {
|
||||
ty::ty_nil => w.write_char('n'),
|
||||
ty::ty_bot => w.write_char('z'),
|
||||
|
|
@ -307,7 +307,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_proto(w: io::writer, cx: @ctxt, proto: ty::fn_proto) {
|
||||
fn enc_proto(w: io::Writer, cx: @ctxt, proto: ty::fn_proto) {
|
||||
w.write_str(&"f");
|
||||
match proto {
|
||||
ty::proto_bare => w.write_str(&"n"),
|
||||
|
|
@ -318,7 +318,7 @@ fn enc_proto(w: io::writer, cx: @ctxt, proto: ty::fn_proto) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_mode(w: io::writer, cx: @ctxt, m: mode) {
|
||||
fn enc_mode(w: io::Writer, cx: @ctxt, m: mode) {
|
||||
match ty::resolved_mode(cx.tcx, m) {
|
||||
by_mutbl_ref => w.write_char('&'),
|
||||
by_move => w.write_char('-'),
|
||||
|
|
@ -328,7 +328,7 @@ fn enc_mode(w: io::writer, cx: @ctxt, m: mode) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_purity(w: io::writer, p: purity) {
|
||||
fn enc_purity(w: io::Writer, p: purity) {
|
||||
match p {
|
||||
pure_fn => w.write_char('p'),
|
||||
impure_fn => w.write_char('i'),
|
||||
|
|
@ -337,7 +337,7 @@ fn enc_purity(w: io::writer, p: purity) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_ty_fn(w: io::writer, cx: @ctxt, ft: ty::fn_ty) {
|
||||
fn enc_ty_fn(w: io::Writer, cx: @ctxt, ft: ty::fn_ty) {
|
||||
enc_proto(w, cx, ft.proto);
|
||||
enc_purity(w, ft.purity);
|
||||
enc_bounds(w, cx, ft.bounds);
|
||||
|
|
@ -353,7 +353,7 @@ fn enc_ty_fn(w: io::writer, cx: @ctxt, ft: ty::fn_ty) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_bounds(w: io::writer, cx: @ctxt, bs: @~[ty::param_bound]) {
|
||||
fn enc_bounds(w: io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) {
|
||||
for vec::each(*bs) |bound| {
|
||||
match bound {
|
||||
ty::bound_send => w.write_char('S'),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import syntax::attr;
|
|||
import syntax::codemap::span;
|
||||
import std::map::{map,hashmap,int_hash,hash_from_strs};
|
||||
import std::smallintmap::{map,smallintmap};
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import util::ppaux::{ty_to_str};
|
||||
import middle::pat_util::{pat_bindings};
|
||||
import syntax::ast_util::{path_to_ident};
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ import visit::vt;
|
|||
import syntax::codemap::span;
|
||||
import syntax::ast::*;
|
||||
import driver::session::session;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import capture::{cap_move, cap_drop, cap_copy, cap_ref};
|
||||
|
||||
export check_crate;
|
||||
|
|
@ -647,7 +647,7 @@ class liveness {
|
|||
}
|
||||
}
|
||||
|
||||
fn write_vars(wr: io::writer,
|
||||
fn write_vars(wr: io::Writer,
|
||||
ln: live_node,
|
||||
test: fn(uint) -> live_node) {
|
||||
let node_base_idx = self.idx(ln, variable(0u));
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ enum opt_result {
|
|||
range_result(result, result),
|
||||
}
|
||||
fn trans_opt(bcx: block, o: opt) -> opt_result {
|
||||
let _icx = bcx.insn_ctxt(~"alt::trans_opt");
|
||||
let _icx = bcx.insn_ctxt("alt::trans_opt");
|
||||
let ccx = bcx.ccx();
|
||||
let mut bcx = bcx;
|
||||
match o {
|
||||
|
|
@ -303,7 +303,7 @@ fn get_options(ccx: @crate_ctxt, m: match_, col: uint) -> ~[opt] {
|
|||
fn extract_variant_args(bcx: block, pat_id: ast::node_id,
|
||||
vdefs: {enm: def_id, var: def_id}, val: ValueRef) ->
|
||||
{vals: ~[ValueRef], bcx: block} {
|
||||
let _icx = bcx.insn_ctxt(~"alt::extract_variant_args");
|
||||
let _icx = bcx.insn_ctxt("alt::extract_variant_args");
|
||||
let ccx = bcx.fcx.ccx;
|
||||
let enum_ty_substs = match check ty::get(node_id_type(bcx, pat_id))
|
||||
.struct {
|
||||
|
|
@ -449,7 +449,7 @@ fn compile_submatch(bcx: block, m: match_, vals: ~[ValueRef],
|
|||
For an empty match, a fall-through case must exist
|
||||
*/
|
||||
assert(m.len() > 0u || is_some(chk));
|
||||
let _icx = bcx.insn_ctxt(~"alt::compile_submatch");
|
||||
let _icx = bcx.insn_ctxt("alt::compile_submatch");
|
||||
let mut bcx = bcx;
|
||||
let tcx = bcx.tcx(), dm = tcx.def_map;
|
||||
if m.len() == 0u { Br(bcx, option::get(chk)()); return; }
|
||||
|
|
@ -735,7 +735,7 @@ fn make_phi_bindings(bcx: block,
|
|||
map: ~[exit_node],
|
||||
ids: pat_util::pat_id_map)
|
||||
-> option<phi_bindings_list> {
|
||||
let _icx = bcx.insn_ctxt(~"alt::make_phi_bindings");
|
||||
let _icx = bcx.insn_ctxt("alt::make_phi_bindings");
|
||||
let our_block = bcx.llbb as uint;
|
||||
let mut phi_bindings = ~[];
|
||||
for ids.each |name, node_id| {
|
||||
|
|
@ -815,7 +815,7 @@ fn trans_alt(bcx: block,
|
|||
arms: ~[ast::arm],
|
||||
mode: ast::alt_mode,
|
||||
dest: dest) -> block {
|
||||
let _icx = bcx.insn_ctxt(~"alt::trans_alt");
|
||||
let _icx = bcx.insn_ctxt("alt::trans_alt");
|
||||
do with_scope(bcx, alt_expr.info(), ~"alt") |bcx| {
|
||||
trans_alt_inner(bcx, expr, arms, mode, dest)
|
||||
}
|
||||
|
|
@ -823,7 +823,7 @@ fn trans_alt(bcx: block,
|
|||
|
||||
fn trans_alt_inner(scope_cx: block, expr: @ast::expr, arms: ~[ast::arm],
|
||||
mode: ast::alt_mode, dest: dest) -> block {
|
||||
let _icx = scope_cx.insn_ctxt(~"alt::trans_alt_inner");
|
||||
let _icx = scope_cx.insn_ctxt("alt::trans_alt_inner");
|
||||
let bcx = scope_cx, tcx = bcx.tcx();
|
||||
let mut bodies = ~[], matches = ~[];
|
||||
|
||||
|
|
@ -897,7 +897,7 @@ fn trans_alt_inner(scope_cx: block, expr: @ast::expr, arms: ~[ast::arm],
|
|||
// Not alt-related, but similar to the pattern-munging code above
|
||||
fn bind_irrefutable_pat(bcx: block, pat: @ast::pat, val: ValueRef,
|
||||
make_copy: bool) -> block {
|
||||
let _icx = bcx.insn_ctxt(~"alt::bind_irrefutable_pat");
|
||||
let _icx = bcx.insn_ctxt("alt::bind_irrefutable_pat");
|
||||
let ccx = bcx.fcx.ccx;
|
||||
let mut bcx = bcx;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -15,7 +15,7 @@ fn B(cx: block) -> BuilderRef {
|
|||
return b;
|
||||
}
|
||||
|
||||
fn count_insn(cx: block, category: ~str) {
|
||||
fn count_insn(cx: block, category: &str) {
|
||||
if cx.ccx().sess.count_llvm_insns() {
|
||||
|
||||
let h = cx.ccx().stats.llvm_insns;
|
||||
|
|
@ -70,7 +70,7 @@ fn RetVoid(cx: block) {
|
|||
if cx.unreachable { return; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
count_insn(cx, ~"retvoid");
|
||||
count_insn(cx, "retvoid");
|
||||
llvm::LLVMBuildRetVoid(B(cx));
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ fn Ret(cx: block, V: ValueRef) {
|
|||
if cx.unreachable { return; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
count_insn(cx, ~"ret");
|
||||
count_insn(cx, "ret");
|
||||
llvm::LLVMBuildRet(B(cx), V);
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ fn Br(cx: block, Dest: BasicBlockRef) {
|
|||
if cx.unreachable { return; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
count_insn(cx, ~"br");
|
||||
count_insn(cx, "br");
|
||||
llvm::LLVMBuildBr(B(cx), Dest);
|
||||
}
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ fn CondBr(cx: block, If: ValueRef, Then: BasicBlockRef,
|
|||
if cx.unreachable { return; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
count_insn(cx, ~"condbr");
|
||||
count_insn(cx, "condbr");
|
||||
llvm::LLVMBuildCondBr(B(cx), If, Then, Else);
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ fn IndirectBr(cx: block, Addr: ValueRef, NumDests: uint) {
|
|||
if cx.unreachable { return; }
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
count_insn(cx, ~"indirectbr");
|
||||
count_insn(cx, "indirectbr");
|
||||
llvm::LLVMBuildIndirectBr(B(cx), Addr, NumDests as c_uint);
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ fn Invoke(cx: block, Fn: ValueRef, Args: ~[ValueRef],
|
|||
str::connect(vec::map(Args, |a| val_str(cx.ccx().tn, a)),
|
||||
~", ")};
|
||||
unsafe {
|
||||
count_insn(cx, ~"invoke");
|
||||
count_insn(cx, "invoke");
|
||||
llvm::LLVMBuildInvoke(B(cx), Fn, vec::unsafe::to_ptr(Args),
|
||||
Args.len() as c_uint, Then, Catch,
|
||||
noname());
|
||||
|
|
@ -160,7 +160,7 @@ fn FastInvoke(cx: block, Fn: ValueRef, Args: ~[ValueRef],
|
|||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
unsafe {
|
||||
count_insn(cx, ~"fastinvoke");
|
||||
count_insn(cx, "fastinvoke");
|
||||
let v = llvm::LLVMBuildInvoke(B(cx), Fn, vec::unsafe::to_ptr(Args),
|
||||
Args.len() as c_uint,
|
||||
Then, Catch, noname());
|
||||
|
|
@ -172,7 +172,7 @@ fn Unreachable(cx: block) {
|
|||
if cx.unreachable { return; }
|
||||
cx.unreachable = true;
|
||||
if !cx.terminated {
|
||||
count_insn(cx, ~"unreachable");
|
||||
count_insn(cx, "unreachable");
|
||||
llvm::LLVMBuildUnreachable(B(cx));
|
||||
}
|
||||
}
|
||||
|
|
@ -184,218 +184,218 @@ fn _Undef(val: ValueRef) -> ValueRef {
|
|||
/* Arithmetic */
|
||||
fn Add(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"add");
|
||||
count_insn(cx, "add");
|
||||
return llvm::LLVMBuildAdd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NSWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"nswadd");
|
||||
count_insn(cx, "nswadd");
|
||||
return llvm::LLVMBuildNSWAdd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NUWAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"nuwadd");
|
||||
count_insn(cx, "nuwadd");
|
||||
return llvm::LLVMBuildNUWAdd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FAdd(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"fadd");
|
||||
count_insn(cx, "fadd");
|
||||
return llvm::LLVMBuildFAdd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Sub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"sub");
|
||||
count_insn(cx, "sub");
|
||||
return llvm::LLVMBuildSub(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NSWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"nwsub");
|
||||
count_insn(cx, "nwsub");
|
||||
return llvm::LLVMBuildNSWSub(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NUWSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"nuwsub");
|
||||
count_insn(cx, "nuwsub");
|
||||
return llvm::LLVMBuildNUWSub(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FSub(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"sub");
|
||||
count_insn(cx, "sub");
|
||||
return llvm::LLVMBuildFSub(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Mul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"mul");
|
||||
count_insn(cx, "mul");
|
||||
return llvm::LLVMBuildMul(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NSWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"nswmul");
|
||||
count_insn(cx, "nswmul");
|
||||
return llvm::LLVMBuildNSWMul(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn NUWMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"nuwmul");
|
||||
count_insn(cx, "nuwmul");
|
||||
return llvm::LLVMBuildNUWMul(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FMul(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"fmul");
|
||||
count_insn(cx, "fmul");
|
||||
return llvm::LLVMBuildFMul(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn UDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"udiv");
|
||||
count_insn(cx, "udiv");
|
||||
return llvm::LLVMBuildUDiv(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn SDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"sdiv");
|
||||
count_insn(cx, "sdiv");
|
||||
return llvm::LLVMBuildSDiv(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn ExactSDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"extractsdiv");
|
||||
count_insn(cx, "extractsdiv");
|
||||
return llvm::LLVMBuildExactSDiv(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FDiv(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"fdiv");
|
||||
count_insn(cx, "fdiv");
|
||||
return llvm::LLVMBuildFDiv(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn URem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"urem");
|
||||
count_insn(cx, "urem");
|
||||
return llvm::LLVMBuildURem(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn SRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"srem");
|
||||
count_insn(cx, "srem");
|
||||
return llvm::LLVMBuildSRem(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FRem(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"frem");
|
||||
count_insn(cx, "frem");
|
||||
return llvm::LLVMBuildFRem(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Shl(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"shl");
|
||||
count_insn(cx, "shl");
|
||||
return llvm::LLVMBuildShl(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn LShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"lshr");
|
||||
count_insn(cx, "lshr");
|
||||
return llvm::LLVMBuildLShr(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn AShr(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"ashr");
|
||||
count_insn(cx, "ashr");
|
||||
return llvm::LLVMBuildAShr(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn And(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"and");
|
||||
count_insn(cx, "and");
|
||||
return llvm::LLVMBuildAnd(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Or(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"or");
|
||||
count_insn(cx, "or");
|
||||
return llvm::LLVMBuildOr(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Xor(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"xor");
|
||||
count_insn(cx, "xor");
|
||||
return llvm::LLVMBuildXor(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn BinOp(cx: block, Op: Opcode, LHS: ValueRef, RHS: ValueRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { return _Undef(LHS); }
|
||||
count_insn(cx, ~"binop");
|
||||
count_insn(cx, "binop");
|
||||
return llvm::LLVMBuildBinOp(B(cx), Op, LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn Neg(cx: block, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(V); }
|
||||
count_insn(cx, ~"neg");
|
||||
count_insn(cx, "neg");
|
||||
return llvm::LLVMBuildNeg(B(cx), V, noname());
|
||||
}
|
||||
|
||||
fn NSWNeg(cx: block, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(V); }
|
||||
count_insn(cx, ~"nswneg");
|
||||
count_insn(cx, "nswneg");
|
||||
return llvm::LLVMBuildNSWNeg(B(cx), V, noname());
|
||||
}
|
||||
|
||||
fn NUWNeg(cx: block, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(V); }
|
||||
count_insn(cx, ~"nuwneg");
|
||||
count_insn(cx, "nuwneg");
|
||||
return llvm::LLVMBuildNUWNeg(B(cx), V, noname());
|
||||
}
|
||||
fn FNeg(cx: block, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(V); }
|
||||
count_insn(cx, ~"fneg");
|
||||
count_insn(cx, "fneg");
|
||||
return llvm::LLVMBuildFNeg(B(cx), V, noname());
|
||||
}
|
||||
|
||||
fn Not(cx: block, V: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return _Undef(V); }
|
||||
count_insn(cx, ~"not");
|
||||
count_insn(cx, "not");
|
||||
return llvm::LLVMBuildNot(B(cx), V, noname());
|
||||
}
|
||||
|
||||
/* Memory */
|
||||
fn Malloc(cx: block, Ty: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||
count_insn(cx, ~"malloc");
|
||||
count_insn(cx, "malloc");
|
||||
return llvm::LLVMBuildMalloc(B(cx), Ty, noname());
|
||||
}
|
||||
|
||||
fn ArrayMalloc(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||
count_insn(cx, ~"arraymalloc");
|
||||
count_insn(cx, "arraymalloc");
|
||||
return llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname());
|
||||
}
|
||||
|
||||
fn Alloca(cx: block, Ty: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
|
||||
count_insn(cx, ~"alloca");
|
||||
count_insn(cx, "alloca");
|
||||
return llvm::LLVMBuildAlloca(B(cx), Ty, noname());
|
||||
}
|
||||
|
||||
fn ArrayAlloca(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); }
|
||||
count_insn(cx, ~"arrayalloca");
|
||||
count_insn(cx, "arrayalloca");
|
||||
return llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname());
|
||||
}
|
||||
|
||||
fn Free(cx: block, PointerVal: ValueRef) {
|
||||
if cx.unreachable { return; }
|
||||
count_insn(cx, ~"free");
|
||||
count_insn(cx, "free");
|
||||
llvm::LLVMBuildFree(B(cx), PointerVal);
|
||||
}
|
||||
|
||||
|
|
@ -407,7 +407,7 @@ fn Load(cx: block, PointerVal: ValueRef) -> ValueRef {
|
|||
llvm::LLVMGetElementType(ty) } else { ccx.int_type };
|
||||
return llvm::LLVMGetUndef(eltty);
|
||||
}
|
||||
count_insn(cx, ~"load");
|
||||
count_insn(cx, "load");
|
||||
return llvm::LLVMBuildLoad(B(cx), PointerVal, noname());
|
||||
}
|
||||
|
||||
|
|
@ -416,14 +416,14 @@ fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) {
|
|||
debug!{"Store %s -> %s",
|
||||
val_str(cx.ccx().tn, Val),
|
||||
val_str(cx.ccx().tn, Ptr)};
|
||||
count_insn(cx, ~"store");
|
||||
count_insn(cx, "store");
|
||||
llvm::LLVMBuildStore(B(cx), Val, Ptr);
|
||||
}
|
||||
|
||||
fn GEP(cx: block, Pointer: ValueRef, Indices: ~[ValueRef]) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||
unsafe {
|
||||
count_insn(cx, ~"gep");
|
||||
count_insn(cx, "gep");
|
||||
return llvm::LLVMBuildGEP(B(cx), Pointer, vec::unsafe::to_ptr(Indices),
|
||||
Indices.len() as c_uint, noname());
|
||||
}
|
||||
|
|
@ -434,7 +434,7 @@ fn GEP(cx: block, Pointer: ValueRef, Indices: ~[ValueRef]) -> ValueRef {
|
|||
fn GEPi(cx: block, base: ValueRef, ixs: ~[uint]) -> ValueRef {
|
||||
let mut v: ~[ValueRef] = ~[];
|
||||
for vec::each(ixs) |i| { vec::push(v, C_i32(i as i32)); }
|
||||
count_insn(cx, ~"gepi");
|
||||
count_insn(cx, "gepi");
|
||||
return InBoundsGEP(cx, base, v);
|
||||
}
|
||||
|
||||
|
|
@ -442,7 +442,7 @@ fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: ~[ValueRef]) ->
|
|||
ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||
unsafe {
|
||||
count_insn(cx, ~"inboundsgep");
|
||||
count_insn(cx, "inboundsgep");
|
||||
return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer,
|
||||
vec::unsafe::to_ptr(Indices),
|
||||
Indices.len() as c_uint,
|
||||
|
|
@ -452,138 +452,138 @@ fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: ~[ValueRef]) ->
|
|||
|
||||
fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); }
|
||||
count_insn(cx, ~"structgep");
|
||||
count_insn(cx, "structgep");
|
||||
return llvm::LLVMBuildStructGEP(B(cx), Pointer, Idx as c_uint, noname());
|
||||
}
|
||||
|
||||
fn GlobalString(cx: block, _Str: *libc::c_char) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||
count_insn(cx, ~"globalstring");
|
||||
count_insn(cx, "globalstring");
|
||||
return llvm::LLVMBuildGlobalString(B(cx), _Str, noname());
|
||||
}
|
||||
|
||||
fn GlobalStringPtr(cx: block, _Str: *libc::c_char) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); }
|
||||
count_insn(cx, ~"globalstringptr");
|
||||
count_insn(cx, "globalstringptr");
|
||||
return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname());
|
||||
}
|
||||
|
||||
/* Casts */
|
||||
fn Trunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"trunc");
|
||||
count_insn(cx, "trunc");
|
||||
return llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn ZExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"zext");
|
||||
count_insn(cx, "zext");
|
||||
return llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn SExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"sext");
|
||||
count_insn(cx, "sext");
|
||||
return llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPToUI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"fptoui");
|
||||
count_insn(cx, "fptoui");
|
||||
return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPToSI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"fptosi");
|
||||
count_insn(cx, "fptosi");
|
||||
return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn UIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"uitofp");
|
||||
count_insn(cx, "uitofp");
|
||||
return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn SIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"sitofp");
|
||||
count_insn(cx, "sitofp");
|
||||
return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPTrunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"fptrunc");
|
||||
count_insn(cx, "fptrunc");
|
||||
return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"fpext");
|
||||
count_insn(cx, "fpext");
|
||||
return llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn PtrToInt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"ptrtoint");
|
||||
count_insn(cx, "ptrtoint");
|
||||
return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn IntToPtr(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"inttoptr");
|
||||
count_insn(cx, "inttoptr");
|
||||
return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn BitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"bitcast");
|
||||
count_insn(cx, "bitcast");
|
||||
return llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"zextorbitcast");
|
||||
count_insn(cx, "zextorbitcast");
|
||||
return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"sextorbitcast");
|
||||
count_insn(cx, "sextorbitcast");
|
||||
return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"truncorbitcast");
|
||||
count_insn(cx, "truncorbitcast");
|
||||
return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef,
|
||||
_Name: *u8) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"cast");
|
||||
count_insn(cx, "cast");
|
||||
return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn PointerCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"pointercast");
|
||||
count_insn(cx, "pointercast");
|
||||
return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn IntCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"intcast");
|
||||
count_insn(cx, "intcast");
|
||||
return llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(DestTy); }
|
||||
count_insn(cx, ~"fpcast");
|
||||
count_insn(cx, "fpcast");
|
||||
return llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname());
|
||||
}
|
||||
|
||||
|
|
@ -592,21 +592,21 @@ fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef {
|
|||
fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef)
|
||||
-> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
|
||||
count_insn(cx, ~"icmp");
|
||||
count_insn(cx, "icmp");
|
||||
return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname());
|
||||
}
|
||||
|
||||
fn FCmp(cx: block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef)
|
||||
-> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
|
||||
count_insn(cx, ~"fcmp");
|
||||
count_insn(cx, "fcmp");
|
||||
return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname());
|
||||
}
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
fn EmptyPhi(cx: block, Ty: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
|
||||
count_insn(cx, ~"emptyphi");
|
||||
count_insn(cx, "emptyphi");
|
||||
return llvm::LLVMBuildPhi(B(cx), Ty, noname());
|
||||
}
|
||||
|
||||
|
|
@ -616,7 +616,7 @@ fn Phi(cx: block, Ty: TypeRef, vals: ~[ValueRef], bbs: ~[BasicBlockRef])
|
|||
assert vals.len() == bbs.len();
|
||||
let phi = EmptyPhi(cx, Ty);
|
||||
unsafe {
|
||||
count_insn(cx, ~"addincoming");
|
||||
count_insn(cx, "addincoming");
|
||||
llvm::LLVMAddIncoming(phi, vec::unsafe::to_ptr(vals),
|
||||
vec::unsafe::to_ptr(bbs),
|
||||
vals.len() as c_uint);
|
||||
|
|
@ -671,7 +671,7 @@ fn add_comment(bcx: block, text: ~str) {
|
|||
fn Call(cx: block, Fn: ValueRef, Args: ~[ValueRef]) -> ValueRef {
|
||||
if cx.unreachable { return _UndefReturn(cx, Fn); }
|
||||
unsafe {
|
||||
count_insn(cx, ~"call");
|
||||
count_insn(cx, "call");
|
||||
|
||||
debug!{"Call(Fn=%s, Args=%?)",
|
||||
val_str(cx.ccx().tn, Fn),
|
||||
|
|
@ -685,7 +685,7 @@ fn Call(cx: block, Fn: ValueRef, Args: ~[ValueRef]) -> ValueRef {
|
|||
fn FastCall(cx: block, Fn: ValueRef, Args: ~[ValueRef]) -> ValueRef {
|
||||
if cx.unreachable { return _UndefReturn(cx, Fn); }
|
||||
unsafe {
|
||||
count_insn(cx, ~"fastcall");
|
||||
count_insn(cx, "fastcall");
|
||||
let v = llvm::LLVMBuildCall(B(cx), Fn, vec::unsafe::to_ptr(Args),
|
||||
Args.len() as c_uint, noname());
|
||||
lib::llvm::SetInstructionCallConv(v, lib::llvm::FastCallConv);
|
||||
|
|
@ -697,7 +697,7 @@ fn CallWithConv(cx: block, Fn: ValueRef, Args: ~[ValueRef],
|
|||
Conv: CallConv) -> ValueRef {
|
||||
if cx.unreachable { return _UndefReturn(cx, Fn); }
|
||||
unsafe {
|
||||
count_insn(cx, ~"callwithconv");
|
||||
count_insn(cx, "callwithconv");
|
||||
let v = llvm::LLVMBuildCall(B(cx), Fn, vec::unsafe::to_ptr(Args),
|
||||
Args.len() as c_uint, noname());
|
||||
lib::llvm::SetInstructionCallConv(v, Conv);
|
||||
|
|
@ -708,40 +708,40 @@ fn CallWithConv(cx: block, Fn: ValueRef, Args: ~[ValueRef],
|
|||
fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { return _Undef(Then); }
|
||||
count_insn(cx, ~"select");
|
||||
count_insn(cx, "select");
|
||||
return llvm::LLVMBuildSelect(B(cx), If, Then, Else, noname());
|
||||
}
|
||||
|
||||
fn VAArg(cx: block, list: ValueRef, Ty: TypeRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(Ty); }
|
||||
count_insn(cx, ~"vaarg");
|
||||
count_insn(cx, "vaarg");
|
||||
return llvm::LLVMBuildVAArg(B(cx), list, Ty, noname());
|
||||
}
|
||||
|
||||
fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) ->
|
||||
ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
|
||||
count_insn(cx, ~"extractelement");
|
||||
count_insn(cx, "extractelement");
|
||||
return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname());
|
||||
}
|
||||
|
||||
fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef,
|
||||
Index: ValueRef) {
|
||||
if cx.unreachable { return; }
|
||||
count_insn(cx, ~"insertelement");
|
||||
count_insn(cx, "insertelement");
|
||||
llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
|
||||
}
|
||||
|
||||
fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
|
||||
Mask: ValueRef) {
|
||||
if cx.unreachable { return; }
|
||||
count_insn(cx, ~"shufflevector");
|
||||
count_insn(cx, "shufflevector");
|
||||
llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
|
||||
}
|
||||
|
||||
fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
|
||||
count_insn(cx, ~"extractvalue");
|
||||
count_insn(cx, "extractvalue");
|
||||
return llvm::LLVMBuildExtractValue(
|
||||
B(cx), AggVal, Index as c_uint, noname());
|
||||
}
|
||||
|
|
@ -749,27 +749,27 @@ fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef {
|
|||
fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef,
|
||||
Index: uint) {
|
||||
if cx.unreachable { return; }
|
||||
count_insn(cx, ~"insertvalue");
|
||||
count_insn(cx, "insertvalue");
|
||||
llvm::LLVMBuildInsertValue(B(cx), AggVal, EltVal, Index as c_uint,
|
||||
noname());
|
||||
}
|
||||
|
||||
fn IsNull(cx: block, Val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
|
||||
count_insn(cx, ~"isnull");
|
||||
count_insn(cx, "isnull");
|
||||
return llvm::LLVMBuildIsNull(B(cx), Val, noname());
|
||||
}
|
||||
|
||||
fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef {
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); }
|
||||
count_insn(cx, ~"isnotnull");
|
||||
count_insn(cx, "isnotnull");
|
||||
return llvm::LLVMBuildIsNotNull(B(cx), Val, noname());
|
||||
}
|
||||
|
||||
fn PtrDiff(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef {
|
||||
let ccx = cx.fcx.ccx;
|
||||
if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type); }
|
||||
count_insn(cx, ~"ptrdiff");
|
||||
count_insn(cx, "ptrdiff");
|
||||
return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname());
|
||||
}
|
||||
|
||||
|
|
@ -785,7 +785,7 @@ fn Trap(cx: block) {
|
|||
assert (T as int != 0);
|
||||
let Args: ~[ValueRef] = ~[];
|
||||
unsafe {
|
||||
count_insn(cx, ~"trap");
|
||||
count_insn(cx, "trap");
|
||||
llvm::LLVMBuildCall(b, T, vec::unsafe::to_ptr(Args),
|
||||
Args.len() as c_uint, noname());
|
||||
}
|
||||
|
|
@ -794,20 +794,20 @@ fn Trap(cx: block) {
|
|||
fn LandingPad(cx: block, Ty: TypeRef, PersFn: ValueRef,
|
||||
NumClauses: uint) -> ValueRef {
|
||||
assert !cx.terminated && !cx.unreachable;
|
||||
count_insn(cx, ~"landingpad");
|
||||
count_insn(cx, "landingpad");
|
||||
return llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn,
|
||||
NumClauses as c_uint, noname());
|
||||
}
|
||||
|
||||
fn SetCleanup(cx: block, LandingPad: ValueRef) {
|
||||
count_insn(cx, ~"setcleanup");
|
||||
count_insn(cx, "setcleanup");
|
||||
llvm::LLVMSetCleanup(LandingPad, lib::llvm::True);
|
||||
}
|
||||
|
||||
fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
|
||||
assert (!cx.terminated);
|
||||
cx.terminated = true;
|
||||
count_insn(cx, ~"resume");
|
||||
count_insn(cx, "resume");
|
||||
return llvm::LLVMBuildResume(B(cx), Exn);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -137,11 +137,11 @@ fn allocate_cbox(bcx: block,
|
|||
ck: ty::closure_kind,
|
||||
cdata_ty: ty::t)
|
||||
-> result {
|
||||
let _icx = bcx.insn_ctxt(~"closure::allocate_cbox");
|
||||
let _icx = bcx.insn_ctxt("closure::allocate_cbox");
|
||||
let ccx = bcx.ccx(), tcx = ccx.tcx;
|
||||
|
||||
fn nuke_ref_count(bcx: block, llbox: ValueRef) {
|
||||
let _icx = bcx.insn_ctxt(~"closure::nuke_ref_count");
|
||||
let _icx = bcx.insn_ctxt("closure::nuke_ref_count");
|
||||
// Initialize ref count to arbitrary value for debugging:
|
||||
let ccx = bcx.ccx();
|
||||
let llbox = PointerCast(bcx, llbox, T_opaque_box_ptr(ccx));
|
||||
|
|
@ -178,7 +178,7 @@ type closure_result = {
|
|||
fn store_environment(bcx: block,
|
||||
bound_values: ~[environment_value],
|
||||
ck: ty::closure_kind) -> closure_result {
|
||||
let _icx = bcx.insn_ctxt(~"closure::store_environment");
|
||||
let _icx = bcx.insn_ctxt("closure::store_environment");
|
||||
let ccx = bcx.ccx(), tcx = ccx.tcx;
|
||||
|
||||
// compute the shape of the closure
|
||||
|
|
@ -251,7 +251,7 @@ fn build_closure(bcx0: block,
|
|||
ck: ty::closure_kind,
|
||||
id: ast::node_id,
|
||||
include_ret_handle: option<ValueRef>) -> closure_result {
|
||||
let _icx = bcx0.insn_ctxt(~"closure::build_closure");
|
||||
let _icx = bcx0.insn_ctxt("closure::build_closure");
|
||||
// If we need to, package up the iterator body to call
|
||||
let mut env_vals = ~[];
|
||||
let mut bcx = bcx0;
|
||||
|
|
@ -312,7 +312,7 @@ fn load_environment(fcx: fn_ctxt,
|
|||
cap_vars: ~[capture::capture_var],
|
||||
load_ret_handle: bool,
|
||||
ck: ty::closure_kind) {
|
||||
let _icx = fcx.insn_ctxt(~"closure::load_environment");
|
||||
let _icx = fcx.insn_ctxt("closure::load_environment");
|
||||
let bcx = raw_block(fcx, false, fcx.llloadenv);
|
||||
|
||||
// Load a pointer to the closure data, skipping over the box header:
|
||||
|
|
@ -354,7 +354,7 @@ fn trans_expr_fn(bcx: block,
|
|||
cap_clause: ast::capture_clause,
|
||||
is_loop_body: option<option<ValueRef>>,
|
||||
dest: dest) -> block {
|
||||
let _icx = bcx.insn_ctxt(~"closure::trans_expr_fn");
|
||||
let _icx = bcx.insn_ctxt("closure::trans_expr_fn");
|
||||
if dest == ignore { return bcx; }
|
||||
let ccx = bcx.ccx();
|
||||
let fty = node_id_type(bcx, id);
|
||||
|
|
@ -407,7 +407,7 @@ fn make_fn_glue(
|
|||
t: ty::t,
|
||||
glue_fn: fn@(block, v: ValueRef, t: ty::t) -> block)
|
||||
-> block {
|
||||
let _icx = cx.insn_ctxt(~"closure::make_fn_glue");
|
||||
let _icx = cx.insn_ctxt("closure::make_fn_glue");
|
||||
let bcx = cx;
|
||||
let tcx = cx.tcx();
|
||||
|
||||
|
|
@ -439,7 +439,7 @@ fn make_opaque_cbox_take_glue(
|
|||
cboxptr: ValueRef) // ptr to ptr to the opaque closure
|
||||
-> block {
|
||||
// Easy cases:
|
||||
let _icx = bcx.insn_ctxt(~"closure::make_opaque_cbox_take_glue");
|
||||
let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_take_glue");
|
||||
match ck {
|
||||
ty::ck_block => return bcx,
|
||||
ty::ck_box => {
|
||||
|
|
@ -491,7 +491,7 @@ fn make_opaque_cbox_drop_glue(
|
|||
ck: ty::closure_kind,
|
||||
cboxptr: ValueRef) // ptr to the opaque closure
|
||||
-> block {
|
||||
let _icx = bcx.insn_ctxt(~"closure::make_opaque_cbox_drop_glue");
|
||||
let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_drop_glue");
|
||||
match ck {
|
||||
ty::ck_block => bcx,
|
||||
ty::ck_box => {
|
||||
|
|
@ -510,7 +510,7 @@ fn make_opaque_cbox_free_glue(
|
|||
ck: ty::closure_kind,
|
||||
cbox: ValueRef) // ptr to ptr to the opaque closure
|
||||
-> block {
|
||||
let _icx = bcx.insn_ctxt(~"closure::make_opaque_cbox_free_glue");
|
||||
let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_free_glue");
|
||||
match ck {
|
||||
ty::ck_block => return bcx,
|
||||
ty::ck_box | ty::ck_uniq => { /* hard cases: */ }
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import base::get_insn_ctxt;
|
|||
|
||||
fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
|
||||
-> ValueRef {
|
||||
let _icx = cx.insn_ctxt(~"trans_lit");
|
||||
let _icx = cx.insn_ctxt("trans_lit");
|
||||
match lit.node {
|
||||
ast::lit_int(i, t) => C_integral(T_int_ty(cx, t), i as u64, True),
|
||||
ast::lit_uint(u, t) => C_integral(T_uint_ty(cx, t), u, False),
|
||||
|
|
@ -82,7 +82,7 @@ fn const_autoderef(cx: @crate_ctxt, ty: ty::t, v: ValueRef)
|
|||
|
||||
|
||||
fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
|
||||
let _icx = cx.insn_ctxt(~"const_expr");
|
||||
let _icx = cx.insn_ctxt("const_expr");
|
||||
match e.node {
|
||||
ast::expr_lit(lit) => consts::const_lit(cx, e, *lit),
|
||||
ast::expr_binary(b, e1, e2) => {
|
||||
|
|
@ -366,7 +366,7 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
|
|||
}
|
||||
|
||||
fn trans_const(ccx: @crate_ctxt, e: @ast::expr, id: ast::node_id) {
|
||||
let _icx = ccx.insn_ctxt(~"trans_const");
|
||||
let _icx = ccx.insn_ctxt("trans_const");
|
||||
let v = const_expr(ccx, e);
|
||||
|
||||
// The scalars come back as 1st class LLVM vals
|
||||
|
|
|
|||
|
|
@ -511,7 +511,7 @@ fn build_wrap_fn_(ccx: @crate_ctxt,
|
|||
arg_builder: wrap_arg_builder,
|
||||
ret_builder: wrap_ret_builder) {
|
||||
|
||||
let _icx = ccx.insn_ctxt(~"foreign::build_wrap_fn_");
|
||||
let _icx = ccx.insn_ctxt("foreign::build_wrap_fn_");
|
||||
let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, none);
|
||||
let bcx = top_scope_block(fcx, none);
|
||||
let lltop = bcx.llbb;
|
||||
|
|
@ -571,18 +571,18 @@ fn build_wrap_fn_(ccx: @crate_ctxt,
|
|||
fn trans_foreign_mod(ccx: @crate_ctxt,
|
||||
foreign_mod: ast::foreign_mod, abi: ast::foreign_abi) {
|
||||
|
||||
let _icx = ccx.insn_ctxt(~"foreign::trans_foreign_mod");
|
||||
let _icx = ccx.insn_ctxt("foreign::trans_foreign_mod");
|
||||
|
||||
fn build_shim_fn(ccx: @crate_ctxt,
|
||||
foreign_item: @ast::foreign_item,
|
||||
tys: @c_stack_tys,
|
||||
cc: lib::llvm::CallConv) -> ValueRef {
|
||||
|
||||
let _icx = ccx.insn_ctxt(~"foreign::build_shim_fn");
|
||||
let _icx = ccx.insn_ctxt("foreign::build_shim_fn");
|
||||
|
||||
fn build_args(bcx: block, tys: @c_stack_tys,
|
||||
llargbundle: ValueRef) -> ~[ValueRef] {
|
||||
let _icx = bcx.insn_ctxt(~"foreign::shim::build_args");
|
||||
let _icx = bcx.insn_ctxt("foreign::shim::build_args");
|
||||
let mut llargvals = ~[];
|
||||
let mut i = 0u;
|
||||
let n = vec::len(tys.arg_tys);
|
||||
|
|
@ -628,7 +628,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
|
|||
|
||||
fn build_ret(bcx: block, tys: @c_stack_tys,
|
||||
llargbundle: ValueRef, llretval: ValueRef) {
|
||||
let _icx = bcx.insn_ctxt(~"foreign::shim::build_ret");
|
||||
let _icx = bcx.insn_ctxt("foreign::shim::build_ret");
|
||||
match tys.x86_64_tys {
|
||||
some(x86_64) => {
|
||||
do vec::iteri(x86_64.attrs) |i, a| {
|
||||
|
|
@ -719,11 +719,11 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
|
|||
llshimfn: ValueRef,
|
||||
llwrapfn: ValueRef) {
|
||||
|
||||
let _icx = ccx.insn_ctxt(~"foreign::build_wrap_fn");
|
||||
let _icx = ccx.insn_ctxt("foreign::build_wrap_fn");
|
||||
|
||||
fn build_args(bcx: block, tys: @c_stack_tys,
|
||||
llwrapfn: ValueRef, llargbundle: ValueRef) {
|
||||
let _icx = bcx.insn_ctxt(~"foreign::wrap::build_args");
|
||||
let _icx = bcx.insn_ctxt("foreign::wrap::build_args");
|
||||
let mut i = 0u;
|
||||
let n = vec::len(tys.arg_tys);
|
||||
let implicit_args = first_real_arg; // return + env
|
||||
|
|
@ -738,7 +738,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
|
|||
|
||||
fn build_ret(bcx: block, _tys: @c_stack_tys,
|
||||
_llargbundle: ValueRef) {
|
||||
let _icx = bcx.insn_ctxt(~"foreign::wrap::build_ret");
|
||||
let _icx = bcx.insn_ctxt("foreign::wrap::build_ret");
|
||||
RetVoid(bcx);
|
||||
}
|
||||
|
||||
|
|
@ -987,12 +987,12 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
|||
fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
||||
body: ast::blk, llwrapfn: ValueRef, id: ast::node_id) {
|
||||
|
||||
let _icx = ccx.insn_ctxt(~"foreign::build_foreign_fn");
|
||||
let _icx = ccx.insn_ctxt("foreign::build_foreign_fn");
|
||||
|
||||
fn build_rust_fn(ccx: @crate_ctxt, path: ast_map::path,
|
||||
decl: ast::fn_decl, body: ast::blk,
|
||||
id: ast::node_id) -> ValueRef {
|
||||
let _icx = ccx.insn_ctxt(~"foreign::foreign::build_rust_fn");
|
||||
let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn");
|
||||
let t = ty::node_id_to_type(ccx.tcx, id);
|
||||
let ps = link::mangle_internal_name_by_path(
|
||||
ccx, vec::append_one(path, ast_map::path_name(@~"__rust_abi")));
|
||||
|
|
@ -1005,11 +1005,11 @@ fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
|||
fn build_shim_fn(ccx: @crate_ctxt, path: ast_map::path,
|
||||
llrustfn: ValueRef, tys: @c_stack_tys) -> ValueRef {
|
||||
|
||||
let _icx = ccx.insn_ctxt(~"foreign::foreign::build_shim_fn");
|
||||
let _icx = ccx.insn_ctxt("foreign::foreign::build_shim_fn");
|
||||
|
||||
fn build_args(bcx: block, tys: @c_stack_tys,
|
||||
llargbundle: ValueRef) -> ~[ValueRef] {
|
||||
let _icx = bcx.insn_ctxt(~"foreign::extern::shim::build_args");
|
||||
let _icx = bcx.insn_ctxt("foreign::extern::shim::build_args");
|
||||
let mut llargvals = ~[];
|
||||
let mut i = 0u;
|
||||
let n = vec::len(tys.arg_tys);
|
||||
|
|
@ -1042,11 +1042,11 @@ fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
|||
fn build_wrap_fn(ccx: @crate_ctxt, llshimfn: ValueRef,
|
||||
llwrapfn: ValueRef, tys: @c_stack_tys) {
|
||||
|
||||
let _icx = ccx.insn_ctxt(~"foreign::foreign::build_wrap_fn");
|
||||
let _icx = ccx.insn_ctxt("foreign::foreign::build_wrap_fn");
|
||||
|
||||
fn build_args(bcx: block, tys: @c_stack_tys,
|
||||
llwrapfn: ValueRef, llargbundle: ValueRef) {
|
||||
let _icx = bcx.insn_ctxt(~"foreign::foreign::wrap::build_args");
|
||||
let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_args");
|
||||
match tys.x86_64_tys {
|
||||
option::some(x86_64) => {
|
||||
let mut atys = x86_64.arg_tys;
|
||||
|
|
@ -1100,7 +1100,7 @@ fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
|||
|
||||
fn build_ret(bcx: block, tys: @c_stack_tys,
|
||||
llargbundle: ValueRef) {
|
||||
let _icx = bcx.insn_ctxt(~"foreign::foreign::wrap::build_ret");
|
||||
let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_ret");
|
||||
match tys.x86_64_tys {
|
||||
option::some(x86_64) => {
|
||||
if x86_64.sret || !tys.ret_def {
|
||||
|
|
@ -1144,7 +1144,7 @@ fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
|
|||
fn register_foreign_fn(ccx: @crate_ctxt, sp: span,
|
||||
path: ast_map::path, node_id: ast::node_id)
|
||||
-> ValueRef {
|
||||
let _icx = ccx.insn_ctxt(~"foreign::register_foreign_fn");
|
||||
let _icx = ccx.insn_ctxt("foreign::register_foreign_fn");
|
||||
let t = ty::node_id_to_type(ccx.tcx, node_id);
|
||||
let (llargtys, llretty, ret_ty) = c_arg_and_ret_lltys(ccx, node_id);
|
||||
return if ccx.sess.targ_cfg.arch == arch_x86_64 {
|
||||
|
|
|
|||
|
|
@ -20,15 +20,29 @@ import syntax::print::pprust::expr_to_str;
|
|||
|
||||
fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
|
||||
methods: ~[@ast::method], tps: ~[ast::ty_param]) {
|
||||
let _icx = ccx.insn_ctxt(~"impl::trans_impl");
|
||||
let _icx = ccx.insn_ctxt("impl::trans_impl");
|
||||
if tps.len() > 0u { return; }
|
||||
let sub_path = vec::append_one(path, path_name(name));
|
||||
for vec::each(methods) |m| {
|
||||
if m.tps.len() == 0u {
|
||||
let llfn = get_item_val(ccx, m.id);
|
||||
let self_ty = ty::node_id_to_type(ccx.tcx, m.self_id);
|
||||
let self_arg = match m.self_ty.node {
|
||||
ast::sty_static => { no_self }
|
||||
_ => { impl_self(ty::node_id_to_type(ccx.tcx, m.self_id)) }
|
||||
ast::sty_box(_) => {
|
||||
impl_self(ty::mk_imm_box(ccx.tcx, self_ty))
|
||||
}
|
||||
ast::sty_uniq(_) => {
|
||||
impl_self(ty::mk_imm_uniq(ccx.tcx, self_ty))
|
||||
}
|
||||
// XXX: Is this right at all?
|
||||
ast::sty_region(*) => {
|
||||
impl_self(ty::mk_imm_ptr(ccx.tcx, self_ty))
|
||||
}
|
||||
ast::sty_value => {
|
||||
ccx.sess.unimpl(~"by value self type not implemented");
|
||||
}
|
||||
ast::sty_by_ref => { impl_self(self_ty) }
|
||||
};
|
||||
|
||||
trans_fn(ccx,
|
||||
|
|
@ -41,7 +55,7 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
|
|||
}
|
||||
|
||||
fn trans_self_arg(bcx: block, base: @ast::expr, derefs: uint) -> result {
|
||||
let _icx = bcx.insn_ctxt(~"impl::trans_self_arg");
|
||||
let _icx = bcx.insn_ctxt("impl::trans_self_arg");
|
||||
let basety = expr_ty(bcx, base);
|
||||
let m_by_ref = ast::expl(ast::by_ref);
|
||||
let mut temp_cleanups = ~[];
|
||||
|
|
@ -59,7 +73,7 @@ fn trans_self_arg(bcx: block, base: @ast::expr, derefs: uint) -> result {
|
|||
fn trans_method_callee(bcx: block, callee_id: ast::node_id,
|
||||
self: @ast::expr, mentry: typeck::method_map_entry)
|
||||
-> lval_maybe_callee {
|
||||
let _icx = bcx.insn_ctxt(~"impl::trans_method_callee");
|
||||
let _icx = bcx.insn_ctxt("impl::trans_method_callee");
|
||||
match mentry.origin {
|
||||
typeck::method_static(did) => {
|
||||
let {bcx, val} = trans_self_arg(bcx, self, mentry.derefs);
|
||||
|
|
@ -89,7 +103,7 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
|
|||
|
||||
fn trans_static_method_callee(bcx: block, method_id: ast::def_id,
|
||||
callee_id: ast::node_id) -> lval_maybe_callee {
|
||||
let _icx = bcx.insn_ctxt(~"impl::trans_static_method_callee");
|
||||
let _icx = bcx.insn_ctxt("impl::trans_static_method_callee");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
let mname = if method_id.crate == ast::local_crate {
|
||||
|
|
@ -175,7 +189,7 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
|
|||
trait_id: ast::def_id, n_method: uint,
|
||||
vtbl: typeck::vtable_origin)
|
||||
-> lval_maybe_callee {
|
||||
let _icx = bcx.insn_ctxt(~"impl::trans_monomorphized_callee");
|
||||
let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee");
|
||||
match vtbl {
|
||||
typeck::vtable_static(impl_did, impl_substs, sub_origins) => {
|
||||
let ccx = bcx.ccx();
|
||||
|
|
@ -210,7 +224,7 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
|
|||
fn trans_trait_callee(bcx: block, val: ValueRef,
|
||||
callee_ty: ty::t, n_method: uint)
|
||||
-> lval_maybe_callee {
|
||||
let _icx = bcx.insn_ctxt(~"impl::trans_trait_callee");
|
||||
let _icx = bcx.insn_ctxt("impl::trans_trait_callee");
|
||||
let ccx = bcx.ccx();
|
||||
let vtable = Load(bcx, PointerCast(bcx, GEPi(bcx, val, ~[0u, 0u]),
|
||||
T_ptr(T_ptr(T_vtable()))));
|
||||
|
|
@ -299,7 +313,7 @@ fn get_vtable(ccx: @crate_ctxt, origin: typeck::vtable_origin)
|
|||
}
|
||||
|
||||
fn make_vtable(ccx: @crate_ctxt, ptrs: ~[ValueRef]) -> ValueRef {
|
||||
let _icx = ccx.insn_ctxt(~"impl::make_vtable");
|
||||
let _icx = ccx.insn_ctxt("impl::make_vtable");
|
||||
let tbl = C_struct(ptrs);
|
||||
let vt_gvar = str::as_c_str(ccx.names(~"vtable"), |buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf)
|
||||
|
|
@ -312,7 +326,7 @@ fn make_vtable(ccx: @crate_ctxt, ptrs: ~[ValueRef]) -> ValueRef {
|
|||
|
||||
fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
|
||||
vtables: typeck::vtable_res) -> ValueRef {
|
||||
let _icx = ccx.insn_ctxt(~"impl::make_impl_vtable");
|
||||
let _icx = ccx.insn_ctxt("impl::make_impl_vtable");
|
||||
let tcx = ccx.tcx;
|
||||
|
||||
// XXX: This should support multiple traits.
|
||||
|
|
@ -345,7 +359,7 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
|
|||
|
||||
fn trans_cast(bcx: block, val: @ast::expr, id: ast::node_id, dest: dest)
|
||||
-> block {
|
||||
let _icx = bcx.insn_ctxt(~"impl::trans_cast");
|
||||
let _icx = bcx.insn_ctxt("impl::trans_cast");
|
||||
if dest == ignore { return trans_expr(bcx, val, ignore); }
|
||||
let ccx = bcx.ccx();
|
||||
let v_ty = expr_ty(bcx, val);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t {
|
|||
}
|
||||
|
||||
fn get_fill(bcx: block, vptr: ValueRef) -> ValueRef {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::get_fill");
|
||||
let _icx = bcx.insn_ctxt("tvec::get_fill");
|
||||
Load(bcx, GEPi(bcx, vptr, ~[0u, abi::vec_elt_fill]))
|
||||
}
|
||||
fn set_fill(bcx: block, vptr: ValueRef, fill: ValueRef) {
|
||||
|
|
@ -48,12 +48,12 @@ fn get_bodyptr(bcx: block, vptr: ValueRef) -> ValueRef {
|
|||
|
||||
fn get_dataptr(bcx: block, vptr: ValueRef)
|
||||
-> ValueRef {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::get_dataptr");
|
||||
let _icx = bcx.insn_ctxt("tvec::get_dataptr");
|
||||
GEPi(bcx, vptr, ~[0u, abi::vec_elt_elems, 0u])
|
||||
}
|
||||
|
||||
fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::pointer_add");
|
||||
let _icx = bcx.insn_ctxt("tvec::pointer_add");
|
||||
let old_ty = val_ty(ptr);
|
||||
let bptr = PointerCast(bcx, ptr, T_ptr(T_i8()));
|
||||
return PointerCast(bcx, InBoundsGEP(bcx, bptr, ~[bytes]), old_ty);
|
||||
|
|
@ -61,7 +61,7 @@ fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef {
|
|||
|
||||
fn alloc_raw(bcx: block, unit_ty: ty::t,
|
||||
fill: ValueRef, alloc: ValueRef, heap: heap) -> result {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::alloc_uniq");
|
||||
let _icx = bcx.insn_ctxt("tvec::alloc_uniq");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty);
|
||||
|
|
@ -79,7 +79,7 @@ fn alloc_uniq_raw(bcx: block, unit_ty: ty::t,
|
|||
}
|
||||
|
||||
fn alloc_vec(bcx: block, unit_ty: ty::t, elts: uint, heap: heap) -> result {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::alloc_uniq");
|
||||
let _icx = bcx.insn_ctxt("tvec::alloc_uniq");
|
||||
let ccx = bcx.ccx();
|
||||
let llunitty = type_of::type_of(ccx, unit_ty);
|
||||
let unit_sz = llsize_of(ccx, llunitty);
|
||||
|
|
@ -92,7 +92,7 @@ fn alloc_vec(bcx: block, unit_ty: ty::t, elts: uint, heap: heap) -> result {
|
|||
}
|
||||
|
||||
fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> result {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::duplicate_uniq");
|
||||
let _icx = bcx.insn_ctxt("tvec::duplicate_uniq");
|
||||
|
||||
let fill = get_fill(bcx, get_bodyptr(bcx, vptr));
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
|
|
@ -110,7 +110,7 @@ fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> result {
|
|||
|
||||
fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) ->
|
||||
block {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::make_drop_glue_unboxed");
|
||||
let _icx = bcx.insn_ctxt("tvec::make_drop_glue_unboxed");
|
||||
let tcx = bcx.tcx(), unit_ty = ty::sequence_element_type(tcx, vec_ty);
|
||||
if ty::type_needs_drop(tcx, unit_ty) {
|
||||
iter_vec_unboxed(bcx, vptr, vec_ty, base::drop_ty)
|
||||
|
|
@ -124,7 +124,7 @@ enum evec_elements {
|
|||
|
||||
fn trans_evec(bcx: block, elements: evec_elements,
|
||||
vst: ast::vstore, id: ast::node_id, dest: dest) -> block {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::trans_evec");
|
||||
let _icx = bcx.insn_ctxt("tvec::trans_evec");
|
||||
let ccx = bcx.ccx();
|
||||
let mut bcx = bcx;
|
||||
|
||||
|
|
@ -318,7 +318,7 @@ fn get_base_and_len(cx: block, v: ValueRef, e_ty: ty::t)
|
|||
|
||||
fn trans_estr(bcx: block, s: @~str, vstore: option<ast::vstore>,
|
||||
dest: dest) -> block {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::trans_estr");
|
||||
let _icx = bcx.insn_ctxt("tvec::trans_estr");
|
||||
if dest == base::ignore { return bcx; }
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
|
|
@ -362,7 +362,7 @@ type iter_vec_block = fn(block, ValueRef, ty::t) -> block;
|
|||
|
||||
fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t,
|
||||
fill: ValueRef, f: iter_vec_block) -> block {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::iter_vec_raw");
|
||||
let _icx = bcx.insn_ctxt("tvec::iter_vec_raw");
|
||||
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
|
||||
|
|
@ -393,14 +393,14 @@ fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t,
|
|||
|
||||
fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t,
|
||||
fill: ValueRef, f: iter_vec_block) -> block {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::iter_vec_uniq");
|
||||
let _icx = bcx.insn_ctxt("tvec::iter_vec_uniq");
|
||||
let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr));
|
||||
iter_vec_raw(bcx, data_ptr, vec_ty, fill, f)
|
||||
}
|
||||
|
||||
fn iter_vec_unboxed(bcx: block, body_ptr: ValueRef, vec_ty: ty::t,
|
||||
f: iter_vec_block) -> block {
|
||||
let _icx = bcx.insn_ctxt(~"tvec::iter_vec_unboxed");
|
||||
let _icx = bcx.insn_ctxt("tvec::iter_vec_unboxed");
|
||||
let fill = get_fill(bcx, body_ptr);
|
||||
let dataptr = get_dataptr(bcx, body_ptr);
|
||||
return iter_vec_raw(bcx, dataptr, vec_ty, fill, f);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export make_free_glue, autoderef, duplicate;
|
|||
|
||||
fn make_free_glue(bcx: block, vptrptr: ValueRef, t: ty::t)
|
||||
-> block {
|
||||
let _icx = bcx.insn_ctxt(~"uniq::make_free_glue");
|
||||
let _icx = bcx.insn_ctxt("uniq::make_free_glue");
|
||||
let vptr = Load(bcx, vptrptr);
|
||||
do with_cond(bcx, IsNotNull(bcx, vptr)) |bcx| {
|
||||
let content_ty = content_ty(t);
|
||||
|
|
@ -33,7 +33,7 @@ fn autoderef(bcx: block, v: ValueRef, t: ty::t) -> {v: ValueRef, t: ty::t} {
|
|||
}
|
||||
|
||||
fn duplicate(bcx: block, v: ValueRef, t: ty::t) -> result {
|
||||
let _icx = bcx.insn_ctxt(~"uniq::duplicate");
|
||||
let _icx = bcx.insn_ctxt("uniq::duplicate");
|
||||
let content_ty = content_ty(t);
|
||||
let {bcx: bcx, box: dst_box, body: dst_body} =
|
||||
malloc_unique(bcx, content_ty);
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ import std::map::str_hash;
|
|||
type self_info = {
|
||||
self_ty: ty::t,
|
||||
node_id: ast::node_id,
|
||||
explicit_self: ast::self_ty_
|
||||
};
|
||||
|
||||
type fn_ctxt_ =
|
||||
|
|
@ -367,14 +368,20 @@ fn check_fn(ccx: @crate_ctxt,
|
|||
|
||||
fn check_method(ccx: @crate_ctxt, method: @ast::method,
|
||||
self_info: self_info) {
|
||||
|
||||
check_bare_fn(ccx, method.decl, method.body, method.id, some(self_info));
|
||||
}
|
||||
|
||||
fn check_class_member(ccx: @crate_ctxt, class_t: self_info,
|
||||
fn check_class_member(ccx: @crate_ctxt, self_ty: ty::t,
|
||||
node_id: ast::node_id,
|
||||
cm: @ast::class_member) {
|
||||
match cm.node {
|
||||
ast::instance_var(_,t,_,_,_) => (),
|
||||
ast::class_method(m) => check_method(ccx, m, class_t)
|
||||
ast::class_method(m) => {
|
||||
let class_t = {self_ty: self_ty, node_id: node_id,
|
||||
explicit_self: m.self_ty.node};
|
||||
check_method(ccx, m, class_t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -404,9 +411,11 @@ fn check_no_duplicate_fields(tcx: ty::ctxt, fields:
|
|||
fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def,
|
||||
id: ast::node_id, span: span) {
|
||||
let tcx = ccx.tcx;
|
||||
let class_t = {self_ty: ty::node_id_to_type(tcx, id), node_id: id};
|
||||
let self_ty = ty::node_id_to_type(tcx, id);
|
||||
|
||||
do option::iter(struct_def.ctor) |ctor| {
|
||||
let class_t = {self_ty: self_ty, node_id: id,
|
||||
explicit_self: ast::sty_by_ref};
|
||||
// typecheck the ctor
|
||||
check_bare_fn(ccx, ctor.node.dec,
|
||||
ctor.node.body, ctor.node.id,
|
||||
|
|
@ -416,6 +425,8 @@ fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def,
|
|||
}
|
||||
|
||||
do option::iter(struct_def.dtor) |dtor| {
|
||||
let class_t = {self_ty: self_ty, node_id: id,
|
||||
explicit_self: ast::sty_by_ref};
|
||||
// typecheck the dtor
|
||||
check_bare_fn(ccx, ast_util::dtor_dec(),
|
||||
dtor.node.body, dtor.node.id,
|
||||
|
|
@ -426,7 +437,7 @@ fn check_struct(ccx: @crate_ctxt, struct_def: @ast::struct_def,
|
|||
|
||||
// typecheck the members
|
||||
for struct_def.members.each |m| {
|
||||
check_class_member(ccx, class_t, m);
|
||||
check_class_member(ccx, self_ty, id, m);
|
||||
}
|
||||
// Check that there's at least one field
|
||||
let (fields,_) = split_class_items(struct_def.members);
|
||||
|
|
@ -450,9 +461,12 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
|||
let rp = ccx.tcx.region_paramd_items.contains_key(it.id);
|
||||
debug!{"item_impl %s with id %d rp %b",
|
||||
*it.ident, it.id, rp};
|
||||
let self_info = {self_ty: ccx.to_ty(rscope::type_rscope(rp), ty),
|
||||
node_id: it.id };
|
||||
for ms.each |m| { check_method(ccx, m, self_info);}
|
||||
let self_ty = ccx.to_ty(rscope::type_rscope(rp), ty);
|
||||
for ms.each |m| {
|
||||
let self_info = {self_ty: self_ty, node_id: it.id,
|
||||
explicit_self: m.self_ty.node };
|
||||
check_method(ccx, m, self_info)
|
||||
}
|
||||
}
|
||||
ast::item_trait(_, _, trait_methods) => {
|
||||
for trait_methods.each |trait_method| {
|
||||
|
|
@ -463,7 +477,8 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
|||
}
|
||||
provided(m) => {
|
||||
let self_info = {self_ty: ty::mk_self(ccx.tcx),
|
||||
node_id: it.id};
|
||||
node_id: it.id,
|
||||
explicit_self: m.self_ty.node};
|
||||
check_method(ccx, m, self_info);
|
||||
}
|
||||
}
|
||||
|
|
@ -742,7 +757,8 @@ fn check_expr(fcx: @fn_ctxt, expr: @ast::expr,
|
|||
// declared on the impl declaration e.g., `impl<A,B> for ~[(A,B)]`
|
||||
// would return ($0, $1) where $0 and $1 are freshly instantiated type
|
||||
// variables.
|
||||
fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty {
|
||||
fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id, require_rp: bool)
|
||||
-> ty_param_substs_and_ty {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
let {n_tps, rp, raw_ty} = if did.crate == ast::local_crate {
|
||||
|
|
@ -778,6 +794,7 @@ fn impl_self_ty(fcx: @fn_ctxt, did: ast::def_id) -> ty_param_substs_and_ty {
|
|||
raw_ty: ity.ty}
|
||||
};
|
||||
|
||||
let rp = rp || require_rp;
|
||||
let self_r = if rp {some(fcx.infcx.next_region_var_nb())} else {none};
|
||||
let tps = fcx.infcx.next_ty_vars(n_tps);
|
||||
|
||||
|
|
@ -2216,7 +2233,10 @@ fn ty_param_bounds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
|
|||
ast::def_self(_) => {
|
||||
match fcx.self_info {
|
||||
some(self_info) => {
|
||||
return no_params(self_info.self_ty);
|
||||
let self_region = fcx.in_scope_regions.find(ty::br_self);
|
||||
return no_params(method::transform_self_type_for_method(
|
||||
fcx.tcx(), self_region,
|
||||
self_info.self_ty, self_info.explicit_self));
|
||||
}
|
||||
none => {
|
||||
fcx.ccx.tcx.sess.span_bug(sp, ~"def_self with no self_info");
|
||||
|
|
|
|||
|
|
@ -20,28 +20,30 @@ type candidate = {
|
|||
entry: method_map_entry
|
||||
};
|
||||
|
||||
fn transform_self_type_for_method(fcx: @fn_ctxt,
|
||||
impl_ty: ty::t,
|
||||
method_info: MethodInfo)
|
||||
fn transform_self_type_for_method
|
||||
(tcx: ty::ctxt,
|
||||
self_region: option<ty::region>,
|
||||
impl_ty: ty::t,
|
||||
self_type: ast::self_ty_)
|
||||
-> ty::t {
|
||||
match method_info.self_type {
|
||||
match self_type {
|
||||
sty_static => {
|
||||
fcx.tcx().sess.bug(~"calling transform_self_type_for_method on \
|
||||
static method");
|
||||
tcx.sess.bug(~"calling transform_self_type_for_method on \
|
||||
static method");
|
||||
}
|
||||
sty_by_ref | sty_value => {
|
||||
impl_ty
|
||||
}
|
||||
sty_region(r, mutability) => {
|
||||
// XXX: dummy_sp is unfortunate here.
|
||||
let region = ast_region_to_region(fcx, fcx, dummy_sp(), r);
|
||||
mk_rptr(fcx.ccx.tcx, region, { ty: impl_ty, mutbl: mutability })
|
||||
sty_region(mutability) => {
|
||||
mk_rptr(tcx,
|
||||
self_region.expect(~"self region missing for &self param"),
|
||||
{ ty: impl_ty, mutbl: mutability })
|
||||
}
|
||||
sty_box(mutability) => {
|
||||
mk_box(fcx.ccx.tcx, { ty: impl_ty, mutbl: mutability })
|
||||
mk_box(tcx, { ty: impl_ty, mutbl: mutability })
|
||||
}
|
||||
sty_uniq(mutability) => {
|
||||
mk_uniq(fcx.ccx.tcx, { ty: impl_ty, mutbl: mutability })
|
||||
mk_uniq(tcx, { ty: impl_ty, mutbl: mutability })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -368,14 +370,17 @@ class lookup {
|
|||
// Check whether this impl has a method with the right name.
|
||||
for im.methods.find(|m| m.ident == self.m_name).each |m| {
|
||||
|
||||
let need_rp = match m.self_type { ast::sty_region(_) => true,
|
||||
_ => false };
|
||||
|
||||
// determine the `self` of the impl with fresh
|
||||
// variables for each parameter:
|
||||
let {substs: impl_substs, ty: impl_ty} =
|
||||
impl_self_ty(self.fcx, im.did);
|
||||
impl_self_ty(self.fcx, im.did, need_rp);
|
||||
|
||||
let impl_ty = transform_self_type_for_method(self.fcx,
|
||||
impl_ty,
|
||||
*m);
|
||||
let impl_ty = transform_self_type_for_method(
|
||||
self.tcx(), impl_substs.self_r,
|
||||
impl_ty, m.self_type);
|
||||
|
||||
// Depending on our argument, we find potential
|
||||
// matches either by checking subtypability or
|
||||
|
|
|
|||
|
|
@ -22,6 +22,17 @@ fn replace_bound_regions_in_fn_ty(
|
|||
|
||||
let mut all_tys = ty::tys_in_fn_ty(fn_ty);
|
||||
|
||||
match self_info {
|
||||
some({explicit_self: ast::sty_region(m), _}) => {
|
||||
let region = ty::re_bound(ty::br_self);
|
||||
let ty = ty::mk_rptr(tcx, region,
|
||||
{ ty: ty::mk_self(tcx), mutbl: m });
|
||||
vec::push(all_tys, ty);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
for self_ty.each |t| { vec::push(all_tys, t) }
|
||||
|
||||
debug!{"replace_bound_regions_in_fn_ty(self_info.self_ty=%?, fn_ty=%s, \
|
||||
|
|
@ -50,7 +61,7 @@ fn replace_bound_regions_in_fn_ty(
|
|||
// Glue updated self_ty back together with its original node_id.
|
||||
let new_self_info = match self_info {
|
||||
some(s) => match check t_self {
|
||||
some(t) => some({self_ty: t, node_id: s.node_id})
|
||||
some(t) => some({self_ty: t with s})
|
||||
// this 'none' case shouldn't happen
|
||||
},
|
||||
none => none
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ fn lookup_vtable(fcx: @fn_ctxt, sp: span, ty: ty::t, trait_ty: ty::t,
|
|||
// check whether the type unifies with the type
|
||||
// that the impl is for, and continue if not
|
||||
let {substs: substs, ty: for_ty} =
|
||||
impl_self_ty(fcx, im.did);
|
||||
impl_self_ty(fcx, im.did, false);
|
||||
let im_bs = ty::lookup_item_type(tcx, im.did).bounds;
|
||||
match fcx.mk_subty(ty, for_ty) {
|
||||
result::err(_) => again,
|
||||
|
|
|
|||
|
|
@ -77,10 +77,10 @@ fn default_config(input_crate: ~str) -> config {
|
|||
}
|
||||
}
|
||||
|
||||
type program_output = fn~(~str, ~[~str]) ->
|
||||
type program_output = fn~((&str), (&[~str])) ->
|
||||
{status: int, out: ~str, err: ~str};
|
||||
|
||||
fn mock_program_output(_prog: ~str, _args: ~[~str]) -> {
|
||||
fn mock_program_output(_prog: &str, _args: &[~str]) -> {
|
||||
status: int, out: ~str, err: ~str
|
||||
} {
|
||||
{
|
||||
|
|
@ -231,7 +231,7 @@ fn should_find_pandoc() {
|
|||
output_format: pandoc_html
|
||||
with default_config(~"test")
|
||||
};
|
||||
let mock_program_output = fn~(_prog: ~str, _args: ~[~str]) -> {
|
||||
let mock_program_output = fn~(_prog: &str, _args: &[~str]) -> {
|
||||
status: int, out: ~str, err: ~str
|
||||
} {
|
||||
{
|
||||
|
|
@ -248,7 +248,7 @@ fn should_error_with_no_pandoc() {
|
|||
output_format: pandoc_html
|
||||
with default_config(~"test")
|
||||
};
|
||||
let mock_program_output = fn~(_prog: ~str, _args: ~[~str]) -> {
|
||||
let mock_program_output = fn~(_prog: &str, _args: &[~str]) -> {
|
||||
status: int, out: ~str, err: ~str
|
||||
} {
|
||||
{
|
||||
|
|
|
|||
|
|
@ -83,7 +83,9 @@ fn write_markdown(
|
|||
doc: doc::doc,
|
||||
+writer_factory: writer_factory
|
||||
) {
|
||||
do par::map(doc.pages) |page| {
|
||||
// FIXME #2484: There is easy parallelism to be had here but
|
||||
// we don't want to spawn too many pandoc processes
|
||||
do doc.pages.map |page| {
|
||||
let ctxt = {
|
||||
w: writer_factory(page)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ fn pandoc_writer(
|
|||
];
|
||||
|
||||
do generic_writer |markdown| {
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
debug!{"pandoc cmd: %s", pandoc_cmd};
|
||||
debug!{"pandoc args: %s", str::connect(pandoc_args, ~" ")};
|
||||
|
|
@ -97,7 +97,7 @@ fn pandoc_writer(
|
|||
let pipe_out = os::pipe();
|
||||
let pipe_err = os::pipe();
|
||||
let pid = run::spawn_process(
|
||||
pandoc_cmd, pandoc_args, none, none,
|
||||
pandoc_cmd, pandoc_args, &none, &none,
|
||||
pipe_in.in, pipe_out.out, pipe_err.out);
|
||||
|
||||
let writer = io::fd_writer(pipe_in.out, false);
|
||||
|
|
@ -254,9 +254,9 @@ mod test {
|
|||
}
|
||||
|
||||
fn write_file(path: ~str, s: ~str) {
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
match io::file_writer(path, ~[io::create, io::truncate]) {
|
||||
match io::file_writer(path, ~[io::Create, io::Truncate]) {
|
||||
result::ok(writer) => {
|
||||
writer.write_str(s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import std::time::precise_time_s;
|
|||
import std::map;
|
||||
import std::map::{map, hashmap};
|
||||
|
||||
import io::reader;
|
||||
import io::Reader;
|
||||
|
||||
fn main(argv: ~[~str]) {
|
||||
#macro[
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std;
|
||||
import dvec::dvec;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
fn collect_raw(num: uint) -> ~[uint] {
|
||||
let mut result = ~[];
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import std::map::hashmap;
|
|||
import std::deque;
|
||||
import std::deque::t;
|
||||
import std::par;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import comm::*;
|
||||
import int::abs;
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ type bfs_result = ~[node_id];
|
|||
fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
|
||||
let r = rand::xorshift();
|
||||
|
||||
fn choose_edge(i: node_id, j: node_id, scale: uint, r: rand::rng)
|
||||
fn choose_edge(i: node_id, j: node_id, scale: uint, r: rand::Rng)
|
||||
-> (node_id, node_id) {
|
||||
|
||||
let A = 0.57;
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
// xfail-pretty
|
||||
|
||||
use std;
|
||||
import io::writer;
|
||||
import io::writer_util;
|
||||
import io::Writer;
|
||||
import io::WriterUtil;
|
||||
|
||||
import pipes::{port, chan, shared_chan};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
// xfail-pretty
|
||||
|
||||
use std;
|
||||
import io::writer;
|
||||
import io::writer_util;
|
||||
import io::Writer;
|
||||
import io::WriterUtil;
|
||||
|
||||
import pipes::{port, port_set, chan};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// I *think* it's the same, more or less.
|
||||
|
||||
use std;
|
||||
import io::writer;
|
||||
import io::writer_util;
|
||||
import io::Writer;
|
||||
import io::WriterUtil;
|
||||
|
||||
enum request {
|
||||
get_count,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import vec;
|
|||
import uint;
|
||||
import int;
|
||||
import str;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
fn LINE_LENGTH() -> uint { return 60u; }
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ fn select_random(r: u32, genelist: ~[aminoacids]) -> char {
|
|||
return bisect(genelist, 0u, vec::len::<aminoacids>(genelist) - 1u, r);
|
||||
}
|
||||
|
||||
fn make_random_fasta(wr: io::writer, id: ~str, desc: ~str, genelist: ~[aminoacids], n: int) {
|
||||
fn make_random_fasta(wr: io::Writer, id: ~str, desc: ~str, genelist: ~[aminoacids], n: int) {
|
||||
wr.write_line(~">" + id + ~" " + desc);
|
||||
let rng = @{mut last: rand::rng().next()};
|
||||
let mut op: ~str = ~"";
|
||||
|
|
@ -58,7 +58,7 @@ fn make_random_fasta(wr: io::writer, id: ~str, desc: ~str, genelist: ~[aminoacid
|
|||
if str::len(op) > 0u { wr.write_line(op); }
|
||||
}
|
||||
|
||||
fn make_repeat_fasta(wr: io::writer, id: ~str, desc: ~str, s: ~str, n: int) unsafe {
|
||||
fn make_repeat_fasta(wr: io::Writer, id: ~str, desc: ~str, s: ~str, n: int) unsafe {
|
||||
wr.write_line(~">" + id + ~" " + desc);
|
||||
let mut op: ~str = ~"";
|
||||
let sl: uint = str::len(s);
|
||||
|
|
@ -85,7 +85,7 @@ fn main(args: ~[~str]) {
|
|||
};
|
||||
|
||||
let writer = if os::getenv(~"RUST_BENCH").is_some() {
|
||||
result::get(io::file_writer(~"./shootout-fasta.data", ~[io::truncate, io::create]))
|
||||
result::get(io::file_writer(~"./shootout-fasta.data", ~[io::Truncate, io::Create]))
|
||||
} else {
|
||||
io::stdout()
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
// writes pbm image to output path
|
||||
|
||||
use std;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import std::map::hashmap;
|
||||
|
||||
struct cmplx {
|
||||
|
|
@ -90,12 +90,12 @@ fn chanmb(i: uint, size: uint, ch: comm::chan<line>) -> ()
|
|||
|
||||
type devnull = {dn: int};
|
||||
|
||||
impl devnull: io::writer {
|
||||
impl devnull: io::Writer {
|
||||
fn write(_b: &[const u8]) {}
|
||||
fn seek(_i: int, _s: io::seek_style) {}
|
||||
fn seek(_i: int, _s: io::SeekStyle) {}
|
||||
fn tell() -> uint {0_u}
|
||||
fn flush() -> int {0}
|
||||
fn get_type() -> io::writer_type { io::file }
|
||||
fn get_type() -> io::WriterType { io::File }
|
||||
}
|
||||
|
||||
fn writer(path: ~str, writech: comm::chan<comm::chan<line>>, size: uint)
|
||||
|
|
@ -103,9 +103,9 @@ fn writer(path: ~str, writech: comm::chan<comm::chan<line>>, size: uint)
|
|||
let p: comm::port<line> = comm::port();
|
||||
let ch = comm::chan(p);
|
||||
comm::send(writech, ch);
|
||||
let cout: io::writer = match path {
|
||||
let cout: io::Writer = match path {
|
||||
~"" => {
|
||||
{dn: 0} as io::writer
|
||||
{dn: 0} as io::Writer
|
||||
}
|
||||
~"-" => {
|
||||
io::stdout()
|
||||
|
|
@ -113,7 +113,7 @@ fn writer(path: ~str, writech: comm::chan<comm::chan<line>>, size: uint)
|
|||
_ => {
|
||||
result::get(
|
||||
io::file_writer(path,
|
||||
~[io::create, io::truncate]))
|
||||
~[io::Create, io::Truncate]))
|
||||
}
|
||||
};
|
||||
cout.write_line(~"P4");
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
use std;
|
||||
|
||||
import std::{time, getopts};
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
import int::range;
|
||||
import pipes::port;
|
||||
import pipes::chan;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use std;
|
||||
import std::smallintmap;
|
||||
import std::smallintmap::smallintmap;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
fn append_sequential(min: uint, max: uint, map: smallintmap<uint>) {
|
||||
for uint::range(min, max) |i| {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std;
|
||||
|
||||
import std::bitv;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
// Computes a single solution to a given 9x9 sudoku
|
||||
//
|
||||
|
|
@ -28,7 +28,7 @@ type grid = ~[~[mut u8]];
|
|||
enum grid_t { grid_ctor(grid), }
|
||||
|
||||
// read a sudoku problem from file f
|
||||
fn read_grid(f: io::reader) -> grid_t {
|
||||
fn read_grid(f: io::Reader) -> grid_t {
|
||||
assert f.read_line() == ~"9,9"; /* assert first line is exactly "9,9" */
|
||||
|
||||
let g = vec::from_fn(10u, {|_i|
|
||||
|
|
@ -116,7 +116,7 @@ fn solve_grid(g: grid_t) {
|
|||
}
|
||||
}
|
||||
|
||||
fn write_grid(f: io::writer, g: grid_t) {
|
||||
fn write_grid(f: io::Writer, g: grid_t) {
|
||||
for u8::range(0u8, 9u8) |row| {
|
||||
f.write_str(fmt!{"%u", (*g)[row][0] as uint});
|
||||
for u8::range(1u8, 9u8) |col| {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import std::map;
|
|||
import std::map::hashmap;
|
||||
import vec;
|
||||
import io;
|
||||
import io::writer_util;
|
||||
import io::WriterUtil;
|
||||
|
||||
import std::time;
|
||||
import u64;
|
||||
|
|
@ -73,7 +73,7 @@ fn join(t: joinable_task) {
|
|||
t.recv()
|
||||
}
|
||||
|
||||
impl io::reader: word_reader {
|
||||
impl io::Reader: word_reader {
|
||||
fn read_word() -> option<~str> { read_word(self) }
|
||||
}
|
||||
|
||||
|
|
@ -331,7 +331,7 @@ fn main(argv: ~[~str]) {
|
|||
+ u64::str(elapsed) + ~"ms");
|
||||
}
|
||||
|
||||
fn read_word(r: io::reader) -> option<~str> {
|
||||
fn read_word(r: io::Reader) -> option<~str> {
|
||||
let mut w = ~"";
|
||||
|
||||
while !r.eof() {
|
||||
|
|
@ -350,7 +350,7 @@ fn is_word_char(c: char) -> bool {
|
|||
|
||||
class random_word_reader: word_reader {
|
||||
let mut remaining: uint;
|
||||
let rng: rand::rng;
|
||||
let rng: rand::Rng;
|
||||
new(count: uint) {
|
||||
self.remaining = count;
|
||||
self.rng = rand::rng();
|
||||
|
|
|
|||
11
src/test/compile-fail/arc-rw-cond-shouldnt-escape.rs
Normal file
11
src/test/compile-fail/arc-rw-cond-shouldnt-escape.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// error-pattern: reference is not valid outside of its lifetime
|
||||
use std;
|
||||
import std::arc;
|
||||
fn main() {
|
||||
let x = ~arc::rw_arc(1);
|
||||
let mut y = none;
|
||||
do x.write_cond |_one, cond| {
|
||||
y = some(cond);
|
||||
}
|
||||
option::unwrap(y).wait();
|
||||
}
|
||||
12
src/test/compile-fail/arc-rw-read-mode-shouldnt-escape.rs
Normal file
12
src/test/compile-fail/arc-rw-read-mode-shouldnt-escape.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// error-pattern: reference is not valid outside of its lifetime
|
||||
use std;
|
||||
import std::arc;
|
||||
fn main() {
|
||||
let x = ~arc::rw_arc(1);
|
||||
let mut y = none;
|
||||
do x.write_downgrade |write_mode| {
|
||||
y = some(x.downgrade(write_mode));
|
||||
}
|
||||
// Adding this line causes a method unification failure instead
|
||||
// do (&option::unwrap(y)).read |state| { assert *state == 1; }
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// error-pattern: reference is not valid outside of its lifetime
|
||||
use std;
|
||||
import std::arc;
|
||||
fn main() {
|
||||
let x = ~arc::rw_arc(1);
|
||||
let mut y = none;
|
||||
do x.write_downgrade |write_mode| {
|
||||
do (&write_mode).write_cond |_one, cond| {
|
||||
y = some(cond);
|
||||
}
|
||||
}
|
||||
option::unwrap(y).wait();
|
||||
}
|
||||
12
src/test/compile-fail/arc-rw-write-mode-shouldnt-escape.rs
Normal file
12
src/test/compile-fail/arc-rw-write-mode-shouldnt-escape.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// error-pattern: reference is not valid outside of its lifetime
|
||||
use std;
|
||||
import std::arc;
|
||||
fn main() {
|
||||
let x = ~arc::rw_arc(1);
|
||||
let mut y = none;
|
||||
do x.write_downgrade |write_mode| {
|
||||
y = some(write_mode);
|
||||
}
|
||||
// Adding this line causes a method unification failure instead
|
||||
// do (&option::unwrap(y)).write |state| { assert *state == 1; }
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
fn use(_i: int) {}
|
||||
fn user(_i: int) {}
|
||||
|
||||
fn foo() {
|
||||
// Here, i is *moved* into the closure: Not actually OK
|
||||
let mut i = 0;
|
||||
do task::spawn {
|
||||
use(i); //~ ERROR mutable variables cannot be implicitly captured
|
||||
user(i); //~ ERROR mutable variables cannot be implicitly captured
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ fn bar() {
|
|||
let mut i = 0;
|
||||
while i < 10 {
|
||||
do task::spawn {
|
||||
use(i); //~ ERROR mutable variables cannot be implicitly captured
|
||||
user(i); //~ ERROR mutable variables cannot be implicitly captured
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ fn car() {
|
|||
let mut i = 0;
|
||||
while i < 10 {
|
||||
do task::spawn |copy i| {
|
||||
use(i);
|
||||
user(i);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
|
|
|||
11
src/test/compile-fail/sync-rwlock-cond-shouldnt-escape.rs
Normal file
11
src/test/compile-fail/sync-rwlock-cond-shouldnt-escape.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// error-pattern: reference is not valid outside of its lifetime
|
||||
use std;
|
||||
import std::sync;
|
||||
fn main() {
|
||||
let x = ~sync::rwlock();
|
||||
let mut y = none;
|
||||
do x.write_cond |cond| {
|
||||
y = some(cond);
|
||||
}
|
||||
option::unwrap(y).wait();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// error-pattern: reference is not valid outside of its lifetime
|
||||
use std;
|
||||
import std::sync;
|
||||
fn main() {
|
||||
let x = ~sync::rwlock();
|
||||
let mut y = none;
|
||||
do x.write_downgrade |write_mode| {
|
||||
y = some(x.downgrade(write_mode));
|
||||
}
|
||||
// Adding this line causes a method unification failure instead
|
||||
// do (&option::unwrap(y)).read { }
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
// error-pattern: reference is not valid outside of its lifetime
|
||||
use std;
|
||||
import std::sync;
|
||||
fn main() {
|
||||
let x = ~sync::rwlock();
|
||||
let mut y = none;
|
||||
do x.write_downgrade |write_mode| {
|
||||
do (&write_mode).write_cond |cond| {
|
||||
y = some(cond);
|
||||
}
|
||||
}
|
||||
option::unwrap(y).wait();
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// error-pattern: reference is not valid outside of its lifetime
|
||||
use std;
|
||||
import std::sync;
|
||||
fn main() {
|
||||
let x = ~sync::rwlock();
|
||||
let mut y = none;
|
||||
do x.write_downgrade |write_mode| {
|
||||
y = some(write_mode);
|
||||
}
|
||||
// Adding this line causes a method unification failure instead
|
||||
// do (&option::unwrap(y)).write { }
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
// xfail-test
|
||||
|
||||
use std;
|
||||
|
||||
fn f() {
|
||||
}
|
||||
|
||||
import std::io::println; //~ ERROR view items must be declared at the top
|
||||
import std::net; //~ ERROR view items must be declared at the top
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue