1
Fork 0

more testing fallout from core->std/std->extra move

This commit is contained in:
Ted Horst 2013-05-23 15:06:29 -05:00
parent 6e2b082adc
commit 34cfd2183b
7 changed files with 147 additions and 145 deletions

View file

@ -17,14 +17,14 @@ This document does not serve as a tutorial introduction to the
language. Background familiarity with the language is assumed. A separate
[tutorial] document is available to help acquire such background familiarity.
This document also does not serve as a reference to the [core] or [standard]
This document also does not serve as a reference to the [standard] or [extra]
libraries included in the language distribution. Those libraries are
documented separately by extracting documentation attributes from their
source code.
[tutorial]: tutorial.html
[core]: core/index.html
[standard]: std/index.html
[extra]: extra/index.html
## Disclaimer
@ -441,7 +441,7 @@ expression context, the final namespace qualifier is omitted.
Two examples of paths with type arguments:
~~~~
# use core::hashmap::HashMap;
# use std::hashmap::HashMap;
# fn f() {
# fn id<T:Copy>(t: T) -> T { t }
type t = HashMap<int,~str>; // Type arguments used in a type expression
@ -768,9 +768,9 @@ Three examples of `extern mod` declarations:
~~~~~~~~{.xfail-test}
extern mod pcre (uuid = "54aba0f8-a7b1-4beb-92f1-4cf625264841");
extern mod std; // equivalent to: extern mod std ( name = "std" );
extern mod extra; // equivalent to: extern mod extra ( name = "extra" );
extern mod ruststd (name = "std"); // linking to 'std' under another name
extern mod rustextra (name = "extra"); // linking to 'extra' under another name
~~~~~~~~
##### Use declarations
@ -802,19 +802,19 @@ Use declarations support a number of convenient shortcuts:
An example of `use` declarations:
~~~~
use core::float::sin;
use core::str::{slice, contains};
use core::option::Some;
use std::float::sin;
use std::str::{slice, contains};
use std::option::Some;
fn main() {
// Equivalent to 'info!(core::float::sin(1.0));'
// Equivalent to 'info!(std::float::sin(1.0));'
info!(sin(1.0));
// Equivalent to 'info!(core::option::Some(1.0));'
// Equivalent to 'info!(std::option::Some(1.0));'
info!(Some(1.0));
// Equivalent to
// 'info!(core::str::contains(core::str::slice("foo", 0, 1), "oo"));'
// 'info!(std::str::contains(std::str::slice("foo", 0, 1), "oo"));'
info!(contains(slice("foo", 0, 1), "oo"));
}
~~~~
@ -1327,7 +1327,7 @@ with the exception that they may not have a body
and are instead terminated by a semicolon.
~~~
# use core::libc::{c_char, FILE};
# use std::libc::{c_char, FILE};
# #[nolink]
extern {
@ -1436,7 +1436,7 @@ Some primitive Rust operations are defined in Rust code,
rather than being implemented directly in C or assembly language.
The definitions of these operations have to be easy for the compiler to find.
The `lang` attribute makes it possible to declare these operations.
For example, the `str` module in the Rust core library defines the string equality function:
For example, the `str` module in the Rust standard library defines the string equality function:
~~~ {.xfail-test}
#[lang="str_eq"]
@ -1562,7 +1562,7 @@ impl<T: Eq> Eq for Foo<T> {
Supported traits for `deriving` are:
* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`.
* Serialization: `Encodable`, `Decodable`. These require `std`.
* Serialization: `Encodable`, `Decodable`. These require `extra`.
* `Clone` and `DeepClone`, to perform (deep) copies.
* `IterBytes`, to iterate over the bytes in a data type.
* `Rand`, to create a random instance of a data type.
@ -1885,25 +1885,25 @@ Binary operators expressions are given in terms of
#### Arithmetic operators
Binary arithmetic expressions are syntactic sugar for calls to built-in traits,
defined in the `core::ops` module of the `core` library.
defined in the `std::ops` module of the `std` library.
This means that arithmetic operators can be overridden for user-defined types.
The default meaning of the operators on standard types is given here.
`+`
: Addition and vector/string concatenation.
Calls the `add` method on the `core::ops::Add` trait.
Calls the `add` method on the `std::ops::Add` trait.
`-`
: Subtraction.
Calls the `sub` method on the `core::ops::Sub` trait.
Calls the `sub` method on the `std::ops::Sub` trait.
`*`
: Multiplication.
Calls the `mul` method on the `core::ops::Mul` trait.
Calls the `mul` method on the `std::ops::Mul` trait.
`/`
: Quotient.
Calls the `div` method on the `core::ops::Div` trait.
Calls the `div` method on the `std::ops::Div` trait.
`%`
: Remainder.
Calls the `rem` method on the `core::ops::Rem` trait.
Calls the `rem` method on the `std::ops::Rem` trait.
#### Bitwise operators
@ -1914,19 +1914,19 @@ The default meaning of the operators on standard types is given here.
`&`
: And.
Calls the `bitand` method of the `core::ops::BitAnd` trait.
Calls the `bitand` method of the `std::ops::BitAnd` trait.
`|`
: Inclusive or.
Calls the `bitor` method of the `core::ops::BitOr` trait.
Calls the `bitor` method of the `std::ops::BitOr` trait.
`^`
: Exclusive or.
Calls the `bitxor` method of the `core::ops::BitXor` trait.
Calls the `bitxor` method of the `std::ops::BitXor` trait.
`<<`
: Logical left shift.
Calls the `shl` method of the `core::ops::Shl` trait.
Calls the `shl` method of the `std::ops::Shl` trait.
`>>`
: Logical right shift.
Calls the `shr` method of the `core::ops::Shr` trait.
Calls the `shr` method of the `std::ops::Shr` trait.
#### Lazy boolean operators
@ -1947,22 +1947,22 @@ The default meaning of the operators on standard types is given here.
`==`
: Equal to.
Calls the `eq` method on the `core::cmp::Eq` trait.
Calls the `eq` method on the `std::cmp::Eq` trait.
`!=`
: Unequal to.
Calls the `ne` method on the `core::cmp::Eq` trait.
Calls the `ne` method on the `std::cmp::Eq` trait.
`<`
: Less than.
Calls the `lt` method on the `core::cmp::Ord` trait.
Calls the `lt` method on the `std::cmp::Ord` trait.
`>`
: Greater than.
Calls the `gt` method on the `core::cmp::Ord` trait.
Calls the `gt` method on the `std::cmp::Ord` trait.
`<=`
: Less than or equal.
Calls the `le` method on the `core::cmp::Ord` trait.
Calls the `le` method on the `std::cmp::Ord` trait.
`>=`
: Greater than or equal.
Calls the `ge` method on the `core::cmp::Ord` trait.
Calls the `ge` method on the `std::cmp::Ord` trait.
#### Type cast expressions
@ -2121,11 +2121,11 @@ then the expression completes.
Some examples of call expressions:
~~~~
# use core::from_str::FromStr::from_str;
# use std::from_str::FromStr;
# fn add(x: int, y: int) -> int { 0 }
let x: int = add(1, 2);
let pi = from_str::<f32>("3.14");
let pi = FromStr::from_str::<f32>("3.14");
~~~~
### Lambda expressions
@ -3168,7 +3168,7 @@ execute, after which it is *descheduled* at a loop-edge or similar
preemption point, and another task within is scheduled, pseudo-randomly.
An executing task can yield control at any time, by making a library call to
`core::task::yield`, which deschedules it immediately. Entering any other
`std::task::yield`, which deschedules it immediately. Entering any other
non-executing state (blocked, dead) similarly deschedules the task.
@ -3181,7 +3181,7 @@ run-time. It is smaller and simpler than many modern language runtimes. It is
tightly integrated into the language's execution model of memory, tasks,
communication and logging.
> **Note:** The runtime library will merge with the `core` library in future versions of Rust.
> **Note:** The runtime library will merge with the `std` library in future versions of Rust.
### Memory allocation

View file

@ -12,7 +12,7 @@ The following is a minimal example of calling a foreign function which will comp
installed:
~~~~ {.xfail-test}
use core::libc::size_t;
use std::libc::size_t;
#[link_args = "-lsnappy"]
extern {
@ -42,7 +42,7 @@ runtime.
The `extern` block can be extended to cover the entire snappy API:
~~~~ {.xfail-test}
use core::libc::{c_int, size_t};
use std::libc::{c_int, size_t};
#[link_args = "-lsnappy"]
extern {
@ -149,9 +149,9 @@ A type with the same functionality as owned boxes can be implemented by
wrapping `malloc` and `free`:
~~~~
use core::libc::{c_void, size_t, malloc, free};
use core::unstable::intrinsics;
use core::util;
use std::libc::{c_void, size_t, malloc, free};
use std::unstable::intrinsics;
use std::util;
// a wrapper around the handle returned by the foreign code
pub struct Unique<T> {
@ -161,7 +161,7 @@ pub struct Unique<T> {
pub impl<T: Owned> Unique<T> {
fn new(value: T) -> Unique<T> {
unsafe {
let ptr = malloc(core::sys::size_of::<T>() as size_t) as *mut T;
let ptr = malloc(std::sys::size_of::<T>() as size_t) as *mut T;
assert!(!ptr::is_null(ptr));
// `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
intrinsics::move_val_init(&mut *ptr, value);

View file

@ -39,40 +39,40 @@ data through the global _exchange heap_.
While Rust's type system provides the building blocks needed for safe
and efficient tasks, all of the task functionality itself is implemented
in the core and standard libraries, which are still under development
in the standard and extra libraries, which are still under development
and do not always present a consistent or complete interface.
For your reference, these are the standard modules involved in Rust
concurrency at this writing:
* [`core::task`] - All code relating to tasks and task scheduling,
* [`core::comm`] - The message passing interface,
* [`core::pipes`] - The underlying messaging infrastructure,
* [`std::comm`] - Additional messaging types based on `core::pipes`,
* [`std::sync`] - More exotic synchronization tools, including locks,
* [`std::arc`] - The ARC (atomically reference counted) type,
* [`std::task`] - All code relating to tasks and task scheduling,
* [`std::comm`] - The message passing interface,
* [`std::pipes`] - The underlying messaging infrastructure,
* [`extra::comm`] - Additional messaging types based on `std::pipes`,
* [`extra::sync`] - More exotic synchronization tools, including locks,
* [`extra::arc`] - The ARC (atomically reference counted) type,
for safely sharing immutable data,
* [`std::future`] - A type representing values that may be computed concurrently and retrieved at a later time.
* [`extra::future`] - A type representing values that may be computed concurrently and retrieved at a later time.
[`core::task`]: core/task.html
[`core::comm`]: core/comm.html
[`core::pipes`]: core/pipes.html
[`std::task`]: std/task.html
[`std::comm`]: std/comm.html
[`std::sync`]: std/sync.html
[`std::arc`]: std/arc.html
[`std::future`]: std/future.html
[`std::pipes`]: std/pipes.html
[`extra::comm`]: extra/comm.html
[`extra::sync`]: extra/sync.html
[`extra::arc`]: extra/arc.html
[`extra::future`]: extra/future.html
# Basics
The programming interface for creating and managing tasks lives
in the `task` module of the `core` library, and is thus available to all
in the `task` module of the `std` library, and is thus available to all
Rust code by default. At its simplest, creating a task is a matter of
calling the `spawn` function with a closure argument. `spawn` executes the
closure in the new task.
~~~~
# use core::io::println;
# use core::task::spawn;
# use std::io::println;
# use std::task::spawn;
// Print something profound in a different task using a named function
fn print_message() { println("I am running in a different task!"); }
@ -90,7 +90,7 @@ do spawn {
In Rust, there is nothing special about creating tasks: a task is not a
concept that appears in the language semantics. Instead, Rust's type system
provides all the tools necessary to implement safe concurrency: particularly,
_owned types_. The language leaves the implementation details to the core
_owned types_. The language leaves the implementation details to the standard
library.
The `spawn` function has a very simple type signature: `fn spawn(f:
@ -101,8 +101,8 @@ execution. Like any closure, the function passed to `spawn` may capture
an environment that it carries across tasks.
~~~
# use core::io::println;
# use core::task::spawn;
# use std::io::println;
# use std::task::spawn;
# fn generate_task_number() -> int { 0 }
// Generate some state locally
let child_task_number = generate_task_number();
@ -118,8 +118,8 @@ in parallel. Thus, on a multicore machine, running the following code
should interleave the output in vaguely random order.
~~~
# use core::io::print;
# use core::task::spawn;
# use std::io::print;
# use std::task::spawn;
for int::range(0, 20) |child_task_number| {
do spawn {
@ -147,8 +147,8 @@ endpoint. Consider the following example of calculating two results
concurrently:
~~~~
# use core::task::spawn;
# use core::comm::{stream, Port, Chan};
# use std::task::spawn;
# use std::comm::{stream, Port, Chan};
let (port, chan): (Port<int>, Chan<int>) = stream();
@ -169,7 +169,7 @@ stream for sending and receiving integers (the left-hand side of the `let`,
a tuple into its component parts).
~~~~
# use core::comm::{stream, Chan, Port};
# use std::comm::{stream, Chan, Port};
let (port, chan): (Port<int>, Chan<int>) = stream();
~~~~
@ -178,8 +178,8 @@ which will wait to receive the data on the port. The next statement
spawns the child task.
~~~~
# use core::task::spawn;
# use core::comm::stream;
# use std::task::spawn;
# use std::comm::stream;
# fn some_expensive_computation() -> int { 42 }
# let (port, chan) = stream();
do spawn || {
@ -199,7 +199,7 @@ computation, then waits for the child's result to arrive on the
port:
~~~~
# use core::comm::{stream};
# use std::comm::{stream};
# fn some_other_expensive_computation() {}
# let (port, chan) = stream::<int>();
# chan.send(0);
@ -214,8 +214,8 @@ example needed to compute multiple results across a number of tasks? The
following program is ill-typed:
~~~ {.xfail-test}
# use core::task::{spawn};
# use core::comm::{stream, Port, Chan};
# use std::task::{spawn};
# use std::comm::{stream, Port, Chan};
# fn some_expensive_computation() -> int { 42 }
let (port, chan) = stream();
@ -234,8 +234,8 @@ Instead we can use a `SharedChan`, a type that allows a single
`Chan` to be shared by multiple senders.
~~~
# use core::task::spawn;
# use core::comm::{stream, SharedChan};
# use std::task::spawn;
# use std::comm::{stream, SharedChan};
let (port, chan) = stream();
let chan = SharedChan::new(chan);
@ -267,8 +267,8 @@ illustrate the point. For reference, written with multiple streams, it
might look like the example below.
~~~
# use core::task::spawn;
# use core::comm::stream;
# use std::task::spawn;
# use std::comm::stream;
// Create a vector of ports, one for each child task
let ports = do vec::from_fn(3) |init_val| {
@ -285,7 +285,7 @@ let result = ports.foldl(0, |accum, port| *accum + port.recv() );
~~~
## Futures
With `std::future`, rust has a mechanism for requesting a computation and getting the result
With `extra::future`, rust has a mechanism for requesting a computation and getting the result
later.
The basic example below illustrates this.
@ -296,7 +296,7 @@ fn fib(n: uint) -> uint {
12586269025
}
let mut delayed_fib = std::future::spawn (|| fib(50) );
let mut delayed_fib = extra::future::spawn (|| fib(50) );
make_a_sandwich();
println(fmt!("fib(50) = %?", delayed_fib.get()))
~~~
@ -319,7 +319,7 @@ fn partial_sum(start: uint) -> f64 {
}
fn main() {
let mut futures = vec::from_fn(1000, |ind| do std::future::spawn { partial_sum(ind) });
let mut futures = vec::from_fn(1000, |ind| do extra::future::spawn { partial_sum(ind) });
let mut final_res = 0f64;
for futures.each_mut |ft| {
@ -344,7 +344,7 @@ All tasks are, by default, _linked_ to each other. That means that the fates
of all tasks are intertwined: if one fails, so do all the others.
~~~
# use core::task::spawn;
# use std::task::spawn;
# fn do_some_work() { loop { task::yield() } }
# do task::try {
// Create a child task that fails
@ -384,7 +384,7 @@ enum. If the child task terminates successfully, `try` will
return an `Ok` result; if the child task fails, `try` will return
an `Error` result.
[`Result`]: core/result.html
[`Result`]: std/result.html
> ***Note:*** A failed task does not currently produce a useful error
> value (`try` always returns `Err(())`). In the
@ -428,8 +428,8 @@ internally, with additional logic to wait for the child task to finish
before returning. Hence:
~~~
# use core::comm::{stream, Chan, Port};
# use core::task::{spawn, try};
# use std::comm::{stream, Chan, Port};
# use std::task::{spawn, try};
# fn sleep_forever() { loop { task::yield() } }
# do task::try {
let (receiver, sender): (Port<int>, Chan<int>) = stream();
@ -493,7 +493,7 @@ fail!();
A very common thing to do is to spawn a child task where the parent
and child both need to exchange messages with each other. The
function `std::comm::DuplexStream()` supports this pattern. We'll
function `extra::comm::DuplexStream()` supports this pattern. We'll
look briefly at how to use it.
To see how `DuplexStream()` works, we will create a child task
@ -502,7 +502,7 @@ the string in response. The child terminates when it receives `0`.
Here is the function that implements the child task:
~~~~
# use std::comm::DuplexStream;
# use extra::comm::DuplexStream;
fn stringifier(channel: &DuplexStream<~str, uint>) {
let mut value: uint;
loop {
@ -524,8 +524,8 @@ response itself is simply the stringified version of the received value,
Here is the code for the parent task:
~~~~
# use core::task::spawn;
# use std::comm::DuplexStream;
# use std::task::spawn;
# use extra::comm::DuplexStream;
# fn stringifier(channel: &DuplexStream<~str, uint>) {
# let mut value: uint;
# loop {

View file

@ -730,7 +730,7 @@ fn point_from_direction(dir: Direction) -> Point {
Enum variants may also be structs. For example:
~~~~
# use core::float;
# use std::float;
# struct Point { x: float, y: float }
# fn square(x: float) -> float { x * x }
enum Shape {
@ -1366,11 +1366,11 @@ let exchange_crayons: ~str = ~"Black, BlizzardBlue, Blue";
~~~
Both vectors and strings support a number of useful
[methods](#functions-and-methods), defined in [`core::vec`]
and [`core::str`]. Here are some examples.
[methods](#functions-and-methods), defined in [`std::vec`]
and [`std::str`]. Here are some examples.
[`core::vec`]: core/vec.html
[`core::str`]: core/str.html
[`std::vec`]: std/vec.html
[`std::str`]: std/str.html
~~~
# enum Crayon {
@ -1583,7 +1583,7 @@ words, it is a function that takes an owned closure that takes no
arguments.
~~~~
use core::task::spawn;
use std::task::spawn;
do spawn() || {
debug!("I'm a task, whatever");
@ -1595,7 +1595,7 @@ lists back to back. Since that is so unsightly, empty argument lists
may be omitted from `do` expressions.
~~~~
# use core::task::spawn;
# use std::task::spawn;
do spawn {
debug!("Kablam!");
}
@ -1629,7 +1629,7 @@ fn each(v: &[int], op: &fn(v: &int) -> bool) {
And using this function to iterate over a vector:
~~~~
# use each = core::vec::each;
# use each = std::vec::each;
each([2, 4, 8, 5, 16], |n| {
if *n % 2 != 0 {
println("found odd number!");
@ -1645,7 +1645,7 @@ out of the loop, you just write `break`. To skip ahead
to the next iteration, write `loop`.
~~~~
# use each = core::vec::each;
# use each = std::vec::each;
for each([2, 4, 8, 5, 16]) |n| {
if *n % 2 != 0 {
println("found odd number!");
@ -1660,7 +1660,7 @@ normally allowed in closures, in a block that appears as the body of a
the enclosing function, not just the loop body.
~~~~
# use each = core::vec::each;
# use each = std::vec::each;
fn contains(v: &[int], elt: int) -> bool {
for each(v) |x| {
if (*x == elt) { return true; }
@ -1675,7 +1675,7 @@ In these situations it can be convenient to lean on Rust's
argument patterns to bind `x` to the actual value, not the pointer.
~~~~
# use each = core::vec::each;
# use each = std::vec::each;
# fn contains(v: &[int], elt: int) -> bool {
for each(v) |&x| {
if (x == elt) { return true; }
@ -1810,8 +1810,8 @@ impl Circle {
To call such a method, just prefix it with the type name and a double colon:
~~~~
# use core::float::consts::pi;
# use core::float::sqrt;
# use std::float::consts::pi;
# use std::float::sqrt;
struct Circle { radius: float }
impl Circle {
fn new(area: float) -> Circle { Circle { radius: sqrt(area / pi) } }
@ -1857,7 +1857,7 @@ illegal to copy and pass by value.
Generic `type`, `struct`, and `enum` declarations follow the same pattern:
~~~~
# use core::hashmap::HashMap;
# use std::hashmap::HashMap;
type Set<T> = HashMap<T, ()>;
struct Stack<T> {
@ -2081,8 +2081,8 @@ name and a double colon. The compiler uses type inference to decide which
implementation to use.
~~~~
# use core::float::consts::pi;
# use core::float::sqrt;
# use std::float::consts::pi;
# use std::float::sqrt;
trait Shape { fn new(area: float) -> Self; }
struct Circle { radius: float }
struct Square { length: float }
@ -2238,8 +2238,8 @@ trait Circle : Shape { fn radius(&self) -> float; }
Now, we can implement `Circle` on a type only if we also implement `Shape`.
~~~~
# use core::float::consts::pi;
# use core::float::sqrt;
# use std::float::consts::pi;
# use std::float::sqrt;
# trait Shape { fn area(&self) -> float; }
# trait Circle : Shape { fn radius(&self) -> float; }
# struct Point { x: float, y: float }
@ -2274,8 +2274,8 @@ fn radius_times_area<T: Circle>(c: T) -> float {
Likewise, supertrait methods may also be called on trait objects.
~~~ {.xfail-test}
# use core::float::consts::pi;
# use core::float::sqrt;
# use std::float::consts::pi;
# use std::float::sqrt;
# trait Shape { fn area(&self) -> float; }
# trait Circle : Shape { fn radius(&self) -> float; }
# struct Point { x: float, y: float }
@ -2292,7 +2292,7 @@ let nonsense = mycircle.radius() * mycircle.area();
## Deriving implementations for traits
A small number of traits in `core` and `std` can have implementations
A small number of traits in `std` and `std` can have implementations
that can be automatically derived. These instances are specified by
placing the `deriving` attribute on a data type declaration. For
example, the following will mean that `Circle` has an implementation
@ -2541,17 +2541,17 @@ as well as an inscrutable string of alphanumerics. These are both
part of Rust's library versioning scheme. The alphanumerics are
a hash representing the crate metadata.
## The core library
## The std library
The Rust core library provides runtime features required by the language,
The Rust std library provides runtime features required by the language,
including the task scheduler and memory allocators, as well as library
support for Rust built-in types, platform abstractions, and other commonly
used features.
[`core`] includes modules corresponding to each of the integer types, each of
[`std`] includes modules corresponding to each of the integer types, each of
the floating point types, the [`bool`] type, [tuples], [characters], [strings],
[vectors], [managed boxes], [owned boxes],
and unsafe and borrowed [pointers]. Additionally, `core` provides
and unsafe and borrowed [pointers]. Additionally, `std` provides
some pervasive types ([`option`] and [`result`]),
[task] creation and [communication] primitives,
platform abstractions ([`os`] and [`path`]), basic
@ -2561,47 +2561,47 @@ common traits ([`kinds`], [`ops`], [`cmp`], [`num`],
### Core injection and the Rust prelude
`core` is imported at the topmost level of every crate by default, as
`std` is imported at the topmost level of every crate by default, as
if the first line of each crate was
extern mod core;
extern mod std;
This means that the contents of core can be accessed from from any context
with the `core::` path prefix, as in `use core::vec`, `use core::task::spawn`,
This means that the contents of std can be accessed from from any context
with the `std::` path prefix, as in `use std::vec`, `use std::task::spawn`,
etc.
Additionally, `core` contains a `prelude` module that reexports many of the
most common core modules, types and traits. The contents of the prelude are
Additionally, `std` contains a `prelude` module that reexports many of the
most common std modules, types and traits. The contents of the prelude are
imported into every *module* by default. Implicitly, all modules behave as if
they contained the following prologue:
use core::prelude::*;
use std::prelude::*;
[`core`]: core/index.html
[`bool`]: core/bool.html
[tuples]: core/tuple.html
[characters]: core/char.html
[strings]: core/str.html
[vectors]: core/vec.html
[managed boxes]: core/managed.html
[owned boxes]: core/owned.html
[pointers]: core/ptr.html
[`option`]: core/option.html
[`result`]: core/result.html
[task]: core/task.html
[communication]: core/comm.html
[`os`]: core/os.html
[`path`]: core/path.html
[`io`]: core/io.html
[containers]: core/container.html
[`hashmap`]: core/hashmap.html
[`kinds`]: core/kinds.html
[`ops`]: core/ops.html
[`cmp`]: core/cmp.html
[`num`]: core/num.html
[`to_str`]: core/to_str.html
[`clone`]: core/clone.html
[`libc`]: core/libc.html
[`std`]: std/index.html
[`bool`]: std/bool.html
[tuples]: std/tuple.html
[characters]: std/char.html
[strings]: std/str.html
[vectors]: std/vec.html
[managed boxes]: std/managed.html
[owned boxes]: std/owned.html
[pointers]: std/ptr.html
[`option`]: std/option.html
[`result`]: std/result.html
[task]: std/task.html
[communication]: std/comm.html
[`os`]: std/os.html
[`path`]: std/path.html
[`io`]: std/io.html
[containers]: std/container.html
[`hashmap`]: std/hashmap.html
[`kinds`]: std/kinds.html
[`ops`]: std/ops.html
[`cmp`]: std/cmp.html
[`num`]: std/num.html
[`to_str`]: std/to_str.html
[`clone`]: std/clone.html
[`libc`]: std/libc.html
# What next?

View file

@ -57,8 +57,8 @@ while cur < len(lines):
if not ignore:
if not re.search(r"\bfn main\b", block):
block = "fn main() {\n" + block + "\n}\n"
if not re.search(r"\bextern mod std\b", block):
block = "extern mod std;\n" + block
if not re.search(r"\bextern mod extra\b", block):
block = "extern mod extra;\n" + block
block = """#[ forbid(ctypes) ];
#[ forbid(deprecated_pattern) ];
#[ forbid(implicit_copies) ];

View file

@ -431,6 +431,7 @@ pub fn main() {
#[cfg(test)]
mod tests {
use super::*;
use core::io;
fn repl() -> Repl {
Repl {

View file

@ -13,6 +13,7 @@
use context::Ctx;
use core::hashmap::HashMap;
use core::path::Path;
use core::prelude::*;
use std::tempfile::mkdtemp;
use util::{PkgId, default_version};
use path_util::{target_executable_in_workspace, target_library_in_workspace,