Merge remote-tracking branch 'original/incoming' into incoming
This commit is contained in:
commit
0e3bec0ced
222 changed files with 2009 additions and 1665 deletions
|
|
@ -9,9 +9,11 @@ Aleksander Balicki <balicki.aleksander@gmail.com>
|
|||
Alex Rønne Petersen <alex@lycus.org>
|
||||
Alexander Stavonin <a.stavonin@gmail.com>
|
||||
Andreas Gal <gal@mozilla.com>
|
||||
Andrew Paseltiner <apaseltiner@gmail.com>
|
||||
Arkaitz Jimenez <arkaitzj@gmail.com>
|
||||
Armin Ronacher <armin.ronacher@active-4.com>
|
||||
Austin Seipp <mad.one@gmail.com>
|
||||
auREAX <mark@xn--hwg34fba.ws>
|
||||
Ben Blum <bblum@andrew.cmu.edu>
|
||||
Ben Striegel <ben.striegel@gmail.com>
|
||||
Benjamin Herr <ben@0x539.de>
|
||||
|
|
@ -41,6 +43,7 @@ Evan McClanahan <evan@evanmcc.com>
|
|||
Francisco Souza <f@souza.cc>
|
||||
Gareth Daniel Smith <garethdanielsmith@gmail.com>
|
||||
Glenn Willen <gwillen@nerdnet.org>
|
||||
Gonçalo Cabrita <_@gmcabrita.com>
|
||||
Graham Fawcett <fawcett@uwindsor.ca>
|
||||
Grahame Bowland <grahame@angrygoats.net>
|
||||
Haitao Li <lihaitao@gmail.com>
|
||||
|
|
@ -103,4 +106,5 @@ Tomoki Aonuma <uasi@99cm.org>
|
|||
Tycho Sci <tychosci@gmail.com>
|
||||
Vincent Belliard <vincent@famillebelliard.fr>
|
||||
Wade Mealing <wmealing@gmail.com>
|
||||
Yasuhiro Fujii <y-fujii@mimosa-pudica.net>
|
||||
Zack Corr <zackcorr95@gmail.com>
|
||||
|
|
|
|||
73
configure
vendored
73
configure
vendored
|
|
@ -295,6 +295,7 @@ opt manage-submodules 1 "let the build manage the git submodules"
|
|||
opt mingw-cross 0 "cross-compile for win32 using mingw"
|
||||
opt clang 0 "prefer clang to gcc for building the runtime"
|
||||
opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
|
||||
opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched kernels)"
|
||||
valopt prefix "/usr/local" "set installation prefix"
|
||||
valopt local-rust-root "/usr/local" "set prefix for local rust binary"
|
||||
valopt llvm-root "" "set LLVM root"
|
||||
|
|
@ -343,6 +344,11 @@ probe CFG_PDFLATEX pdflatex
|
|||
probe CFG_XETEX xetex
|
||||
probe CFG_LUATEX luatex
|
||||
probe CFG_NODE nodejs node
|
||||
if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ]
|
||||
then
|
||||
probe CFG_PAXCTL paxctl /sbin/paxctl
|
||||
probe CFG_ZCAT zcat
|
||||
fi
|
||||
|
||||
if [ ! -z "$CFG_PANDOC" ]
|
||||
then
|
||||
|
|
@ -354,6 +360,51 @@ then
|
|||
fi
|
||||
fi
|
||||
|
||||
if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ]
|
||||
then
|
||||
if [ ! -z "$CFG_ENABLE_PAX_FLAGS" -a -z "$CFG_PAXCTL" ]
|
||||
then
|
||||
err "enabled PaX markings but no paxctl binary found"
|
||||
fi
|
||||
|
||||
if [ -z "$CFG_DISABLE_PAX_FLAGS" ]
|
||||
then
|
||||
# GRSecurity/PaX detection. This can be very flaky.
|
||||
GRSEC_DETECTED=
|
||||
|
||||
# /dev/grsec only exists if CONFIG_GRKERNSEC_NO_RBAC is not set.
|
||||
# /proc/sys/kernel/grsecurity is not available if ÇONFIG_GRKERNSEC_SYSCTL is not set.
|
||||
if [ -e /dev/grsec -o -d /proc/sys/kernel/grsecurity ]
|
||||
then
|
||||
GRSEC_DETECTED=1
|
||||
# /proc/config.gz is normally only available to root, and only if CONFIG_IKCONFIG_PROC has been set.
|
||||
elif [ -r /proc/config.gz -a ! -z "$CFG_ZCAT" ]
|
||||
then
|
||||
if "$CFG_ZCAT" /proc/config.gz | grep --quiet "CONFIG_GRKERNSEC=y"
|
||||
then
|
||||
GRSEC_DETECTED=1
|
||||
fi
|
||||
# Flaky.
|
||||
elif grep --quiet grsec /proc/version
|
||||
then
|
||||
GRSEC_DETECTED=1
|
||||
fi
|
||||
|
||||
if [ ! -z "$GRSEC_DETECTED" ]
|
||||
then
|
||||
step_msg "GRSecurity: yes"
|
||||
if [ ! -z "$CFG_PAXCTL" ]
|
||||
then
|
||||
CFG_ENABLE_PAX_FLAGS=1
|
||||
else
|
||||
warn "GRSecurity kernel detected but no paxctl binary found: not setting CFG_ENABLE_PAX_FLAGS"
|
||||
fi
|
||||
else
|
||||
step_msg "GRSecurity: no"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -z "$CFG_ENABLE_LOCAL_RUST" ]
|
||||
then
|
||||
if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc ]
|
||||
|
|
@ -523,15 +574,23 @@ then
|
|||
msg "git: submodule sync"
|
||||
"${CFG_GIT}" submodule --quiet sync
|
||||
|
||||
msg "git: submodule update"
|
||||
"${CFG_GIT}" submodule --quiet update --init
|
||||
need_ok "git failed"
|
||||
|
||||
msg "git: submodule foreach sync"
|
||||
"${CFG_GIT}" submodule --quiet foreach --recursive git submodule sync
|
||||
need_ok "git failed"
|
||||
|
||||
msg "git: submodule foreach update"
|
||||
"${CFG_GIT}" submodule --quiet update --init --recursive
|
||||
need_ok "git failed"
|
||||
|
||||
# NB: this is just for the sake of getting the submodule SHA1 values
|
||||
# and status written into the build log.
|
||||
msg "git: submodule status"
|
||||
"${CFG_GIT}" submodule status --recursive
|
||||
|
||||
msg "git: submodule update"
|
||||
"${CFG_GIT}" submodule --quiet update --init --recursive
|
||||
need_ok "git failed"
|
||||
|
||||
msg "git: submodule clobber"
|
||||
"${CFG_GIT}" submodule --quiet foreach --recursive git clean -dxf
|
||||
need_ok "git failed"
|
||||
|
|
@ -699,6 +758,12 @@ putvar CFG_C_COMPILER
|
|||
putvar CFG_LIBDIR
|
||||
putvar CFG_DISABLE_MANAGE_SUBMODULES
|
||||
|
||||
if [ ! -z "$CFG_ENABLE_PAX_FLAGS" ]
|
||||
then
|
||||
putvar CFG_ENABLE_PAX_FLAGS
|
||||
putvar CFG_PAXCTL
|
||||
fi
|
||||
|
||||
if [ ! -z $BAD_PANDOC ]
|
||||
then
|
||||
CFG_PANDOC=
|
||||
|
|
|
|||
|
|
@ -60,9 +60,10 @@ while ((line = lines[cur++]) != null) {
|
|||
var html = '<pre class="cm-s-default">', curstr = "", curstyle = null;
|
||||
function add(str, style) {
|
||||
if (style != curstyle) {
|
||||
if (curstyle) html += '<span class="cm-' + curstyle + '">' + curstr
|
||||
+ "</span>";
|
||||
else if (curstr) html += curstr;
|
||||
if (curstyle) html +=
|
||||
'<span class="cm-' + CodeMirror.htmlEscape(curstyle) + '">' +
|
||||
CodeMirror.htmlEscape(curstr) + "</span>";
|
||||
else if (curstr) html += CodeMirror.htmlEscape(curstr);
|
||||
curstr = str; curstyle = style;
|
||||
} else curstr += str;
|
||||
}
|
||||
|
|
|
|||
269
doc/rust.md
269
doc/rust.md
|
|
@ -773,8 +773,8 @@ A view item manages the namespace of a module; it does not define new items
|
|||
but simply changes the visibility of other items. There are several kinds of
|
||||
view item:
|
||||
|
||||
* [extern mod declarations](#extern-mod-declarations)
|
||||
* [use declarations](#use-declarations)
|
||||
* [`extern mod` declarations](#extern-mod-declarations)
|
||||
* [`use` declarations](#use-declarations)
|
||||
|
||||
##### Extern mod declarations
|
||||
|
||||
|
|
@ -784,7 +784,7 @@ link_attrs : link_attr [ ',' link_attrs ] + ;
|
|||
link_attr : ident '=' literal ;
|
||||
~~~~~~~~
|
||||
|
||||
An _extern mod declaration_ specifies a dependency on an external crate.
|
||||
An _`extern mod` declaration_ specifies a dependency on an external crate.
|
||||
The external crate is then bound into the declaring scope as the `ident` provided in the `extern_mod_decl`.
|
||||
|
||||
The external crate is resolved to a specific `soname` at compile time, and a
|
||||
|
|
@ -960,24 +960,12 @@ pure fn pure_length<T>(ls: List<T>) -> uint { ... }
|
|||
pure fn nonempty_list<T>(ls: List<T>) -> bool { pure_length(ls) > 0u }
|
||||
~~~~
|
||||
|
||||
*TODO:* should actually define referential transparency.
|
||||
|
||||
The effect checking rules previously enumerated are a restricted set
|
||||
of typechecking rules meant to approximate the universe of observably
|
||||
referentially transparent Rust procedures conservatively. Sometimes,
|
||||
these rules are *too* restrictive. Rust allows programmers to violate
|
||||
these rules by writing pure functions that the compiler cannot prove
|
||||
to be referentially transparent, using "unsafe blocks". When writing
|
||||
code that uses unsafe blocks, programmers should always be aware that
|
||||
they have an obligation to show that the code *behaves* referentially
|
||||
transparently at all times, even if the compiler cannot *prove*
|
||||
automatically that the code is referentially transparent. In the
|
||||
presence of unsafe blocks, the compiler provides no static guarantee
|
||||
that the code will behave as expected at runtime. Rather, the
|
||||
programmer has an independent obligation to verify the semantics of
|
||||
the pure functions they write.
|
||||
|
||||
*TODO:* last two sentences are vague.
|
||||
These purity-checking rules approximate the concept of referential transparency:
|
||||
that a call-expression could be rewritten with the literal-expression of its return value, without changing the meaning of the program.
|
||||
Since they are an approximation, sometimes these rules are *too* restrictive.
|
||||
Rust allows programmers to violate these rules using [`unsafe` blocks](#unsafe-blocks).
|
||||
As with any `unsafe` block, those that violate static purity carry transfer the burden of safety-proof from the compiler to the programmer.
|
||||
Programmers should exercise caution when breaking such rules.
|
||||
|
||||
An example of a pure function that uses an unsafe block:
|
||||
|
||||
|
|
@ -1045,6 +1033,28 @@ Similarly, [trait](#traits) bounds can be specified for type
|
|||
parameters to allow methods with that trait to be called on values
|
||||
of that type.
|
||||
|
||||
#### Unsafe functions
|
||||
|
||||
Unsafe functions are those containing unsafe operations that are not contained in an [`unsafe` block](#unsafe-blocks).
|
||||
|
||||
Unsafe operations are those that potentially violate the memory-safety guarantees of Rust's static semantics.
|
||||
Specifically, the following operations are considered unsafe:
|
||||
|
||||
- Dereferencing a [raw pointer](#pointer-types)
|
||||
- Casting a [raw pointer](#pointer-types) to a safe pointer type
|
||||
- Breaking the [purity-checking rules](#pure-functions)
|
||||
- Calling an unsafe function
|
||||
|
||||
##### Unsafe blocks
|
||||
|
||||
A block of code can also be prefixed with the `unsafe` keyword,
|
||||
to permit a sequence of unsafe operations in an otherwise-safe function.
|
||||
This facility exists because the static semantics of a Rust are a necessary approximation of the dynamic semantics.
|
||||
When a programmer has sufficient conviction that a sequence of unsafe operations is actually safe,
|
||||
they can encapsulate that sequence (taken as a whole) within an `unsafe` block.
|
||||
The compiler will consider uses of such code "safe", to the surrounding context.
|
||||
|
||||
|
||||
#### Extern functions
|
||||
|
||||
Extern functions are part of Rust's foreign function interface, providing
|
||||
|
|
@ -1059,7 +1069,7 @@ extern fn new_vec() -> ~[int] { ~[] }
|
|||
~~~
|
||||
|
||||
Extern functions may not be called from Rust code, but their value
|
||||
may be taken as an unsafe `u8` pointer.
|
||||
may be taken as a raw `u8` pointer.
|
||||
|
||||
~~~
|
||||
# extern fn new_vec() -> ~[int] { ~[] }
|
||||
|
|
@ -1468,6 +1478,25 @@ structure of expressions. Blocks themselves are expressions, so the nesting
|
|||
sequence of block, statement, expression, and block can repeatedly nest to an
|
||||
arbitrary depth.
|
||||
|
||||
#### Lvalues, rvalues and temporaries
|
||||
|
||||
Expressions are divided into two main categories: _lvalues_ and _rvalues_.
|
||||
Likewise within each expression, sub-expressions may occur in _lvalue context_ or _rvalue context_.
|
||||
The evaluation of an expression depends both on its own category and the context it occurs within.
|
||||
|
||||
Path, field and index expressions are lvalues.
|
||||
All other expressions are rvalues.
|
||||
|
||||
The left operand of an assignment expression and the operand of the borrow operator are lvalue contexts.
|
||||
All other expression contexts are rvalue contexts.
|
||||
|
||||
When an lvalue is evaluated in an _lvalue context_, it denotes a memory location;
|
||||
when evaluated in an _rvalue context_, it denotes the value held _in_ that memory location.
|
||||
|
||||
When an rvalue is used in lvalue context, a temporary un-named lvalue is created and used instead.
|
||||
A temporary's lifetime equals the largest lifetime of any borrowed pointer that points to it.
|
||||
|
||||
|
||||
### Literal expressions
|
||||
|
||||
A _literal expression_ consists of one of the [literal](#literals)
|
||||
|
|
@ -1708,9 +1737,9 @@ A type cast expression is denoted with the binary operator `as`.
|
|||
Executing an `as` expression casts the value on the left-hand side to the type
|
||||
on the right-hand side.
|
||||
|
||||
A numeric value can be cast to any numeric type. An unsafe pointer value can
|
||||
be cast to or from any integral type or unsafe pointer type. Any other cast
|
||||
is unsupported and will fail to compile.
|
||||
A numeric value can be cast to any numeric type.
|
||||
A raw pointer value can be cast to or from any integral type or raw pointer type.
|
||||
Any other cast is unsupported and will fail to compile.
|
||||
|
||||
An example of an `as` expression:
|
||||
|
||||
|
|
@ -2277,30 +2306,25 @@ logging level:
|
|||
// Full version, logging a value.
|
||||
log(core::error, ~"file not found: " + filename);
|
||||
|
||||
// Log-level abbreviated, since core::* is imported by default.
|
||||
// Log-level abbreviated, since core::* is used by default.
|
||||
log(error, ~"file not found: " + filename);
|
||||
|
||||
// Formatting the message using a format-string and #fmt
|
||||
// Formatting the message using a format-string and fmt!
|
||||
log(error, fmt!("file not found: %s", filename));
|
||||
|
||||
// Using the #error macro, that expands to the previous call.
|
||||
// Using the error! macro, that expands to the previous call.
|
||||
error!("file not found: %s", filename);
|
||||
~~~~
|
||||
|
||||
A `log` expression is *not evaluated* when logging at the specified
|
||||
logging-level, module or task is disabled at runtime. This makes inactive
|
||||
`log` expressions very cheap; they should be used extensively in Rust
|
||||
code, as diagnostic aids, as they add little overhead beyond a single
|
||||
integer-compare and branch at runtime.
|
||||
A `log` expression is *not evaluated* when logging at the specified logging-level, module or task is disabled at runtime.
|
||||
This makes inactive `log` expressions very cheap;
|
||||
they should be used extensively in Rust code, as diagnostic aids,
|
||||
as they add little overhead beyond a single integer-compare and branch at runtime.
|
||||
|
||||
Logging is presently implemented as a language built-in feature, as it makes
|
||||
use of compiler-provided logic for allocating the associated per-module
|
||||
logging-control structures visible to the runtime, and lazily evaluating
|
||||
arguments. In the future, as more of the supporting compiler-provided logic is
|
||||
moved into libraries, logging is likely to move to a component of the core
|
||||
library. It is best to use the macro forms of logging (*#error*,
|
||||
*#debug*, etc.) to minimize disruption to code using the logging facility
|
||||
when it is changed.
|
||||
Logging is presently implemented as a language built-in feature,
|
||||
as it makes use of compiler-provided, per-module data tables and flags.
|
||||
In the future, logging will move into a library, and will no longer be a core expression type.
|
||||
It is therefore recommended to use the macro forms of logging (`error!`, `debug!`, etc.) to minimize disruption in code that uses logging.
|
||||
|
||||
|
||||
### Assert expressions
|
||||
|
|
@ -2481,27 +2505,53 @@ tuple of arguments.
|
|||
Enumerated types cannot be denoted *structurally* as types, but must be
|
||||
denoted by named reference to an [*enumeration* item](#enumerations).
|
||||
|
||||
### Box types
|
||||
### Pointer types
|
||||
|
||||
Box types are represented as pointers. There are three flavours of
|
||||
pointers:
|
||||
All pointers in Rust are explicit first-class values.
|
||||
They can be copied, stored into data structures, and returned from functions.
|
||||
There are four varieties of pointer in Rust:
|
||||
|
||||
Shared boxes (`@`)
|
||||
: These are reference-counted boxes. Their type is written
|
||||
`@content`, for example `@int` means a shared box containing an
|
||||
integer. Copying a value of such a type means copying the pointer
|
||||
and increasing the reference count.
|
||||
Managed pointers (`@`)
|
||||
: These point to managed heap allocations (or "boxes") in the task-local, managed heap.
|
||||
Managed pointers are written `@content`,
|
||||
for example `@int` means a managed pointer to a managed box containing an integer.
|
||||
Copying a managed pointer is a "shallow" operation:
|
||||
it involves only copying the pointer itself
|
||||
(as well as any reference-count or GC-barriers required by the managed heap).
|
||||
Dropping a managed pointer does not necessarily release the box it points to;
|
||||
the lifecycles of managed boxes are subject to an unspecified garbage collection algorithm.
|
||||
|
||||
Unique boxes (`~`)
|
||||
: Unique boxes have only a single owner, and are freed when their
|
||||
owner releases them. They are written `~content`. Copying a
|
||||
unique box involves copying the contents into a new box.
|
||||
Owning pointers (`~`)
|
||||
: These point to owned heap allocations (or "boxes") in the shared, inter-task heap.
|
||||
Each owned box has a single owning pointer; pointer and pointee retain a 1:1 relationship at all times.
|
||||
Owning pointers are written `~content`,
|
||||
for example `~int` means an owning pointer to an owned box containing an integer.
|
||||
Copying an owned box is a "deep" operation:
|
||||
it involves allocating a new owned box and copying the contents of the old box into the new box.
|
||||
Releasing an owning pointer immediately releases its corresponding owned box.
|
||||
|
||||
Unsafe pointers (`*`)
|
||||
: Unsafe pointers are pointers without safety guarantees or
|
||||
language-enforced semantics. Their type is written `*content`.
|
||||
They can be copied and dropped freely. Dereferencing an unsafe
|
||||
pointer is part of the unsafe sub-dialect of Rust.
|
||||
Borrowed pointers (`&`)
|
||||
: These point to memory _owned by some other value_.
|
||||
Borrowed pointers arise by (automatic) conversion from owning pointers, managed pointers,
|
||||
or by applying the borrowing operator `&` to some other value,
|
||||
including [lvalues, rvalues or temporaries](#lvalues-rvalues-and-temporaries).
|
||||
Borrowed pointers are written `&content`, or in some cases `&f/content` for some lifetime-variable `f`,
|
||||
for example `&int` means a borrowed pointer to an integer.
|
||||
Copying a borrowed pointer is a "shallow" operation:
|
||||
it involves only copying the pointer itself.
|
||||
Releasing a borrowed pointer typically has no effect on the value it points to,
|
||||
with the exception of temporary values,
|
||||
which are released when the last borrowed pointer to them is released.
|
||||
|
||||
Raw pointers (`*`)
|
||||
: Raw pointers are pointers without safety or liveness guarantees.
|
||||
Raw pointers are written `*content`,
|
||||
for example `*int` means a raw pointer to an integer.
|
||||
Copying or dropping a raw pointer is has no effect on the lifecycle of any other value.
|
||||
Dereferencing a raw pointer or converting it to any other pointer type is an [`unsafe` operation](#unsafe-functions).
|
||||
Raw pointers are generally discouraged in Rust code;
|
||||
they exist to support interoperability with foreign code,
|
||||
and writing performance-critical or low-level functions.
|
||||
|
||||
### Function types
|
||||
|
||||
|
|
@ -2678,20 +2728,17 @@ the box values pointing to it. Since box values may themselves be passed in
|
|||
and out of frames, or stored in the heap, heap allocations may outlive the
|
||||
frame they are allocated within.
|
||||
|
||||
|
||||
### Memory ownership
|
||||
|
||||
A task owns all memory it can *safely* reach through local variables,
|
||||
shared or unique boxes, and/or references. Sharing memory between tasks can
|
||||
only be accomplished using *unsafe* constructs, such as raw pointer
|
||||
operations or calling C code.
|
||||
as well as managed, owning and borrowed pointers.
|
||||
|
||||
When a task sends a value that has the `send` trait over a channel, it
|
||||
loses ownership of the value sent and can no longer refer to it. This is
|
||||
statically guaranteed by the combined use of "move semantics" and the
|
||||
compiler-checked _meaning_ of the `send` trait: it is only instantiated
|
||||
for (transitively) unique kinds of data constructor and pointers, never shared
|
||||
pointers.
|
||||
When a task sends a value that has the `Send` trait to another task,
|
||||
it loses ownership of the value sent and can no longer refer to it.
|
||||
This is statically guaranteed by the combined use of "move semantics",
|
||||
and the compiler-checked _meaning_ of the `Send` trait:
|
||||
it is only instantiated for (transitively) sendable kinds of data constructor and pointers,
|
||||
never including managed or borrowed pointers.
|
||||
|
||||
When a stack frame is exited, its local allocations are all released, and its
|
||||
references to boxes (both shared and owned) are dropped.
|
||||
|
|
@ -2737,14 +2784,12 @@ aside a copy of that value to refer to. If this is not semantically safe (for
|
|||
example, if the referred-to value contains mutable fields), it will reject the
|
||||
program. If the compiler deems copying the value expensive, it will warn.
|
||||
|
||||
A function can be declared to take an argument by mutable reference. This
|
||||
allows the function to write to the slot that the reference refers to.
|
||||
|
||||
An example function that accepts an value by mutable reference:
|
||||
A function with an argument of type `&mut T`, for some type `T`, can write to
|
||||
the slot that its argument refers to. An example of such a function is:
|
||||
|
||||
~~~~~~~~
|
||||
fn incr(&i: int) {
|
||||
i = i + 1;
|
||||
fn incr(i: &mut int) {
|
||||
*i = *i + 1;
|
||||
}
|
||||
~~~~~~~~
|
||||
|
||||
|
|
@ -2832,54 +2877,21 @@ exploiting.]
|
|||
|
||||
### Communication between tasks
|
||||
|
||||
With the exception of *unsafe* blocks, Rust tasks are isolated from
|
||||
interfering with one another's memory directly. Instead of manipulating shared
|
||||
storage, Rust tasks communicate with one another using a typed, asynchronous,
|
||||
simplex message-passing system.
|
||||
Rust tasks are isolated and generally unable to interfere with one another's memory directly,
|
||||
except through [`unsafe` code](#unsafe-functions).
|
||||
All contact between tasks is mediated by safe forms of ownership transfer,
|
||||
and data races on memory are prohibited by the type system.
|
||||
|
||||
A _port_ is a communication endpoint that can *receive* messages. Ports
|
||||
receive messages from channels.
|
||||
Inter-task communication and co-ordination facilities are provided in the standard library.
|
||||
These include:
|
||||
- synchronous and asynchronous communication channels with various communication topologies
|
||||
- read-only and read-write shared variables with various safe mutual exclusion patterns
|
||||
- simple locks and semaphores
|
||||
|
||||
A _channel_ is a communication endpoint that can *send* messages. Channels
|
||||
send messages to ports.
|
||||
|
||||
Each port is implicitly boxed and mutable; as such a port has a unique
|
||||
per-task identity and cannot be replicated or transmitted. If a port value is
|
||||
copied, both copies refer to the *same* port. New ports can be
|
||||
constructed dynamically and stored in data structures.
|
||||
|
||||
Each channel is bound to a port when the channel is constructed, so the
|
||||
destination port for a channel must exist before the channel itself. A channel
|
||||
cannot be rebound to a different port from the one it was constructed with.
|
||||
|
||||
Channels are weak: a channel does not keep the port it is bound to
|
||||
alive. Ports are owned by their allocating task and cannot be sent over
|
||||
channels; if a task dies its ports die with it, and all channels bound to
|
||||
those ports no longer function. Messages sent to a channel connected to a dead
|
||||
port will be dropped.
|
||||
|
||||
Channels are immutable types with meaning known to the runtime; channels can
|
||||
be sent over channels.
|
||||
|
||||
Many channels can be bound to the same port, but each channel is bound to a
|
||||
single port. In other words, channels and ports exist in an N:1 relationship,
|
||||
N channels to 1 port. ^[It may help to remember nautical terminology
|
||||
when differentiating channels from ports. Many different waterways --
|
||||
channels -- may lead to the same port.]
|
||||
|
||||
Each port and channel can carry only one type of message. The message type is
|
||||
encoded as a parameter of the channel or port type. The message type of a
|
||||
channel is equal to the message type of the port it is bound to. The types of
|
||||
messages must satisfy the `send` built-in trait.
|
||||
|
||||
Messages are generally sent asynchronously, with optional
|
||||
rate-limiting on the transmit side. Each port contains a message
|
||||
queue and sending a message over a channel merely means inserting it
|
||||
into the associated port's queue; message receipt is the
|
||||
responsibility of the receiving task.
|
||||
|
||||
Messages are sent on channels and received on ports using standard library
|
||||
functions.
|
||||
When such facilities carry values, the values are restricted to the [`Send` type-kind](#type-kinds).
|
||||
Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks.
|
||||
Thus access to an entire data structure can be mediated through its owning "root" value;
|
||||
no further locking or copying is required to avoid data races within the substructure of such a value.
|
||||
|
||||
|
||||
### Task lifecycle
|
||||
|
|
@ -2896,12 +2908,11 @@ A task begins its lifecycle -- once it has been spawned -- in the *running*
|
|||
state. In this state it executes the statements of its entry function, and any
|
||||
functions called by the entry function.
|
||||
|
||||
A task may transition from the *running* state to the *blocked* state any time
|
||||
it makes a blocking receive call on a port, or attempts a rate-limited
|
||||
blocking send on a channel. When the communication expression can be completed
|
||||
-- when a message arrives at a sender, or a queue drains sufficiently to
|
||||
complete a rate-limited send -- then the blocked task will unblock and
|
||||
transition back to *running*.
|
||||
A task may transition from the *running* state to the *blocked*
|
||||
state any time it makes a blocking communication call. When the
|
||||
call can be completed -- when a message arrives at a sender, or a
|
||||
buffer opens to receive a message -- then the blocked task will
|
||||
unblock and transition back to *running*.
|
||||
|
||||
A task may transition to the *failing* state at any time, due being
|
||||
killed by some external event or internally, from the evaluation of a
|
||||
|
|
@ -2952,7 +2963,7 @@ An example of a `spawn` call:
|
|||
|
||||
~~~~
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
|
||||
do task::spawn {
|
||||
// let task run, do other things
|
||||
|
|
@ -2974,7 +2985,7 @@ An example of a send:
|
|||
|
||||
~~~~
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
comm::send(ch, ~"hello, world");
|
||||
~~~~
|
||||
|
||||
|
|
@ -2990,7 +3001,7 @@ An example of a *receive*:
|
|||
|
||||
~~~~~~~~
|
||||
# let po = comm::Port();
|
||||
# let ch = comm::Chan(po);
|
||||
# let ch = comm::Chan(&po);
|
||||
# comm::send(ch, ~"");
|
||||
let s = comm::recv(po);
|
||||
~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ forbidden.
|
|||
To take as an argument a fragment of Rust code, write `$` followed by a name
|
||||
(for use on the right-hand side), followed by a `:`, followed by the sort of
|
||||
fragment to match (the most common ones are `ident`, `expr`, `ty`, `pat`, and
|
||||
`block`). Anything not preceeded by a `$` is taken literally. The standard
|
||||
`block`). Anything not preceded by a `$` is taken literally. The standard
|
||||
rules of tokenization apply,
|
||||
|
||||
So `($x:ident => (($e:expr)))`, though excessively fancy, would create a macro
|
||||
|
|
@ -88,7 +88,7 @@ position).
|
|||
|
||||
Going back to the motivating example, suppose that we wanted each invocation
|
||||
of `early_return` to potentially accept multiple "special" identifiers. The
|
||||
syntax `$(...)*` accepts zero or more occurences of its contents, much like
|
||||
syntax `$(...)*` accepts zero or more occurrences of its contents, much like
|
||||
the Kleene star operator in regular expressions. It also supports a separator
|
||||
token (a comma-separated list could be written `$(...),*`), and `+` instead of
|
||||
`*` to mean "at least one".
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ In particular, there are currently two independent modules that provide
|
|||
a message passing interface to Rust code: `core::comm` and `core::pipes`.
|
||||
`core::comm` is an older, less efficient system that is being phased out
|
||||
in favor of `pipes`. At some point the existing `core::comm` API will
|
||||
be romoved and the user-facing portions of `core::pipes` will be moved
|
||||
be removed and the user-facing portions of `core::pipes` will be moved
|
||||
to `core::comm`. In this tutorial we will discuss `pipes` and ignore
|
||||
the `comm` API.
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ concurrency at the moment.
|
|||
* [`core::comm`] - The deprecated message passing API
|
||||
* [`core::pipes`] - The new message passing infrastructure and API
|
||||
* [`std::comm`] - Higher level messaging types based on `core::pipes`
|
||||
* [`std::sync`] - More exotic synchronization tools, including locks
|
||||
* [`std::sync`] - More exotic synchronization tools, including locks
|
||||
* [`std::arc`] - The ARC type, for safely sharing immutable data
|
||||
* [`std::par`] - Some basic tools for implementing parallel algorithms
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ commonly used, which we will cover presently.
|
|||
|
||||
The simplest way to create a pipe is to use the `pipes::stream`
|
||||
function to create a `(Chan, Port)` pair. In Rust parlance a 'channel'
|
||||
is a sending endpoint of a pipe, and a 'port' is the recieving
|
||||
is a sending endpoint of a pipe, and a 'port' is the receiving
|
||||
endpoint. Consider the following example of performing two calculations
|
||||
concurrently.
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ let (chan, port): (Chan<int>, Port<int>) = stream();
|
|||
~~~~
|
||||
|
||||
The channel will be used by the child task to send data to the parent task,
|
||||
which will wait to recieve the data on the port. The next statement
|
||||
which will wait to receive the data on the port. The next statement
|
||||
spawns the child task.
|
||||
|
||||
~~~~
|
||||
|
|
@ -307,7 +307,7 @@ unrecoverable within a single task - once a task fails there is no way
|
|||
to "catch" the exception.
|
||||
|
||||
All tasks are, by default, _linked_ to each other, meaning their fate
|
||||
is interwined, and if one fails so do all of them.
|
||||
is intertwined, and if one fails so do all of them.
|
||||
|
||||
~~~
|
||||
# use task::spawn;
|
||||
|
|
|
|||
501
doc/tutorial.md
501
doc/tutorial.md
|
|
@ -152,9 +152,9 @@ example, by changing `io::println` to some nonexistent function), and
|
|||
then compile it, you'll see an error message like this:
|
||||
|
||||
~~~~ {.notrust}
|
||||
hello.rs:2:4: 2:16 error: unresolved name: io::print_it
|
||||
hello.rs:2 io::print_it("hello? yes, this is rust");
|
||||
^~~~~~~~~~~~
|
||||
hello.rs:2:4: 2:16 error: unresolved name: io::print_with_unicorns
|
||||
hello.rs:2 io::print_with_unicorns("hello? yes, this is rust");
|
||||
^~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~
|
||||
|
||||
In its simplest form, a Rust program is a `.rs` file with some types
|
||||
|
|
@ -162,12 +162,7 @@ and functions defined in it. If it has a `main` function, it can be
|
|||
compiled to an executable. Rust does not allow code that's not a
|
||||
declaration to appear at the top level of the file—all statements must
|
||||
live inside a function. Rust programs can also be compiled as
|
||||
libraries, and included in other programs. The `extern mod std`
|
||||
directive that appears at the top of many examples imports the
|
||||
[standard library][std], described in more detail [later
|
||||
on](#modules-and-crates).
|
||||
|
||||
[std]: http://doc.rust-lang.org/doc/std
|
||||
libraries, and included in other programs.
|
||||
|
||||
## Editing Rust code
|
||||
|
||||
|
|
@ -178,9 +173,11 @@ included in that directory. In particular, if you are running emacs
|
|||
24, then using emacs's internal package manager to install `rust-mode`
|
||||
is the easiest way to keep it up to date. There is also a package for
|
||||
Sublime Text 2, available both [standalone][sublime] and through
|
||||
[Sublime Package Control][sublime-pkg].
|
||||
[Sublime Package Control][sublime-pkg], and support for Kate
|
||||
under `src/etc/kate`.
|
||||
|
||||
Other editors are not provided for yet. If you end up writing a Rust
|
||||
There is ctags support via `src/etc/ctags.rust`, but many other
|
||||
tools and editors are not provided for yet. If you end up writing a Rust
|
||||
mode for your favorite editor, let us know so that we can link to it.
|
||||
|
||||
[sublime]: http://github.com/dbp/sublime-rust
|
||||
|
|
@ -191,7 +188,7 @@ mode for your favorite editor, let us know so that we can link to it.
|
|||
Assuming you've programmed in any C-family language (C++, Java,
|
||||
JavaScript, C#, or PHP), Rust will feel familiar. Code is arranged
|
||||
in blocks delineated by curly braces; there are control structures
|
||||
for branching and looping, like the familiar `if` and `when`; function
|
||||
for branching and looping, like the familiar `if` and `while`; function
|
||||
calls are written `myfunc(arg1, arg2)`; operators are written the same
|
||||
and mostly have the same precedence as in C; comments are again like C.
|
||||
|
||||
|
|
@ -227,18 +224,24 @@ while count < 10 {
|
|||
}
|
||||
~~~~
|
||||
|
||||
Although Rust can almost always infer the types of local variables, it
|
||||
can help readability to specify a variable's type by following it with
|
||||
a colon, then the type name.
|
||||
Although Rust can almost always infer the types of local variables, you
|
||||
can specify a variable's type by following it with a colon, then the type
|
||||
name.
|
||||
|
||||
~~~~
|
||||
let my_favorite_value: float = 57.8;
|
||||
let my_favorite_value: int = my_favorite_value as int;
|
||||
let monster_size: float = 57.8;
|
||||
let imaginary_size = monster_size * 10.0;
|
||||
let monster_size: int = 50;
|
||||
~~~~
|
||||
|
||||
Local variables may shadow earlier declarations, as in the previous
|
||||
example in which `my_favorite_value` is first declared as a `float`
|
||||
then a second `my_favorite_value` is declared as an int.
|
||||
example in which `monster_size` is first declared as a `float`
|
||||
then a second `monster_size` is declared as an int. If you were to actually
|
||||
compile this example though, the compiler will see that the second
|
||||
`monster_size` is unused, assume that you have made a mistake, and issue
|
||||
a warning. For occasions where unused variables are intentional, their
|
||||
name may be prefixed with an underscore to silence the warning, like
|
||||
`let _monster_size = 50;`.
|
||||
|
||||
Rust identifiers follow the same rules as C; they start with an alphabetic
|
||||
character or an underscore, and after that may contain any sequence of
|
||||
|
|
@ -248,14 +251,14 @@ underscores where they help readability, while writing types in camel case.
|
|||
|
||||
~~~
|
||||
let my_variable = 100;
|
||||
type MyType = int; // built-in types though are _not_ camel case
|
||||
type MyType = int; // some built-in types are _not_ camel case
|
||||
~~~
|
||||
|
||||
## Expression syntax
|
||||
|
||||
Though it isn't apparent in all code, there is a fundamental
|
||||
difference between Rust's syntax and its predecessors in this family
|
||||
of languages. Many constructs that are statements in C are expressions
|
||||
difference between Rust's syntax and predecessors like C.
|
||||
Many constructs that are statements in C are expressions
|
||||
in Rust, allowing code to be more concise. For example, you might
|
||||
write a piece of code like this:
|
||||
|
||||
|
|
@ -275,24 +278,25 @@ But, in Rust, you don't have to repeat the name `price`:
|
|||
|
||||
~~~~
|
||||
# let item = "salad";
|
||||
let price = if item == "salad" {
|
||||
3.50
|
||||
} else if item == "muffin" {
|
||||
2.25
|
||||
} else {
|
||||
2.00
|
||||
};
|
||||
let price =
|
||||
if item == "salad" {
|
||||
3.50
|
||||
} else if item == "muffin" {
|
||||
2.25
|
||||
} else {
|
||||
2.00
|
||||
};
|
||||
~~~~
|
||||
|
||||
Both pieces of code are exactly equivalent—they assign a value to
|
||||
`price` depending on the condition that holds. Note that the
|
||||
semicolons are omitted from the blocks in the second snippet. This is
|
||||
`price` depending on the condition that holds. Note that there
|
||||
are not semicolons in the blocks of the second snippet. This is
|
||||
important; the lack of a semicolon after the last statement in a
|
||||
braced block gives the whole block the value of that last expression.
|
||||
|
||||
Put another way, the semicolon in Rust *ignores the value of an expression*.
|
||||
Thus, if the branches of the `if` had looked like `{ 4; }`, the above example
|
||||
would simply assign nil (void) to `price`. But without the semicolon, each
|
||||
would simply assign `()` (nil or void) to `price`. But without the semicolon, each
|
||||
branch has a different value, and `price` gets the value of the branch that
|
||||
was taken.
|
||||
|
||||
|
|
@ -320,7 +324,6 @@ something—in which case you'll have embedded it in a bigger statement.
|
|||
# fn foo() -> bool { true }
|
||||
# fn bar() -> bool { true }
|
||||
# fn baz() -> bool { true }
|
||||
|
||||
// `let` is not an expression, so it is semi-colon terminated;
|
||||
let x = foo();
|
||||
|
||||
|
|
@ -346,12 +349,11 @@ if x {
|
|||
let y = if x { foo() } else { bar() };
|
||||
~~~
|
||||
|
||||
This may sound a bit intricate, but it is super-useful, and it will
|
||||
grow on you (hopefully).
|
||||
This may sound intricate, but it is super-useful and will grow on you.
|
||||
|
||||
## Types
|
||||
|
||||
The basic types include the usual boolean, integral, and floating point types.
|
||||
The basic types include the usual boolean, integral, and floating-point types.
|
||||
|
||||
------------------------- -----------------------------------------------
|
||||
`()` Nil, the type that has only a single value
|
||||
|
|
@ -360,17 +362,18 @@ The basic types include the usual boolean, integral, and floating point types.
|
|||
`i8`, `i16`, `i32`, `i64` Signed integers with a specific size (in bits)
|
||||
`u8`, `u16`, `u32`, `u64` Unsigned integers with a specific size
|
||||
`float` The largest floating-point type efficiently supported on the target machine
|
||||
`f32`, `f64` Floating-point types with a specific size.
|
||||
`char` A Unicode character (32 bits).
|
||||
`f32`, `f64` Floating-point types with a specific size
|
||||
`char` A Unicode character (32 bits)
|
||||
------------------------- -----------------------------------------------
|
||||
|
||||
These can be combined in composite types, which will be described in
|
||||
more detail later on (the `T`s here stand for any other type):
|
||||
more detail later on (the `T`s here stand for any other type,
|
||||
while N should be a literal number):
|
||||
|
||||
------------------------- -----------------------------------------------
|
||||
`[T * N]` Vector (like an array in other languages) with N elements
|
||||
`[mut T * N]` Mutable vector with N elements
|
||||
`(T1, T2)` Tuple type. Any arity above 1 is supported
|
||||
`(T1, T2)` Tuple type; any arity above 1 is supported
|
||||
`&T`, `~T`, `@T` [Pointer types](#boxes-and-pointers)
|
||||
------------------------- -----------------------------------------------
|
||||
|
||||
|
|
@ -392,7 +395,7 @@ the type `fn() -> bool` or the function declaration `fn foo() -> bool
|
|||
optionally write `-> ()`, but usually the return annotation is simply
|
||||
left off, as in `fn main() { ... }`.
|
||||
|
||||
Types can be given names with `type` declarations:
|
||||
Types can be given names or aliases with `type` declarations:
|
||||
|
||||
~~~~
|
||||
type MonsterSize = uint;
|
||||
|
|
@ -401,9 +404,25 @@ type MonsterSize = uint;
|
|||
This will provide a synonym, `MonsterSize`, for unsigned integers. It will not
|
||||
actually create a new, incompatible type—`MonsterSize` and `uint` can be used
|
||||
interchangeably, and using one where the other is expected is not a type
|
||||
error. Read about [single-variant enums](#single_variant_enum)
|
||||
further on if you need to create a type name that's not just a
|
||||
synonym.
|
||||
error.
|
||||
|
||||
To create data types which are not synonyms, `struct` and `enum`
|
||||
can be used. They're described in more detail below, but they look like this:
|
||||
|
||||
~~~~
|
||||
enum HidingPlaces {
|
||||
Closet(uint),
|
||||
UnderTheBed(uint)
|
||||
}
|
||||
|
||||
struct HeroicBabysitter {
|
||||
bedtime_stories: uint,
|
||||
sharpened_stakes: uint
|
||||
}
|
||||
|
||||
struct BabysitterSize(uint); // a single-variant struct
|
||||
enum MonsterSize = uint; // a single-variant enum
|
||||
~~~~
|
||||
|
||||
## Literals
|
||||
|
||||
|
|
@ -435,10 +454,38 @@ The nil literal is written just like the type: `()`. The keywords
|
|||
|
||||
Character literals are written between single quotes, as in `'x'`. Just as in
|
||||
C, Rust understands a number of character escapes, using the backslash
|
||||
character, `\n`, `\r`, and `\t` being the most common. String literals,
|
||||
character, such as `\n`, `\r`, and `\t`. String literals,
|
||||
written between double quotes, allow the same escape sequences. Rust strings
|
||||
may contain newlines.
|
||||
|
||||
## Constants
|
||||
|
||||
Compile-time constants are declared with `const`. All scalar types,
|
||||
like integers and floats, may be declared `const`, as well as fixed
|
||||
length vectors, static strings (more on this later), and structs.
|
||||
Constants may be declared in any scope and may refer to other
|
||||
constants. Constant declarations are not type inferred, so must always
|
||||
have a type annotation. By convention they are written in all capital
|
||||
letters.
|
||||
|
||||
~~~
|
||||
// Scalars can be constants
|
||||
const MY_PASSWORD: int = 12345;
|
||||
|
||||
// Scalar constants can be combined with other constants
|
||||
const MY_DOGGIES_PASSWORD: int = MY_PASSWORD + 1;
|
||||
|
||||
// Fixed-length vectors
|
||||
const MY_VECTORY_PASSWORD: [int * 5] = [1, 2, 3, 4, 5];
|
||||
|
||||
// Static strings
|
||||
const MY_STRINGY_PASSWORD: &static/str = "12345";
|
||||
|
||||
// Structs
|
||||
struct Password { value: int }
|
||||
const MY_STRUCTY_PASSWORD: Password = Password { value: MY_PASSWORD };
|
||||
~~~
|
||||
|
||||
## Operators
|
||||
|
||||
Rust's set of operators contains very few surprises. Arithmetic is done with
|
||||
|
|
@ -466,8 +513,8 @@ assert y == 4u;
|
|||
|
||||
The main difference with C is that `++` and `--` are missing, and that
|
||||
the logical bitwise operators have higher precedence — in C, `x & 2 > 0`
|
||||
comes out as `x & (2 > 0)`, in Rust, it means `(x & 2) > 0`, which is
|
||||
more likely to be what you expect (unless you are a C veteran).
|
||||
means `x & (2 > 0)`, but in Rust, it means `(x & 2) > 0`, which is
|
||||
more likely what a novice expects.
|
||||
|
||||
## Syntax extensions
|
||||
|
||||
|
|
@ -556,18 +603,14 @@ underscore (`_`) is a wildcard pattern that matches everything.
|
|||
|
||||
The patterns in an match arm are followed by a fat arrow, `=>`, then an
|
||||
expression to evaluate. Each case is separated by commas. It's often
|
||||
convenient to use a block expression for a case, in which case the
|
||||
convenient to use a block expression for each case, in which case the
|
||||
commas are optional.
|
||||
|
||||
~~~
|
||||
# let my_number = 1;
|
||||
match my_number {
|
||||
0 => {
|
||||
io::println("zero")
|
||||
}
|
||||
_ => {
|
||||
io::println("something else")
|
||||
}
|
||||
0 => { io::println("zero") }
|
||||
_ => { io::println("something else") }
|
||||
}
|
||||
~~~
|
||||
|
||||
|
|
@ -686,12 +729,13 @@ omitted from the type, such an assignment would result in a type error.
|
|||
|
||||
Structs can be destructured in `match` patterns. The basic syntax is
|
||||
`Name {fieldname: pattern, ...}`:
|
||||
|
||||
~~~~
|
||||
# struct Point { x: float, y: float }
|
||||
# let mypoint = Point { x: 0.0, y: 0.0 };
|
||||
match mypoint {
|
||||
Point { x: 0.0, y: y } => { io::println(y.to_str()); }
|
||||
Point { x: x, y: y } => { io::println(x.to_str() + " " + y.to_str()); }
|
||||
Point { x: 0.0, y: yy } => { io::println(yy.to_str()); }
|
||||
Point { x: xx, y: yy } => { io::println(xx.to_str() + " " + yy.to_str()); }
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
@ -699,6 +743,35 @@ In general, the field names of a struct do not have to appear in the same
|
|||
order they appear in the type. When you are not interested in all
|
||||
the fields of a struct, a struct pattern may end with `, _` (as in
|
||||
`Name {field1, _}`) to indicate that you're ignoring all other fields.
|
||||
Additionally, struct fields have a shorthand matching form that simply
|
||||
reuses the field name as the binding name.
|
||||
|
||||
~~~
|
||||
# struct Point { x: float, y: float }
|
||||
# let mypoint = Point { x: 0.0, y: 0.0 };
|
||||
match mypoint {
|
||||
Point { x, _ } => { io::println(x.to_str()) }
|
||||
}
|
||||
~~~
|
||||
|
||||
Structs are the only type in Rust that may have user-defined destructors,
|
||||
using `drop` blocks, inside of which the struct's value may be referred
|
||||
to with the name `self`.
|
||||
|
||||
~~~
|
||||
struct TimeBomb {
|
||||
explosivity: uint,
|
||||
|
||||
drop {
|
||||
for iter::repeat(self.explosivity) {
|
||||
io::println(fmt!("blam!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
> ***Note***: This destructor syntax is temporary. Eventually destructors
|
||||
> will be defined for any type using [traits](#traits).
|
||||
|
||||
## Enums
|
||||
|
||||
|
|
@ -781,7 +854,7 @@ dereference (`*`) unary operator:
|
|||
|
||||
~~~~
|
||||
# enum GizmoId = int;
|
||||
let my_gizmo_id = GizmoId(10);
|
||||
let my_gizmo_id: GizmoId = GizmoId(10);
|
||||
let id_int: int = *my_gizmo_id;
|
||||
~~~~
|
||||
|
||||
|
|
@ -842,12 +915,8 @@ back to [later](#modules-and-crates)). They are introduced with the
|
|||
the return type follows the arrow.
|
||||
|
||||
~~~~
|
||||
fn repeat(string: &str, count: int) -> ~str {
|
||||
let mut result = ~"";
|
||||
for count.times {
|
||||
result += string;
|
||||
}
|
||||
return result;
|
||||
fn line(a: int, b: int, x: int) -> int {
|
||||
return a * x + b;
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
@ -857,21 +926,8 @@ also return a value by having its top level block produce an
|
|||
expression.
|
||||
|
||||
~~~~
|
||||
# const copernicus: int = 0;
|
||||
fn int_to_str(i: int) -> ~str {
|
||||
if i == copernicus {
|
||||
return ~"tube sock";
|
||||
} else {
|
||||
return ~"violin";
|
||||
}
|
||||
}
|
||||
~~~~
|
||||
|
||||
~~~~
|
||||
# const copernicus: int = 0;
|
||||
fn int_to_str(i: int) -> ~str {
|
||||
if i == copernicus { ~"tube sock" }
|
||||
else { ~"violin" }
|
||||
fn line(a: int, b: int, x: int) -> int {
|
||||
a * x + b
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
@ -885,6 +941,16 @@ fn do_nothing_the_hard_way() -> () { return (); }
|
|||
fn do_nothing_the_easy_way() { }
|
||||
~~~~
|
||||
|
||||
Ending the function with a semicolon like so is equivalent to returning `()`.
|
||||
|
||||
~~~~
|
||||
fn line(a: int, b: int, x: int) -> int { a * x + b }
|
||||
fn oops(a: int, b: int, x: int) -> () { a * x + b; }
|
||||
|
||||
assert 8 == line(5, 3, 1);
|
||||
assert () == oops(5, 3, 1);
|
||||
~~~~
|
||||
|
||||
Methods are like functions, except that they are defined for a specific
|
||||
'self' type (like 'this' in C++). Calling a method is done with
|
||||
dot notation, as in `my_vec.len()`. Methods may be defined on most
|
||||
|
|
@ -984,7 +1050,7 @@ easy for programmers to reason about. Heap isolation has the
|
|||
additional benefit that garbage collection must only be done
|
||||
per-heap. Rust never "stops the world" to reclaim memory.
|
||||
|
||||
Complete isolation of heaps between tasks implies that any data
|
||||
Complete isolation of heaps between tasks would, however, mean that any data
|
||||
transferred between tasks must be copied. While this is a fine and
|
||||
useful way to implement communication between tasks, it is also very
|
||||
inefficient for large data structures. Because of this, Rust also
|
||||
|
|
@ -1096,6 +1162,9 @@ If you really want to copy a unique box you must say so explicitly.
|
|||
~~~~
|
||||
let x = ~10;
|
||||
let y = copy x;
|
||||
|
||||
let z = *x + *y;
|
||||
assert z == 20;
|
||||
~~~~
|
||||
|
||||
This is where the 'move' operator comes in. It is similar to
|
||||
|
|
@ -1104,9 +1173,11 @@ from `x` to `y`, without violating the constraint that it only has a
|
|||
single owner (if you used assignment instead of the move operator, the
|
||||
box would, in principle, be copied).
|
||||
|
||||
~~~~
|
||||
~~~~ {.xfail-test}
|
||||
let x = ~10;
|
||||
let y = move x;
|
||||
|
||||
let z = *x + *y; // would cause an error: use of moved variable: `x`
|
||||
~~~~
|
||||
|
||||
Owned boxes, when they do not contain any managed boxes, can be sent
|
||||
|
|
@ -1208,6 +1279,73 @@ For a more in-depth explanation of borrowed pointers, read the
|
|||
|
||||
[borrowtut]: tutorial-borrowed-ptr.html
|
||||
|
||||
## Dereferencing pointers
|
||||
|
||||
Rust uses the unary star operator (`*`) to access the contents of a
|
||||
box or pointer, similarly to C.
|
||||
|
||||
~~~
|
||||
let managed = @10;
|
||||
let owned = ~20;
|
||||
let borrowed = &30;
|
||||
|
||||
let sum = *managed + *owned + *borrowed;
|
||||
~~~
|
||||
|
||||
Dereferenced mutable pointers may appear on the left hand side of
|
||||
assignments, in which case the value they point to is modified.
|
||||
|
||||
~~~
|
||||
let managed = @mut 10;
|
||||
let owned = ~mut 20;
|
||||
|
||||
let mut value = 30;
|
||||
let borrowed = &mut value;
|
||||
|
||||
*managed = *owned + 10;
|
||||
*owned = *borrowed + 100;
|
||||
*borrowed = *managed + 1000;
|
||||
~~~
|
||||
|
||||
Pointers have high operator precedence, but lower precedence than the
|
||||
dot operator used for field and method access. This can lead to some
|
||||
awkward code filled with parenthesis.
|
||||
|
||||
~~~
|
||||
# struct Point { x: float, y: float }
|
||||
# enum Shape { Rectangle(Point, Point) }
|
||||
# impl Shape { fn area() -> int { 0 } }
|
||||
let start = @Point { x: 10f, y: 20f };
|
||||
let end = ~Point { x: (*start).x + 100f, y: (*start).y + 100f };
|
||||
let rect = &Rectangle(*start, *end);
|
||||
let area = (*rect).area();
|
||||
~~~
|
||||
|
||||
To combat this ugliness the dot operator performs _automatic pointer
|
||||
dereferencing_ on the receiver (the value on the left hand side of the
|
||||
dot), so in most cases dereferencing the receiver is not necessary.
|
||||
|
||||
~~~
|
||||
# struct Point { x: float, y: float }
|
||||
# enum Shape { Rectangle(Point, Point) }
|
||||
# impl Shape { fn area() -> int { 0 } }
|
||||
let start = @Point { x: 10f, y: 20f };
|
||||
let end = ~Point { x: start.x + 100f, y: start.y + 100f };
|
||||
let rect = &Rectangle(*start, *end);
|
||||
let area = rect.area();
|
||||
~~~
|
||||
|
||||
Auto-dereferencing is performed through any number of pointers. If you
|
||||
felt inclined you could write something silly like
|
||||
|
||||
~~~
|
||||
# struct Point { x: float, y: float }
|
||||
let point = &@~Point { x: 10f, y: 20f };
|
||||
io::println(fmt!("%f", point.x));
|
||||
~~~
|
||||
|
||||
The indexing operator (`[]`) is also auto-dereferencing.
|
||||
|
||||
# Vectors and strings
|
||||
|
||||
Vectors are a contiguous section of memory containing zero or more
|
||||
|
|
@ -1219,52 +1357,23 @@ pointers to vectors are also called 'slices'.
|
|||
enum Crayon {
|
||||
Almond, AntiqueBrass, Apricot,
|
||||
Aquamarine, Asparagus, AtomicTangerine,
|
||||
BananaMania, Beaver, Bittersweet
|
||||
BananaMania, Beaver, Bittersweet,
|
||||
Black, BlizzardBlue, Blue
|
||||
}
|
||||
|
||||
// A fixed-size stack vector
|
||||
let stack_crayons: [Crayon * 3] = [Almond, AntiqueBrass, Apricot];
|
||||
|
||||
// A borrowed pointer to stack allocated vector
|
||||
let stack_crayons: &[Crayon] = &[Almond, AntiqueBrass, Apricot];
|
||||
let stack_crayons: &[Crayon] = &[Aquamarine, Asparagus, AtomicTangerine];
|
||||
|
||||
// A local heap (managed) vector of crayons
|
||||
let local_crayons: @[Crayon] = @[Aquamarine, Asparagus, AtomicTangerine];
|
||||
let local_crayons: @[Crayon] = @[BananaMania, Beaver, Bittersweet];
|
||||
|
||||
// An exchange heap (owned) vector of crayons
|
||||
let exchange_crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
|
||||
let exchange_crayons: ~[Crayon] = ~[Black, BlizzardBlue, Blue];
|
||||
~~~
|
||||
|
||||
Vector literals are enclosed in square brackets and dereferencing is
|
||||
also done with square brackets (zero-based):
|
||||
|
||||
~~~~
|
||||
# enum Crayon { Almond, AntiqueBrass, Apricot,
|
||||
# Aquamarine, Asparagus, AtomicTangerine,
|
||||
# BananaMania, Beaver, Bittersweet };
|
||||
# fn draw_scene(c: Crayon) { }
|
||||
|
||||
let crayons = [BananaMania, Beaver, Bittersweet];
|
||||
match crayons[0] {
|
||||
Bittersweet => draw_scene(crayons[0]),
|
||||
_ => ()
|
||||
}
|
||||
~~~~
|
||||
|
||||
By default, vectors are immutable—you can not replace their elements.
|
||||
The type written as `[mut T]` is a vector with mutable
|
||||
elements. Mutable vector literals are written `[mut]` (empty) or `[mut
|
||||
1, 2, 3]` (with elements).
|
||||
|
||||
~~~~
|
||||
# enum Crayon { Almond, AntiqueBrass, Apricot,
|
||||
# Aquamarine, Asparagus, AtomicTangerine,
|
||||
# BananaMania, Beaver, Bittersweet };
|
||||
|
||||
let crayons = [mut BananaMania, Beaver, Bittersweet];
|
||||
crayons[0] = AtomicTangerine;
|
||||
~~~~
|
||||
|
||||
The `+` operator means concatenation when applied to vector types.
|
||||
|
||||
~~~~
|
||||
|
|
@ -1275,20 +1384,12 @@ The `+` operator means concatenation when applied to vector types.
|
|||
let my_crayons = ~[Almond, AntiqueBrass, Apricot];
|
||||
let your_crayons = ~[BananaMania, Beaver, Bittersweet];
|
||||
|
||||
// Add two vectors to create a new one
|
||||
let our_crayons = my_crayons + your_crayons;
|
||||
~~~~
|
||||
|
||||
The `+=` operator also works as expected, provided the assignee
|
||||
lives in a mutable slot.
|
||||
|
||||
~~~~
|
||||
# enum Crayon { Almond, AntiqueBrass, Apricot,
|
||||
# Aquamarine, Asparagus, AtomicTangerine,
|
||||
# BananaMania, Beaver, Bittersweet };
|
||||
|
||||
let mut my_crayons = ~[Almond, AntiqueBrass, Apricot];
|
||||
let your_crayons = ~[BananaMania, Beaver, Bittersweet];
|
||||
|
||||
// += will append to a vector, provided it leves
|
||||
// in a mutable slot
|
||||
let mut my_crayons = move my_crayons;
|
||||
my_crayons += your_crayons;
|
||||
~~~~
|
||||
|
||||
|
|
@ -1297,30 +1398,79 @@ my_crayons += your_crayons;
|
|||
> not well supported yet, owned vectors are often the most
|
||||
> usable.
|
||||
|
||||
Strings are simply vectors of `[u8]`, though they have a distinct
|
||||
type. They support most of the same allocation aptions as
|
||||
Indexing into vectors is done with square brackets:
|
||||
|
||||
~~~~
|
||||
# enum Crayon { Almond, AntiqueBrass, Apricot,
|
||||
# Aquamarine, Asparagus, AtomicTangerine,
|
||||
# BananaMania, Beaver, Bittersweet };
|
||||
# fn draw_scene(c: Crayon) { }
|
||||
let crayons: [Crayon * 3] = [BananaMania, Beaver, Bittersweet];
|
||||
match crayons[0] {
|
||||
Bittersweet => draw_scene(crayons[0]),
|
||||
_ => ()
|
||||
}
|
||||
~~~~
|
||||
|
||||
The elements of a vector _inherit the mutability of the vector_,
|
||||
and as such individual elements may not be reassigned when the
|
||||
vector lives in an immutable slot.
|
||||
|
||||
~~~ {.xfail-test}
|
||||
# enum Crayon { Almond, AntiqueBrass, Apricot,
|
||||
# Aquamarine, Asparagus, AtomicTangerine,
|
||||
# BananaMania, Beaver, Bittersweet };
|
||||
let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
|
||||
|
||||
crayons[0] = Apricot; // ERROR: Can't assign to immutable vector
|
||||
~~~
|
||||
|
||||
Moving it into a mutable slot makes the elements assignable.
|
||||
|
||||
~~~
|
||||
# enum Crayon { Almond, AntiqueBrass, Apricot,
|
||||
# Aquamarine, Asparagus, AtomicTangerine,
|
||||
# BananaMania, Beaver, Bittersweet };
|
||||
let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
|
||||
|
||||
// Put the vector into a mutable slot
|
||||
let mut mutable_crayons = move crayons;
|
||||
|
||||
// Now it's mutable to the bone
|
||||
mutable_crayons[0] = Apricot;
|
||||
~~~
|
||||
|
||||
This is a simple example of Rust's _dual-mode data structures_, also
|
||||
referred to as _freezing and thawing_.
|
||||
|
||||
Strings are implemented with vectors of `u8`, though they have a distinct
|
||||
type. They support most of the same allocation options as
|
||||
vectors, though the string literal without a storage sigil, e.g.
|
||||
`"foo"` is treated differently than a comparable vector (`[foo]`).
|
||||
Where
|
||||
Whereas plain vectors are stack-allocated fixed-length vectors,
|
||||
plain strings are region pointers to read-only memory. Strings
|
||||
are always immutable.
|
||||
|
||||
~~~
|
||||
// A plain string is a slice to read-only (static) memory
|
||||
let stack_crayons: &str = "Almond, AntiqueBrass, Apricot";
|
||||
|
||||
// The same thing, but without
|
||||
let stack_crayons: &str = &"Almond, AntiqueBrass, Apricot";
|
||||
// The same thing, but with the `&`
|
||||
let stack_crayons: &str = &"Aquamarine, Asparagus, AtomicTangerine";
|
||||
|
||||
// A local heap (managed) string
|
||||
let local_crayons: @str = @"Aquamarine, Asparagus, AtomicTangerine";
|
||||
let local_crayons: @str = @"BananMania, Beaver, Bittersweet";
|
||||
|
||||
// An exchange heap (owned) string
|
||||
let exchange_crayons: ~str = ~"BananaMania, Beaver, Bittersweet";
|
||||
let exchange_crayons: ~str = ~"Black, BlizzardBlue, Blue";
|
||||
~~~
|
||||
|
||||
Both vectors and strings support a number of useful
|
||||
[methods](#implementation). While we haven't covered methods yet,
|
||||
most vector functionality is provided by methods, so let's have a
|
||||
brief look at a few common ones.
|
||||
[methods](#functions-and-methods), defined in [`core::vec`]
|
||||
and [`core::str`]. Here are some examples.
|
||||
|
||||
[`core::vec`]: core/vec.html
|
||||
[`core::str`]: core/str.html
|
||||
|
||||
~~~
|
||||
# use io::println;
|
||||
|
|
@ -1403,7 +1553,7 @@ access local variables in the enclosing scope.
|
|||
|
||||
~~~~
|
||||
let mut max = 0;
|
||||
(~[1, 2, 3]).map(|x| if *x > max { max = *x });
|
||||
[1, 2, 3].map(|x| if *x > max { max = *x });
|
||||
~~~~
|
||||
|
||||
Stack closures are very efficient because their environment is
|
||||
|
|
@ -1431,8 +1581,7 @@ This code creates a closure that adds a given string to its argument,
|
|||
returns it from a function, and then calls it:
|
||||
|
||||
~~~~
|
||||
extern mod std;
|
||||
|
||||
# extern mod std;
|
||||
fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
|
||||
return fn@(s: ~str) -> ~str { s + suffix };
|
||||
}
|
||||
|
|
@ -1479,7 +1628,7 @@ fn call_twice(f: fn()) { f(); f(); }
|
|||
call_twice(|| { ~"I am an inferred stack closure"; } );
|
||||
call_twice(fn&() { ~"I am also a stack closure"; } );
|
||||
call_twice(fn@() { ~"I am a managed closure"; });
|
||||
call_twice(fn~() { ~"I am a owned closure"; });
|
||||
call_twice(fn~() { ~"I am an owned closure"; });
|
||||
fn bare_function() { ~"I am a plain function"; }
|
||||
call_twice(bare_function);
|
||||
~~~~
|
||||
|
|
@ -1490,9 +1639,12 @@ call_twice(bare_function);
|
|||
|
||||
## Do syntax
|
||||
|
||||
Closures in Rust are frequently used in combination with higher-order
|
||||
functions to simulate control structures like `if` and
|
||||
`loop`. Consider this function that iterates over a vector of
|
||||
The `do` expression is syntactic sugar for use with functions which
|
||||
take a closure as a final argument, because closures in Rust
|
||||
are so frequently used in combination with higher-order
|
||||
functions.
|
||||
|
||||
Consider this function which iterates over a vector of
|
||||
integers, passing in a pointer to each integer in the vector:
|
||||
|
||||
~~~~
|
||||
|
|
@ -1537,8 +1689,7 @@ do each(&[1, 2, 3]) |n| {
|
|||
The call is prefixed with the keyword `do` and, instead of writing the
|
||||
final closure inside the argument list it is moved outside of the
|
||||
parenthesis where it looks visually more like a typical block of
|
||||
code. The `do` expression is purely syntactic sugar for a call that
|
||||
takes a final closure argument.
|
||||
code.
|
||||
|
||||
`do` is often used for task spawning.
|
||||
|
||||
|
|
@ -1632,6 +1783,10 @@ fn contains(v: &[int], elt: int) -> bool {
|
|||
|
||||
`for` syntax only works with stack closures.
|
||||
|
||||
> ***Note:*** This is, essentially, a special loop protocol:
|
||||
> the keywords `break`, `loop`, and `return` work, in varying degree,
|
||||
> with `while`, `loop`, `do`, and `for` constructs.
|
||||
|
||||
# Generics
|
||||
|
||||
Throughout this tutorial, we've been defining functions that act only on
|
||||
|
|
@ -2036,6 +2191,9 @@ The compiler will now look for `poultry/chicken.rs` and
|
|||
and `poultry::turkey`. You can also provide a `poultry.rs` to add
|
||||
content to the `poultry` module itself.
|
||||
|
||||
The compiler then builds the crate as a platform-specific shared library or
|
||||
executable which can be distributed.
|
||||
|
||||
## Using other crates
|
||||
|
||||
Having compiled a crate that contains the `#[crate_type = "lib"]`
|
||||
|
|
@ -2082,7 +2240,7 @@ Rust program.
|
|||
|
||||
This library is documented [here][core].
|
||||
|
||||
[core]: http://doc.rust-lang.org/doc/core
|
||||
[core]: core/index.html
|
||||
|
||||
## A minimal example
|
||||
|
||||
|
|
@ -2090,22 +2248,22 @@ Now for something that you can actually compile yourself. We have
|
|||
these two files:
|
||||
|
||||
~~~~
|
||||
// mylib.rs
|
||||
#[link(name = "mylib", vers = "1.0")];
|
||||
fn world() -> ~str { ~"world" }
|
||||
// world.rs
|
||||
#[link(name = "world", vers = "1.0")];
|
||||
fn explore() -> ~str { ~"world" }
|
||||
~~~~
|
||||
|
||||
~~~~ {.ignore}
|
||||
// main.rs
|
||||
extern mod mylib;
|
||||
fn main() { io::println(~"hello " + mylib::world()); }
|
||||
extern mod world;
|
||||
fn main() { io::println(~"hello " + world::explore()); }
|
||||
~~~~
|
||||
|
||||
Now compile and run like this (adjust to your platform if necessary):
|
||||
|
||||
~~~~ {.notrust}
|
||||
> rustc --lib mylib.rs
|
||||
> rustc main.rs -L .
|
||||
> rustc --lib world.rs # compiles libworld-94839cbfe144198-1.0.so
|
||||
> rustc main.rs -L . # compiles main
|
||||
> ./main
|
||||
"hello world"
|
||||
~~~~
|
||||
|
|
@ -2125,12 +2283,14 @@ fn main() {
|
|||
}
|
||||
~~~~
|
||||
|
||||
|
||||
It is also possible to import just the name of a module (`use
|
||||
std::list;`, then use `list::find`), to import all identifiers exported
|
||||
by a given module (`use io::*`), or to import a specific set
|
||||
of identifiers (`use math::{min, max, pi}`).
|
||||
|
||||
You can rename an identifier when importing using the `=` operator:
|
||||
Rust uses different namespaces for modules, types, and values. You
|
||||
can also rename an identifier when importing using the `=` operator:
|
||||
|
||||
~~~~
|
||||
use prnt = io::println;
|
||||
|
|
@ -2154,27 +2314,6 @@ This defines a rock-solid encryption algorithm. Code outside of the
|
|||
module can refer to the `enc::encrypt` and `enc::decrypt` identifiers
|
||||
just fine, but it does not have access to `enc::super_secret_number`.
|
||||
|
||||
## Namespaces
|
||||
|
||||
Rust uses three different namespaces: one for modules, one for types,
|
||||
and one for values. This means that this code is valid:
|
||||
|
||||
~~~~
|
||||
#[legacy_exports]
|
||||
mod buffalo {
|
||||
type buffalo = int;
|
||||
fn buffalo<buffalo>(+buffalo: buffalo) -> buffalo { buffalo }
|
||||
}
|
||||
fn main() {
|
||||
let buffalo: buffalo::buffalo = 1;
|
||||
buffalo::buffalo::<buffalo::buffalo>(buffalo::buffalo(buffalo));
|
||||
}
|
||||
~~~~
|
||||
|
||||
You don't want to write things like that, but it *is* very practical
|
||||
to not have to worry about name clashes between types, values, and
|
||||
modules.
|
||||
|
||||
## Resolution
|
||||
|
||||
The resolution process in Rust simply goes up the chain of contexts,
|
||||
|
|
@ -2190,7 +2329,7 @@ Identifiers can shadow each other. In this program, `x` is of type
|
|||
type MyType = ~str;
|
||||
fn main() {
|
||||
type MyType = int;
|
||||
let x: MyType;
|
||||
let x: MyType = 17;
|
||||
}
|
||||
~~~~
|
||||
|
||||
|
|
@ -2198,13 +2337,17 @@ An `use` directive will only import into the namespaces for which
|
|||
identifiers are actually found. Consider this example:
|
||||
|
||||
~~~~
|
||||
mod foo { fn bar() {} }
|
||||
fn baz() {
|
||||
let bar = 10u;
|
||||
mod foo {
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let bar = 10;
|
||||
|
||||
{
|
||||
use foo::bar;
|
||||
let quux = bar;
|
||||
assert quux == 10;
|
||||
}
|
||||
}
|
||||
~~~~
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@ ifdef CFG_ENABLE_LOCAL_RUST
|
|||
$(Q)$(S)src/etc/local_stage0.sh $(CFG_HOST_TRIPLE) $(CFG_LOCAL_RUST_ROOT)
|
||||
else
|
||||
$(Q)$(S)src/etc/get-snapshot.py $(CFG_HOST_TRIPLE) $(SNAPSHOT_FILE)
|
||||
ifdef CFG_ENABLE_PAX_FLAGS
|
||||
@$(call E, apply PaX flags: $@)
|
||||
@"$(CFG_PAXCTL)" -cm "$@"
|
||||
endif
|
||||
endif
|
||||
$(Q)touch $@
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X): \
|
|||
$$(TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3))
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$<
|
||||
ifdef CFG_ENABLE_PAX_FLAGS
|
||||
@$$(call E, apply PaX flags: $$@)
|
||||
@"$(CFG_PAXCTL)" -cm "$$@"
|
||||
endif
|
||||
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC): \
|
||||
$$(COMPILER_CRATE) $$(COMPILER_INPUTS) \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
This is preliminary version of the Rust compiler, libraries and tools
|
||||
This is a preliminary version of the Rust compiler, libraries and tools
|
||||
|
||||
Source layout:
|
||||
|
||||
|
|
|
|||
|
|
@ -1889,7 +1889,8 @@ Commands:
|
|||
set-method Change the method for a source.");
|
||||
}
|
||||
|
||||
fn main(argv: ~[~str]) {
|
||||
fn main() {
|
||||
let argv = os::args();
|
||||
let o = build_cargo_options(argv);
|
||||
|
||||
if vec::len(o.free) < 2u {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ use common::mode_pretty;
|
|||
use common::mode;
|
||||
use util::logv;
|
||||
|
||||
fn main(++args: ~[~str]) {
|
||||
fn main() {
|
||||
let args = os::args();
|
||||
let config = parse_config(args);
|
||||
log_config(config);
|
||||
run_tests(config);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ if not src_dir:
|
|||
run_pass = os.path.join(src_dir, "src", "test", "run-pass")
|
||||
run_pass = os.path.abspath(run_pass)
|
||||
stage2_tests = []
|
||||
take_args = {}
|
||||
|
||||
for t in os.listdir(run_pass):
|
||||
if t.endswith(".rs") and not (
|
||||
|
|
@ -30,8 +29,6 @@ for t in os.listdir(run_pass):
|
|||
"xfail-fast" in s or
|
||||
"xfail-win32" in s):
|
||||
stage2_tests.append(t)
|
||||
if "fn main(args:" in s or "fn main(++args:" in s:
|
||||
take_args[t] = True
|
||||
f.close()
|
||||
|
||||
stage2_tests.sort()
|
||||
|
|
@ -64,9 +61,6 @@ for t in stage2_tests:
|
|||
p = os.path.join("test", "run-pass", t)
|
||||
p = p.replace("\\", "\\\\")
|
||||
d.write(" out.write_str(~\"run-pass [stage2]: %s\\n\");\n" % p)
|
||||
if t in take_args:
|
||||
d.write(" t_%d::main(~[~\"arg0\"]);\n" % i)
|
||||
else:
|
||||
d.write(" t_%d::main();\n" % i)
|
||||
d.write(" t_%d::main();\n" % i)
|
||||
i += 1
|
||||
d.write("}\n")
|
||||
|
|
|
|||
|
|
@ -599,7 +599,8 @@ fn check_variants(files: &[Path], cx: context) {
|
|||
}
|
||||
}
|
||||
|
||||
fn main(args: ~[~str]) {
|
||||
fn main() {
|
||||
let args = os::args();
|
||||
if vec::len(args) != 2u {
|
||||
error!("usage: %s <testdir>", args[0]);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Managed vectors
|
||||
|
||||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cast::transmute;
|
||||
|
|
@ -21,7 +21,7 @@ extern mod rustrt {
|
|||
#[abi = "rust-intrinsic"]
|
||||
extern mod rusti {
|
||||
#[legacy_exports];
|
||||
fn move_val_init<T>(&dst: T, -src: T);
|
||||
fn move_val_init<T>(dst: &mut T, -src: T);
|
||||
}
|
||||
|
||||
/// Returns the number of elements the vector can hold without reallocating
|
||||
|
|
@ -176,7 +176,7 @@ pub mod raw {
|
|||
push_slow(v, move initval);
|
||||
}
|
||||
}
|
||||
// This doesn't bother to make sure we have space.
|
||||
|
||||
#[inline(always)] // really pretty please
|
||||
pub unsafe fn push_fast<T>(v: &mut @[const T], initval: T) {
|
||||
let repr: **VecRepr = ::cast::reinterpret_cast(&v);
|
||||
|
|
@ -184,7 +184,7 @@ pub mod raw {
|
|||
(**repr).unboxed.fill += sys::size_of::<T>();
|
||||
let p = addr_of(&((**repr).unboxed.data));
|
||||
let p = ptr::offset(p, fill) as *mut T;
|
||||
rusti::move_val_init(*p, move initval);
|
||||
rusti::move_val_init(&mut(*p), move initval);
|
||||
}
|
||||
|
||||
pub unsafe fn push_slow<T>(v: &mut @[const T], initval: T) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
//! Unsafe operations
|
||||
#[forbid(deprecated_mode)]
|
||||
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern mod rusti {
|
||||
|
|
@ -18,7 +19,7 @@ pub unsafe fn reinterpret_cast<T, U>(src: &T) -> U {
|
|||
* The forget function will take ownership of the provided value but neglect
|
||||
* to run any required cleanup or memory-management operations on it. This
|
||||
* can be used for various acts of magick, particularly when using
|
||||
* reinterpret_cast on managed pointer types.
|
||||
* reinterpret_cast on pointer types.
|
||||
*/
|
||||
#[inline(always)]
|
||||
pub unsafe fn forget<T>(thing: T) { rusti::forget(move thing); }
|
||||
|
|
|
|||
|
|
@ -40,15 +40,15 @@ pub extern mod c_double {
|
|||
#[link_name="fmax"] pure fn fmax(a: c_double, b: c_double) -> c_double;
|
||||
#[link_name="fmin"] pure fn fmin(a: c_double, b: c_double) -> c_double;
|
||||
pure fn nextafter(x: c_double, y: c_double) -> c_double;
|
||||
pure fn frexp(n: c_double, &value: c_int) -> c_double;
|
||||
pure fn frexp(n: c_double, value: &mut c_int) -> c_double;
|
||||
pure fn hypot(x: c_double, y: c_double) -> c_double;
|
||||
pure fn ldexp(x: c_double, n: c_int) -> c_double;
|
||||
#[cfg(unix)]
|
||||
#[link_name="lgamma_r"] pure fn lgamma(n: c_double,
|
||||
&sign: c_int) -> c_double;
|
||||
sign: &mut c_int) -> c_double;
|
||||
#[cfg(windows)]
|
||||
#[link_name="__lgamma_r"] pure fn lgamma(n: c_double,
|
||||
&sign: c_int) -> c_double;
|
||||
sign: &mut c_int) -> c_double;
|
||||
// renamed: log is a reserved keyword; ln seems more natural, too
|
||||
#[link_name="log"] pure fn ln(n: c_double) -> c_double;
|
||||
// renamed: "logb" /often/ is confused for log2 by beginners
|
||||
|
|
@ -58,7 +58,7 @@ pub extern mod c_double {
|
|||
pure fn log10(n: c_double) -> c_double;
|
||||
pure fn log2(n: c_double) -> c_double;
|
||||
#[link_name="ilogb"] pure fn ilog_radix(n: c_double) -> c_int;
|
||||
pure fn modf(n: c_double, &iptr: c_double) -> c_double;
|
||||
pure fn modf(n: c_double, iptr: &mut c_double) -> c_double;
|
||||
pure fn pow(n: c_double, e: c_double) -> c_double;
|
||||
// FIXME (#1379): enable when rounding modes become available
|
||||
// pure fn rint(n: c_double) -> c_double;
|
||||
|
|
@ -110,7 +110,7 @@ pub extern mod c_float {
|
|||
#[link_name="fdimf"] pure fn abs_sub(a: c_float, b: c_float) -> c_float;
|
||||
#[link_name="floorf"] pure fn floor(n: c_float) -> c_float;
|
||||
#[link_name="frexpf"] pure fn frexp(n: c_float,
|
||||
&value: c_int) -> c_float;
|
||||
value: &mut c_int) -> c_float;
|
||||
#[link_name="fmaf"] pure fn mul_add(a: c_float,
|
||||
b: c_float, c: c_float) -> c_float;
|
||||
#[link_name="fmaxf"] pure fn fmax(a: c_float, b: c_float) -> c_float;
|
||||
|
|
@ -122,11 +122,11 @@ pub extern mod c_float {
|
|||
|
||||
#[cfg(unix)]
|
||||
#[link_name="lgammaf_r"] pure fn lgamma(n: c_float,
|
||||
&sign: c_int) -> c_float;
|
||||
sign: &mut c_int) -> c_float;
|
||||
|
||||
#[cfg(windows)]
|
||||
#[link_name="__lgammaf_r"] pure fn lgamma(n: c_float,
|
||||
&sign: c_int) -> c_float;
|
||||
sign: &mut c_int) -> c_float;
|
||||
|
||||
#[link_name="logf"] pure fn ln(n: c_float) -> c_float;
|
||||
#[link_name="logbf"] pure fn log_radix(n: c_float) -> c_float;
|
||||
|
|
@ -135,7 +135,7 @@ pub extern mod c_float {
|
|||
#[link_name="log10f"] pure fn log10(n: c_float) -> c_float;
|
||||
#[link_name="ilogbf"] pure fn ilog_radix(n: c_float) -> c_int;
|
||||
#[link_name="modff"] pure fn modf(n: c_float,
|
||||
&iptr: c_float) -> c_float;
|
||||
iptr: &mut c_float) -> c_float;
|
||||
#[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float;
|
||||
// FIXME (#1379): enable when rounding modes become available
|
||||
// #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ will once again be the preferred module for intertask communication.
|
|||
|
||||
*/
|
||||
|
||||
// NB: transitionary, de-mode-ing
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use either::Either;
|
||||
|
|
@ -74,7 +74,7 @@ pub fn Port<T: Send>() -> Port<T> {
|
|||
|
||||
impl<T: Send> Port<T> {
|
||||
|
||||
fn chan() -> Chan<T> { Chan(self) }
|
||||
fn chan() -> Chan<T> { Chan(&self) }
|
||||
fn send(v: T) { self.chan().send(move v) }
|
||||
fn recv() -> T { recv(self) }
|
||||
fn peek() -> bool { peek(self) }
|
||||
|
|
@ -166,7 +166,7 @@ fn as_raw_port<T: Send, U>(ch: comm::Chan<T>, f: fn(*rust_port) -> U) -> U {
|
|||
* Constructs a channel. The channel is bound to the port used to
|
||||
* construct it.
|
||||
*/
|
||||
pub fn Chan<T: Send>(&&p: Port<T>) -> Chan<T> {
|
||||
pub fn Chan<T: Send>(p: &Port<T>) -> Chan<T> {
|
||||
Chan_(rustrt::get_port_id((**p).po))
|
||||
}
|
||||
|
||||
|
|
@ -304,19 +304,19 @@ extern mod rusti {
|
|||
|
||||
|
||||
#[test]
|
||||
fn create_port_and_chan() { let p = Port::<int>(); Chan(p); }
|
||||
fn create_port_and_chan() { let p = Port::<int>(); Chan(&p); }
|
||||
|
||||
#[test]
|
||||
fn send_int() {
|
||||
let p = Port::<int>();
|
||||
let c = Chan(p);
|
||||
let c = Chan(&p);
|
||||
send(c, 22);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn send_recv_fn() {
|
||||
let p = Port::<int>();
|
||||
let c = Chan::<int>(p);
|
||||
let c = Chan::<int>(&p);
|
||||
send(c, 42);
|
||||
assert (recv(p) == 42);
|
||||
}
|
||||
|
|
@ -324,7 +324,7 @@ fn send_recv_fn() {
|
|||
#[test]
|
||||
fn send_recv_fn_infer() {
|
||||
let p = Port();
|
||||
let c = Chan(p);
|
||||
let c = Chan(&p);
|
||||
send(c, 42);
|
||||
assert (recv(p) == 42);
|
||||
}
|
||||
|
|
@ -332,23 +332,23 @@ fn send_recv_fn_infer() {
|
|||
#[test]
|
||||
fn chan_chan_infer() {
|
||||
let p = Port(), p2 = Port::<int>();
|
||||
let c = Chan(p);
|
||||
send(c, Chan(p2));
|
||||
let c = Chan(&p);
|
||||
send(c, Chan(&p2));
|
||||
recv(p);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chan_chan() {
|
||||
let p = Port::<Chan<int>>(), p2 = Port::<int>();
|
||||
let c = Chan(p);
|
||||
send(c, Chan(p2));
|
||||
let c = Chan(&p);
|
||||
send(c, Chan(&p2));
|
||||
recv(p);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peek() {
|
||||
let po = Port();
|
||||
let ch = Chan(po);
|
||||
let ch = Chan(&po);
|
||||
assert !peek(po);
|
||||
send(ch, ());
|
||||
assert peek(po);
|
||||
|
|
@ -360,8 +360,8 @@ fn test_peek() {
|
|||
fn test_select2_available() {
|
||||
let po_a = Port();
|
||||
let po_b = Port();
|
||||
let ch_a = Chan(po_a);
|
||||
let ch_b = Chan(po_b);
|
||||
let ch_a = Chan(&po_a);
|
||||
let ch_b = Chan(&po_b);
|
||||
|
||||
send(ch_a, ~"a");
|
||||
|
||||
|
|
@ -376,8 +376,8 @@ fn test_select2_available() {
|
|||
fn test_select2_rendezvous() {
|
||||
let po_a = Port();
|
||||
let po_b = Port();
|
||||
let ch_a = Chan(po_a);
|
||||
let ch_b = Chan(po_b);
|
||||
let ch_a = Chan(&po_a);
|
||||
let ch_b = Chan(&po_b);
|
||||
|
||||
for iter::repeat(10) {
|
||||
do task::spawn {
|
||||
|
|
@ -400,8 +400,8 @@ fn test_select2_rendezvous() {
|
|||
fn test_select2_stress() {
|
||||
let po_a = Port();
|
||||
let po_b = Port();
|
||||
let ch_a = Chan(po_a);
|
||||
let ch_b = Chan(po_b);
|
||||
let ch_a = Chan(&po_a);
|
||||
let ch_b = Chan(&po_b);
|
||||
|
||||
let msgs = 100;
|
||||
let times = 4u;
|
||||
|
|
@ -436,7 +436,7 @@ fn test_select2_stress() {
|
|||
#[test]
|
||||
fn test_recv_chan() {
|
||||
let po = Port();
|
||||
let ch = Chan(po);
|
||||
let ch = Chan(&po);
|
||||
send(ch, ~"flower");
|
||||
assert recv_chan(ch) == ~"flower";
|
||||
}
|
||||
|
|
@ -445,7 +445,7 @@ fn test_recv_chan() {
|
|||
#[should_fail]
|
||||
#[ignore(cfg(windows))]
|
||||
fn test_recv_chan_dead() {
|
||||
let ch = Chan(Port());
|
||||
let ch = Chan(&Port());
|
||||
send(ch, ~"flower");
|
||||
recv_chan(ch);
|
||||
}
|
||||
|
|
@ -454,7 +454,7 @@ fn test_recv_chan_dead() {
|
|||
#[ignore(cfg(windows))]
|
||||
fn test_recv_chan_wrong_task() {
|
||||
let po = Port();
|
||||
let ch = Chan(po);
|
||||
let ch = Chan(&po);
|
||||
send(ch, ~"flower");
|
||||
assert result::is_err(&task::try(||
|
||||
recv_chan(ch)
|
||||
|
|
|
|||
|
|
@ -36,227 +36,185 @@ Implicitly, all crates behave as if they included the following prologue:
|
|||
// Don't link to core. We are core.
|
||||
#[no_core];
|
||||
|
||||
#[legacy_exports];
|
||||
|
||||
#[warn(deprecated_mode)];
|
||||
#[warn(deprecated_pattern)];
|
||||
|
||||
#[warn(vecs_implicitly_copyable)];
|
||||
#[deny(non_camel_case_types)];
|
||||
|
||||
export int, i8, i16, i32, i64;
|
||||
export uint, u8, u16, u32, u64;
|
||||
export float, f32, f64;
|
||||
export box, char, str, ptr, vec, at_vec, bool;
|
||||
export either, option, result, iter;
|
||||
export gc, io, libc, os, run, rand, sys, cast, logging;
|
||||
export comm, task, future, pipes;
|
||||
export extfmt;
|
||||
// The test harness links against core, so don't include runtime in tests.
|
||||
// FIXME (#2861): Uncomment this after snapshot gets updated.
|
||||
//#[cfg(notest)]
|
||||
export rt;
|
||||
export tuple;
|
||||
export to_str, to_bytes;
|
||||
export from_str;
|
||||
export util;
|
||||
export dvec, dvec_iter;
|
||||
export dlist, dlist_iter;
|
||||
export send_map;
|
||||
export hash;
|
||||
export cmp;
|
||||
export num;
|
||||
export path;
|
||||
export mutable;
|
||||
export flate;
|
||||
export unit;
|
||||
export uniq;
|
||||
export repr;
|
||||
export cleanup;
|
||||
export reflect;
|
||||
|
||||
// NDM seems to be necessary for resolve to work
|
||||
export option_iter;
|
||||
|
||||
// This creates some APIs that I do not want to commit to, but it must be
|
||||
// exported from core in order for uv to remain in std (see #2648).
|
||||
export private;
|
||||
|
||||
|
||||
// Built-in-type support modules
|
||||
|
||||
/// Operations and constants for `int`
|
||||
#[path = "int-template"]
|
||||
mod int {
|
||||
pub mod int {
|
||||
pub use inst::{ pow };
|
||||
#[path = "int.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `i8`
|
||||
#[path = "int-template"]
|
||||
mod i8 {
|
||||
pub mod i8 {
|
||||
#[path = "i8.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `i16`
|
||||
#[path = "int-template"]
|
||||
mod i16 {
|
||||
pub mod i16 {
|
||||
#[path = "i16.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `i32`
|
||||
#[path = "int-template"]
|
||||
mod i32 {
|
||||
pub mod i32 {
|
||||
#[path = "i32.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `i64`
|
||||
#[path = "int-template"]
|
||||
mod i64 {
|
||||
pub mod i64 {
|
||||
#[path = "i64.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `uint`
|
||||
#[path = "uint-template"]
|
||||
mod uint {
|
||||
pub mod uint {
|
||||
pub use inst::{
|
||||
div_ceil, div_round, div_floor, iterate,
|
||||
next_power_of_two
|
||||
};
|
||||
#[path = "uint.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `u8`
|
||||
#[path = "uint-template"]
|
||||
mod u8 {
|
||||
pub mod u8 {
|
||||
pub use inst::is_ascii;
|
||||
#[path = "u8.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `u16`
|
||||
#[path = "uint-template"]
|
||||
mod u16 {
|
||||
pub mod u16 {
|
||||
#[path = "u16.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `u32`
|
||||
#[path = "uint-template"]
|
||||
mod u32 {
|
||||
pub mod u32 {
|
||||
#[path = "u32.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
/// Operations and constants for `u64`
|
||||
#[path = "uint-template"]
|
||||
mod u64 {
|
||||
pub mod u64 {
|
||||
#[path = "u64.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
|
||||
|
||||
mod box;
|
||||
mod char;
|
||||
mod float;
|
||||
mod f32;
|
||||
mod f64;
|
||||
mod str;
|
||||
mod ptr;
|
||||
mod vec;
|
||||
mod at_vec;
|
||||
mod bool;
|
||||
mod tuple;
|
||||
mod unit;
|
||||
mod uniq;
|
||||
pub mod box;
|
||||
pub mod char;
|
||||
pub mod float;
|
||||
pub mod f32;
|
||||
pub mod f64;
|
||||
pub mod str;
|
||||
pub mod ptr;
|
||||
pub mod vec;
|
||||
pub mod at_vec;
|
||||
pub mod bool;
|
||||
pub mod tuple;
|
||||
pub mod unit;
|
||||
pub mod uniq;
|
||||
|
||||
// Ubiquitous-utility-type modules
|
||||
|
||||
#[cfg(notest)]
|
||||
mod ops;
|
||||
mod cmp;
|
||||
mod num;
|
||||
mod hash;
|
||||
mod either;
|
||||
mod iter;
|
||||
mod logging;
|
||||
mod option;
|
||||
pub mod ops;
|
||||
pub mod cmp;
|
||||
pub mod num;
|
||||
pub mod hash;
|
||||
pub mod either;
|
||||
pub mod iter;
|
||||
pub mod logging;
|
||||
pub mod option;
|
||||
#[path="iter-trait"]
|
||||
mod option_iter {
|
||||
pub mod option_iter {
|
||||
#[path = "option.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
mod result;
|
||||
mod to_str;
|
||||
mod to_bytes;
|
||||
mod from_str;
|
||||
mod util;
|
||||
pub mod result;
|
||||
pub mod to_str;
|
||||
pub mod to_bytes;
|
||||
pub mod from_str;
|
||||
pub mod util;
|
||||
|
||||
// Data structure modules
|
||||
|
||||
mod dvec;
|
||||
pub mod dvec;
|
||||
#[path="iter-trait"]
|
||||
mod dvec_iter {
|
||||
pub mod dvec_iter {
|
||||
#[path = "dvec.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
mod dlist;
|
||||
pub mod dlist;
|
||||
#[path="iter-trait"]
|
||||
mod dlist_iter {
|
||||
pub mod dlist_iter {
|
||||
#[path ="dlist.rs"]
|
||||
mod inst;
|
||||
pub mod inst;
|
||||
}
|
||||
mod send_map;
|
||||
pub mod send_map;
|
||||
|
||||
// Concurrency
|
||||
mod comm;
|
||||
mod task {
|
||||
pub mod comm;
|
||||
pub mod task {
|
||||
pub mod local_data;
|
||||
mod local_data_priv;
|
||||
pub mod spawn;
|
||||
pub mod rt;
|
||||
}
|
||||
mod future;
|
||||
mod pipes;
|
||||
pub mod future;
|
||||
pub mod pipes;
|
||||
|
||||
// Runtime and language-primitive support
|
||||
|
||||
mod gc;
|
||||
mod io;
|
||||
mod libc;
|
||||
mod os;
|
||||
mod path;
|
||||
mod rand;
|
||||
mod run;
|
||||
mod sys;
|
||||
mod cast;
|
||||
mod mutable;
|
||||
mod flate;
|
||||
mod repr;
|
||||
mod cleanup;
|
||||
mod reflect;
|
||||
pub mod gc;
|
||||
pub mod io;
|
||||
pub mod libc;
|
||||
pub mod os;
|
||||
pub mod path;
|
||||
pub mod rand;
|
||||
pub mod run;
|
||||
pub mod sys;
|
||||
pub mod cast;
|
||||
pub mod mutable;
|
||||
pub mod flate;
|
||||
pub mod repr;
|
||||
pub mod cleanup;
|
||||
pub mod reflect;
|
||||
|
||||
// Modules supporting compiler-generated code
|
||||
// Exported but not part of the public interface
|
||||
|
||||
#[legacy_exports]
|
||||
mod extfmt;
|
||||
pub mod extfmt;
|
||||
// The test harness links against core, so don't include runtime in tests.
|
||||
#[cfg(notest)]
|
||||
#[legacy_exports]
|
||||
mod rt;
|
||||
pub mod rt;
|
||||
|
||||
// Ideally not exported, but currently is.
|
||||
pub mod private;
|
||||
|
||||
// For internal use, not exported
|
||||
|
||||
// For internal use, not exported.
|
||||
mod unicode;
|
||||
mod private;
|
||||
mod cmath;
|
||||
mod stackwalk;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,101 +2,76 @@
|
|||
|
||||
// Export various ubiquitous types, constructors, methods.
|
||||
|
||||
use option::{Some, None};
|
||||
use Option = option::Option;
|
||||
use result::{Result, Ok, Err};
|
||||
pub use option::{Some, None};
|
||||
pub use Option = option::Option;
|
||||
pub use result::{Result, Ok, Err};
|
||||
|
||||
use Path = path::Path;
|
||||
use GenericPath = path::GenericPath;
|
||||
use WindowsPath = path::WindowsPath;
|
||||
use PosixPath = path::PosixPath;
|
||||
pub use Path = path::Path;
|
||||
pub use GenericPath = path::GenericPath;
|
||||
pub use WindowsPath = path::WindowsPath;
|
||||
pub use PosixPath = path::PosixPath;
|
||||
|
||||
use tuple::{TupleOps, ExtendedTupleOps};
|
||||
use str::{StrSlice, UniqueStr};
|
||||
use vec::{ConstVector, CopyableVector, ImmutableVector};
|
||||
use vec::{ImmutableEqVector, ImmutableCopyableVector};
|
||||
use vec::{MutableVector, MutableCopyableVector};
|
||||
use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
|
||||
use iter::{CopyableOrderedIter, Times, TimesIx};
|
||||
use num::Num;
|
||||
use ptr::Ptr;
|
||||
use to_str::ToStr;
|
||||
|
||||
export Path, WindowsPath, PosixPath, GenericPath;
|
||||
export Option, Some, None;
|
||||
export Result, Ok, Err;
|
||||
export extensions;
|
||||
// The following exports are the extension impls for numeric types
|
||||
export Num, Times, TimesIx;
|
||||
// The following exports are the common traits
|
||||
export StrSlice, UniqueStr;
|
||||
export ConstVector, CopyableVector, ImmutableVector;
|
||||
export ImmutableEqVector, ImmutableCopyableVector, IterTraitExtensions;
|
||||
export MutableVector, MutableCopyableVector;
|
||||
export BaseIter, CopyableIter, CopyableOrderedIter, ExtendedIter, EqIter;
|
||||
export TupleOps, ExtendedTupleOps;
|
||||
export Ptr;
|
||||
export ToStr;
|
||||
pub use tuple::{TupleOps, ExtendedTupleOps};
|
||||
pub use str::{StrSlice, UniqueStr};
|
||||
pub use vec::{ConstVector, CopyableVector, ImmutableVector};
|
||||
pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
|
||||
pub use vec::{MutableVector, MutableCopyableVector};
|
||||
pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
|
||||
pub use iter::{CopyableOrderedIter, Times, TimesIx};
|
||||
pub use num::Num;
|
||||
pub use ptr::Ptr;
|
||||
pub use to_str::ToStr;
|
||||
|
||||
// The following exports are the core operators and kinds
|
||||
// The compiler has special knowlege of these so we must not duplicate them
|
||||
// when compiling for testing
|
||||
#[cfg(notest)]
|
||||
use ops::{Const, Copy, Send, Owned};
|
||||
pub use ops::{Const, Copy, Send, Owned};
|
||||
#[cfg(notest)]
|
||||
use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
|
||||
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
|
||||
#[cfg(notest)]
|
||||
use ops::{Shl, Shr, Index};
|
||||
|
||||
#[cfg(notest)]
|
||||
export Const, Copy, Send, Owned;
|
||||
#[cfg(notest)]
|
||||
export Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor;
|
||||
#[cfg(notest)]
|
||||
export Shl, Shr, Index;
|
||||
pub use ops::{Shl, Shr, Index};
|
||||
|
||||
#[cfg(test)]
|
||||
extern mod coreops(name = "core", vers = "0.4");
|
||||
|
||||
#[cfg(test)]
|
||||
use coreops::ops::{Const, Copy, Send, Owned};
|
||||
pub use coreops::ops::{Const, Copy, Send, Owned};
|
||||
#[cfg(test)]
|
||||
use coreops::ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
|
||||
pub use coreops::ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr};
|
||||
#[cfg(test)]
|
||||
use coreops::ops::{Shl, Shr, Index};
|
||||
pub use coreops::ops::{BitXor};
|
||||
#[cfg(test)]
|
||||
pub use coreops::ops::{Shl, Shr, Index};
|
||||
|
||||
|
||||
// Export the log levels as global constants. Higher levels mean
|
||||
// more-verbosity. Error is the bottom level, default logging level is
|
||||
// warn-and-below.
|
||||
|
||||
export error, warn, info, debug;
|
||||
|
||||
/// The error log level
|
||||
const error : u32 = 0_u32;
|
||||
pub const error : u32 = 0_u32;
|
||||
/// The warning log level
|
||||
const warn : u32 = 1_u32;
|
||||
pub const warn : u32 = 1_u32;
|
||||
/// The info log level
|
||||
const info : u32 = 2_u32;
|
||||
pub const info : u32 = 2_u32;
|
||||
/// The debug log level
|
||||
const debug : u32 = 3_u32;
|
||||
pub const debug : u32 = 3_u32;
|
||||
|
||||
// A curious inner-module that's not exported that contains the binding
|
||||
// 'core' so that macro-expanded references to core::error and such
|
||||
// can be resolved within libcore.
|
||||
#[doc(hidden)] // FIXME #3538
|
||||
mod core {
|
||||
#[legacy_exports];
|
||||
const error : u32 = 0_u32;
|
||||
const warn : u32 = 1_u32;
|
||||
const info : u32 = 2_u32;
|
||||
const debug : u32 = 3_u32;
|
||||
pub const error : u32 = 0_u32;
|
||||
pub const warn : u32 = 1_u32;
|
||||
pub const info : u32 = 2_u32;
|
||||
pub const debug : u32 = 3_u32;
|
||||
}
|
||||
|
||||
// Similar to above. Some magic to make core testable.
|
||||
#[cfg(test)]
|
||||
mod std {
|
||||
#[legacy_exports];
|
||||
extern mod std(vers = "0.4");
|
||||
use std::test;
|
||||
pub use std::test;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
|
|||
*/
|
||||
|
||||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
type DListLink<T> = Option<DListNode<T>>;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ Note that recursive use is not permitted.
|
|||
*/
|
||||
|
||||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cast::reinterpret_cast;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
//! A type that represents one of two alternatives
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
#[doc(hidden)];
|
||||
// NB: transitionary, de-mode-ing.
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
/*
|
||||
Syntax Extension: fmt
|
||||
|
|
@ -41,11 +44,10 @@ use option::{Some, None};
|
|||
*/
|
||||
|
||||
// Functions used by the fmt extension at compile time
|
||||
mod ct {
|
||||
#[legacy_exports];
|
||||
enum Signedness { Signed, Unsigned, }
|
||||
enum Caseness { CaseUpper, CaseLower, }
|
||||
enum Ty {
|
||||
pub mod ct {
|
||||
pub enum Signedness { Signed, Unsigned, }
|
||||
pub enum Caseness { CaseUpper, CaseLower, }
|
||||
pub enum Ty {
|
||||
TyBool,
|
||||
TyStr,
|
||||
TyChar,
|
||||
|
|
@ -56,14 +58,14 @@ mod ct {
|
|||
TyFloat,
|
||||
TyPoly,
|
||||
}
|
||||
enum Flag {
|
||||
pub enum Flag {
|
||||
FlagLeftJustify,
|
||||
FlagLeftZeroPad,
|
||||
FlagSpaceForSign,
|
||||
FlagSignAlways,
|
||||
FlagAlternate,
|
||||
}
|
||||
enum Count {
|
||||
pub enum Count {
|
||||
CountIs(int),
|
||||
CountIsParam(int),
|
||||
CountIsNextParam,
|
||||
|
|
@ -71,7 +73,7 @@ mod ct {
|
|||
}
|
||||
|
||||
// A formatted conversion from an expression to a string
|
||||
type Conv =
|
||||
pub type Conv =
|
||||
{param: Option<int>,
|
||||
flags: ~[Flag],
|
||||
width: Count,
|
||||
|
|
@ -80,10 +82,10 @@ mod ct {
|
|||
|
||||
|
||||
// A fragment of the output sequence
|
||||
enum Piece { PieceString(~str), PieceConv(Conv), }
|
||||
type ErrorFn = fn@(&str) -> ! ;
|
||||
pub enum Piece { PieceString(~str), PieceConv(Conv), }
|
||||
pub type ErrorFn = fn@(&str) -> ! ;
|
||||
|
||||
fn parse_fmt_string(s: &str, error: ErrorFn) -> ~[Piece] {
|
||||
pub fn parse_fmt_string(s: &str, error: ErrorFn) -> ~[Piece] {
|
||||
let mut pieces: ~[Piece] = ~[];
|
||||
let lim = str::len(s);
|
||||
let mut buf = ~"";
|
||||
|
|
@ -118,7 +120,7 @@ mod ct {
|
|||
flush_buf(move buf, &mut pieces);
|
||||
move pieces
|
||||
}
|
||||
fn peek_num(s: &str, i: uint, lim: uint) ->
|
||||
pub fn peek_num(s: &str, i: uint, lim: uint) ->
|
||||
Option<{num: uint, next: uint}> {
|
||||
let mut j = i;
|
||||
let mut accum = 0u;
|
||||
|
|
@ -140,7 +142,8 @@ mod ct {
|
|||
None
|
||||
}
|
||||
}
|
||||
fn parse_conversion(s: &str, i: uint, lim: uint, error: ErrorFn) ->
|
||||
pub fn parse_conversion(s: &str, i: uint, lim: uint,
|
||||
error: ErrorFn) ->
|
||||
{piece: Piece, next: uint} {
|
||||
let parm = parse_parameter(s, i, lim);
|
||||
let flags = parse_flags(s, parm.next, lim);
|
||||
|
|
@ -155,7 +158,7 @@ mod ct {
|
|||
ty: ty.ty}),
|
||||
next: ty.next};
|
||||
}
|
||||
fn parse_parameter(s: &str, i: uint, lim: uint) ->
|
||||
pub fn parse_parameter(s: &str, i: uint, lim: uint) ->
|
||||
{param: Option<int>, next: uint} {
|
||||
if i >= lim { return {param: None, next: i}; }
|
||||
let num = peek_num(s, i, lim);
|
||||
|
|
@ -170,7 +173,7 @@ mod ct {
|
|||
}
|
||||
};
|
||||
}
|
||||
fn parse_flags(s: &str, i: uint, lim: uint) ->
|
||||
pub fn parse_flags(s: &str, i: uint, lim: uint) ->
|
||||
{flags: ~[Flag], next: uint} {
|
||||
let noflags: ~[Flag] = ~[];
|
||||
if i >= lim { return {flags: move noflags, next: i}; }
|
||||
|
|
@ -198,7 +201,7 @@ mod ct {
|
|||
more(FlagAlternate, s, i, lim)
|
||||
} else { {flags: move noflags, next: i} };
|
||||
}
|
||||
fn parse_count(s: &str, i: uint, lim: uint)
|
||||
pub fn parse_count(s: &str, i: uint, lim: uint)
|
||||
-> {count: Count, next: uint} {
|
||||
return if i >= lim {
|
||||
{count: CountImplied, next: i}
|
||||
|
|
@ -220,7 +223,7 @@ mod ct {
|
|||
}
|
||||
};
|
||||
}
|
||||
fn parse_precision(s: &str, i: uint, lim: uint) ->
|
||||
pub fn parse_precision(s: &str, i: uint, lim: uint) ->
|
||||
{count: Count, next: uint} {
|
||||
return if i >= lim {
|
||||
{count: CountImplied, next: i}
|
||||
|
|
@ -236,7 +239,7 @@ mod ct {
|
|||
}
|
||||
} else { {count: CountImplied, next: i} };
|
||||
}
|
||||
fn parse_type(s: &str, i: uint, lim: uint, error: ErrorFn) ->
|
||||
pub fn parse_type(s: &str, i: uint, lim: uint, error: ErrorFn) ->
|
||||
{ty: Ty, next: uint} {
|
||||
if i >= lim { error(~"missing type in conversion"); }
|
||||
let tstr = str::slice(s, i, i+1u);
|
||||
|
|
@ -274,21 +277,20 @@ mod ct {
|
|||
// decisions made a runtime. If it proves worthwhile then some of these
|
||||
// conditions can be evaluated at compile-time. For now though it's cleaner to
|
||||
// implement it 0this way, I think.
|
||||
mod rt {
|
||||
#[legacy_exports];
|
||||
const flag_none : u32 = 0u32;
|
||||
const flag_left_justify : u32 = 0b00000000000000000000000000000001u32;
|
||||
const flag_left_zero_pad : u32 = 0b00000000000000000000000000000010u32;
|
||||
const flag_space_for_sign : u32 = 0b00000000000000000000000000000100u32;
|
||||
const flag_sign_always : u32 = 0b00000000000000000000000000001000u32;
|
||||
const flag_alternate : u32 = 0b00000000000000000000000000010000u32;
|
||||
pub mod rt {
|
||||
pub const flag_none : u32 = 0u32;
|
||||
pub const flag_left_justify : u32 = 0b00000000000001u32;
|
||||
pub const flag_left_zero_pad : u32 = 0b00000000000010u32;
|
||||
pub const flag_space_for_sign : u32 = 0b00000000000100u32;
|
||||
pub const flag_sign_always : u32 = 0b00000000001000u32;
|
||||
pub const flag_alternate : u32 = 0b00000000010000u32;
|
||||
|
||||
enum Count { CountIs(int), CountImplied, }
|
||||
enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, }
|
||||
pub enum Count { CountIs(int), CountImplied, }
|
||||
pub enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, }
|
||||
|
||||
type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
|
||||
pub type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
|
||||
|
||||
pure fn conv_int(cv: Conv, i: int) -> ~str {
|
||||
pub pure fn conv_int(cv: Conv, i: int) -> ~str {
|
||||
let radix = 10;
|
||||
let prec = get_int_precision(cv);
|
||||
let mut s : ~str = int_to_str_prec(i, radix, prec);
|
||||
|
|
@ -301,7 +303,7 @@ mod rt {
|
|||
}
|
||||
return unsafe { pad(cv, s, PadSigned) };
|
||||
}
|
||||
pure fn conv_uint(cv: Conv, u: uint) -> ~str {
|
||||
pub pure fn conv_uint(cv: Conv, u: uint) -> ~str {
|
||||
let prec = get_int_precision(cv);
|
||||
let mut rs =
|
||||
match cv.ty {
|
||||
|
|
@ -313,17 +315,17 @@ mod rt {
|
|||
};
|
||||
return unsafe { pad(cv, rs, PadUnsigned) };
|
||||
}
|
||||
pure fn conv_bool(cv: Conv, b: bool) -> ~str {
|
||||
pub pure fn conv_bool(cv: Conv, b: bool) -> ~str {
|
||||
let s = if b { ~"true" } else { ~"false" };
|
||||
// run the boolean conversion through the string conversion logic,
|
||||
// giving it the same rules for precision, etc.
|
||||
return conv_str(cv, s);
|
||||
}
|
||||
pure fn conv_char(cv: Conv, c: char) -> ~str {
|
||||
pub pure fn conv_char(cv: Conv, c: char) -> ~str {
|
||||
let mut s = str::from_char(c);
|
||||
return unsafe { pad(cv, s, PadNozero) };
|
||||
}
|
||||
pure fn conv_str(cv: Conv, s: &str) -> ~str {
|
||||
pub pure fn conv_str(cv: Conv, s: &str) -> ~str {
|
||||
// For strings, precision is the maximum characters
|
||||
// displayed
|
||||
let mut unpadded = match cv.precision {
|
||||
|
|
@ -336,7 +338,7 @@ mod rt {
|
|||
};
|
||||
return unsafe { pad(cv, unpadded, PadNozero) };
|
||||
}
|
||||
pure fn conv_float(cv: Conv, f: float) -> ~str {
|
||||
pub pure fn conv_float(cv: Conv, f: float) -> ~str {
|
||||
let (to_str, digits) = match cv.precision {
|
||||
CountIs(c) => (float::to_str_exact, c as uint),
|
||||
CountImplied => (float::to_str, 6u)
|
||||
|
|
@ -351,14 +353,14 @@ mod rt {
|
|||
}
|
||||
return unsafe { pad(cv, s, PadFloat) };
|
||||
}
|
||||
pure fn conv_poly<T>(cv: Conv, v: &T) -> ~str {
|
||||
pub pure fn conv_poly<T>(cv: Conv, v: &T) -> ~str {
|
||||
let s = sys::log_str(v);
|
||||
return conv_str(cv, s);
|
||||
}
|
||||
|
||||
// Convert an int to string with minimum number of digits. If precision is
|
||||
// 0 and num is 0 then the result is the empty string.
|
||||
pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str {
|
||||
pub pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str {
|
||||
return if num < 0 {
|
||||
~"-" + uint_to_str_prec(-num as uint, radix, prec)
|
||||
} else { uint_to_str_prec(num as uint, radix, prec) };
|
||||
|
|
@ -367,7 +369,8 @@ mod rt {
|
|||
// Convert a uint to string with a minimum number of digits. If precision
|
||||
// is 0 and num is 0 then the result is the empty string. Could move this
|
||||
// to uint: but it doesn't seem all that useful.
|
||||
pure fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str {
|
||||
pub pure fn uint_to_str_prec(num: uint, radix: uint,
|
||||
prec: uint) -> ~str {
|
||||
return if prec == 0u && num == 0u {
|
||||
~""
|
||||
} else {
|
||||
|
|
@ -380,16 +383,16 @@ mod rt {
|
|||
} else { move s }
|
||||
};
|
||||
}
|
||||
pure fn get_int_precision(cv: Conv) -> uint {
|
||||
pub pure fn get_int_precision(cv: Conv) -> uint {
|
||||
return match cv.precision {
|
||||
CountIs(c) => c as uint,
|
||||
CountImplied => 1u
|
||||
};
|
||||
}
|
||||
|
||||
enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
|
||||
pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
|
||||
|
||||
impl PadMode : Eq {
|
||||
pub impl PadMode : Eq {
|
||||
pure fn eq(other: &PadMode) -> bool {
|
||||
match (self, (*other)) {
|
||||
(PadSigned, PadSigned) => true,
|
||||
|
|
@ -405,7 +408,7 @@ mod rt {
|
|||
pure fn ne(other: &PadMode) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
|
||||
pub fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
|
||||
let mut s = move s; // sadtimes
|
||||
let uwidth : uint = match cv.width {
|
||||
CountImplied => return s,
|
||||
|
|
@ -458,209 +461,13 @@ mod rt {
|
|||
}
|
||||
return padstr + s;
|
||||
}
|
||||
pure fn have_flag(flags: u32, f: u32) -> bool {
|
||||
flags & f != 0
|
||||
}
|
||||
}
|
||||
|
||||
// Remove after snapshot
|
||||
|
||||
// Functions used by the fmt extension at runtime. For now there are a lot of
|
||||
// decisions made a runtime. If it proves worthwhile then some of these
|
||||
// conditions can be evaluated at compile-time. For now though it's cleaner to
|
||||
// implement it 0this way, I think.
|
||||
mod rt2 {
|
||||
#[legacy_exports];
|
||||
const flag_none : u32 = 0u32;
|
||||
const flag_left_justify : u32 = 0b00000000000000000000000000000001u32;
|
||||
const flag_left_zero_pad : u32 = 0b00000000000000000000000000000010u32;
|
||||
const flag_space_for_sign : u32 = 0b00000000000000000000000000000100u32;
|
||||
const flag_sign_always : u32 = 0b00000000000000000000000000001000u32;
|
||||
const flag_alternate : u32 = 0b00000000000000000000000000010000u32;
|
||||
|
||||
enum Count { CountIs(int), CountImplied, }
|
||||
enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, }
|
||||
|
||||
type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
|
||||
|
||||
pure fn conv_int(cv: Conv, i: int) -> ~str {
|
||||
let radix = 10;
|
||||
let prec = get_int_precision(cv);
|
||||
let mut s : ~str = int_to_str_prec(i, radix, prec);
|
||||
if 0 <= i {
|
||||
if have_flag(cv.flags, flag_sign_always) {
|
||||
unsafe { str::unshift_char(&mut s, '+') };
|
||||
} else if have_flag(cv.flags, flag_space_for_sign) {
|
||||
unsafe { str::unshift_char(&mut s, ' ') };
|
||||
}
|
||||
}
|
||||
return unsafe { pad(cv, s, PadSigned) };
|
||||
}
|
||||
pure fn conv_uint(cv: Conv, u: uint) -> ~str {
|
||||
let prec = get_int_precision(cv);
|
||||
let mut rs =
|
||||
match cv.ty {
|
||||
TyDefault => uint_to_str_prec(u, 10u, prec),
|
||||
TyHexLower => uint_to_str_prec(u, 16u, prec),
|
||||
TyHexUpper => str::to_upper(uint_to_str_prec(u, 16u, prec)),
|
||||
TyBits => uint_to_str_prec(u, 2u, prec),
|
||||
TyOctal => uint_to_str_prec(u, 8u, prec)
|
||||
};
|
||||
return unsafe { pad(cv, rs, PadUnsigned) };
|
||||
}
|
||||
pure fn conv_bool(cv: Conv, b: bool) -> ~str {
|
||||
let s = if b { ~"true" } else { ~"false" };
|
||||
// run the boolean conversion through the string conversion logic,
|
||||
// giving it the same rules for precision, etc.
|
||||
return conv_str(cv, s);
|
||||
}
|
||||
pure fn conv_char(cv: Conv, c: char) -> ~str {
|
||||
let mut s = str::from_char(c);
|
||||
return unsafe { pad(cv, s, PadNozero) };
|
||||
}
|
||||
pure fn conv_str(cv: Conv, s: &str) -> ~str {
|
||||
// For strings, precision is the maximum characters
|
||||
// displayed
|
||||
let mut unpadded = match cv.precision {
|
||||
CountImplied => s.to_unique(),
|
||||
CountIs(max) => if max as uint < str::char_len(s) {
|
||||
str::substr(s, 0u, max as uint)
|
||||
} else {
|
||||
s.to_unique()
|
||||
}
|
||||
};
|
||||
return unsafe { pad(cv, unpadded, PadNozero) };
|
||||
}
|
||||
pure fn conv_float(cv: Conv, f: float) -> ~str {
|
||||
let (to_str, digits) = match cv.precision {
|
||||
CountIs(c) => (float::to_str_exact, c as uint),
|
||||
CountImplied => (float::to_str, 6u)
|
||||
};
|
||||
let mut s = unsafe { to_str(f, digits) };
|
||||
if 0.0 <= f {
|
||||
if have_flag(cv.flags, flag_sign_always) {
|
||||
s = ~"+" + s;
|
||||
} else if have_flag(cv.flags, flag_space_for_sign) {
|
||||
s = ~" " + s;
|
||||
}
|
||||
}
|
||||
return unsafe { pad(cv, s, PadFloat) };
|
||||
}
|
||||
pure fn conv_poly<T>(cv: Conv, v: &T) -> ~str {
|
||||
let s = sys::log_str(v);
|
||||
return conv_str(cv, s);
|
||||
}
|
||||
|
||||
// Convert an int to string with minimum number of digits. If precision is
|
||||
// 0 and num is 0 then the result is the empty string.
|
||||
pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str {
|
||||
return if num < 0 {
|
||||
~"-" + uint_to_str_prec(-num as uint, radix, prec)
|
||||
} else { uint_to_str_prec(num as uint, radix, prec) };
|
||||
}
|
||||
|
||||
// Convert a uint to string with a minimum number of digits. If precision
|
||||
// is 0 and num is 0 then the result is the empty string. Could move this
|
||||
// to uint: but it doesn't seem all that useful.
|
||||
pure fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str {
|
||||
return if prec == 0u && num == 0u {
|
||||
~""
|
||||
} else {
|
||||
let s = uint::to_str(num, radix);
|
||||
let len = str::char_len(s);
|
||||
if len < prec {
|
||||
let diff = prec - len;
|
||||
let pad = str::from_chars(vec::from_elem(diff, '0'));
|
||||
pad + s
|
||||
} else { move s }
|
||||
};
|
||||
}
|
||||
pure fn get_int_precision(cv: Conv) -> uint {
|
||||
return match cv.precision {
|
||||
CountIs(c) => c as uint,
|
||||
CountImplied => 1u
|
||||
};
|
||||
}
|
||||
|
||||
enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
|
||||
|
||||
impl PadMode : Eq {
|
||||
pure fn eq(other: &PadMode) -> bool {
|
||||
match (self, (*other)) {
|
||||
(PadSigned, PadSigned) => true,
|
||||
(PadUnsigned, PadUnsigned) => true,
|
||||
(PadNozero, PadNozero) => true,
|
||||
(PadFloat, PadFloat) => true,
|
||||
(PadSigned, _) => false,
|
||||
(PadUnsigned, _) => false,
|
||||
(PadNozero, _) => false,
|
||||
(PadFloat, _) => false
|
||||
}
|
||||
}
|
||||
pure fn ne(other: &PadMode) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
|
||||
let mut s = move s; // sadtimes
|
||||
let uwidth : uint = match cv.width {
|
||||
CountImplied => return s,
|
||||
CountIs(width) => {
|
||||
// FIXME: width should probably be uint (see Issue #1996)
|
||||
width as uint
|
||||
}
|
||||
};
|
||||
let strlen = str::char_len(s);
|
||||
if uwidth <= strlen { return s; }
|
||||
let mut padchar = ' ';
|
||||
let diff = uwidth - strlen;
|
||||
if have_flag(cv.flags, flag_left_justify) {
|
||||
let padstr = str::from_chars(vec::from_elem(diff, padchar));
|
||||
return s + padstr;
|
||||
}
|
||||
let {might_zero_pad, signed} = match mode {
|
||||
PadNozero => {might_zero_pad:false, signed:false},
|
||||
PadSigned => {might_zero_pad:true, signed:true },
|
||||
PadFloat => {might_zero_pad:true, signed:true},
|
||||
PadUnsigned => {might_zero_pad:true, signed:false}
|
||||
};
|
||||
pure fn have_precision(cv: Conv) -> bool {
|
||||
return match cv.precision { CountImplied => false, _ => true };
|
||||
}
|
||||
let zero_padding = {
|
||||
if might_zero_pad && have_flag(cv.flags, flag_left_zero_pad) &&
|
||||
(!have_precision(cv) || mode == PadFloat) {
|
||||
padchar = '0';
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
let padstr = str::from_chars(vec::from_elem(diff, padchar));
|
||||
// This is completely heinous. If we have a signed value then
|
||||
// potentially rip apart the intermediate result and insert some
|
||||
// zeros. It may make sense to convert zero padding to a precision
|
||||
// instead.
|
||||
|
||||
if signed && zero_padding && s.len() > 0 {
|
||||
let head = str::shift_char(&mut s);
|
||||
if head == '+' || head == '-' || head == ' ' {
|
||||
let headstr = str::from_chars(vec::from_elem(1u, head));
|
||||
return headstr + padstr + s;
|
||||
}
|
||||
else {
|
||||
str::unshift_char(&mut s, head);
|
||||
}
|
||||
}
|
||||
return padstr + s;
|
||||
}
|
||||
pure fn have_flag(flags: u32, f: u32) -> bool {
|
||||
pub pure fn have_flag(flags: u32, f: u32) -> bool {
|
||||
flags & f != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[legacy_exports];
|
||||
#[test]
|
||||
fn fmt_slice() {
|
||||
let s = "abc";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
// tjc: allowing deprecated modes due to function issue.
|
||||
// can re-forbid them after snapshot
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
/*!
|
||||
|
|
@ -86,7 +87,7 @@ pub fn from_port<A:Send>(port: future_pipe::client::waiting<A>) ->
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_fn<A>(+f: ~fn() -> A) -> Future<A> {
|
||||
pub fn from_fn<A>(f: ~fn() -> A) -> Future<A> {
|
||||
/*!
|
||||
* Create a future from a function.
|
||||
*
|
||||
|
|
@ -98,7 +99,7 @@ pub fn from_fn<A>(+f: ~fn() -> A) -> Future<A> {
|
|||
Future {state: Pending(move f)}
|
||||
}
|
||||
|
||||
pub fn spawn<A:Send>(+blk: fn~() -> A) -> Future<A> {
|
||||
pub fn spawn<A:Send>(blk: fn~() -> A) -> Future<A> {
|
||||
/*!
|
||||
* Create a future from a unique closure.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use T = inst::T;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ Basic input/output
|
|||
|
||||
*/
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use result::Result;
|
||||
|
||||
use cmp::Eq;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
// workaround our lack of traits and lack of macros. See core.{rc,rs} for
|
||||
// how this file is used.
|
||||
|
||||
#[warn(deprecated_mode)];
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cmp::{Eq, Ord};
|
||||
use inst::{IMPL_T, EACH, SIZE_HINT};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ The iteration traits and common implementation
|
|||
|
||||
*/
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cmp::{Eq, Ord};
|
||||
|
||||
/// A function used to initialize the elements of a sequence
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ dynamic checks: your program will fail if you attempt to perform
|
|||
mutation when the data structure should be immutable.
|
||||
|
||||
*/
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use util::with;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
// Core operators and kinds.
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
#[lang="const"]
|
||||
pub trait Const {
|
||||
// Empty.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,37 @@
|
|||
/*!
|
||||
* Operations on the ubiquitous `option` type.
|
||||
*
|
||||
* Type `option` represents an optional value.
|
||||
*
|
||||
* Every `Option<T>` value can either be `Some(T)` or `none`. Where in other
|
||||
* languages you might use a nullable type, in Rust you would use an option
|
||||
* type.
|
||||
*/
|
||||
|
||||
// NB: transitionary, de-mode-ing.
|
||||
#[warn(deprecated_mode)];
|
||||
Operations on the ubiquitous `Option` type.
|
||||
|
||||
Type `Option` represents an optional value.
|
||||
|
||||
Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
|
||||
languages you might use a nullable type, in Rust you would use an option
|
||||
type.
|
||||
|
||||
Options are most commonly used with pattern matching to query the presence
|
||||
of a value and take action, always accounting for the `None` case.
|
||||
|
||||
# Example
|
||||
|
||||
~~~
|
||||
let msg = Some(~"howdy");
|
||||
|
||||
// Take a reference to the contained string
|
||||
match msg {
|
||||
Some(ref m) => io::println(m),
|
||||
None => ()
|
||||
}
|
||||
|
||||
// Remove the contained string, destroying the Option
|
||||
let unwrapped_msg = match move msg {
|
||||
Some(move m) => m,
|
||||
None => ~"default message"
|
||||
};
|
||||
~~~
|
||||
|
||||
*/
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cmp::Eq;
|
||||
|
|
@ -22,12 +44,19 @@ pub enum Option<T> {
|
|||
|
||||
pub pure fn get<T: Copy>(opt: &Option<T>) -> T {
|
||||
/*!
|
||||
* Gets the value out of an option
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the value equals `none`
|
||||
*/
|
||||
Gets the value out of an option
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `None`
|
||||
|
||||
# Safety note
|
||||
|
||||
In general, because this function may fail, its use is discouraged
|
||||
(calling `get` on `None` is akin to dereferencing a null pointer).
|
||||
Instead, prefer to use pattern matching and handle the `None`
|
||||
case explicitly.
|
||||
*/
|
||||
|
||||
match *opt {
|
||||
Some(copy x) => return x,
|
||||
|
|
@ -37,11 +66,18 @@ pub pure fn get<T: Copy>(opt: &Option<T>) -> T {
|
|||
|
||||
pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
|
||||
/*!
|
||||
* Gets an immutable reference to the value inside an option.
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the value equals `none`
|
||||
Gets an immutable reference to the value inside an option.
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `None`
|
||||
|
||||
# Safety note
|
||||
|
||||
In general, because this function may fail, its use is discouraged
|
||||
(calling `get` on `None` is akin to dereferencing a null pointer).
|
||||
Instead, prefer to use pattern matching and handle the `None`
|
||||
case explicitly.
|
||||
*/
|
||||
match *opt {
|
||||
Some(ref x) => x,
|
||||
|
|
@ -154,10 +190,20 @@ pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
|
|||
#[inline(always)]
|
||||
pub pure fn unwrap<T>(opt: Option<T>) -> T {
|
||||
/*!
|
||||
* Moves a value out of an option type and returns it.
|
||||
*
|
||||
* Useful primarily for getting strings, vectors and unique pointers out
|
||||
* of option types without copying them.
|
||||
Moves a value out of an option type and returns it.
|
||||
|
||||
Useful primarily for getting strings, vectors and unique pointers out
|
||||
of option types without copying them.
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `None`.
|
||||
|
||||
# Safety note
|
||||
|
||||
In general, because this function may fail, its use is discouraged.
|
||||
Instead, prefer to use pattern matching and handle the `None`
|
||||
case explicitly.
|
||||
*/
|
||||
match move opt {
|
||||
Some(move x) => move x,
|
||||
|
|
@ -165,9 +211,16 @@ pub pure fn unwrap<T>(opt: Option<T>) -> T {
|
|||
}
|
||||
}
|
||||
|
||||
/// The ubiquitous option dance.
|
||||
#[inline(always)]
|
||||
pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
|
||||
/*!
|
||||
The option dance. Moves a value out of an option type and returns it,
|
||||
replacing the original with `None`.
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `None`.
|
||||
*/
|
||||
if opt.is_none() { fail ~"option::swap_unwrap none" }
|
||||
unwrap(util::replace(opt, None))
|
||||
}
|
||||
|
|
@ -201,18 +254,38 @@ impl<T> &Option<T> {
|
|||
pure fn iter(f: fn(x: &T)) { iter(self, f) }
|
||||
/// Maps a `some` value from one type to another by reference
|
||||
pure fn map<U>(f: fn(x: &T) -> U) -> Option<U> { map(self, f) }
|
||||
/// Gets an immutable reference to the value inside a `some`.
|
||||
/**
|
||||
Gets an immutable reference to the value inside an option.
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `None`
|
||||
|
||||
# Safety note
|
||||
|
||||
In general, because this function may fail, its use is discouraged
|
||||
(calling `get` on `None` is akin to dereferencing a null pointer).
|
||||
Instead, prefer to use pattern matching and handle the `None`
|
||||
case explicitly.
|
||||
*/
|
||||
pure fn get_ref() -> &self/T { get_ref(self) }
|
||||
}
|
||||
|
||||
impl<T: Copy> Option<T> {
|
||||
/**
|
||||
* Gets the value out of an option
|
||||
*
|
||||
* # Failure
|
||||
*
|
||||
* Fails if the value equals `none`
|
||||
*/
|
||||
Gets the value out of an option
|
||||
|
||||
# Failure
|
||||
|
||||
Fails if the value equals `None`
|
||||
|
||||
# Safety note
|
||||
|
||||
In general, because this function may fail, its use is discouraged
|
||||
(calling `get` on `None` is akin to dereferencing a null pointer).
|
||||
Instead, prefer to use pattern matching and handle the `None`
|
||||
case explicitly.
|
||||
*/
|
||||
pure fn get() -> T { get(&self) }
|
||||
pure fn get_default(def: T) -> T { get_default(&self, def) }
|
||||
/**
|
||||
|
|
@ -252,10 +325,10 @@ impl<T: Eq> Option<T> : Eq {
|
|||
#[test]
|
||||
fn test_unwrap_ptr() {
|
||||
let x = ~0;
|
||||
let addr_x = ptr::p2::addr_of(&(*x));
|
||||
let addr_x = ptr::addr_of(&(*x));
|
||||
let opt = Some(x);
|
||||
let y = unwrap(opt);
|
||||
let addr_y = ptr::p2::addr_of(&(*y));
|
||||
let addr_y = ptr::addr_of(&(*y));
|
||||
assert addr_x == addr_y;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
/*!
|
||||
|
|
@ -132,7 +132,7 @@ mod global_env {
|
|||
let env_ch = get_global_env_chan();
|
||||
let po = comm::Port();
|
||||
comm::send(env_ch, MsgGetEnv(str::from_slice(n),
|
||||
comm::Chan(po)));
|
||||
comm::Chan(&po)));
|
||||
comm::recv(po)
|
||||
}
|
||||
|
||||
|
|
@ -141,14 +141,14 @@ mod global_env {
|
|||
let po = comm::Port();
|
||||
comm::send(env_ch, MsgSetEnv(str::from_slice(n),
|
||||
str::from_slice(v),
|
||||
comm::Chan(po)));
|
||||
comm::Chan(&po)));
|
||||
comm::recv(po)
|
||||
}
|
||||
|
||||
pub fn env() -> ~[(~str,~str)] {
|
||||
let env_ch = get_global_env_chan();
|
||||
let po = comm::Port();
|
||||
comm::send(env_ch, MsgEnv(comm::Chan(po)));
|
||||
comm::send(env_ch, MsgEnv(comm::Chan(&po)));
|
||||
comm::recv(po)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ bounded and unbounded protocols allows for less code duplication.
|
|||
*/
|
||||
|
||||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
// tjc: allowing deprecated modes due to function issue,
|
||||
// re-forbid after snapshot
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cmp::Eq;
|
||||
|
|
@ -859,7 +860,7 @@ endpoint is passed to the new task.
|
|||
pub fn spawn_service<T: Send, Tb: Send>(
|
||||
init: extern fn() -> (SendPacketBuffered<T, Tb>,
|
||||
RecvPacketBuffered<T, Tb>),
|
||||
+service: fn~(v: RecvPacketBuffered<T, Tb>))
|
||||
service: fn~(v: RecvPacketBuffered<T, Tb>))
|
||||
-> SendPacketBuffered<T, Tb>
|
||||
{
|
||||
let (client, server) = init();
|
||||
|
|
@ -883,7 +884,7 @@ receive state.
|
|||
pub fn spawn_service_recv<T: Send, Tb: Send>(
|
||||
init: extern fn() -> (RecvPacketBuffered<T, Tb>,
|
||||
SendPacketBuffered<T, Tb>),
|
||||
+service: fn~(v: SendPacketBuffered<T, Tb>))
|
||||
service: fn~(v: SendPacketBuffered<T, Tb>))
|
||||
-> RecvPacketBuffered<T, Tb>
|
||||
{
|
||||
let (client, server) = init();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
// tjc: Re-forbid deprecated modes once a snapshot fixes the
|
||||
// function problem
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
#[doc(hidden)];
|
||||
|
|
@ -45,7 +46,7 @@ type GlobalPtr = *libc::uintptr_t;
|
|||
pub unsafe fn chan_from_global_ptr<T: Send>(
|
||||
global: GlobalPtr,
|
||||
task_fn: fn() -> task::TaskBuilder,
|
||||
+f: fn~(comm::Port<T>)
|
||||
f: fn~(comm::Port<T>)
|
||||
) -> comm::Chan<T> {
|
||||
|
||||
enum Msg {
|
||||
|
|
@ -63,7 +64,7 @@ pub unsafe fn chan_from_global_ptr<T: Send>(
|
|||
let (setup_po, setup_ch) = do task_fn().spawn_conversation
|
||||
|move f, setup_po, setup_ch| {
|
||||
let po = comm::Port::<T>();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
comm::send(setup_ch, ch);
|
||||
|
||||
// Wait to hear if we are the official instance of
|
||||
|
|
@ -109,7 +110,7 @@ pub fn test_from_global_chan1() {
|
|||
|
||||
// The global channel
|
||||
let globchan = 0;
|
||||
let globchanp = ptr::p2::addr_of(&globchan);
|
||||
let globchanp = ptr::addr_of(&globchan);
|
||||
|
||||
// Create the global channel, attached to a new task
|
||||
let ch = unsafe {
|
||||
|
|
@ -122,7 +123,7 @@ pub fn test_from_global_chan1() {
|
|||
};
|
||||
// Talk to it
|
||||
let po = comm::Port();
|
||||
comm::send(ch, comm::Chan(po));
|
||||
comm::send(ch, comm::Chan(&po));
|
||||
assert comm::recv(po) == true;
|
||||
|
||||
// This one just reuses the previous channel
|
||||
|
|
@ -135,7 +136,7 @@ pub fn test_from_global_chan1() {
|
|||
|
||||
// Talk to the original global task
|
||||
let po = comm::Port();
|
||||
comm::send(ch, comm::Chan(po));
|
||||
comm::send(ch, comm::Chan(&po));
|
||||
assert comm::recv(po) == true;
|
||||
}
|
||||
|
||||
|
|
@ -145,10 +146,10 @@ pub fn test_from_global_chan2() {
|
|||
for iter::repeat(100) {
|
||||
// The global channel
|
||||
let globchan = 0;
|
||||
let globchanp = ptr::p2::addr_of(&globchan);
|
||||
let globchanp = ptr::addr_of(&globchan);
|
||||
|
||||
let resultpo = comm::Port();
|
||||
let resultch = comm::Chan(resultpo);
|
||||
let resultch = comm::Chan(&resultpo);
|
||||
|
||||
// Spawn a bunch of tasks that all want to compete to
|
||||
// create the global channel
|
||||
|
|
@ -165,7 +166,7 @@ pub fn test_from_global_chan2() {
|
|||
}
|
||||
};
|
||||
let po = comm::Port();
|
||||
comm::send(ch, comm::Chan(po));
|
||||
comm::send(ch, comm::Chan(&po));
|
||||
// We are The winner if our version of the
|
||||
// task was installed
|
||||
let winner = comm::recv(po);
|
||||
|
|
@ -203,7 +204,7 @@ pub fn test_from_global_chan2() {
|
|||
*/
|
||||
pub unsafe fn weaken_task(f: fn(comm::Port<()>)) {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
unsafe {
|
||||
rustrt::rust_task_weaken(cast::reinterpret_cast(&ch));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
//! Unsafe pointer utility functions
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cmp::{Eq, Ord};
|
||||
use libc::{c_void, size_t};
|
||||
|
||||
|
|
@ -28,12 +31,6 @@ extern mod rusti {
|
|||
#[inline(always)]
|
||||
pub pure fn addr_of<T>(val: &T) -> *T { unsafe { rusti::addr_of(*val) } }
|
||||
|
||||
pub mod p2 {
|
||||
/// Get an unsafe pointer to a value
|
||||
#[inline(always)]
|
||||
pub pure fn addr_of<T>(val: &T) -> *T { unsafe { rusti::addr_of(*val) } }
|
||||
}
|
||||
|
||||
/// Get an unsafe mut pointer to a value
|
||||
#[inline(always)]
|
||||
pub pure fn mut_addr_of<T>(val: &T) -> *mut T {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Random number generation
|
||||
|
||||
// NB: transitional, de-mode-ing.
|
||||
#[warn(deprecated_mode)];
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
#[allow(non_camel_case_types)] // runtime type
|
||||
|
|
@ -310,7 +310,7 @@ pub fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng {
|
|||
|
||||
|
||||
// used to make space in TLS for a random number generator
|
||||
fn tls_rng_state(+_v: @RandRes) {}
|
||||
fn tls_rng_state(_v: @RandRes) {}
|
||||
|
||||
/**
|
||||
* Gives back a lazily initialized task-local random number generator,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ Runtime type reflection
|
|||
|
||||
*/
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor};
|
||||
use libc::c_void;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ More runtime type reflection
|
|||
|
||||
*/
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use dvec::DVec;
|
||||
use io::{Writer, WriterUtil};
|
||||
use libc::c_void;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
//! A type representing either success or failure
|
||||
|
||||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cmp::Eq;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
//! Process spawning
|
||||
|
|
@ -296,7 +296,7 @@ pub fn program_output(prog: &str, args: &[~str]) ->
|
|||
// or the other. FIXME (#2625): Surely there's a much more
|
||||
// clever way to do this.
|
||||
let p = comm::Port();
|
||||
let ch = comm::Chan(p);
|
||||
let ch = comm::Chan(&p);
|
||||
do task::spawn_sched(task::SingleThreaded) {
|
||||
let errput = readclose(pipe_err.in);
|
||||
comm::send(ch, (2, move errput));
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
#[legacy_modes]; // tjc: remove after snapshot
|
||||
|
||||
// NB: transitionary, de-mode-ing.
|
||||
// XXX: Can't do this because frame_address needs a deprecated mode.
|
||||
//#[forbid(deprecated_mode)];
|
||||
// XXX: Can't forbid this because frame_address needs a deprecated mode.
|
||||
#[allow(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cast::reinterpret_cast;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
* some heavy-duty uses, try std::rope.
|
||||
*/
|
||||
|
||||
#[warn(deprecated_mode)];
|
||||
#[warn(deprecated_pattern)];
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cmp::{Eq, Ord};
|
||||
use libc::size_t;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
// tjc: Deprecated modes allowed because of function arg issue
|
||||
// in task::spawn. Re-forbid after snapshot.
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
/*!
|
||||
|
|
@ -219,7 +220,7 @@ pub type TaskOpts = {
|
|||
// FIXME (#2585): Replace the 'consumed' bit with move mode on self
|
||||
pub enum TaskBuilder = {
|
||||
opts: TaskOpts,
|
||||
gen_body: fn@(+v: fn~()) -> fn~(),
|
||||
gen_body: fn@(v: fn~()) -> fn~(),
|
||||
can_not_copy: Option<util::NonCopyable>,
|
||||
mut consumed: bool,
|
||||
};
|
||||
|
|
@ -232,7 +233,7 @@ pub enum TaskBuilder = {
|
|||
pub fn task() -> TaskBuilder {
|
||||
TaskBuilder({
|
||||
opts: default_task_opts(),
|
||||
gen_body: |+body| move body, // Identity function
|
||||
gen_body: |body| move body, // Identity function
|
||||
can_not_copy: None,
|
||||
mut consumed: false,
|
||||
})
|
||||
|
|
@ -409,7 +410,7 @@ impl TaskBuilder {
|
|||
* generator by applying the task body which results from the
|
||||
* existing body generator to the new body generator.
|
||||
*/
|
||||
fn add_wrapper(wrapper: fn@(+v: fn~()) -> fn~()) -> TaskBuilder {
|
||||
fn add_wrapper(wrapper: fn@(v: fn~()) -> fn~()) -> TaskBuilder {
|
||||
let prev_gen_body = self.gen_body;
|
||||
let notify_chan = if self.opts.notify_chan.is_none() {
|
||||
None
|
||||
|
|
@ -441,7 +442,7 @@ impl TaskBuilder {
|
|||
* When spawning into a new scheduler, the number of threads requested
|
||||
* must be greater than zero.
|
||||
*/
|
||||
fn spawn(+f: fn~()) {
|
||||
fn spawn(f: fn~()) {
|
||||
let notify_chan = if self.opts.notify_chan.is_none() {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -459,7 +460,7 @@ impl TaskBuilder {
|
|||
spawn::spawn_raw(move opts, x.gen_body(move f));
|
||||
}
|
||||
/// Runs a task, while transfering ownership of one argument to the child.
|
||||
fn spawn_with<A: Send>(arg: A, +f: fn~(+v: A)) {
|
||||
fn spawn_with<A: Send>(arg: A, f: fn~(v: A)) {
|
||||
let arg = ~mut Some(move arg);
|
||||
do self.spawn |move arg, move f| {
|
||||
f(option::swap_unwrap(arg))
|
||||
|
|
@ -477,12 +478,12 @@ impl TaskBuilder {
|
|||
* otherwise be required to establish communication from the parent
|
||||
* to the child.
|
||||
*/
|
||||
fn spawn_listener<A: Send>(+f: fn~(comm::Port<A>)) -> comm::Chan<A> {
|
||||
fn spawn_listener<A: Send>(f: fn~(comm::Port<A>)) -> comm::Chan<A> {
|
||||
let setup_po = comm::Port();
|
||||
let setup_ch = comm::Chan(setup_po);
|
||||
let setup_ch = comm::Chan(&setup_po);
|
||||
do self.spawn |move f| {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
comm::send(setup_ch, ch);
|
||||
f(move po);
|
||||
}
|
||||
|
|
@ -493,10 +494,10 @@ impl TaskBuilder {
|
|||
* Runs a new task, setting up communication in both directions
|
||||
*/
|
||||
fn spawn_conversation<A: Send, B: Send>
|
||||
(+f: fn~(comm::Port<A>, comm::Chan<B>))
|
||||
(f: fn~(comm::Port<A>, comm::Chan<B>))
|
||||
-> (comm::Port<B>, comm::Chan<A>) {
|
||||
let from_child = comm::Port();
|
||||
let to_parent = comm::Chan(from_child);
|
||||
let to_parent = comm::Chan(&from_child);
|
||||
let to_child = do self.spawn_listener |move f, from_parent| {
|
||||
f(from_parent, to_parent)
|
||||
};
|
||||
|
|
@ -516,9 +517,9 @@ impl TaskBuilder {
|
|||
* # Failure
|
||||
* Fails if a future_result was already set for this task.
|
||||
*/
|
||||
fn try<T: Send>(+f: fn~() -> T) -> Result<T,()> {
|
||||
fn try<T: Send>(f: fn~() -> T) -> Result<T,()> {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
let mut result = None;
|
||||
|
||||
let fr_task_builder = self.future_result(|+r| {
|
||||
|
|
@ -555,7 +556,7 @@ pub fn default_task_opts() -> TaskOpts {
|
|||
|
||||
/* Spawn convenience functions */
|
||||
|
||||
pub fn spawn(+f: fn~()) {
|
||||
pub fn spawn(f: fn~()) {
|
||||
/*!
|
||||
* Creates and executes a new child task
|
||||
*
|
||||
|
|
@ -568,7 +569,7 @@ pub fn spawn(+f: fn~()) {
|
|||
task().spawn(move f)
|
||||
}
|
||||
|
||||
pub fn spawn_unlinked(+f: fn~()) {
|
||||
pub fn spawn_unlinked(f: fn~()) {
|
||||
/*!
|
||||
* Creates a child task unlinked from the current one. If either this
|
||||
* task or the child task fails, the other will not be killed.
|
||||
|
|
@ -577,7 +578,7 @@ pub fn spawn_unlinked(+f: fn~()) {
|
|||
task().unlinked().spawn(move f)
|
||||
}
|
||||
|
||||
pub fn spawn_supervised(+f: fn~()) {
|
||||
pub fn spawn_supervised(f: fn~()) {
|
||||
/*!
|
||||
* Creates a child task unlinked from the current one. If either this
|
||||
* task or the child task fails, the other will not be killed.
|
||||
|
|
@ -586,7 +587,7 @@ pub fn spawn_supervised(+f: fn~()) {
|
|||
task().supervised().spawn(move f)
|
||||
}
|
||||
|
||||
pub fn spawn_with<A:Send>(+arg: A, +f: fn~(+v: A)) {
|
||||
pub fn spawn_with<A:Send>(arg: A, f: fn~(v: A)) {
|
||||
/*!
|
||||
* Runs a task, while transfering ownership of one argument to the
|
||||
* child.
|
||||
|
|
@ -600,7 +601,7 @@ pub fn spawn_with<A:Send>(+arg: A, +f: fn~(+v: A)) {
|
|||
task().spawn_with(move arg, move f)
|
||||
}
|
||||
|
||||
pub fn spawn_listener<A:Send>(+f: fn~(comm::Port<A>)) -> comm::Chan<A> {
|
||||
pub fn spawn_listener<A:Send>(f: fn~(comm::Port<A>)) -> comm::Chan<A> {
|
||||
/*!
|
||||
* Runs a new task while providing a channel from the parent to the child
|
||||
*
|
||||
|
|
@ -611,7 +612,7 @@ pub fn spawn_listener<A:Send>(+f: fn~(comm::Port<A>)) -> comm::Chan<A> {
|
|||
}
|
||||
|
||||
pub fn spawn_conversation<A: Send, B: Send>
|
||||
(+f: fn~(comm::Port<A>, comm::Chan<B>))
|
||||
(f: fn~(comm::Port<A>, comm::Chan<B>))
|
||||
-> (comm::Port<B>, comm::Chan<A>) {
|
||||
/*!
|
||||
* Runs a new task, setting up communication in both directions
|
||||
|
|
@ -622,7 +623,7 @@ pub fn spawn_conversation<A: Send, B: Send>
|
|||
task().spawn_conversation(move f)
|
||||
}
|
||||
|
||||
pub fn spawn_sched(mode: SchedMode, +f: fn~()) {
|
||||
pub fn spawn_sched(mode: SchedMode, f: fn~()) {
|
||||
/*!
|
||||
* Creates a new scheduler and executes a task on it
|
||||
*
|
||||
|
|
@ -639,7 +640,7 @@ pub fn spawn_sched(mode: SchedMode, +f: fn~()) {
|
|||
task().sched_mode(mode).spawn(move f)
|
||||
}
|
||||
|
||||
pub fn try<T:Send>(+f: fn~() -> T) -> Result<T,()> {
|
||||
pub fn try<T:Send>(f: fn~() -> T) -> Result<T,()> {
|
||||
/*!
|
||||
* Execute a function in another task and return either the return value
|
||||
* of the function or result::err.
|
||||
|
|
@ -772,7 +773,7 @@ fn test_cant_dup_task_builder() {
|
|||
#[test] #[ignore(cfg(windows))]
|
||||
fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
do spawn_unlinked {
|
||||
do spawn_unlinked {
|
||||
// Give middle task a chance to fail-but-not-kill-us.
|
||||
|
|
@ -802,7 +803,7 @@ fn test_spawn_unlinked_sup_fail_down() {
|
|||
#[test] #[should_fail] #[ignore(cfg(windows))]
|
||||
fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
|
||||
let po = comm::Port::<()>();
|
||||
let _ch = comm::Chan(po);
|
||||
let _ch = comm::Chan(&po);
|
||||
// Unidirectional "parenting" shouldn't override bidirectional linked.
|
||||
// We have to cheat with opts - the interface doesn't support them because
|
||||
// they don't make sense (redundant with task().supervised()).
|
||||
|
|
@ -845,7 +846,7 @@ fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
|
|||
#[test] #[should_fail] #[ignore(cfg(windows))]
|
||||
fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails
|
||||
let po = comm::Port::<()>();
|
||||
let _ch = comm::Chan(po);
|
||||
let _ch = comm::Chan(&po);
|
||||
// Default options are to spawn linked & unsupervised.
|
||||
do spawn { fail; }
|
||||
comm::recv(po); // We should get punted awake
|
||||
|
|
@ -917,7 +918,7 @@ fn test_spawn_linked_sup_propagate_sibling() {
|
|||
#[test]
|
||||
fn test_run_basic() {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
do task().spawn {
|
||||
comm::send(ch, ());
|
||||
}
|
||||
|
|
@ -927,7 +928,7 @@ fn test_run_basic() {
|
|||
#[test]
|
||||
fn test_add_wrapper() {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
let b0 = task();
|
||||
let b1 = do b0.add_wrapper |body| {
|
||||
fn~() {
|
||||
|
|
@ -961,7 +962,7 @@ fn test_back_to_the_future_result() {
|
|||
#[test]
|
||||
fn test_spawn_listiner_bidi() {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
let ch = do spawn_listener |po| {
|
||||
// Now the child has a port called 'po' to read from and
|
||||
// an environment-captured channel called 'ch'.
|
||||
|
|
@ -1017,7 +1018,7 @@ fn test_spawn_sched_no_threads() {
|
|||
#[test]
|
||||
fn test_spawn_sched() {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
|
||||
fn f(i: int, ch: comm::Chan<()>) {
|
||||
let parent_sched_id = rt::rust_get_sched_id();
|
||||
|
|
@ -1041,7 +1042,7 @@ fn test_spawn_sched() {
|
|||
#[test]
|
||||
fn test_spawn_sched_childs_on_same_sched() {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
|
||||
do spawn_sched(SingleThreaded) {
|
||||
let parent_sched_id = rt::rust_get_sched_id();
|
||||
|
|
@ -1075,9 +1076,9 @@ fn test_spawn_sched_blocking() {
|
|||
for iter::repeat(20u) {
|
||||
|
||||
let start_po = comm::Port();
|
||||
let start_ch = comm::Chan(start_po);
|
||||
let start_ch = comm::Chan(&start_po);
|
||||
let fin_po = comm::Port();
|
||||
let fin_ch = comm::Chan(fin_po);
|
||||
let fin_ch = comm::Chan(&fin_po);
|
||||
|
||||
let lock = testrt::rust_dbg_lock_create();
|
||||
|
||||
|
|
@ -1105,12 +1106,12 @@ fn test_spawn_sched_blocking() {
|
|||
}
|
||||
|
||||
let setup_po = comm::Port();
|
||||
let setup_ch = comm::Chan(setup_po);
|
||||
let setup_ch = comm::Chan(&setup_po);
|
||||
let parent_po = comm::Port();
|
||||
let parent_ch = comm::Chan(parent_po);
|
||||
let parent_ch = comm::Chan(&parent_po);
|
||||
do spawn {
|
||||
let child_po = comm::Port();
|
||||
comm::send(setup_ch, comm::Chan(child_po));
|
||||
comm::send(setup_ch, comm::Chan(&child_po));
|
||||
pingpong(child_po, parent_ch);
|
||||
};
|
||||
|
||||
|
|
@ -1126,15 +1127,15 @@ fn test_spawn_sched_blocking() {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn avoid_copying_the_body(spawnfn: fn(+v: fn~())) {
|
||||
fn avoid_copying_the_body(spawnfn: fn(v: fn~())) {
|
||||
let p = comm::Port::<uint>();
|
||||
let ch = comm::Chan(p);
|
||||
let ch = comm::Chan(&p);
|
||||
|
||||
let x = ~1;
|
||||
let x_in_parent = ptr::p2::addr_of(&(*x)) as uint;
|
||||
let x_in_parent = ptr::addr_of(&(*x)) as uint;
|
||||
|
||||
do spawnfn {
|
||||
let x_in_child = ptr::p2::addr_of(&(*x)) as uint;
|
||||
let x_in_child = ptr::addr_of(&(*x)) as uint;
|
||||
comm::send(ch, x_in_child);
|
||||
}
|
||||
|
||||
|
|
@ -1149,7 +1150,7 @@ fn test_avoid_copying_the_body_spawn() {
|
|||
|
||||
#[test]
|
||||
fn test_avoid_copying_the_body_spawn_listener() {
|
||||
do avoid_copying_the_body |+f| {
|
||||
do avoid_copying_the_body |f| {
|
||||
spawn_listener(fn~(move f, _po: comm::Port<int>) {
|
||||
f();
|
||||
});
|
||||
|
|
@ -1167,7 +1168,7 @@ fn test_avoid_copying_the_body_task_spawn() {
|
|||
|
||||
#[test]
|
||||
fn test_avoid_copying_the_body_spawn_listener_1() {
|
||||
do avoid_copying_the_body |+f| {
|
||||
do avoid_copying_the_body |f| {
|
||||
task().spawn_listener(fn~(move f, _po: comm::Port<int>) {
|
||||
f();
|
||||
});
|
||||
|
|
@ -1195,7 +1196,7 @@ fn test_avoid_copying_the_body_unlinked() {
|
|||
#[test]
|
||||
fn test_platform_thread() {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
do task().sched_mode(PlatformThread).spawn {
|
||||
comm::send(ch, ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ pub unsafe fn local_data_modify<T: Owned>(
|
|||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_tls_multitask() unsafe {
|
||||
fn test_tls_multitask() unsafe {
|
||||
fn my_key(_x: @~str) { }
|
||||
local_data_set(my_key, @~"parent data");
|
||||
do task::spawn unsafe {
|
||||
|
|
@ -94,7 +94,7 @@ pub fn test_tls_multitask() unsafe {
|
|||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_tls_overwrite() unsafe {
|
||||
fn test_tls_overwrite() unsafe {
|
||||
fn my_key(_x: @~str) { }
|
||||
local_data_set(my_key, @~"first data");
|
||||
local_data_set(my_key, @~"next data"); // Shouldn't leak.
|
||||
|
|
@ -102,7 +102,7 @@ pub fn test_tls_overwrite() unsafe {
|
|||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_tls_pop() unsafe {
|
||||
fn test_tls_pop() unsafe {
|
||||
fn my_key(_x: @~str) { }
|
||||
local_data_set(my_key, @~"weasel");
|
||||
assert *(local_data_pop(my_key).get()) == ~"weasel";
|
||||
|
|
@ -111,7 +111,7 @@ pub fn test_tls_pop() unsafe {
|
|||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_tls_modify() unsafe {
|
||||
fn test_tls_modify() unsafe {
|
||||
fn my_key(_x: @~str) { }
|
||||
local_data_modify(my_key, |data| {
|
||||
match data {
|
||||
|
|
@ -130,7 +130,7 @@ pub fn test_tls_modify() unsafe {
|
|||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_tls_crust_automorestack_memorial_bug() unsafe {
|
||||
fn test_tls_crust_automorestack_memorial_bug() unsafe {
|
||||
// This might result in a stack-canary clobber if the runtime fails to set
|
||||
// sp_limit to 0 when calling the cleanup extern - it might automatically
|
||||
// jump over to the rust stack, which causes next_c_sp to get recorded as
|
||||
|
|
@ -143,7 +143,7 @@ pub fn test_tls_crust_automorestack_memorial_bug() unsafe {
|
|||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_tls_multiple_types() unsafe {
|
||||
fn test_tls_multiple_types() unsafe {
|
||||
fn str_key(_x: @~str) { }
|
||||
fn box_key(_x: @@()) { }
|
||||
fn int_key(_x: @int) { }
|
||||
|
|
@ -155,7 +155,7 @@ pub fn test_tls_multiple_types() unsafe {
|
|||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_tls_overwrite_multiple_types() {
|
||||
fn test_tls_overwrite_multiple_types() {
|
||||
fn str_key(_x: @~str) { }
|
||||
fn box_key(_x: @@()) { }
|
||||
fn int_key(_x: @int) { }
|
||||
|
|
@ -171,7 +171,7 @@ pub fn test_tls_overwrite_multiple_types() {
|
|||
#[test]
|
||||
#[should_fail]
|
||||
#[ignore(cfg(windows))]
|
||||
pub fn test_tls_cleanup_on_failure() unsafe {
|
||||
fn test_tls_cleanup_on_failure() unsafe {
|
||||
fn str_key(_x: @~str) { }
|
||||
fn box_key(_x: @@()) { }
|
||||
fn int_key(_x: @int) { }
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ impl LocalData: Eq {
|
|||
|
||||
// We use dvec because it's the best data structure in core. If TLS is used
|
||||
// heavily in future, this could be made more efficient with a proper map.
|
||||
pub type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData);
|
||||
type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData);
|
||||
// Has to be a pointer at outermost layer; the foreign call returns void *.
|
||||
pub type TaskLocalMap = @dvec::DVec<Option<TaskLocalElement>>;
|
||||
type TaskLocalMap = @dvec::DVec<Option<TaskLocalElement>>;
|
||||
|
||||
pub extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
|
||||
extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
|
||||
assert !map_ptr.is_null();
|
||||
// Get and keep the single reference that was created at the beginning.
|
||||
let _map: TaskLocalMap = cast::reinterpret_cast(&map_ptr);
|
||||
|
|
@ -29,7 +29,7 @@ pub extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
|
|||
}
|
||||
|
||||
// Gets the map from the runtime. Lazily initialises if not done so already.
|
||||
pub unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
|
||||
unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
|
||||
|
||||
// Relies on the runtime initialising the pointer to null.
|
||||
// NOTE: The map's box lives in TLS invisibly referenced once. Each time
|
||||
|
|
@ -52,7 +52,7 @@ pub unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn key_to_key_value<T: Owned>(
|
||||
unsafe fn key_to_key_value<T: Owned>(
|
||||
key: LocalDataKey<T>) -> *libc::c_void {
|
||||
|
||||
// Keys are closures, which are (fnptr,envptr) pairs. Use fnptr.
|
||||
|
|
@ -62,7 +62,7 @@ pub unsafe fn key_to_key_value<T: Owned>(
|
|||
}
|
||||
|
||||
// If returning Some(..), returns with @T with the map's reference. Careful!
|
||||
pub unsafe fn local_data_lookup<T: Owned>(
|
||||
unsafe fn local_data_lookup<T: Owned>(
|
||||
map: TaskLocalMap, key: LocalDataKey<T>)
|
||||
-> Option<(uint, *libc::c_void)> {
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ pub unsafe fn local_data_lookup<T: Owned>(
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn local_get_helper<T: Owned>(
|
||||
unsafe fn local_get_helper<T: Owned>(
|
||||
task: *rust_task, key: LocalDataKey<T>,
|
||||
do_pop: bool) -> Option<@T> {
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#[doc(hidden)]; // FIXME #3538
|
||||
#[warn(deprecated_mode)];
|
||||
|
||||
use rt::rust_task;
|
||||
use rt::rust_closure;
|
||||
|
|
@ -69,16 +70,16 @@ macro_rules! move_it (
|
|||
{ $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); move y } }
|
||||
)
|
||||
|
||||
pub type TaskSet = send_map::linear::LinearMap<*rust_task,()>;
|
||||
type TaskSet = send_map::linear::LinearMap<*rust_task,()>;
|
||||
|
||||
pub fn new_taskset() -> TaskSet {
|
||||
fn new_taskset() -> TaskSet {
|
||||
send_map::linear::LinearMap()
|
||||
}
|
||||
pub fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) {
|
||||
fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) {
|
||||
let didnt_overwrite = tasks.insert(task, ());
|
||||
assert didnt_overwrite;
|
||||
}
|
||||
pub fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) {
|
||||
fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) {
|
||||
let was_present = tasks.remove(&task);
|
||||
assert was_present;
|
||||
}
|
||||
|
|
@ -87,7 +88,7 @@ pub fn taskset_each(tasks: &TaskSet, blk: fn(v: *rust_task) -> bool) {
|
|||
}
|
||||
|
||||
// One of these per group of linked-failure tasks.
|
||||
pub type TaskGroupData = {
|
||||
type TaskGroupData = {
|
||||
// All tasks which might kill this group. When this is empty, the group
|
||||
// can be "GC"ed (i.e., its link in the ancestor list can be removed).
|
||||
mut members: TaskSet,
|
||||
|
|
@ -95,12 +96,12 @@ pub type TaskGroupData = {
|
|||
// tasks in this group.
|
||||
mut descendants: TaskSet,
|
||||
};
|
||||
pub type TaskGroupArc = private::Exclusive<Option<TaskGroupData>>;
|
||||
type TaskGroupArc = private::Exclusive<Option<TaskGroupData>>;
|
||||
|
||||
pub type TaskGroupInner = &mut Option<TaskGroupData>;
|
||||
type TaskGroupInner = &mut Option<TaskGroupData>;
|
||||
|
||||
// A taskgroup is 'dead' when nothing can cause it to fail; only members can.
|
||||
pub pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
|
||||
pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
|
||||
(&tg.members).is_empty()
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ pub pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
|
|||
// taskgroup which was spawned-unlinked. Tasks from intermediate generations
|
||||
// have references to the middle of the list; when intermediate generations
|
||||
// die, their node in the list will be collected at a descendant's spawn-time.
|
||||
pub type AncestorNode = {
|
||||
type AncestorNode = {
|
||||
// Since the ancestor list is recursive, we end up with references to
|
||||
// exclusives within other exclusives. This is dangerous business (if
|
||||
// circular references arise, deadlock and memory leaks are imminent).
|
||||
|
|
@ -124,16 +125,16 @@ pub type AncestorNode = {
|
|||
// Recursive rest of the list.
|
||||
mut ancestors: AncestorList,
|
||||
};
|
||||
pub enum AncestorList = Option<private::Exclusive<AncestorNode>>;
|
||||
enum AncestorList = Option<private::Exclusive<AncestorNode>>;
|
||||
|
||||
// Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety.
|
||||
#[inline(always)]
|
||||
pub fn access_group<U>(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U {
|
||||
fn access_group<U>(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U {
|
||||
unsafe { x.with(blk) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn access_ancestors<U>(x: &private::Exclusive<AncestorNode>,
|
||||
fn access_ancestors<U>(x: &private::Exclusive<AncestorNode>,
|
||||
blk: fn(x: &mut AncestorNode) -> U) -> U {
|
||||
unsafe { x.with(blk) }
|
||||
}
|
||||
|
|
@ -146,7 +147,7 @@ pub fn access_ancestors<U>(x: &private::Exclusive<AncestorNode>,
|
|||
// (3) As a bonus, coalesces away all 'dead' taskgroup nodes in the list.
|
||||
// FIXME(#2190): Change Option<fn@(...)> to Option<fn&(...)>, to save on
|
||||
// allocations. Once that bug is fixed, changing the sigil should suffice.
|
||||
pub fn each_ancestor(list: &mut AncestorList,
|
||||
fn each_ancestor(list: &mut AncestorList,
|
||||
bail_opt: Option<fn@(TaskGroupInner)>,
|
||||
forward_blk: fn(TaskGroupInner) -> bool)
|
||||
-> bool {
|
||||
|
|
@ -271,7 +272,7 @@ pub fn each_ancestor(list: &mut AncestorList,
|
|||
}
|
||||
|
||||
// One of these per task.
|
||||
pub struct TCB {
|
||||
struct TCB {
|
||||
me: *rust_task,
|
||||
// List of tasks with whose fates this one's is intertwined.
|
||||
tasks: TaskGroupArc, // 'none' means the group has failed.
|
||||
|
|
@ -303,7 +304,7 @@ pub struct TCB {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
|
||||
fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
|
||||
is_main: bool, notifier: Option<AutoNotify>) -> TCB {
|
||||
|
||||
let notifier = move notifier;
|
||||
|
|
@ -318,7 +319,7 @@ pub fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
|
|||
}
|
||||
}
|
||||
|
||||
pub struct AutoNotify {
|
||||
struct AutoNotify {
|
||||
notify_chan: Chan<Notification>,
|
||||
mut failed: bool,
|
||||
drop {
|
||||
|
|
@ -327,14 +328,14 @@ pub struct AutoNotify {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn AutoNotify(chan: Chan<Notification>) -> AutoNotify {
|
||||
fn AutoNotify(chan: Chan<Notification>) -> AutoNotify {
|
||||
AutoNotify {
|
||||
notify_chan: chan,
|
||||
failed: true // Un-set above when taskgroup successfully made.
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
|
||||
fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
|
||||
is_member: bool) -> bool {
|
||||
let newstate = util::replace(state, None);
|
||||
// If 'None', the group was failing. Can't enlist.
|
||||
|
|
@ -350,7 +351,7 @@ pub fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
|
|||
}
|
||||
|
||||
// NB: Runs in destructor/post-exit context. Can't 'fail'.
|
||||
pub fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
|
||||
fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
|
||||
is_member: bool) {
|
||||
let newstate = util::replace(state, None);
|
||||
// If 'None', already failing and we've already gotten a kill signal.
|
||||
|
|
@ -363,7 +364,7 @@ pub fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
|
|||
}
|
||||
|
||||
// NB: Runs in destructor/post-exit context. Can't 'fail'.
|
||||
pub fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
|
||||
fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
|
||||
// NB: We could do the killing iteration outside of the group arc, by
|
||||
// having "let mut newstate" here, swapping inside, and iterating after.
|
||||
// But that would let other exiting tasks fall-through and exit while we
|
||||
|
|
@ -405,7 +406,7 @@ macro_rules! taskgroup_key (
|
|||
() => (cast::transmute((-2 as uint, 0u)))
|
||||
)
|
||||
|
||||
pub fn gen_child_taskgroup(linked: bool, supervised: bool)
|
||||
fn gen_child_taskgroup(linked: bool, supervised: bool)
|
||||
-> (TaskGroupArc, AncestorList, bool) {
|
||||
let spawner = rt::rust_get_task();
|
||||
/*######################################################################*
|
||||
|
|
@ -487,7 +488,7 @@ pub fn gen_child_taskgroup(linked: bool, supervised: bool)
|
|||
}
|
||||
}
|
||||
|
||||
pub fn spawn_raw(opts: TaskOpts, +f: fn~()) {
|
||||
pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
|
||||
let (child_tg, ancestors, is_main) =
|
||||
gen_child_taskgroup(opts.linked, opts.supervised);
|
||||
|
||||
|
|
@ -532,7 +533,7 @@ pub fn spawn_raw(opts: TaskOpts, +f: fn~()) {
|
|||
fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc,
|
||||
ancestors: AncestorList, is_main: bool,
|
||||
notify_chan: Option<Chan<Notification>>,
|
||||
+f: fn~()) -> fn~() {
|
||||
f: fn~()) -> fn~() {
|
||||
let child_data = ~mut Some((move child_arc, move ancestors));
|
||||
return fn~(move notify_chan, move child_data, move f) {
|
||||
// Agh. Get move-mode items into the closure. FIXME (#2829)
|
||||
|
|
@ -636,7 +637,7 @@ pub fn spawn_raw(opts: TaskOpts, +f: fn~()) {
|
|||
#[test]
|
||||
fn test_spawn_raw_simple() {
|
||||
let po = comm::Port();
|
||||
let ch = comm::Chan(po);
|
||||
let ch = comm::Chan(&po);
|
||||
do spawn_raw(default_task_opts()) {
|
||||
comm::send(ch, ());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Miscellaneous helpers for common patterns.
|
|||
*/
|
||||
|
||||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: re-forbid deprecated modes after snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
use cmp::Eq;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Vectors
|
||||
|
||||
#[warn(deprecated_mode)];
|
||||
#[warn(deprecated_pattern)];
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
#[warn(non_camel_case_types)];
|
||||
|
||||
use cmp::{Eq, Ord};
|
||||
|
|
@ -18,9 +18,10 @@ extern mod rustrt {
|
|||
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern mod rusti {
|
||||
fn move_val_init<T>(&dst: T, -src: T);
|
||||
fn move_val_init<T>(dst: &mut T, -src: T);
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if a vector contains no elements
|
||||
pub pure fn is_empty<T>(v: &[const T]) -> bool {
|
||||
as_const_buf(v, |_p, len| len == 0u)
|
||||
|
|
@ -104,7 +105,7 @@ pub pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> ~[T] {
|
|||
do as_mut_buf(v) |p, _len| {
|
||||
let mut i: uint = 0u;
|
||||
while i < n_elts {
|
||||
rusti::move_val_init(*ptr::mut_offset(p, i), op(i));
|
||||
rusti::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
|
|
@ -489,7 +490,7 @@ unsafe fn push_fast<T>(v: &mut ~[T], initval: T) {
|
|||
(**repr).unboxed.fill += sys::size_of::<T>();
|
||||
let p = addr_of(&((**repr).unboxed.data));
|
||||
let p = ptr::offset(p, fill) as *mut T;
|
||||
rusti::move_val_init(*p, move initval);
|
||||
rusti::move_val_init(&mut(*p), move initval);
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
|
|
@ -1769,7 +1770,7 @@ pub mod raw {
|
|||
do as_mut_buf(v) |p, _len| {
|
||||
let mut box2 = None;
|
||||
box2 <-> box;
|
||||
rusti::move_val_init(*ptr::mut_offset(p, i),
|
||||
rusti::move_val_init(&mut(*ptr::mut_offset(p, i)),
|
||||
option::unwrap(move box2));
|
||||
}
|
||||
}
|
||||
|
|
@ -1918,10 +1919,9 @@ impl<A: Copy> &[A]: iter::CopyableIter<A> {
|
|||
}
|
||||
pure fn to_vec() -> ~[A] { iter::to_vec(&self) }
|
||||
|
||||
// FIXME--bug in resolve prevents this from working (#2611)
|
||||
// fn flat_map_to_vec<B:copy,IB:base_iter<B>>(op: fn(A) -> IB) -> ~[B] {
|
||||
// iter::flat_map_to_vec(self, op)
|
||||
// }
|
||||
pure fn flat_map_to_vec<B:Copy,IB:BaseIter<B>>(op: fn(A) -> IB) -> ~[B] {
|
||||
iter::flat_map_to_vec(&self, op)
|
||||
}
|
||||
|
||||
pub pure fn find(p: fn(a: A) -> bool) -> Option<A> {
|
||||
iter::find(&self, p)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
/**
|
||||
* Concurrency-enabled mechanisms for sharing mutable and/or immutable state
|
||||
* between tasks.
|
||||
|
|
|
|||
|
|
@ -31,9 +31,10 @@ use libc::size_t;
|
|||
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern mod rusti {
|
||||
fn move_val_init<T>(&dst: T, -src: T);
|
||||
fn move_val_init<T>(dst: &mut T, -src: T);
|
||||
fn needs_drop<T>() -> bool;
|
||||
}
|
||||
|
||||
extern mod rustrt {
|
||||
#[rust_stack]
|
||||
fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
|
||||
|
|
@ -127,7 +128,6 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
|
|||
(reinterpret_cast(&(p & !1)), p & 1 == 1)
|
||||
}
|
||||
|
||||
// The duplication between the POD and non-POD functions is annoying.
|
||||
impl &Arena {
|
||||
// Functions for the POD part of the arena
|
||||
fn alloc_pod_grow(n_bytes: uint, align: uint) -> *u8 {
|
||||
|
|
@ -166,7 +166,7 @@ impl &Arena {
|
|||
let tydesc = sys::get_type_desc::<T>();
|
||||
let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
|
||||
let ptr: *mut T = reinterpret_cast(&ptr);
|
||||
rusti::move_val_init(*ptr, op());
|
||||
rusti::move_val_init(&mut (*ptr), op());
|
||||
return reinterpret_cast(&ptr);
|
||||
}
|
||||
}
|
||||
|
|
@ -217,7 +217,7 @@ impl &Arena {
|
|||
// has *not* been initialized yet.
|
||||
*ty_ptr = reinterpret_cast(&tydesc);
|
||||
// Actually initialize it
|
||||
rusti::move_val_init(*ptr, op());
|
||||
rusti::move_val_init(&mut(*ptr), op());
|
||||
// Now that we are done, update the tydesc to indicate that
|
||||
// the object is there.
|
||||
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use vec::{to_mut, from_elem};
|
||||
|
||||
|
|
@ -553,7 +553,7 @@ pure fn land(w0: uint, w1: uint) -> uint { return w0 & w1; }
|
|||
pure fn right(_w0: uint, w1: uint) -> uint { return w1; }
|
||||
|
||||
impl Bitv: ops::Index<uint,bool> {
|
||||
pure fn index(+i: uint) -> bool {
|
||||
pure fn index(i: uint) -> bool {
|
||||
self.get(i)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
* great care must be taken to ensure that a reference to the c_vec::t is
|
||||
* still held if needed.
|
||||
*/
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
/**
|
||||
* The type representing a foreign chunk of memory
|
||||
|
|
@ -111,7 +112,7 @@ pub fn get<T: Copy>(t: CVec<T>, ofs: uint) -> T {
|
|||
*
|
||||
* Fails if `ofs` is greater or equal to the length of the vector
|
||||
*/
|
||||
pub fn set<T: Copy>(t: CVec<T>, ofs: uint, +v: T) {
|
||||
pub fn set<T: Copy>(t: CVec<T>, ofs: uint, v: T) {
|
||||
assert ofs < len(t);
|
||||
unsafe { *ptr::mut_offset((*t).base, ofs) = v };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
/// A dynamic, mutable location.
|
||||
///
|
||||
/// Similar to a mutable option type, but friendlier.
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ pub struct DuplexStream<T: Send, U: Send> {
|
|||
}
|
||||
|
||||
impl<T: Send, U: Send> DuplexStream<T, U> : Channel<T> {
|
||||
fn send(+x: T) {
|
||||
fn send(x: T) {
|
||||
self.chan.send(move x)
|
||||
}
|
||||
|
||||
fn try_send(+x: T) -> bool {
|
||||
fn try_send(x: T) -> bool {
|
||||
self.chan.try_send(move x)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
//! Unsafe debugging functions for inspecting values.
|
||||
|
||||
use cast::reinterpret_cast;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! A deque. Untested as of yet. Likely buggy
|
||||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(non_camel_case_types)];
|
||||
|
||||
use option::{Some, None};
|
||||
|
|
@ -200,7 +200,7 @@ mod tests {
|
|||
assert (deq.get(3) == d);
|
||||
}
|
||||
|
||||
fn test_parameterized<T: Copy Eq Owned>(a: T, +b: T, +c: T, +d: T) {
|
||||
fn test_parameterized<T: Copy Eq Owned>(a: T, b: T, c: T, d: T) {
|
||||
let deq: deque::Deque<T> = deque::create::<T>();
|
||||
assert (deq.size() == 0u);
|
||||
deq.add_front(a);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#[forbid(deprecated_mode)];
|
||||
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
|
||||
// cursor model. See the specification here:
|
||||
// http://www.matroska.org/technical/specs/rfc/index.html
|
||||
|
|
@ -17,7 +18,7 @@ pub type Doc = {data: @~[u8], start: uint, end: uint};
|
|||
type TaggedDoc = {tag: uint, doc: Doc};
|
||||
|
||||
impl Doc: ops::Index<uint,Doc> {
|
||||
pure fn index(+tag: uint) -> Doc {
|
||||
pure fn index(tag: uint) -> Doc {
|
||||
unsafe {
|
||||
get_doc(self, tag)
|
||||
}
|
||||
|
|
@ -563,11 +564,11 @@ impl EbmlDeserializer: serialization::Deserializer {
|
|||
|
||||
#[test]
|
||||
fn test_option_int() {
|
||||
fn serialize_1<S: serialization::Serializer>(&&s: S, v: int) {
|
||||
fn serialize_1<S: serialization::Serializer>(s: &S, v: int) {
|
||||
s.emit_i64(v as i64);
|
||||
}
|
||||
|
||||
fn serialize_0<S: serialization::Serializer>(&&s: S, v: Option<int>) {
|
||||
fn serialize_0<S: serialization::Serializer>(s: &S, v: Option<int>) {
|
||||
do s.emit_enum(~"core::option::t") {
|
||||
match v {
|
||||
None => s.emit_enum_variant(
|
||||
|
|
@ -581,11 +582,11 @@ fn test_option_int() {
|
|||
}
|
||||
}
|
||||
|
||||
fn deserialize_1<S: serialization::Deserializer>(&&s: S) -> int {
|
||||
fn deserialize_1<S: serialization::Deserializer>(s: &S) -> int {
|
||||
s.read_i64() as int
|
||||
}
|
||||
|
||||
fn deserialize_0<S: serialization::Deserializer>(&&s: S) -> Option<int> {
|
||||
fn deserialize_0<S: serialization::Deserializer>(s: &S) -> Option<int> {
|
||||
do s.read_enum(~"core::option::t") {
|
||||
do s.read_enum_variant |i| {
|
||||
match i {
|
||||
|
|
@ -608,11 +609,11 @@ fn test_option_int() {
|
|||
debug!("v == %?", v);
|
||||
let bytes = do io::with_bytes_writer |wr| {
|
||||
let ebml_w = ebml::Writer(wr);
|
||||
serialize_0(ebml_w, v);
|
||||
serialize_0(&ebml_w, v);
|
||||
};
|
||||
let ebml_doc = ebml::Doc(@bytes);
|
||||
let deser = ebml_deserializer(ebml_doc);
|
||||
let v1 = deserialize_0(deser);
|
||||
let v1 = deserialize_0(&deser);
|
||||
debug!("v1 == %?", v1);
|
||||
assert v == v1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#[forbid(deprecated_mode)];
|
||||
use serialization2;
|
||||
|
||||
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
|
||||
|
|
@ -31,7 +32,7 @@ struct TaggedDoc {
|
|||
}
|
||||
|
||||
impl Doc: ops::Index<uint,Doc> {
|
||||
pure fn index(+tag: uint) -> Doc {
|
||||
pure fn index(tag: uint) -> Doc {
|
||||
unsafe {
|
||||
get_doc(self, tag)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[warn(deprecated_mode)];
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
/*!
|
||||
* A functional key,value store that works on anything.
|
||||
|
|
@ -26,7 +26,7 @@ enum TreeNode<K, V> {
|
|||
pub fn init<K, V>() -> Treemap<K, V> { @Empty }
|
||||
|
||||
/// Insert a value into the map
|
||||
pub fn insert<K: Copy Eq Ord, V: Copy>(m: Treemap<K, V>, +k: K, +v: V)
|
||||
pub fn insert<K: Copy Eq Ord, V: Copy>(m: Treemap<K, V>, k: K, v: V)
|
||||
-> Treemap<K, V> {
|
||||
@match m {
|
||||
@Empty => Node(@k, @v, @Empty, @Empty),
|
||||
|
|
@ -41,7 +41,7 @@ pub fn insert<K: Copy Eq Ord, V: Copy>(m: Treemap<K, V>, +k: K, +v: V)
|
|||
}
|
||||
|
||||
/// Find a value based on the key
|
||||
pub fn find<K: Eq Ord, V: Copy>(m: Treemap<K, V>, +k: K) -> Option<V> {
|
||||
pub fn find<K: Eq Ord, V: Copy>(m: Treemap<K, V>, k: K) -> Option<V> {
|
||||
match *m {
|
||||
Empty => None,
|
||||
Node(@ref kk, @copy v, left, right) => {
|
||||
|
|
|
|||
|
|
@ -61,8 +61,7 @@
|
|||
* do_work(input, output);
|
||||
* }
|
||||
*/
|
||||
|
||||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use core::cmp::Eq;
|
||||
use core::result::{Err, Ok};
|
||||
|
|
@ -162,7 +161,7 @@ fn name_str(nm: &Name) -> ~str {
|
|||
};
|
||||
}
|
||||
|
||||
fn find_opt(opts: &[Opt], +nm: Name) -> Option<uint> {
|
||||
fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
|
||||
vec::position(opts, |opt| opt.name == nm)
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +213,7 @@ pub type Result = result::Result<Matches, Fail_>;
|
|||
*/
|
||||
pub fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe {
|
||||
let n_opts = vec::len::<Opt>(opts);
|
||||
fn f(+_x: uint) -> ~[Optval] { return ~[]; }
|
||||
fn f(_x: uint) -> ~[Optval] { return ~[]; }
|
||||
let vals = vec::to_mut(vec::from_fn(n_opts, f));
|
||||
let mut free: ~[~str] = ~[];
|
||||
let l = vec::len(args);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Rust JSON serialization library
|
||||
// Copyright (c) 2011 Google Inc.
|
||||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
#[forbid(non_camel_case_types)];
|
||||
|
||||
//! json serialization
|
||||
|
|
@ -399,7 +399,7 @@ priv impl Parser {
|
|||
while char::is_whitespace(self.ch) { self.bump(); }
|
||||
}
|
||||
|
||||
fn parse_ident(ident: &str, +value: Json) -> Result<Json, Error> {
|
||||
fn parse_ident(ident: &str, value: Json) -> Result<Json, Error> {
|
||||
if str::all(ident, |c| c == self.next_char()) {
|
||||
self.bump();
|
||||
Ok(move value)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! A standard linked list
|
||||
#[warn(deprecated_mode)];
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use core::cmp::Eq;
|
||||
use core::option;
|
||||
|
|
@ -56,7 +56,7 @@ pub fn find<T: Copy>(ls: @List<T>, f: fn((&T)) -> bool) -> Option<T> {
|
|||
}
|
||||
|
||||
/// Returns true if a list contains an element with the given value
|
||||
pub fn has<T: Copy Eq>(ls: @List<T>, +elt: T) -> bool {
|
||||
pub fn has<T: Copy Eq>(ls: @List<T>, elt: T) -> bool {
|
||||
for each(ls) |e| {
|
||||
if *e == elt { return true; }
|
||||
}
|
||||
|
|
@ -114,7 +114,7 @@ pub pure fn append<T: Copy>(l: @List<T>, m: @List<T>) -> @List<T> {
|
|||
/*
|
||||
/// Push one element into the front of a list, returning a new list
|
||||
/// THIS VERSION DOESN'T ACTUALLY WORK
|
||||
pure fn push<T: Copy>(ll: &mut @list<T>, +vv: T) {
|
||||
pure fn push<T: Copy>(ll: &mut @list<T>, vv: T) {
|
||||
ll = &mut @cons(vv, *ll)
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//! A map type
|
||||
|
||||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use io::WriterUtil;
|
||||
use to_str::ToStr;
|
||||
|
|
@ -28,7 +27,7 @@ pub trait Map<K:Eq IterBytes Hash Copy, V: Copy> {
|
|||
*
|
||||
* Returns true if the key did not already exist in the map
|
||||
*/
|
||||
fn insert(v: K, +v: V) -> bool;
|
||||
fn insert(v: K, v: V) -> bool;
|
||||
|
||||
/// Returns true if the map contains a value for the specified key
|
||||
fn contains_key(key: K) -> bool;
|
||||
|
|
@ -59,7 +58,7 @@ pub trait Map<K:Eq IterBytes Hash Copy, V: Copy> {
|
|||
fn clear();
|
||||
|
||||
/// Iterate over all the key/value pairs in the map by value
|
||||
pure fn each(fn(key: K, +value: V) -> bool);
|
||||
pure fn each(fn(key: K, value: V) -> bool);
|
||||
|
||||
/// Iterate over all the keys in the map by value
|
||||
pure fn each_key(fn(key: K) -> bool);
|
||||
|
|
@ -213,7 +212,7 @@ pub mod chained {
|
|||
}
|
||||
}
|
||||
|
||||
fn insert(k: K, +v: V) -> bool {
|
||||
fn insert(k: K, v: V) -> bool {
|
||||
let hash = k.hash_keyed(0,0) as uint;
|
||||
match self.search_tbl(&k, hash) {
|
||||
NotFound => {
|
||||
|
|
@ -294,7 +293,7 @@ pub mod chained {
|
|||
self.chains = chains(initial_capacity);
|
||||
}
|
||||
|
||||
pure fn each(blk: fn(key: K, +value: V) -> bool) {
|
||||
pure fn each(blk: fn(key: K, value: V) -> bool) {
|
||||
self.each_ref(|k, v| blk(*k, *v))
|
||||
}
|
||||
|
||||
|
|
@ -348,7 +347,7 @@ pub mod chained {
|
|||
}
|
||||
|
||||
impl<K:Eq IterBytes Hash Copy, V: Copy> T<K, V>: ops::Index<K, V> {
|
||||
pure fn index(+k: K) -> V {
|
||||
pure fn index(k: K) -> V {
|
||||
unsafe {
|
||||
self.get(k)
|
||||
}
|
||||
|
|
@ -382,7 +381,7 @@ pub fn set_add<K:Eq IterBytes Hash Const Copy>(set: Set<K>, key: K) -> bool {
|
|||
}
|
||||
|
||||
/// Convert a set into a vector.
|
||||
pub fn vec_from_set<T:Eq IterBytes Hash Copy>(s: Set<T>) -> ~[T] {
|
||||
pub pure fn vec_from_set<T:Eq IterBytes Hash Copy>(s: Set<T>) -> ~[T] {
|
||||
do vec::build_sized(s.size()) |push| {
|
||||
for s.each_key() |k| {
|
||||
push(k);
|
||||
|
|
@ -459,7 +458,7 @@ impl<K: Eq IterBytes Hash Copy, V: Copy> @Mut<LinearMap<K, V>>:
|
|||
}
|
||||
}
|
||||
|
||||
pure fn each(op: fn(key: K, +value: V) -> bool) {
|
||||
pure fn each(op: fn(key: K, value: V) -> bool) {
|
||||
unsafe {
|
||||
do self.borrow_imm |p| {
|
||||
p.each(|k, v| op(*k, *v))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
//! High-level interface to libuv's TCP functionality
|
||||
// XXX Need FFI fixes
|
||||
#[allow(deprecated_mode)];
|
||||
|
||||
use ip = net_ip;
|
||||
use uv::iotask;
|
||||
|
|
@ -121,8 +123,8 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
|
|||
let result_po = core::comm::Port::<ConnAttempt>();
|
||||
let closed_signal_po = core::comm::Port::<()>();
|
||||
let conn_data = {
|
||||
result_ch: core::comm::Chan(result_po),
|
||||
closed_signal_ch: core::comm::Chan(closed_signal_po)
|
||||
result_ch: core::comm::Chan(&result_po),
|
||||
closed_signal_ch: core::comm::Chan(&closed_signal_po)
|
||||
};
|
||||
let conn_data_ptr = ptr::addr_of(&conn_data);
|
||||
let reader_po = core::comm::Port::<result::Result<~[u8], TcpErrData>>();
|
||||
|
|
@ -130,7 +132,7 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
|
|||
*(stream_handle_ptr as *mut uv::ll::uv_tcp_t) = uv::ll::tcp_t();
|
||||
let socket_data = @{
|
||||
reader_po: reader_po,
|
||||
reader_ch: core::comm::Chan(reader_po),
|
||||
reader_ch: core::comm::Chan(&reader_po),
|
||||
stream_handle_ptr: stream_handle_ptr,
|
||||
connect_req: uv::ll::connect_t(),
|
||||
write_req: uv::ll::write_t(),
|
||||
|
|
@ -324,7 +326,7 @@ pub fn read_start(sock: &TcpSocket)
|
|||
* * `sock` - a `net::tcp::tcp_socket` that you wish to stop reading on
|
||||
*/
|
||||
pub fn read_stop(sock: &TcpSocket,
|
||||
+read_port: comm::Port<result::Result<~[u8], TcpErrData>>) ->
|
||||
read_port: comm::Port<result::Result<~[u8], TcpErrData>>) ->
|
||||
result::Result<(), TcpErrData> unsafe {
|
||||
log(debug, fmt!("taking the read_port out of commission %?", read_port));
|
||||
let socket_data = ptr::addr_of(&(*sock.socket_data));
|
||||
|
|
@ -471,7 +473,7 @@ pub fn accept(new_conn: TcpNewConnection)
|
|||
*(stream_handle_ptr as *mut uv::ll::uv_tcp_t) = uv::ll::tcp_t();
|
||||
let client_socket_data = @{
|
||||
reader_po: reader_po,
|
||||
reader_ch: core::comm::Chan(reader_po),
|
||||
reader_ch: core::comm::Chan(&reader_po),
|
||||
stream_handle_ptr : stream_handle_ptr,
|
||||
connect_req : uv::ll::connect_t(),
|
||||
write_req : uv::ll::write_t(),
|
||||
|
|
@ -482,7 +484,7 @@ pub fn accept(new_conn: TcpNewConnection)
|
|||
(*client_socket_data_ptr).stream_handle_ptr;
|
||||
|
||||
let result_po = core::comm::Port::<Option<TcpErrData>>();
|
||||
let result_ch = core::comm::Chan(result_po);
|
||||
let result_ch = core::comm::Chan(&result_po);
|
||||
|
||||
// UNSAFE LIBUV INTERACTION BEGIN
|
||||
// .. normally this happens within the context of
|
||||
|
|
@ -558,8 +560,8 @@ pub fn accept(new_conn: TcpNewConnection)
|
|||
*/
|
||||
pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint,
|
||||
iotask: IoTask,
|
||||
+on_establish_cb: fn~(comm::Chan<Option<TcpErrData>>),
|
||||
+new_connect_cb: fn~(TcpNewConnection,
|
||||
on_establish_cb: fn~(comm::Chan<Option<TcpErrData>>),
|
||||
new_connect_cb: fn~(TcpNewConnection,
|
||||
comm::Chan<Option<TcpErrData>>))
|
||||
-> result::Result<(), TcpListenErrData> unsafe {
|
||||
do listen_common(move host_ip, port, backlog, iotask, on_establish_cb)
|
||||
|
|
@ -575,17 +577,17 @@ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint,
|
|||
|
||||
fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint,
|
||||
iotask: IoTask,
|
||||
+on_establish_cb: fn~(comm::Chan<Option<TcpErrData>>),
|
||||
+on_connect_cb: fn~(*uv::ll::uv_tcp_t))
|
||||
on_establish_cb: fn~(comm::Chan<Option<TcpErrData>>),
|
||||
on_connect_cb: fn~(*uv::ll::uv_tcp_t))
|
||||
-> result::Result<(), TcpListenErrData> unsafe {
|
||||
let stream_closed_po = core::comm::Port::<()>();
|
||||
let kill_po = core::comm::Port::<Option<TcpErrData>>();
|
||||
let kill_ch = core::comm::Chan(kill_po);
|
||||
let kill_ch = core::comm::Chan(&kill_po);
|
||||
let server_stream = uv::ll::tcp_t();
|
||||
let server_stream_ptr = ptr::addr_of(&server_stream);
|
||||
let server_data = {
|
||||
server_stream_ptr: server_stream_ptr,
|
||||
stream_closed_ch: core::comm::Chan(stream_closed_po),
|
||||
stream_closed_ch: core::comm::Chan(&stream_closed_po),
|
||||
kill_ch: kill_ch,
|
||||
on_connect_cb: move on_connect_cb,
|
||||
iotask: iotask,
|
||||
|
|
@ -749,7 +751,7 @@ impl TcpSocket {
|
|||
|
||||
/// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket`
|
||||
impl TcpSocketBuf: io::Reader {
|
||||
fn read(buf: &[mut u8], +len: uint) -> uint {
|
||||
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 {
|
||||
let read_result = read(&self.data.sock, 0u);
|
||||
|
|
@ -785,13 +787,13 @@ impl TcpSocketBuf: io::Reader {
|
|||
let mut bytes = ~[0];
|
||||
if self.read(bytes, 1u) == 0 { fail } else { bytes[0] as int }
|
||||
}
|
||||
fn unread_byte(+amt: int) {
|
||||
fn unread_byte(amt: int) {
|
||||
self.data.buf.unshift(amt as u8);
|
||||
}
|
||||
fn eof() -> bool {
|
||||
false // noop
|
||||
}
|
||||
fn seek(+dist: int, +seek: io::SeekStyle) {
|
||||
fn seek(dist: int, seek: io::SeekStyle) {
|
||||
log(debug, fmt!("tcp_socket_buf seek stub %? %?", dist, seek));
|
||||
// noop
|
||||
}
|
||||
|
|
@ -813,7 +815,7 @@ impl TcpSocketBuf: io::Writer {
|
|||
err_data.err_name, err_data.err_msg));
|
||||
}
|
||||
}
|
||||
fn seek(+dist: int, +seek: io::SeekStyle) {
|
||||
fn seek(dist: int, seek: io::SeekStyle) {
|
||||
log(debug, fmt!("tcp_socket_buf seek stub %? %?", dist, seek));
|
||||
// noop
|
||||
}
|
||||
|
|
@ -832,7 +834,7 @@ impl TcpSocketBuf: io::Writer {
|
|||
|
||||
fn tear_down_socket_data(socket_data: @TcpSocketData) unsafe {
|
||||
let closed_po = core::comm::Port::<()>();
|
||||
let closed_ch = core::comm::Chan(closed_po);
|
||||
let closed_ch = core::comm::Chan(&closed_po);
|
||||
let close_data = {
|
||||
closed_ch: closed_ch
|
||||
};
|
||||
|
|
@ -895,7 +897,7 @@ fn read_stop_common_impl(socket_data: *TcpSocketData) ->
|
|||
result::Result<(), TcpErrData> unsafe {
|
||||
let stream_handle_ptr = (*socket_data).stream_handle_ptr;
|
||||
let stop_po = core::comm::Port::<Option<TcpErrData>>();
|
||||
let stop_ch = core::comm::Chan(stop_po);
|
||||
let stop_ch = core::comm::Chan(&stop_po);
|
||||
do iotask::interact((*socket_data).iotask) |loop_ptr| unsafe {
|
||||
log(debug, ~"in interact cb for tcp::read_stop");
|
||||
match uv::ll::read_stop(stream_handle_ptr as *uv::ll::uv_stream_t) {
|
||||
|
|
@ -922,7 +924,7 @@ fn read_start_common_impl(socket_data: *TcpSocketData)
|
|||
result::Result<~[u8], TcpErrData>>, TcpErrData> unsafe {
|
||||
let stream_handle_ptr = (*socket_data).stream_handle_ptr;
|
||||
let start_po = core::comm::Port::<Option<uv::ll::uv_err_data>>();
|
||||
let start_ch = core::comm::Chan(start_po);
|
||||
let start_ch = core::comm::Chan(&start_po);
|
||||
log(debug, ~"in tcp::read_start before interact loop");
|
||||
do iotask::interact((*socket_data).iotask) |loop_ptr| unsafe {
|
||||
log(debug, fmt!("in tcp::read_start interact cb %?", loop_ptr));
|
||||
|
|
@ -961,7 +963,7 @@ fn write_common_impl(socket_data_ptr: *TcpSocketData,
|
|||
let write_buf_vec_ptr = ptr::addr_of(&write_buf_vec);
|
||||
let result_po = core::comm::Port::<TcpWriteResult>();
|
||||
let write_data = {
|
||||
result_ch: core::comm::Chan(result_po)
|
||||
result_ch: core::comm::Chan(&result_po)
|
||||
};
|
||||
let write_data_ptr = ptr::addr_of(&write_data);
|
||||
do iotask::interact((*socket_data_ptr).iotask) |loop_ptr| unsafe {
|
||||
|
|
@ -1277,10 +1279,10 @@ mod test {
|
|||
let expected_resp = ~"pong";
|
||||
|
||||
let server_result_po = core::comm::Port::<~str>();
|
||||
let server_result_ch = core::comm::Chan(server_result_po);
|
||||
let server_result_ch = core::comm::Chan(&server_result_po);
|
||||
|
||||
let cont_po = core::comm::Port::<()>();
|
||||
let cont_ch = core::comm::Chan(cont_po);
|
||||
let cont_ch = core::comm::Chan(&cont_po);
|
||||
// server
|
||||
do task::spawn_sched(task::ManualThreads(1u)) {
|
||||
let actual_req = do comm::listen |server_ch| {
|
||||
|
|
@ -1343,10 +1345,10 @@ mod test {
|
|||
let expected_resp = ~"pong";
|
||||
|
||||
let server_result_po = core::comm::Port::<~str>();
|
||||
let server_result_ch = core::comm::Chan(server_result_po);
|
||||
let server_result_ch = core::comm::Chan(&server_result_po);
|
||||
|
||||
let cont_po = core::comm::Port::<()>();
|
||||
let cont_ch = core::comm::Chan(cont_po);
|
||||
let cont_ch = core::comm::Chan(&cont_po);
|
||||
// server
|
||||
do task::spawn_sched(task::ManualThreads(1u)) {
|
||||
let actual_req = do comm::listen |server_ch| {
|
||||
|
|
@ -1474,7 +1476,7 @@ mod test {
|
|||
str::from_bytes(new_bytes)
|
||||
}
|
||||
|
||||
fn run_tcp_test_server(server_ip: &str, server_port: uint, +resp: ~str,
|
||||
fn run_tcp_test_server(server_ip: &str, server_port: uint, resp: ~str,
|
||||
server_ch: comm::Chan<~str>,
|
||||
cont_ch: comm::Chan<()>,
|
||||
iotask: IoTask) -> ~str {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! Types/fns concerning URLs (see RFC 3986)
|
||||
// tjc: forbid deprecated modes again after a snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use core::cmp::Eq;
|
||||
use map::HashMap;
|
||||
|
|
@ -27,15 +27,15 @@ type UserInfo = {
|
|||
|
||||
pub type Query = ~[(~str, ~str)];
|
||||
|
||||
pub fn Url(scheme: ~str, +user: Option<UserInfo>, +host: ~str,
|
||||
+port: Option<~str>, +path: ~str, +query: Query,
|
||||
+fragment: Option<~str>) -> Url {
|
||||
pub fn Url(scheme: ~str, user: Option<UserInfo>, host: ~str,
|
||||
port: Option<~str>, path: ~str, query: Query,
|
||||
fragment: Option<~str>) -> Url {
|
||||
Url { scheme: move scheme, user: move user, host: move host,
|
||||
port: move port, path: move path, query: move query,
|
||||
fragment: move fragment }
|
||||
}
|
||||
|
||||
fn UserInfo(user: ~str, +pass: Option<~str>) -> UserInfo {
|
||||
fn UserInfo(user: ~str, pass: Option<~str>) -> UserInfo {
|
||||
{user: move user, pass: move pass}
|
||||
}
|
||||
|
||||
|
|
@ -726,7 +726,7 @@ impl Url : Eq {
|
|||
}
|
||||
|
||||
impl Url: IterBytes {
|
||||
pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
|
||||
pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
|
||||
unsafe { self.to_str() }.iter_bytes(lsb0, f)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#[forbid(deprecated_mode)];
|
||||
|
||||
use future_spawn = future::spawn;
|
||||
|
||||
|
||||
|
|
@ -72,7 +74,7 @@ fn map_slices<A: Copy Send, B: Copy Send>(
|
|||
}
|
||||
|
||||
/// A parallel version of map.
|
||||
pub fn map<A: Copy Send, B: Copy Send>(xs: &[A], +f: fn~((&A)) -> B) -> ~[B] {
|
||||
pub fn map<A: Copy Send, B: Copy Send>(xs: &[A], f: fn~((&A)) -> B) -> ~[B] {
|
||||
vec::concat(map_slices(xs, || {
|
||||
fn~(_base: uint, slice : &[A], copy f) -> ~[B] {
|
||||
vec::map(slice, |x| f(x))
|
||||
|
|
@ -82,7 +84,7 @@ pub fn map<A: Copy Send, B: Copy Send>(xs: &[A], +f: fn~((&A)) -> B) -> ~[B] {
|
|||
|
||||
/// A parallel version of mapi.
|
||||
pub fn mapi<A: Copy Send, B: Copy Send>(xs: &[A],
|
||||
+f: fn~(uint, (&A)) -> B) -> ~[B] {
|
||||
f: fn~(uint, (&A)) -> B) -> ~[B] {
|
||||
let slices = map_slices(xs, || {
|
||||
fn~(base: uint, slice : &[A], copy f) -> ~[B] {
|
||||
vec::mapi(slice, |i, x| {
|
||||
|
|
@ -119,7 +121,7 @@ pub fn mapi_factory<A: Copy Send, B: Copy Send>(
|
|||
}
|
||||
|
||||
/// Returns true if the function holds for all elements in the vector.
|
||||
pub fn alli<A: Copy Send>(xs: &[A], +f: fn~(uint, (&A)) -> bool) -> bool {
|
||||
pub fn alli<A: Copy Send>(xs: &[A], f: fn~(uint, (&A)) -> bool) -> bool {
|
||||
do vec::all(map_slices(xs, || {
|
||||
fn~(base: uint, slice : &[A], copy f) -> bool {
|
||||
vec::alli(slice, |i, x| {
|
||||
|
|
@ -130,7 +132,7 @@ pub fn alli<A: Copy Send>(xs: &[A], +f: fn~(uint, (&A)) -> bool) -> bool {
|
|||
}
|
||||
|
||||
/// Returns true if the function holds for any elements in the vector.
|
||||
pub fn any<A: Copy Send>(xs: &[A], +f: fn~(&(A)) -> bool) -> bool {
|
||||
pub fn any<A: Copy Send>(xs: &[A], f: fn~(&(A)) -> bool) -> bool {
|
||||
do vec::any(map_slices(xs, || {
|
||||
fn~(_base : uint, slice: &[A], copy f) -> bool {
|
||||
vec::any(slice, |x| f(x))
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
//! Support code for serialization.
|
||||
|
||||
#[allow(deprecated_mode)];
|
||||
|
||||
/*
|
||||
Core serialization interfaces.
|
||||
*/
|
||||
|
||||
trait Serializer {
|
||||
pub trait Serializer {
|
||||
// Primitive types:
|
||||
fn emit_nil();
|
||||
fn emit_uint(v: uint);
|
||||
|
|
@ -37,7 +39,7 @@ trait Serializer {
|
|||
fn emit_tup_elt(idx: uint, f: fn());
|
||||
}
|
||||
|
||||
trait Deserializer {
|
||||
pub trait Deserializer {
|
||||
// Primitive types:
|
||||
fn read_nil() -> ();
|
||||
|
||||
|
|
@ -81,7 +83,7 @@ trait Deserializer {
|
|||
//
|
||||
// In some cases, these should eventually be coded as traits.
|
||||
|
||||
fn emit_from_vec<S: Serializer, T>(&&s: S, &&v: ~[T], f: fn(&&x: T)) {
|
||||
pub fn emit_from_vec<S: Serializer, T>(&&s: S, &&v: ~[T], f: fn(&&x: T)) {
|
||||
do s.emit_vec(vec::len(v)) {
|
||||
for vec::eachi(v) |i,e| {
|
||||
do s.emit_vec_elt(i) {
|
||||
|
|
@ -91,7 +93,7 @@ fn emit_from_vec<S: Serializer, T>(&&s: S, &&v: ~[T], f: fn(&&x: T)) {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_to_vec<D: Deserializer, T: Copy>(&&d: D, f: fn() -> T) -> ~[T] {
|
||||
pub fn read_to_vec<D: Deserializer, T: Copy>(&&d: D, f: fn() -> T) -> ~[T] {
|
||||
do d.read_vec |len| {
|
||||
do vec::from_fn(len) |i| {
|
||||
d.read_vec_elt(i, || f())
|
||||
|
|
@ -99,7 +101,7 @@ fn read_to_vec<D: Deserializer, T: Copy>(&&d: D, f: fn() -> T) -> ~[T] {
|
|||
}
|
||||
}
|
||||
|
||||
trait SerializerHelpers {
|
||||
pub trait SerializerHelpers {
|
||||
fn emit_from_vec<T>(&&v: ~[T], f: fn(&&x: T));
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +111,7 @@ impl<S: Serializer> S: SerializerHelpers {
|
|||
}
|
||||
}
|
||||
|
||||
trait DeserializerHelpers {
|
||||
pub trait DeserializerHelpers {
|
||||
fn read_to_vec<T: Copy>(f: fn() -> T) -> ~[T];
|
||||
}
|
||||
|
||||
|
|
@ -119,127 +121,128 @@ impl<D: Deserializer> D: DeserializerHelpers {
|
|||
}
|
||||
}
|
||||
|
||||
fn serialize_uint<S: Serializer>(&&s: S, v: uint) {
|
||||
pub fn serialize_uint<S: Serializer>(&&s: S, v: uint) {
|
||||
s.emit_uint(v);
|
||||
}
|
||||
|
||||
fn deserialize_uint<D: Deserializer>(&&d: D) -> uint {
|
||||
pub fn deserialize_uint<D: Deserializer>(&&d: D) -> uint {
|
||||
d.read_uint()
|
||||
}
|
||||
|
||||
fn serialize_u8<S: Serializer>(&&s: S, v: u8) {
|
||||
pub fn serialize_u8<S: Serializer>(&&s: S, v: u8) {
|
||||
s.emit_u8(v);
|
||||
}
|
||||
|
||||
fn deserialize_u8<D: Deserializer>(&&d: D) -> u8 {
|
||||
pub fn deserialize_u8<D: Deserializer>(&&d: D) -> u8 {
|
||||
d.read_u8()
|
||||
}
|
||||
|
||||
fn serialize_u16<S: Serializer>(&&s: S, v: u16) {
|
||||
pub fn serialize_u16<S: Serializer>(&&s: S, v: u16) {
|
||||
s.emit_u16(v);
|
||||
}
|
||||
|
||||
fn deserialize_u16<D: Deserializer>(&&d: D) -> u16 {
|
||||
pub fn deserialize_u16<D: Deserializer>(&&d: D) -> u16 {
|
||||
d.read_u16()
|
||||
}
|
||||
|
||||
fn serialize_u32<S: Serializer>(&&s: S, v: u32) {
|
||||
pub fn serialize_u32<S: Serializer>(&&s: S, v: u32) {
|
||||
s.emit_u32(v);
|
||||
}
|
||||
|
||||
fn deserialize_u32<D: Deserializer>(&&d: D) -> u32 {
|
||||
pub fn deserialize_u32<D: Deserializer>(&&d: D) -> u32 {
|
||||
d.read_u32()
|
||||
}
|
||||
|
||||
fn serialize_u64<S: Serializer>(&&s: S, v: u64) {
|
||||
pub fn serialize_u64<S: Serializer>(&&s: S, v: u64) {
|
||||
s.emit_u64(v);
|
||||
}
|
||||
|
||||
fn deserialize_u64<D: Deserializer>(&&d: D) -> u64 {
|
||||
pub fn deserialize_u64<D: Deserializer>(&&d: D) -> u64 {
|
||||
d.read_u64()
|
||||
}
|
||||
|
||||
fn serialize_int<S: Serializer>(&&s: S, v: int) {
|
||||
pub fn serialize_int<S: Serializer>(&&s: S, v: int) {
|
||||
s.emit_int(v);
|
||||
}
|
||||
|
||||
fn deserialize_int<D: Deserializer>(&&d: D) -> int {
|
||||
pub fn deserialize_int<D: Deserializer>(&&d: D) -> int {
|
||||
d.read_int()
|
||||
}
|
||||
|
||||
fn serialize_i8<S: Serializer>(&&s: S, v: i8) {
|
||||
pub fn serialize_i8<S: Serializer>(&&s: S, v: i8) {
|
||||
s.emit_i8(v);
|
||||
}
|
||||
|
||||
fn deserialize_i8<D: Deserializer>(&&d: D) -> i8 {
|
||||
pub fn deserialize_i8<D: Deserializer>(&&d: D) -> i8 {
|
||||
d.read_i8()
|
||||
}
|
||||
|
||||
fn serialize_i16<S: Serializer>(&&s: S, v: i16) {
|
||||
pub fn serialize_i16<S: Serializer>(&&s: S, v: i16) {
|
||||
s.emit_i16(v);
|
||||
}
|
||||
|
||||
fn deserialize_i16<D: Deserializer>(&&d: D) -> i16 {
|
||||
pub fn deserialize_i16<D: Deserializer>(&&d: D) -> i16 {
|
||||
d.read_i16()
|
||||
}
|
||||
|
||||
fn serialize_i32<S: Serializer>(&&s: S, v: i32) {
|
||||
pub fn serialize_i32<S: Serializer>(&&s: S, v: i32) {
|
||||
s.emit_i32(v);
|
||||
}
|
||||
|
||||
fn deserialize_i32<D: Deserializer>(&&d: D) -> i32 {
|
||||
pub fn deserialize_i32<D: Deserializer>(&&d: D) -> i32 {
|
||||
d.read_i32()
|
||||
}
|
||||
|
||||
fn serialize_i64<S: Serializer>(&&s: S, v: i64) {
|
||||
pub fn serialize_i64<S: Serializer>(&&s: S, v: i64) {
|
||||
s.emit_i64(v);
|
||||
}
|
||||
|
||||
fn deserialize_i64<D: Deserializer>(&&d: D) -> i64 {
|
||||
pub fn deserialize_i64<D: Deserializer>(&&d: D) -> i64 {
|
||||
d.read_i64()
|
||||
}
|
||||
|
||||
fn serialize_str<S: Serializer>(&&s: S, v: &str) {
|
||||
pub fn serialize_str<S: Serializer>(&&s: S, v: &str) {
|
||||
s.emit_str(v);
|
||||
}
|
||||
|
||||
fn deserialize_str<D: Deserializer>(&&d: D) -> ~str {
|
||||
pub fn deserialize_str<D: Deserializer>(&&d: D) -> ~str {
|
||||
d.read_str()
|
||||
}
|
||||
|
||||
fn serialize_float<S: Serializer>(&&s: S, v: float) {
|
||||
pub fn serialize_float<S: Serializer>(&&s: S, v: float) {
|
||||
s.emit_float(v);
|
||||
}
|
||||
|
||||
fn deserialize_float<D: Deserializer>(&&d: D) -> float {
|
||||
pub fn deserialize_float<D: Deserializer>(&&d: D) -> float {
|
||||
d.read_float()
|
||||
}
|
||||
|
||||
fn serialize_f32<S: Serializer>(&&s: S, v: f32) {
|
||||
pub fn serialize_f32<S: Serializer>(&&s: S, v: f32) {
|
||||
s.emit_f32(v);
|
||||
}
|
||||
|
||||
fn deserialize_f32<D: Deserializer>(&&d: D) -> f32 {
|
||||
pub fn deserialize_f32<D: Deserializer>(&&d: D) -> f32 {
|
||||
d.read_f32()
|
||||
}
|
||||
|
||||
fn serialize_f64<S: Serializer>(&&s: S, v: f64) {
|
||||
pub fn serialize_f64<S: Serializer>(&&s: S, v: f64) {
|
||||
s.emit_f64(v);
|
||||
}
|
||||
|
||||
fn deserialize_f64<D: Deserializer>(&&d: D) -> f64 {
|
||||
pub fn deserialize_f64<D: Deserializer>(&&d: D) -> f64 {
|
||||
d.read_f64()
|
||||
}
|
||||
|
||||
fn serialize_bool<S: Serializer>(&&s: S, v: bool) {
|
||||
pub fn serialize_bool<S: Serializer>(&&s: S, v: bool) {
|
||||
s.emit_bool(v);
|
||||
}
|
||||
|
||||
fn deserialize_bool<D: Deserializer>(&&d: D) -> bool {
|
||||
pub fn deserialize_bool<D: Deserializer>(&&d: D) -> bool {
|
||||
d.read_bool()
|
||||
}
|
||||
|
||||
fn serialize_Option<S: Serializer,T>(&&s: S, &&v: Option<T>, st: fn(&&x: T)) {
|
||||
pub fn serialize_Option<S: Serializer,T>(&&s: S, &&v: Option<T>,
|
||||
st: fn(&&x: T)) {
|
||||
do s.emit_enum(~"option") {
|
||||
match v {
|
||||
None => do s.emit_enum_variant(~"none", 0u, 0u) {
|
||||
|
|
@ -254,7 +257,7 @@ fn serialize_Option<S: Serializer,T>(&&s: S, &&v: Option<T>, st: fn(&&x: T)) {
|
|||
}
|
||||
}
|
||||
|
||||
fn deserialize_Option<D: Deserializer,T: Copy>(&&d: D, st: fn() -> T)
|
||||
pub fn deserialize_Option<D: Deserializer,T: Copy>(&&d: D, st: fn() -> T)
|
||||
-> Option<T> {
|
||||
do d.read_enum(~"option") {
|
||||
do d.read_enum_variant |i| {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* A simple map based on a vector for small integer keys. Space requirements
|
||||
* are O(highest integer key).
|
||||
*/
|
||||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use core::option;
|
||||
use core::option::{Some, None};
|
||||
|
|
@ -103,7 +103,7 @@ impl<V: Copy> SmallIntMap<V>: map::Map<uint, V> {
|
|||
pure fn find(key: uint) -> Option<V> { find(self, key) }
|
||||
fn rehash() { fail }
|
||||
|
||||
pure fn each(it: fn(key: uint, +value: V) -> bool) {
|
||||
pure fn each(it: fn(key: uint, value: V) -> bool) {
|
||||
self.each_ref(|k, v| it(*k, *v))
|
||||
}
|
||||
pure fn each_key(it: fn(key: uint) -> bool) {
|
||||
|
|
@ -131,7 +131,7 @@ impl<V: Copy> SmallIntMap<V>: map::Map<uint, V> {
|
|||
}
|
||||
|
||||
impl<V: Copy> SmallIntMap<V>: ops::Index<uint, V> {
|
||||
pure fn index(+key: uint) -> V {
|
||||
pure fn index(key: uint) -> V {
|
||||
unsafe {
|
||||
get(self, key)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,86 +18,72 @@ not required in or otherwise suitable for the core library.
|
|||
|
||||
#[no_core];
|
||||
|
||||
#[legacy_exports];
|
||||
|
||||
#[allow(vecs_implicitly_copyable)];
|
||||
#[deny(non_camel_case_types)];
|
||||
// XXX this is set to allow because there are two methods in serialization
|
||||
// that can't be silenced otherwise. Most every module is set to forbid
|
||||
#[allow(deprecated_mode)];
|
||||
#[forbid(deprecated_pattern)];
|
||||
|
||||
extern mod core(vers = "0.4");
|
||||
use core::*;
|
||||
|
||||
export net, net_tcp, net_ip, net_url;
|
||||
export uv, uv_ll, uv_iotask, uv_global_loop;
|
||||
export c_vec, timer;
|
||||
export sync, arc, comm;
|
||||
export bitv, deque, fun_treemap, list, map;
|
||||
export smallintmap, sort, treemap;
|
||||
export rope, arena, par;
|
||||
export ebml, ebml2;
|
||||
export dbg, getopts, json, rand, sha1, term, time;
|
||||
export prettyprint, prettyprint2;
|
||||
export test, tempfile, serialization, serialization2;
|
||||
export cmp;
|
||||
export base64;
|
||||
export cell;
|
||||
|
||||
// General io and system-services modules
|
||||
|
||||
mod net;
|
||||
mod net_ip;
|
||||
mod net_tcp;
|
||||
mod net_url;
|
||||
pub mod net;
|
||||
pub mod net_ip;
|
||||
pub mod net_tcp;
|
||||
pub mod net_url;
|
||||
|
||||
// libuv modules
|
||||
mod uv;
|
||||
mod uv_ll;
|
||||
mod uv_iotask;
|
||||
mod uv_global_loop;
|
||||
pub mod uv;
|
||||
pub mod uv_ll;
|
||||
pub mod uv_iotask;
|
||||
pub mod uv_global_loop;
|
||||
|
||||
|
||||
// Utility modules
|
||||
|
||||
mod c_vec;
|
||||
mod timer;
|
||||
mod cell;
|
||||
pub mod c_vec;
|
||||
pub mod timer;
|
||||
pub mod cell;
|
||||
|
||||
// Concurrency
|
||||
|
||||
mod sync;
|
||||
mod arc;
|
||||
mod comm;
|
||||
pub mod sync;
|
||||
pub mod arc;
|
||||
pub mod comm;
|
||||
|
||||
// Collections
|
||||
|
||||
mod bitv;
|
||||
mod deque;
|
||||
mod fun_treemap;
|
||||
mod list;
|
||||
mod map;
|
||||
mod rope;
|
||||
mod smallintmap;
|
||||
mod sort;
|
||||
mod treemap;
|
||||
pub mod bitv;
|
||||
pub mod deque;
|
||||
pub mod fun_treemap;
|
||||
pub mod list;
|
||||
pub mod map;
|
||||
pub mod rope;
|
||||
pub mod smallintmap;
|
||||
pub mod sort;
|
||||
pub mod treemap;
|
||||
|
||||
// And ... other stuff
|
||||
|
||||
mod ebml;
|
||||
mod ebml2;
|
||||
mod dbg;
|
||||
mod getopts;
|
||||
mod json;
|
||||
mod sha1;
|
||||
mod md4;
|
||||
mod tempfile;
|
||||
mod term;
|
||||
mod time;
|
||||
mod prettyprint;
|
||||
mod prettyprint2;
|
||||
mod arena;
|
||||
mod par;
|
||||
mod cmp;
|
||||
mod base64;
|
||||
pub mod ebml;
|
||||
pub mod ebml2;
|
||||
pub mod dbg;
|
||||
pub mod getopts;
|
||||
pub mod json;
|
||||
pub mod sha1;
|
||||
pub mod md4;
|
||||
pub mod tempfile;
|
||||
pub mod term;
|
||||
pub mod time;
|
||||
pub mod prettyprint;
|
||||
pub mod prettyprint2;
|
||||
pub mod arena;
|
||||
pub mod par;
|
||||
pub mod cmp;
|
||||
pub mod base64;
|
||||
|
||||
#[cfg(unicode)]
|
||||
mod unicode;
|
||||
|
|
@ -105,10 +91,9 @@ mod unicode;
|
|||
|
||||
// Compiler support modules
|
||||
|
||||
mod test;
|
||||
#[legacy_exports]
|
||||
mod serialization;
|
||||
mod serialization2;
|
||||
pub mod test;
|
||||
pub mod serialization;
|
||||
pub mod serialization2;
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// NB: transitionary, de-mode-ing.
|
||||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
/**
|
||||
* The concurrency primitives you know and love.
|
||||
*
|
||||
|
|
@ -773,7 +773,7 @@ mod tests {
|
|||
let m = ~Mutex();
|
||||
let m2 = ~m.clone();
|
||||
let mut sharedstate = ~0;
|
||||
let ptr = ptr::p2::addr_of(&(*sharedstate));
|
||||
let ptr = ptr::addr_of(&(*sharedstate));
|
||||
do task::spawn {
|
||||
let sharedstate: &mut int =
|
||||
unsafe { cast::reinterpret_cast(&ptr) };
|
||||
|
|
@ -1045,7 +1045,7 @@ mod tests {
|
|||
let (c,p) = pipes::stream();
|
||||
let x2 = ~x.clone();
|
||||
let mut sharedstate = ~0;
|
||||
let ptr = ptr::p2::addr_of(&(*sharedstate));
|
||||
let ptr = ptr::addr_of(&(*sharedstate));
|
||||
do task::spawn {
|
||||
let sharedstate: &mut int =
|
||||
unsafe { cast::reinterpret_cast(&ptr) };
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
// simplest interface possible for representing and running tests
|
||||
// while providing a base that other test frameworks may build off of.
|
||||
|
||||
#[warn(deprecated_mode)];
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use core::cmp::Eq;
|
||||
use either::Either;
|
||||
|
|
@ -286,7 +286,7 @@ fn run_tests(opts: &TestOpts, tests: &[TestDesc],
|
|||
let mut done_idx = 0;
|
||||
|
||||
let p = core::comm::Port();
|
||||
let ch = core::comm::Chan(p);
|
||||
let ch = core::comm::Chan(&p);
|
||||
|
||||
while done_idx < total {
|
||||
while wait_idx < concurrency && run_idx < total {
|
||||
|
|
@ -421,7 +421,7 @@ mod tests {
|
|||
should_fail: false
|
||||
};
|
||||
let p = core::comm::Port();
|
||||
let ch = core::comm::Chan(p);
|
||||
let ch = core::comm::Chan(&p);
|
||||
run_test(desc, ch);
|
||||
let (_, res) = core::comm::recv(p);
|
||||
assert res != TrOk;
|
||||
|
|
@ -437,7 +437,7 @@ mod tests {
|
|||
should_fail: false
|
||||
};
|
||||
let p = core::comm::Port();
|
||||
let ch = core::comm::Chan(p);
|
||||
let ch = core::comm::Chan(&p);
|
||||
run_test(desc, ch);
|
||||
let (_, res) = core::comm::recv(p);
|
||||
assert res == TrIgnored;
|
||||
|
|
@ -454,7 +454,7 @@ mod tests {
|
|||
should_fail: true
|
||||
};
|
||||
let p = core::comm::Port();
|
||||
let ch = core::comm::Chan(p);
|
||||
let ch = core::comm::Chan(&p);
|
||||
run_test(desc, ch);
|
||||
let (_, res) = core::comm::recv(p);
|
||||
assert res == TrOk;
|
||||
|
|
@ -470,7 +470,7 @@ mod tests {
|
|||
should_fail: true
|
||||
};
|
||||
let p = core::comm::Port();
|
||||
let ch = core::comm::Chan(p);
|
||||
let ch = core::comm::Chan(&p);
|
||||
run_test(desc, ch);
|
||||
let (_, res) = core::comm::recv(p);
|
||||
assert res == TrFailed;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use core::cmp::Eq;
|
||||
use libc::{c_char, c_int, c_long, size_t, time_t};
|
||||
|
|
@ -7,16 +7,17 @@ use result::{Result, Ok, Err};
|
|||
|
||||
#[abi = "cdecl"]
|
||||
extern mod rustrt {
|
||||
#[legacy_exports];
|
||||
fn get_time(&sec: i64, &nsec: i32);
|
||||
fn precise_time_ns(&ns: u64);
|
||||
#[legacy_exports]
|
||||
fn get_time(sec: &mut i64, nsec: &mut i32);
|
||||
|
||||
fn precise_time_ns(ns: &mut u64);
|
||||
|
||||
fn rust_tzset();
|
||||
// FIXME: The i64 values can be passed by-val when #2064 is fixed.
|
||||
fn rust_gmtime(&&sec: i64, &&nsec: i32, &&result: Tm);
|
||||
fn rust_localtime(&&sec: i64, &&nsec: i32, &&result: Tm);
|
||||
fn rust_timegm(&&tm: Tm, &sec: i64);
|
||||
fn rust_mktime(&&tm: Tm, &sec: i64);
|
||||
fn rust_timegm(&&tm: Tm, sec: &mut i64);
|
||||
fn rust_mktime(&&tm: Tm, sec: &mut i64);
|
||||
}
|
||||
|
||||
/// A record specifying a time value in seconds and nanoseconds.
|
||||
|
|
@ -36,20 +37,22 @@ impl Timespec : Eq {
|
|||
pub fn get_time() -> Timespec {
|
||||
let mut sec = 0i64;
|
||||
let mut nsec = 0i32;
|
||||
rustrt::get_time(sec, nsec);
|
||||
rustrt::get_time(&mut sec, &mut nsec);
|
||||
return {sec: sec, nsec: nsec};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current value of a high-resolution performance counter
|
||||
* in nanoseconds since an unspecified epoch.
|
||||
*/
|
||||
pub fn precise_time_ns() -> u64 {
|
||||
let mut ns = 0u64;
|
||||
rustrt::precise_time_ns(ns);
|
||||
rustrt::precise_time_ns(&mut ns);
|
||||
ns
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the current value of a high-resolution performance counter
|
||||
* in seconds since an unspecified epoch.
|
||||
|
|
@ -762,9 +765,9 @@ impl Tm {
|
|||
fn to_timespec() -> Timespec {
|
||||
let mut sec = 0i64;
|
||||
if self.tm_gmtoff == 0_i32 {
|
||||
rustrt::rust_timegm(self, sec);
|
||||
rustrt::rust_timegm(self, &mut sec);
|
||||
} else {
|
||||
rustrt::rust_mktime(self, sec);
|
||||
rustrt::rust_mktime(self, &mut sec);
|
||||
}
|
||||
{ sec: sec, nsec: self.tm_nsec }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Utilities that leverage libuv's `uv_timer_*` API
|
||||
|
||||
// tjc: forbid deprecated modes again after snap
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use uv = uv;
|
||||
use uv::iotask;
|
||||
|
|
@ -27,7 +27,7 @@ pub fn delayed_send<T: Copy Send>(iotask: IoTask,
|
|||
msecs: uint, ch: comm::Chan<T>, val: T) {
|
||||
unsafe {
|
||||
let timer_done_po = core::comm::Port::<()>();
|
||||
let timer_done_ch = core::comm::Chan(timer_done_po);
|
||||
let timer_done_ch = core::comm::Chan(&timer_done_po);
|
||||
let timer_done_ch_ptr = ptr::addr_of(&timer_done_ch);
|
||||
let timer = uv::ll::timer_t();
|
||||
let timer_ptr = ptr::addr_of(&timer);
|
||||
|
|
@ -74,7 +74,7 @@ pub fn delayed_send<T: Copy Send>(iotask: IoTask,
|
|||
*/
|
||||
pub fn sleep(iotask: IoTask, msecs: uint) {
|
||||
let exit_po = core::comm::Port::<()>();
|
||||
let exit_ch = core::comm::Chan(exit_po);
|
||||
let exit_ch = core::comm::Chan(&exit_po);
|
||||
delayed_send(iotask, msecs, exit_ch, ());
|
||||
core::comm::recv(exit_po);
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ pub fn recv_timeout<T: Copy Send>(iotask: IoTask,
|
|||
msecs: uint,
|
||||
wait_po: comm::Port<T>) -> Option<T> {
|
||||
let timeout_po = comm::Port::<()>();
|
||||
let timeout_ch = comm::Chan(timeout_po);
|
||||
let timeout_ch = comm::Chan(&timeout_po);
|
||||
delayed_send(iotask, msecs, timeout_ch, ());
|
||||
// FIXME: This could be written clearer (#2618)
|
||||
either::either(
|
||||
|
|
@ -162,7 +162,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_gl_timer_sleep_stress2() {
|
||||
let po = core::comm::Port();
|
||||
let ch = core::comm::Chan(po);
|
||||
let ch = core::comm::Chan(&po);
|
||||
let hl_loop = uv::global_loop::get();
|
||||
|
||||
let repeat = 20u;
|
||||
|
|
@ -240,7 +240,7 @@ mod test {
|
|||
for iter::repeat(times as uint) {
|
||||
let expected = rand::Rng().gen_str(16u);
|
||||
let test_po = core::comm::Port::<~str>();
|
||||
let test_ch = core::comm::Chan(test_po);
|
||||
let test_ch = core::comm::Chan(&test_po);
|
||||
|
||||
do task::spawn() {
|
||||
delayed_send(hl_loop, 50u, test_ch, expected);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* very naive algorithm, but it will probably be updated to be a
|
||||
* red-black tree or something else.
|
||||
*/
|
||||
#[warn(deprecated_mode)];
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use core::cmp::{Eq, Ord};
|
||||
use core::option::{Some, None};
|
||||
|
|
@ -26,7 +26,7 @@ enum TreeNode<K, V> = {
|
|||
pub fn TreeMap<K, V>() -> TreeMap<K, V> { @mut None }
|
||||
|
||||
/// Insert a value into the map
|
||||
pub fn insert<K: Copy Eq Ord, V: Copy>(m: &mut TreeEdge<K, V>, +k: K, +v: V) {
|
||||
pub fn insert<K: Copy Eq Ord, V: Copy>(m: &mut TreeEdge<K, V>, k: K, v: V) {
|
||||
match copy *m {
|
||||
None => {
|
||||
*m = Some(@TreeNode({key: k,
|
||||
|
|
@ -48,7 +48,7 @@ pub fn insert<K: Copy Eq Ord, V: Copy>(m: &mut TreeEdge<K, V>, +k: K, +v: V) {
|
|||
}
|
||||
|
||||
/// Find a value based on the key
|
||||
pub fn find<K: Copy Eq Ord, V: Copy>(m: &const TreeEdge<K, V>, +k: K)
|
||||
pub fn find<K: Copy Eq Ord, V: Copy>(m: &const TreeEdge<K, V>, k: K)
|
||||
-> Option<V> {
|
||||
match copy *m {
|
||||
None => None,
|
||||
|
|
@ -121,7 +121,7 @@ mod tests {
|
|||
insert(m, 1, ());
|
||||
|
||||
let n = @mut 0;
|
||||
fn t(n: @mut int, +k: int, +_v: ()) {
|
||||
fn t(n: @mut int, k: int, _v: ()) {
|
||||
assert (*n == k); *n += 1;
|
||||
}
|
||||
traverse(m, |x,y| t(n, *x, *y));
|
||||
|
|
|
|||
|
|
@ -133,12 +133,12 @@ mod test {
|
|||
|
||||
fn impl_uv_hl_simple_timer(iotask: IoTask) unsafe {
|
||||
let exit_po = core::comm::Port::<bool>();
|
||||
let exit_ch = core::comm::Chan(exit_po);
|
||||
let exit_ch_ptr = ptr::p2::addr_of(&exit_ch);
|
||||
let exit_ch = core::comm::Chan(&exit_po);
|
||||
let exit_ch_ptr = ptr::addr_of(&exit_ch);
|
||||
log(debug, fmt!("EXIT_CH_PTR newly created exit_ch_ptr: %?",
|
||||
exit_ch_ptr));
|
||||
let timer_handle = ll::timer_t();
|
||||
let timer_ptr = ptr::p2::addr_of(&timer_handle);
|
||||
let timer_ptr = ptr::addr_of(&timer_handle);
|
||||
do iotask::interact(iotask) |loop_ptr| unsafe {
|
||||
log(debug, ~"user code inside interact loop!!!");
|
||||
let init_status = ll::timer_init(loop_ptr, timer_ptr);
|
||||
|
|
@ -166,7 +166,7 @@ mod test {
|
|||
fn test_gl_uv_global_loop_high_level_global_timer() unsafe {
|
||||
let hl_loop = get_gl();
|
||||
let exit_po = comm::Port::<()>();
|
||||
let exit_ch = comm::Chan(exit_po);
|
||||
let exit_ch = comm::Chan(&exit_po);
|
||||
task::spawn_sched(task::ManualThreads(1u), || {
|
||||
impl_uv_hl_simple_timer(hl_loop);
|
||||
core::comm::send(exit_ch, ());
|
||||
|
|
@ -182,7 +182,7 @@ mod test {
|
|||
fn test_stress_gl_uv_global_loop_high_level_global_timer() unsafe {
|
||||
let hl_loop = get_gl();
|
||||
let exit_po = core::comm::Port::<()>();
|
||||
let exit_ch = core::comm::Chan(exit_po);
|
||||
let exit_ch = core::comm::Chan(&exit_po);
|
||||
let cycles = 5000u;
|
||||
for iter::repeat(cycles) {
|
||||
task::spawn_sched(task::ManualThreads(1u), || {
|
||||
|
|
|
|||
|
|
@ -4,11 +4,10 @@
|
|||
* The I/O task runs in its own single-threaded scheduler. By using the
|
||||
* `interact` function you can execute code in a uv callback.
|
||||
*/
|
||||
|
||||
// tjc: forbid deprecated modes again after a snapshot
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
use libc::c_void;
|
||||
use ptr::p2::addr_of;
|
||||
use ptr::addr_of;
|
||||
use comm = core::comm;
|
||||
use comm::{Port, Chan, listen};
|
||||
use task::TaskBuilder;
|
||||
|
|
@ -60,7 +59,7 @@ pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask {
|
|||
* via ports/chans.
|
||||
*/
|
||||
pub unsafe fn interact(iotask: IoTask,
|
||||
+cb: fn~(*c_void)) {
|
||||
cb: fn~(*c_void)) {
|
||||
send_msg(iotask, Interaction(move cb));
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +124,7 @@ type IoTaskLoopData = {
|
|||
};
|
||||
|
||||
fn send_msg(iotask: IoTask,
|
||||
+msg: IoTaskMsg) unsafe {
|
||||
msg: IoTaskMsg) unsafe {
|
||||
iotask.op_chan.send(move msg);
|
||||
ll::async_send(iotask.async_handle);
|
||||
}
|
||||
|
|
@ -184,7 +183,7 @@ mod test {
|
|||
let async_handle = ll::async_t();
|
||||
let ah_ptr = ptr::addr_of(&async_handle);
|
||||
let exit_po = core::comm::Port::<()>();
|
||||
let exit_ch = core::comm::Chan(exit_po);
|
||||
let exit_ch = core::comm::Chan(&exit_po);
|
||||
let ah_data = {
|
||||
iotask: iotask,
|
||||
exit_ch: exit_ch
|
||||
|
|
@ -202,7 +201,7 @@ mod test {
|
|||
// high_level_loop
|
||||
unsafe fn spawn_test_loop(exit_ch: comm::Chan<()>) -> IoTask {
|
||||
let iotask_port = comm::Port::<IoTask>();
|
||||
let iotask_ch = comm::Chan(iotask_port);
|
||||
let iotask_ch = comm::Chan(&iotask_port);
|
||||
do task::spawn_sched(task::ManualThreads(1u)) {
|
||||
run_loop(iotask_ch);
|
||||
exit_ch.send(());
|
||||
|
|
@ -223,7 +222,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_uv_iotask_async() unsafe {
|
||||
let exit_po = core::comm::Port::<()>();
|
||||
let exit_ch = core::comm::Chan(exit_po);
|
||||
let exit_ch = core::comm::Chan(&exit_po);
|
||||
let iotask = spawn_test_loop(exit_ch);
|
||||
|
||||
// using this handle to manage the lifetime of the high_level_loop,
|
||||
|
|
@ -233,7 +232,7 @@ mod test {
|
|||
// lives until, at least, all of the impl_uv_hl_async() runs have been
|
||||
// called, at least.
|
||||
let work_exit_po = core::comm::Port::<()>();
|
||||
let work_exit_ch = core::comm::Chan(work_exit_po);
|
||||
let work_exit_ch = core::comm::Chan(&work_exit_po);
|
||||
for iter::repeat(7u) {
|
||||
do task::spawn_sched(task::ManualThreads(1u)) {
|
||||
impl_uv_iotask_async(iotask);
|
||||
|
|
|
|||
|
|
@ -1466,12 +1466,12 @@ pub mod test {
|
|||
let kill_server_msg = ~"does a dog have buddha nature?";
|
||||
let server_resp_msg = ~"mu!";
|
||||
let client_port = core::comm::Port::<~str>();
|
||||
let client_chan = core::comm::Chan::<~str>(client_port);
|
||||
let client_chan = core::comm::Chan::<~str>(&client_port);
|
||||
let server_port = core::comm::Port::<~str>();
|
||||
let server_chan = core::comm::Chan::<~str>(server_port);
|
||||
let server_chan = core::comm::Chan::<~str>(&server_port);
|
||||
|
||||
let continue_port = core::comm::Port::<bool>();
|
||||
let continue_chan = core::comm::Chan::<bool>(continue_port);
|
||||
let continue_chan = core::comm::Chan::<bool>(&continue_port);
|
||||
let continue_chan_ptr = ptr::addr_of(&continue_chan);
|
||||
|
||||
do task::spawn_sched(task::ManualThreads(1)) {
|
||||
|
|
|
|||
|
|
@ -574,7 +574,7 @@ impl<T:cmp::Eq> inferable<T> : cmp::Eq {
|
|||
|
||||
// "resolved" mode: the real modes.
|
||||
#[auto_serialize]
|
||||
enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy }
|
||||
enum rmode { by_ref, by_val, by_move, by_copy }
|
||||
|
||||
impl rmode : to_bytes::IterBytes {
|
||||
pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ trait ext_ctxt_ast_builder {
|
|||
fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
|
||||
-> ast::ty_param;
|
||||
fn arg(name: ident, ty: @ast::ty) -> ast::arg;
|
||||
fn arg_mode(name: ident, ty: @ast::ty, mode: ast::rmode) -> ast::arg;
|
||||
fn expr_block(e: @ast::expr) -> ast::blk;
|
||||
fn fn_decl(+inputs: ~[ast::arg], output: @ast::ty) -> ast::fn_decl;
|
||||
fn item(name: ident, span: span, +node: ast::item_) -> @ast::item;
|
||||
|
|
@ -177,13 +176,6 @@ impl ext_ctxt: ext_ctxt_ast_builder {
|
|||
id: self.next_id()}
|
||||
}
|
||||
|
||||
fn arg_mode(name: ident, ty: @ast::ty, mode: ast::rmode) -> ast::arg {
|
||||
{mode: ast::expl(mode),
|
||||
ty: ty,
|
||||
ident: name,
|
||||
id: self.next_id()}
|
||||
}
|
||||
|
||||
fn block(+stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk {
|
||||
let blk = {view_items: ~[],
|
||||
stmts: stmts,
|
||||
|
|
|
|||
|
|
@ -47,16 +47,15 @@ impl message: gen_send {
|
|||
let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str()));
|
||||
|
||||
let args_ast = (arg_names, tys).map(
|
||||
|n, t| cx.arg_mode(*n, *t, ast::by_copy)
|
||||
|n, t| cx.arg(*n, *t)
|
||||
);
|
||||
|
||||
let pipe_ty = cx.ty_path_ast_builder(
|
||||
path(~[this.data_name()], span)
|
||||
.add_tys(cx.ty_vars(this.ty_params)));
|
||||
let args_ast = vec::append(
|
||||
~[cx.arg_mode(cx.ident_of(~"pipe"),
|
||||
pipe_ty,
|
||||
ast::by_copy)],
|
||||
~[cx.arg(cx.ident_of(~"pipe"),
|
||||
pipe_ty)],
|
||||
args_ast);
|
||||
|
||||
let mut body = ~"{\n";
|
||||
|
|
@ -129,15 +128,14 @@ impl message: gen_send {
|
|||
let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str()));
|
||||
|
||||
let args_ast = (arg_names, tys).map(
|
||||
|n, t| cx.arg_mode(cx.ident_of(*n), *t, ast::by_copy)
|
||||
|n, t| cx.arg(cx.ident_of(*n), *t)
|
||||
);
|
||||
|
||||
let args_ast = vec::append(
|
||||
~[cx.arg_mode(cx.ident_of(~"pipe"),
|
||||
~[cx.arg(cx.ident_of(~"pipe"),
|
||||
cx.ty_path_ast_builder(
|
||||
path(~[this.data_name()], span)
|
||||
.add_tys(cx.ty_vars(this.ty_params))),
|
||||
ast::by_copy)],
|
||||
.add_tys(cx.ty_vars(this.ty_params))))],
|
||||
args_ast);
|
||||
|
||||
let message_args = if arg_names.len() == 0 {
|
||||
|
|
|
|||
|
|
@ -127,14 +127,14 @@ fn consume_non_eol_whitespace(rdr: string_reader) {
|
|||
}
|
||||
}
|
||||
|
||||
fn push_blank_line_comment(rdr: string_reader, &comments: ~[cmnt]) {
|
||||
fn push_blank_line_comment(rdr: string_reader, comments: &mut ~[cmnt]) {
|
||||
debug!(">>> blank-line comment");
|
||||
let v: ~[~str] = ~[];
|
||||
comments.push({style: blank_line, lines: v, pos: rdr.chpos});
|
||||
}
|
||||
|
||||
fn consume_whitespace_counting_blank_lines(rdr: string_reader,
|
||||
&comments: ~[cmnt]) {
|
||||
comments: &mut ~[cmnt]) {
|
||||
while is_whitespace(rdr.curr) && !is_eof(rdr) {
|
||||
if rdr.col == 0u && rdr.curr == '\n' {
|
||||
push_blank_line_comment(rdr, comments);
|
||||
|
|
@ -145,7 +145,7 @@ fn consume_whitespace_counting_blank_lines(rdr: string_reader,
|
|||
|
||||
|
||||
fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
|
||||
&comments: ~[cmnt]) {
|
||||
comments: &mut ~[cmnt]) {
|
||||
debug!(">>> shebang comment");
|
||||
let p = rdr.chpos;
|
||||
debug!("<<< shebang comment");
|
||||
|
|
@ -157,7 +157,7 @@ fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
|
|||
}
|
||||
|
||||
fn read_line_comments(rdr: string_reader, code_to_the_left: bool,
|
||||
&comments: ~[cmnt]) {
|
||||
comments: &mut ~[cmnt]) {
|
||||
debug!(">>> line comments");
|
||||
let p = rdr.chpos;
|
||||
let mut lines: ~[~str] = ~[];
|
||||
|
|
@ -188,8 +188,8 @@ fn all_whitespace(s: ~str, begin: uint, end: uint) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
|
||||
s: ~str, col: uint) unsafe {
|
||||
fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
|
||||
s: ~str, col: uint) {
|
||||
let mut s1;
|
||||
let len = str::len(s);
|
||||
if all_whitespace(s, 0u, uint::min(len, col)) {
|
||||
|
|
@ -202,7 +202,7 @@ fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
|
|||
}
|
||||
|
||||
fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
|
||||
&comments: ~[cmnt]) {
|
||||
comments: &mut ~[cmnt]) {
|
||||
debug!(">>> block comment");
|
||||
let p = rdr.chpos;
|
||||
let mut lines: ~[~str] = ~[];
|
||||
|
|
@ -228,7 +228,7 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
|
|||
debug!("=== block comment level %d", level);
|
||||
if is_eof(rdr) {(rdr as reader).fatal(~"unterminated block comment");}
|
||||
if rdr.curr == '\n' {
|
||||
trim_whitespace_prefix_and_push_line(lines, curr_line, col);
|
||||
trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
|
||||
curr_line = ~"";
|
||||
bump(rdr);
|
||||
} else {
|
||||
|
|
@ -248,8 +248,8 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
|
|||
}
|
||||
}
|
||||
}
|
||||
if str::len(curr_line) != 0u {
|
||||
trim_whitespace_prefix_and_push_line(lines, curr_line, col);
|
||||
if str::len(curr_line) != 0 {
|
||||
trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
|
||||
}
|
||||
let mut style = if code_to_the_left { trailing } else { isolated };
|
||||
consume_non_eol_whitespace(rdr);
|
||||
|
|
@ -267,7 +267,7 @@ fn peeking_at_comment(rdr: string_reader) -> bool {
|
|||
}
|
||||
|
||||
fn consume_comment(rdr: string_reader, code_to_the_left: bool,
|
||||
&comments: ~[cmnt]) {
|
||||
comments: &mut ~[cmnt]) {
|
||||
debug!(">>> consume comment");
|
||||
if rdr.curr == '/' && nextch(rdr) == '/' {
|
||||
read_line_comments(rdr, code_to_the_left, comments);
|
||||
|
|
@ -299,11 +299,11 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
|
|||
consume_non_eol_whitespace(rdr);
|
||||
if rdr.curr == '\n' {
|
||||
code_to_the_left = false;
|
||||
consume_whitespace_counting_blank_lines(rdr, comments);
|
||||
consume_whitespace_counting_blank_lines(rdr, &mut comments);
|
||||
}
|
||||
while peeking_at_comment(rdr) {
|
||||
consume_comment(rdr, code_to_the_left, comments);
|
||||
consume_whitespace_counting_blank_lines(rdr, comments);
|
||||
consume_comment(rdr, code_to_the_left, &mut comments);
|
||||
consume_whitespace_counting_blank_lines(rdr, &mut comments);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ type ctx =
|
|||
fn eval_crate_directives(cx: ctx,
|
||||
cdirs: ~[@ast::crate_directive],
|
||||
prefix: &Path,
|
||||
&view_items: ~[@ast::view_item],
|
||||
&items: ~[@ast::item]) {
|
||||
view_items: &mut~[@ast::view_item],
|
||||
items: &mut~[@ast::item]) {
|
||||
for cdirs.each |sub_cdir| {
|
||||
eval_crate_directive(cx, *sub_cdir, prefix, view_items, items);
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ fn eval_crate_directives_to_mod(cx: ctx, cdirs: ~[@ast::crate_directive],
|
|||
= parse_companion_mod(cx, prefix, suffix);
|
||||
let mut view_items: ~[@ast::view_item] = ~[];
|
||||
let mut items: ~[@ast::item] = ~[];
|
||||
eval_crate_directives(cx, cdirs, prefix, view_items, items);
|
||||
eval_crate_directives(cx, cdirs, prefix, &mut view_items, &mut items);
|
||||
return ({view_items: vec::append(view_items, cview_items),
|
||||
items: vec::append(items, citems)},
|
||||
cattrs);
|
||||
|
|
@ -82,8 +82,8 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
|
|||
}
|
||||
|
||||
fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
|
||||
&view_items: ~[@ast::view_item],
|
||||
&items: ~[@ast::item]) {
|
||||
view_items: &mut ~[@ast::view_item],
|
||||
items: &mut ~[@ast::item]) {
|
||||
match cdir.node {
|
||||
ast::cdir_src_mod(vis, id, attrs) => {
|
||||
let file_path = Path(cdir_path_opt(
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ pub enum ObsoleteSyntax {
|
|||
ObsoleteClassMethod,
|
||||
ObsoleteClassTraits,
|
||||
ObsoletePrivSection,
|
||||
ObsoleteModeInFnType
|
||||
ObsoleteModeInFnType,
|
||||
ObsoleteByMutRefMode
|
||||
}
|
||||
|
||||
impl ObsoleteSyntax : cmp::Eq {
|
||||
|
|
@ -94,6 +95,10 @@ impl parser : ObsoleteReporter {
|
|||
"to use a (deprecated) mode in a fn type, you should \
|
||||
give the argument an explicit name (like `&&v: int`)"
|
||||
),
|
||||
ObsoleteByMutRefMode => (
|
||||
"by-mutable-reference mode",
|
||||
"Declare an argument of type &mut T instead"
|
||||
),
|
||||
};
|
||||
|
||||
self.report(sp, kind, kind_str, desc);
|
||||
|
|
|
|||
|
|
@ -20,13 +20,13 @@ use obsolete::{
|
|||
ObsoleteLowerCaseKindBounds, ObsoleteLet,
|
||||
ObsoleteFieldTerminator, ObsoleteStructCtor,
|
||||
ObsoleteWith, ObsoleteClassMethod, ObsoleteClassTraits,
|
||||
ObsoleteModeInFnType
|
||||
ObsoleteModeInFnType, ObsoleteByMutRefMode
|
||||
};
|
||||
use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
|
||||
bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move,
|
||||
bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
|
||||
bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
|
||||
by_move, by_mutbl_ref, by_ref, by_val, capture_clause,
|
||||
by_move, by_ref, by_val, capture_clause,
|
||||
capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
|
||||
class_immutable, class_mutable,
|
||||
crate, crate_cfg, crate_directive, decl, decl_item, decl_local,
|
||||
|
|
@ -570,7 +570,10 @@ impl parser {
|
|||
|
||||
fn parse_arg_mode() -> mode {
|
||||
if self.eat(token::BINOP(token::AND)) {
|
||||
expl(by_mutbl_ref)
|
||||
self.obsolete(copy self.span,
|
||||
ObsoleteByMutRefMode);
|
||||
// Bogus mode, but doesn't matter since it's an error
|
||||
expl(by_ref)
|
||||
} else if self.eat(token::BINOP(token::MINUS)) {
|
||||
expl(by_move)
|
||||
} else if self.eat(token::ANDAND) {
|
||||
|
|
@ -1275,7 +1278,8 @@ impl parser {
|
|||
|
||||
return match self.token {
|
||||
token::LPAREN | token::LBRACE | token::LBRACKET => {
|
||||
let ket = token::flip_delimiter(self.token);
|
||||
// tjc: ??????
|
||||
let ket = token::flip_delimiter(copy self.token);
|
||||
tt_delim(vec::append(
|
||||
~[parse_tt_tok(self, true)],
|
||||
vec::append(
|
||||
|
|
@ -1296,7 +1300,8 @@ impl parser {
|
|||
return match self.token {
|
||||
token::LBRACE | token::LPAREN | token::LBRACKET => {
|
||||
self.parse_matcher_subseq(name_idx, copy self.token,
|
||||
token::flip_delimiter(self.token))
|
||||
// tjc: not sure why we need a copy
|
||||
token::flip_delimiter(copy self.token))
|
||||
}
|
||||
_ => self.fatal(~"expected open delimiter")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ pure fn can_begin_expr(t: token) -> bool {
|
|||
}
|
||||
|
||||
/// what's the opposite delimiter?
|
||||
fn flip_delimiter(&t: token::token) -> token::token {
|
||||
fn flip_delimiter(t: token::token) -> token::token {
|
||||
match t {
|
||||
token::LPAREN => token::RPAREN,
|
||||
token::LBRACE => token::RBRACE,
|
||||
|
|
|
|||
|
|
@ -1688,7 +1688,6 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl,
|
|||
|
||||
fn mode_to_str(m: ast::mode) -> ~str {
|
||||
match m {
|
||||
ast::expl(ast::by_mutbl_ref) => ~"&",
|
||||
ast::expl(ast::by_move) => ~"-",
|
||||
ast::expl(ast::by_ref) => ~"&&",
|
||||
ast::expl(ast::by_val) => ~"++",
|
||||
|
|
|
|||
2
src/llvm
2
src/llvm
|
|
@ -1 +1 @@
|
|||
Subproject commit c51053bf71de475df6a91204acd9ad78f4747c38
|
||||
Subproject commit dc4cdbf052288794ac418f310e7f5cfa609f5902
|
||||
|
|
@ -67,11 +67,6 @@ command_line_args : public kernel_owned<command_line_args>
|
|||
}
|
||||
};
|
||||
|
||||
// A global that indicates whether Rust typestate claim statements should be
|
||||
// executed Generated code will read this variable directly (I think).
|
||||
// FIXME (#2670): This belongs somewhere else
|
||||
int check_claims = 0;
|
||||
|
||||
void* global_crate_map = NULL;
|
||||
|
||||
/**
|
||||
|
|
@ -94,9 +89,6 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
|
|||
|
||||
update_log_settings(crate_map, env->logspec);
|
||||
|
||||
// Maybe turn on typestate claim checking
|
||||
check_claims = env->check_claims;
|
||||
|
||||
rust_kernel *kernel = new rust_kernel(env);
|
||||
|
||||
// Create the main scheduler and the main task
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#define RUST_MIN_STACK "RUST_MIN_STACK"
|
||||
#define RUST_MAX_STACK "RUST_MAX_STACK"
|
||||
#define RUST_LOG "RUST_LOG"
|
||||
#define CHECK_CLAIMS "CHECK_CLAIMS"
|
||||
#define DETAILED_LEAKS "DETAILED_LEAKS"
|
||||
#define RUST_SEED "RUST_SEED"
|
||||
#define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE"
|
||||
|
|
@ -114,7 +113,6 @@ load_env(int argc, char **argv) {
|
|||
env->min_stack_size = get_min_stk_size();
|
||||
env->max_stack_size = get_max_stk_size();
|
||||
env->logspec = copyenv(RUST_LOG);
|
||||
env->check_claims = getenv(CHECK_CLAIMS) != NULL;
|
||||
env->detailed_leaks = getenv(DETAILED_LEAKS) != NULL;
|
||||
env->rust_seed = copyenv(RUST_SEED);
|
||||
env->poison_on_free = getenv(RUST_POISON_ON_FREE) != NULL;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ struct rust_env {
|
|||
size_t min_stack_size;
|
||||
size_t max_stack_size;
|
||||
char* logspec;
|
||||
bool check_claims;
|
||||
bool detailed_leaks;
|
||||
char* rust_seed;
|
||||
bool poison_on_free;
|
||||
|
|
|
|||
|
|
@ -69,10 +69,6 @@ extern "C" {
|
|||
#define FASTCALL
|
||||
#endif
|
||||
|
||||
/* Controls whether claims are turned into checks */
|
||||
/* Variable name must be kept consistent with trans.rs */
|
||||
extern "C" int check_claims;
|
||||
|
||||
#define CHECKED(call) \
|
||||
{ \
|
||||
int res = (call); \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
check_claims
|
||||
debug_box
|
||||
debug_fn
|
||||
debug_opaque
|
||||
|
|
|
|||
|
|
@ -22,15 +22,15 @@ use syntax::diagnostic;
|
|||
use rustc::driver::session;
|
||||
use rustc::middle::lint;
|
||||
|
||||
fn version(argv0: ~str) {
|
||||
fn version(argv0: &str) {
|
||||
let mut vers = ~"unknown version";
|
||||
let env_vers = env!("CFG_VERSION");
|
||||
if str::len(env_vers) != 0u { vers = env_vers; }
|
||||
if env_vers.len() != 0 { vers = env_vers; }
|
||||
io::println(fmt!("%s %s", argv0, vers));
|
||||
io::println(fmt!("host: %s", host_triple()));
|
||||
}
|
||||
|
||||
fn usage(argv0: ~str) {
|
||||
fn usage(argv0: &str) {
|
||||
io::println(fmt!("Usage: %s [options] <input>\n", argv0) +
|
||||
~"
|
||||
Options:
|
||||
|
|
@ -86,7 +86,7 @@ fn describe_warnings() {
|
|||
let lint_dict = lint::get_lint_dict();
|
||||
let mut max_key = 0;
|
||||
for lint_dict.each_key |k| { max_key = uint::max(k.len(), max_key); }
|
||||
fn padded(max: uint, s: ~str) -> ~str {
|
||||
fn padded(max: uint, s: &str) -> ~str {
|
||||
str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s
|
||||
}
|
||||
io::println(fmt!("\nAvailable lint checks:\n"));
|
||||
|
|
@ -117,14 +117,14 @@ fn describe_debug_flags() {
|
|||
}
|
||||
}
|
||||
|
||||
fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) {
|
||||
fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
|
||||
// Don't display log spew by default. Can override with RUST_LOG.
|
||||
logging::console_off();
|
||||
|
||||
let mut args = args;
|
||||
let mut args = *args;
|
||||
let binary = args.shift();
|
||||
|
||||
if vec::len(args) == 0u { usage(binary); return; }
|
||||
if args.is_empty() { usage(binary); return; }
|
||||
|
||||
let matches =
|
||||
match getopts::getopts(args, opts()) {
|
||||
|
|
@ -229,7 +229,7 @@ bug and need to present an error.
|
|||
*/
|
||||
fn monitor(+f: fn~(diagnostic::emitter)) {
|
||||
let p = comm::Port();
|
||||
let ch = comm::Chan(p);
|
||||
let ch = comm::Chan(&p);
|
||||
|
||||
match do task::try |move f| {
|
||||
|
||||
|
|
@ -277,9 +277,10 @@ fn monitor(+f: fn~(diagnostic::emitter)) {
|
|||
}
|
||||
}
|
||||
|
||||
fn main(args: ~[~str]) {
|
||||
do monitor |demitter| {
|
||||
run_compiler(args, demitter);
|
||||
fn main() {
|
||||
let mut args = os::args();
|
||||
do monitor |move args, demitter| {
|
||||
run_compiler(&args, demitter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -415,34 +415,12 @@ fn mk_test_wrapper(cx: test_ctxt,
|
|||
}
|
||||
|
||||
fn mk_main(cx: test_ctxt) -> @ast::item {
|
||||
let str_pt = path_node(~[cx.sess.ident_of(~"str")]);
|
||||
let str_ty_inner = @{id: cx.sess.next_node_id(),
|
||||
node: ast::ty_path(str_pt, cx.sess.next_node_id()),
|
||||
span: dummy_sp()};
|
||||
let str_ty = @{id: cx.sess.next_node_id(),
|
||||
node: ast::ty_uniq({ty: str_ty_inner, mutbl: ast::m_imm}),
|
||||
span: dummy_sp()};
|
||||
let args_mt = {ty: str_ty, mutbl: ast::m_imm};
|
||||
let args_ty_inner = @{id: cx.sess.next_node_id(),
|
||||
node: ast::ty_vec(args_mt),
|
||||
span: dummy_sp()};
|
||||
let args_ty = {id: cx.sess.next_node_id(),
|
||||
node: ast::ty_uniq({ty: args_ty_inner, mutbl: ast::m_imm}),
|
||||
span: dummy_sp()};
|
||||
|
||||
|
||||
let args_arg: ast::arg =
|
||||
{mode: ast::expl(ast::by_val),
|
||||
ty: @args_ty,
|
||||
ident: cx.sess.ident_of(~"args"),
|
||||
id: cx.sess.next_node_id()};
|
||||
|
||||
let ret_ty = {id: cx.sess.next_node_id(),
|
||||
node: ast::ty_nil,
|
||||
span: dummy_sp()};
|
||||
|
||||
let decl: ast::fn_decl =
|
||||
{inputs: ~[args_arg],
|
||||
{inputs: ~[],
|
||||
output: @ret_ty,
|
||||
cf: ast::return_val};
|
||||
|
||||
|
|
@ -465,9 +443,11 @@ fn mk_main(cx: test_ctxt) -> @ast::item {
|
|||
}
|
||||
|
||||
fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
|
||||
|
||||
// Get the args passed to main so we can pass the to test_main
|
||||
let args_path = path_node(~[cx.sess.ident_of(~"args")]);
|
||||
// Call os::args to generate the vector of test_descs
|
||||
let args_path = path_node(~[
|
||||
cx.sess.ident_of(~"os"),
|
||||
cx.sess.ident_of(~"args")
|
||||
]);
|
||||
|
||||
let args_path_expr_: ast::expr_ = ast::expr_path(args_path);
|
||||
|
||||
|
|
@ -475,6 +455,12 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
|
|||
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
|
||||
node: args_path_expr_, span: dummy_sp()};
|
||||
|
||||
let args_call_expr_ = ast::expr_call(@args_path_expr, ~[], false);
|
||||
|
||||
let args_call_expr: ast::expr =
|
||||
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
|
||||
node: args_call_expr_, span: dummy_sp()};
|
||||
|
||||
// Call __test::test to generate the vector of test_descs
|
||||
let test_path = path_node(~[cx.sess.ident_of(~"tests")]);
|
||||
|
||||
|
|
@ -503,7 +489,7 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
|
|||
|
||||
let test_main_call_expr_: ast::expr_ =
|
||||
ast::expr_call(@test_main_path_expr,
|
||||
~[@args_path_expr, @test_call_expr], false);
|
||||
~[@args_call_expr, @test_call_expr], false);
|
||||
|
||||
let test_main_call_expr: ast::expr =
|
||||
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export metadata_encoding_version;
|
|||
export def_to_str;
|
||||
export encode_ctxt;
|
||||
export write_type;
|
||||
export write_vstore;
|
||||
export encode_def_id;
|
||||
|
||||
type abbrev_map = map::HashMap<ty::t, tyencode::ty_abbrev>;
|
||||
|
|
@ -116,7 +117,7 @@ fn encode_mutability(ebml_w: ebml::Writer, mt: class_mutability) {
|
|||
type entry<T> = {val: T, pos: uint};
|
||||
|
||||
fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: &[ident],
|
||||
&index: ~[entry<~str>], name: ident) {
|
||||
index: &mut ~[entry<~str>], name: ident) {
|
||||
let mut full_path = ~[];
|
||||
full_path.push_all(path);
|
||||
full_path.push(name);
|
||||
|
|
@ -180,6 +181,16 @@ fn write_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
|
|||
tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
|
||||
}
|
||||
|
||||
fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml::Writer, vstore: ty::vstore) {
|
||||
let ty_str_ctxt =
|
||||
@{diag: ecx.diag,
|
||||
ds: def_to_str,
|
||||
tcx: ecx.tcx,
|
||||
reachable: |a| reachable(ecx, a),
|
||||
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
|
||||
tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
|
||||
}
|
||||
|
||||
fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
|
||||
ebml_w.start_tag(tag_items_data_item_type);
|
||||
write_type(ecx, ebml_w, typ);
|
||||
|
|
|
|||
|
|
@ -394,7 +394,6 @@ fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
|
|||
|
||||
fn parse_mode(st: @pstate) -> ast::mode {
|
||||
let m = ast::expl(match next(st) {
|
||||
'&' => ast::by_mutbl_ref,
|
||||
'-' => ast::by_move,
|
||||
'+' => ast::by_copy,
|
||||
'=' => ast::by_ref,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export enc_ty;
|
|||
export enc_bounds;
|
||||
export enc_mode;
|
||||
export enc_arg;
|
||||
export enc_vstore;
|
||||
|
||||
type ctxt = {
|
||||
diag: span_handler,
|
||||
|
|
@ -332,7 +333,6 @@ fn enc_arg(w: io::Writer, cx: @ctxt, arg: ty::arg) {
|
|||
|
||||
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('-'),
|
||||
by_copy => w.write_char('+'),
|
||||
by_ref => w.write_char('='),
|
||||
|
|
|
|||
|
|
@ -490,8 +490,11 @@ impl method_origin: tr {
|
|||
typeck::method_param(mp) => {
|
||||
typeck::method_param({trait_id:mp.trait_id.tr(xcx),.. mp})
|
||||
}
|
||||
typeck::method_trait(did, m) => {
|
||||
typeck::method_trait(did.tr(xcx), m)
|
||||
typeck::method_trait(did, m, vstore) => {
|
||||
typeck::method_trait(did.tr(xcx), m, vstore)
|
||||
}
|
||||
typeck::method_self(did, m) => {
|
||||
typeck::method_self(did.tr(xcx), m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -631,6 +634,7 @@ impl @e::encode_ctxt: get_ty_str_ctxt {
|
|||
trait ebml_writer_helpers {
|
||||
fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg);
|
||||
fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t);
|
||||
fn emit_vstore(ecx: @e::encode_ctxt, vstore: ty::vstore);
|
||||
fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]);
|
||||
fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds);
|
||||
fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty);
|
||||
|
|
@ -643,6 +647,12 @@ impl ebml::Writer: ebml_writer_helpers {
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_vstore(ecx: @e::encode_ctxt, vstore: ty::vstore) {
|
||||
do self.emit_opaque {
|
||||
e::write_vstore(ecx, self, vstore)
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg) {
|
||||
do self.emit_opaque {
|
||||
tyencode::enc_arg(self.writer, ecx.ty_str_ctxt(), arg);
|
||||
|
|
|
|||
|
|
@ -396,10 +396,10 @@ type req_maps = {
|
|||
pure_map: HashMap<ast::node_id, bckerr>
|
||||
};
|
||||
|
||||
fn save_and_restore<T:Copy,U>(&save_and_restore_t: T, f: fn() -> U) -> U {
|
||||
let old_save_and_restore_t = save_and_restore_t;
|
||||
fn save_and_restore<T:Copy,U>(save_and_restore_t: &mut T, f: fn() -> U) -> U {
|
||||
let old_save_and_restore_t = *save_and_restore_t;
|
||||
let u <- f();
|
||||
save_and_restore_t = old_save_and_restore_t;
|
||||
*save_and_restore_t = old_save_and_restore_t;
|
||||
move u
|
||||
}
|
||||
|
||||
|
|
|
|||
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