Merge remote-tracking branch 'original/incoming' into incoming

This commit is contained in:
Simon BD 2012-10-06 13:15:18 -05:00
commit 0e3bec0ced
222 changed files with 2009 additions and 1665 deletions

View file

@ -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
View file

@ -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=

View file

@ -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;
}

View file

@ -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);
~~~~~~~~

View file

@ -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".

View file

@ -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;

View file

@ -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;
}
}
~~~~

View file

@ -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 $@

View file

@ -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) \

View file

@ -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:

View file

@ -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 {

View file

@ -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);

View file

@ -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")

View file

@ -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;

View file

@ -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) {

View file

@ -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); }

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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;
}

View file

@ -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>>;

View file

@ -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;

View file

@ -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

View file

@ -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";

View file

@ -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.
*

View file

@ -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;

View file

@ -4,6 +4,9 @@ Basic input/output
*/
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
use result::Result;
use cmp::Eq;

View file

@ -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};

View file

@ -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

View file

@ -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;

View file

@ -1,5 +1,8 @@
// Core operators and kinds.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];
#[lang="const"]
pub trait Const {
// Empty.

View file

@ -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;
}

View file

@ -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)
}

View file

@ -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();

View file

@ -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));
}

View file

@ -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 {

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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));

View file

@ -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;

View file

@ -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;

View file

@ -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, ());
}

View file

@ -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) { }

View file

@ -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> {

View file

@ -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, ());
}

View file

@ -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;

View file

@ -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)

View file

@ -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.

View file

@ -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);

View file

@ -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)
}
}

View file

@ -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 };
}

View file

@ -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.

View file

@ -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)
}
}

View file

@ -1,4 +1,4 @@
// tjc: forbid deprecated modes again after snap
#[forbid(deprecated_mode)];
//! Unsafe debugging functions for inspecting values.
use cast::reinterpret_cast;

View file

@ -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);

View file

@ -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;
}

View file

@ -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)
}

View file

@ -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) => {

View file

@ -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);

View file

@ -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)

View file

@ -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)
}
*/

View file

@ -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))

View file

@ -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 {

View file

@ -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)
}
}

View file

@ -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))

View file

@ -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| {

View file

@ -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)
}

View file

@ -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;

View file

@ -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) };

View file

@ -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;

View file

@ -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 }
}

View file

@ -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);

View file

@ -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));

View file

@ -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), || {

View file

@ -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);

View file

@ -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)) {

View file

@ -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) {

View file

@ -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,

View file

@ -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 {

View file

@ -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;
}

View file

@ -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(

View file

@ -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);

View file

@ -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")
}

View file

@ -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,

View file

@ -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) => ~"++",

@ -1 +1 @@
Subproject commit c51053bf71de475df6a91204acd9ad78f4747c38
Subproject commit dc4cdbf052288794ac418f310e7f5cfa609f5902

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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); \

View file

@ -1,4 +1,3 @@
check_claims
debug_box
debug_fn
debug_opaque

View file

@ -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);
}
}

View file

@ -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(),

View file

@ -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);

View file

@ -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,

View file

@ -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('='),

View file

@ -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);

View file

@ -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