diff --git a/AUTHORS.txt b/AUTHORS.txt index b5970dd83d4e..e7fa662c603f 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -17,6 +17,7 @@ Ben Striegel Benjamin Herr Benjamin Jackman Benjamin Kircher +Benjamin Peterson Brendan Eich Brian Anderson Brian J. Burg @@ -66,6 +67,7 @@ Kevin Atkinson Kevin Cantu Lennart Kudling Lindsey Kuper +Luca Bruno Magnus Auvinen Margaret Meyerhofer Marijn Haverbeke @@ -76,6 +78,7 @@ Michael Bebenita Michael Sullivan Niko Matsakis Or Brostovski +Orphée Lafond-Lummis Patrick Walton Patrik Kårlin Paul Stansifer diff --git a/Makefile.in b/Makefile.in index fae389798ec7..a7594261c295 100644 --- a/Makefile.in +++ b/Makefile.in @@ -357,6 +357,15 @@ EXTRAFLAGS_STAGE$(1) = $$(RUSTFLAGS_STAGE$(1)) CFGFLAG$(1)_T_$(2)_H_$(3) = stage$(1) +# Pass --cfg stage0 only for the build->host part of stage0; +# if you're building a cross config, the host->* parts are +# effectively stage1, since it uses the just-built stage0. +ifeq ($(1),0) +ifneq ($(strip $(CFG_HOST_TRIPLE)),$(strip $(3))) +CFGFLAG$(1)_T_$(2)_H_$(3) = stage1 +endif +endif + STAGE$(1)_T_$(2)_H_$(3) := \ $$(Q)$$(call CFG_RUN_TARG,$(1), \ $$(CFG_VALGRIND_COMPILE$(1)) \ @@ -528,8 +537,8 @@ endif ifneq ($(findstring install,$(MAKECMDGOALS)),) ifdef DESTDIR - CFG_INFO := $(info cfg: setting CFG_PREFIX via DESTDIR, $(DESTDIR)) - CFG_PREFIX:=$(DESTDIR) + CFG_INFO := $(info cfg: setting CFG_PREFIX via DESTDIR, $(DESTDIR)/$(CFG_PREFIX)) + CFG_PREFIX:=$(DESTDIR)/$(CFG_PREFIX) export CFG_PREFIX endif diff --git a/RELEASES.txt b/RELEASES.txt index dbe7b723261b..8d8f9179f6f7 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -1,5 +1,5 @@ -Version 0.4 (September 2012) ----------------------------- +Version 0.4 (October 2012) +-------------------------- * ~1500 changes, numerous bugfixes @@ -8,13 +8,14 @@ Version 0.4 (September 2012) * Keyword removal: 'again', 'import', 'check', 'new', 'owned', 'send', 'of', 'with', 'to', 'class'. * Classes are replaced with simpler structs - * Method self types + * Explicit method self types * `ret` became `return` and `alt` became `match` * `import` is now `use`; `use is now `extern mod` * `extern mod { ... }` is now `extern { ... }` * `use mod` is the recommended way to import modules * `pub` and `priv` replace deprecated export lists * The syntax of `match` pattern arms now uses fat arrow (=>) + * `main` no longer accepts an args vector; use `os::args` instead * Semantics * Trait implementations are now coherent, ala Haskell typeclasses @@ -25,15 +26,13 @@ Version 0.4 (September 2012) * Typestate was removed * Resolution rewritten to be more reliable * Support for 'dual-mode' data structures (freezing and thawing) - * Last-use analysis is only used for warnings now. Moves must be explicit - for lvalues (TODO: confirm) * Libraries * Most binary operators can now be overloaded via the traits in `core::ops' * `std::net::url` for representing URLs * Sendable hash maps in `core::send_map` - * `core::task' gained a (currently very unsafe) task-local storage API + * `core::task' gained a (currently unsafe) task-local storage API * Concurrency * An efficient new intertask communication primitive called the pipe, @@ -52,8 +51,7 @@ Version 0.4 (September 2012) * Extensive architectural improvements to rustc * Begun a transition away from buggy C++-based reflection (shape) code to Rust-based (visitor) code - * Hash functions improved across the codebase (TODO: need details) - * New lint checks (TODO: which?) + * All hash functions and tables converted to secure, randomized SipHash Version 0.3 (July 2012) ------------------------ diff --git a/doc/rust.css b/doc/rust.css index 3e0988162d73..c49b0fee67ce 100644 --- a/doc/rust.css +++ b/doc/rust.css @@ -1,9 +1,11 @@ body { padding: 1em; margin: 0; + margin-bottom: 4em; font-family: "Helvetica Neue", Helvetica, sans-serif; background-color: white; color: black; + line-height: 1.6em; } body { @@ -12,12 +14,16 @@ body { } h1 { - font-size: 22pt; + font-size: 20pt; margin-top: 2em; - border-bottom: 2px solid silver; + border-bottom: 1px solid silver; + line-height: 1.6em; } -h2 { font-size: 17pt; } -h3 { font-size: 14pt; } +h2 { + font-size: 15pt; + margin-top: 2em; +} +h3 { font-size: 13pt; } pre { margin: 1.1em 0; @@ -27,7 +33,7 @@ pre { a, a:visited, a:link { text-decoration: none; - color: #00438a; + color: rgb(0, 105, 214); } h1 a:link, h1 a:visited, h2 a:link, h2 a:visited, @@ -54,20 +60,12 @@ h3 a:link, h3 a:visited { color: black; } .cm-s-default span.cm-tag {color: #170;} .cm-s-default span.cm-attribute {color: #00c;} -h1.title { - background-image: url('http://www.rust-lang.org/logos/rust-logo-32x32-blk.png'); - background-repeat: no-repeat; - background-position: right; -} - #versioninfo { position: fixed; bottom: 0px; right: 0px; background-color: white; - border-left: solid 1px black; - border-top: solid 1px black; padding: 0.5em; } @@ -99,3 +97,8 @@ td { #TOC ul ul { display: none; } + +#TOC ul { + list-style: none; + padding-left: 0px; +} \ No newline at end of file diff --git a/doc/rust.md b/doc/rust.md index fa9e160f73d2..5fd9622046ad 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -15,17 +15,16 @@ provides three kinds of material: 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 at -to help acquire such background familiarity. +[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 [core] or [standard] libraries included in the language distribution. Those libraries are documented separately by extracting documentation attributes from their -source code. Formatted documentation can be found at the following -locations: +source code. - - Core library: - - Standard library: +[tutorial]: tutorial.html +[core]: core/index.html +[standard]: std/index.html ## Disclaimer @@ -42,14 +41,17 @@ If you have suggestions to make, please try to focus them on *reductions* to the language: possible features that can be combined or omitted. We aim to keep the size and complexity of the language under control. -**Note on grammar:** The grammar for Rust given in this document is rough and -very incomplete; only a modest number of sections have accompanying grammar -rules. Formalizing the grammar accepted by the Rust parser is ongoing work, -but future versions of this document will contain a complete -grammar. Moreover, we hope that this grammar will be extracted and verified -as LL(1) by an automated grammar-analysis tool, and further tested against the -Rust sources. Preliminary versions of this automation exist, but are not yet -complete. +> **Note:** This manual is very out of date. The best source of Rust +> documentation is currently the tutorial. + +> **Note:** The grammar for Rust given in this document is rough and +> very incomplete; only a modest number of sections have accompanying grammar +> rules. Formalizing the grammar accepted by the Rust parser is ongoing work, +> but future versions of this document will contain a complete +> grammar. Moreover, we hope that this grammar will be extracted and verified +> as LL(1) by an automated grammar-analysis tool, and further tested against the +> Rust sources. Preliminary versions of this automation exist, but are not yet +> complete. # Notation @@ -118,19 +120,16 @@ production. See [tokens](#tokens) for more information. ## Input format -Rust input is interpreted as a sequence of Unicode codepoints encoded in -UTF-8. No normalization is performed during input processing. Most Rust -grammar rules are defined in terms of printable ASCII-range codepoints, but -a small number are defined in terms of Unicode properties or explicit -codepoint lists. ^[Surrogate definitions for the special Unicode productions -are provided to the grammar verifier, restricted to ASCII range, when -verifying the grammar in this document.] +Rust input is interpreted as a sequence of Unicode codepoints encoded in UTF-8, +normalized to Unicode normalization form NFKC. +Most Rust grammar rules are defined in terms of printable ASCII-range codepoints, +but a small number are defined in terms of Unicode properties or explicit codepoint lists. +^[Substitute definitions for the special Unicode productions are provided to the grammar verifier, restricted to ASCII range, when verifying the grammar in this document.] ## Special Unicode Productions -The following productions in the Rust grammar are defined in terms of -Unicode properties: `ident`, `non_null`, `non_star`, `non_eol`, `non_slash`, -`non_single_quote` and `non_double_quote`. +The following productions in the Rust grammar are defined in terms of Unicode properties: +`ident`, `non_null`, `non_star`, `non_eol`, `non_slash`, `non_single_quote` and `non_double_quote`. ### Identifiers @@ -203,26 +202,26 @@ grammar as double-quoted strings. Other tokens have exact rules given. The keywords in [crate files](#crate-files) are the following strings: ~~~~~~~~ {.keyword} -export use mod +mod priv pub use ~~~~~~~~ The keywords in [source files](#source-files) are the following strings: ~~~~~~~~ {.keyword} -again assert +as assert break -check const copy -drop -else enum export extern +const copy +do drop +else enum extern fail false fn for if impl let log loop -match mod mut -pure -return -struct +match mod move mut +priv pub pure +ref return +self static struct true trait type -unsafe +unsafe use while ~~~~~~~~ @@ -619,7 +618,7 @@ or a *configuration* in Mesa.] A crate file describes: and copyright. These are used for linking, versioning and distributing crates. * The source-file and directory modules that make up the crate. -* Any `use`, `extern mod` or `export` [view items](#view-items) that apply to +* Any `use` or `extern mod` [view items](#view-items) that apply to the anonymous module at the top-level of the crate's module tree. An example of a crate file: @@ -767,7 +766,7 @@ mod math { #### View items ~~~~~~~~ {.ebnf .gram} -view_item : extern_mod_decl | use_decl | export_decl ; +view_item : extern_mod_decl | use_decl ; ~~~~~~~~ A view item manages the namespace of a module; it does not define new items @@ -776,7 +775,6 @@ view item: * [extern mod declarations](#extern-mod-declarations) * [use declarations](#use-declarations) - * [export declarations](#export-declarations) ##### Extern mod declarations @@ -786,9 +784,8 @@ link_attrs : link_attr [ ',' link_attrs ] + ; link_attr : ident '=' literal ; ~~~~~~~~ -An _extern mod declaration_ specifies a dependency on an external crate. The -external crate is then imported into the declaring scope as the `ident` -provided in the `extern_mod_decl`. +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 runtime linkage requirement to that `soname` is passed to the linker for @@ -828,16 +825,16 @@ linkage-dependency with external crates. Linkage dependencies are independently declared with [`extern mod` declarations](#extern-mod-declarations). -Imports support a number of "convenience" notations: +Use declarations support a number of "convenience" notations: - * Importing as a different name than the imported name, using the + * Rebinding the target name as a new local name, using the syntax `use x = p::q::r;`. - * Importing a list of paths differing only in final element, using - the glob-like brace syntax `use a::b::{c,d,e,f};` - * Importing all paths matching a given prefix, using the glob-like - asterisk syntax `use a::b::*;` + * Simultaneously binding a list of paths differing only in final element, + using the glob-like brace syntax `use a::b::{c,d,e,f};` + * Binding all paths matching a given prefix, + using the glob-like asterisk syntax `use a::b::*;` -An example of imports: +An example of `use` declarations: ~~~~ use foo = core::info; @@ -858,82 +855,11 @@ fn main() { } ~~~~ -##### Export declarations - -~~~~~~~~ {.ebnf .gram} -export_decl : "export" ident [ ',' ident ] * - | "export" ident "::{}" - | "export" ident '{' ident [ ',' ident ] * '}' ; -~~~~~~~~ - -An _export declaration_ restricts the set of local names within a module that -can be accessed from code outside the module. By default, all _local items_ in -a module are exported; imported paths are not automatically re-exported by -default. If a module contains an explicit `export` declaration, this -declaration replaces the default export with the export specified. - -An example of an export: - -~~~~~~~~ -pub mod foo { - #[legacy_exports]; - export primary; - - fn primary() { - helper(1, 2); - helper(3, 4); - } - - fn helper(x: int, y: int) { - ... - } -} - -fn main() { - foo::primary(); // Will compile. -} -~~~~~~~~ - -If, instead of calling `foo::primary` in main, you were to call `foo::helper` -then it would fail to compile: - -~~~~~~~~{.ignore} - foo::helper(2,3) // ERROR: will not compile. -~~~~~~~~ - -Multiple names may be exported from a single export declaration: - -~~~~~~~~ -mod foo { - export primary, secondary; - - fn primary() { - helper(1, 2); - helper(3, 4); - } - - fn secondary() { - ... - } - - fn helper(x: int, y: int) { - ... - } -} -~~~~~~~~ - -When exporting the name of an `enum` type `t`, by default, the module does -*not* implicitly export any of `t`'s constructors. For example: - -~~~~~~~~ -mod foo { - export t; - - enum t {a, b, c} -} -~~~~~~~~ - -Here, `foo` imports `t`, but not `a`, `b`, and `c`. +Like items, `use` declarations are private to the containing module, by default. +Also like items, a `use` declaration can be public, if qualified by the `pub` keyword. +A public `use` declaration can therefore be used to _redirect_ some public name to a different target definition, +even a definition with a private canonical path, inside a different module. +If a sequence of such redirections form a cycle or cannot be unambiguously resolved, they represent a compile-time error. ### Functions @@ -1076,7 +1002,7 @@ pure fn pure_length(ls: List) -> uint { Despite its name, `pure_foldl` is a `fn`, not a `pure fn`, because there is no way in Rust to specify that the higher-order function argument `f` is a pure function. So, to use `foldl` in a pure list length function that a pure function -could then use, we must use an `unchecked` block wrapped around the call to +could then use, we must use an `unsafe` block wrapped around the call to `pure_foldl` in the definition of `pure_length`. #### Generic functions @@ -1092,7 +1018,7 @@ fn iter(seq: ~[T], f: fn(T)) { } fn map(seq: ~[T], f: fn(T) -> U) -> ~[U] { let mut acc = ~[]; - for seq.each |elt| { vec::push(acc, f(elt)); } + for seq.each |elt| { acc.push(f(elt)); } acc } ~~~~ @@ -1300,14 +1226,6 @@ impl circle: shape { } ~~~~ -This defines an implementation named `circle_shape` of trait -`shape` for type `circle`. The name of the implementation is the name -by which it is imported and exported, but has no further significance. -It may be omitted to default to the name of the trait that was -implemented. Implementation names do not conflict the way other names -do: multiple implementations with the same name may exist in a scope at -the same time. - It is possible to define an implementation without referring to a trait. The methods in such an implementation can only be used statically (as direct calls on the values of the type that the diff --git a/doc/tutorial-borrowed-ptr.md b/doc/tutorial-borrowed-ptr.md index 8def9762bce3..8b264a9d609d 100644 --- a/doc/tutorial-borrowed-ptr.md +++ b/doc/tutorial-borrowed-ptr.md @@ -4,7 +4,7 @@ Borrowed pointers are one of the more flexible and powerful tools available in Rust. A borrowed pointer can be used to point anywhere: -into the shared and exchange heaps, into the stack, and even into the +into the managed and exchange heaps, into the stack, and even into the interior of another data structure. With regard to flexibility, it is comparable to a C pointer or C++ reference. However, unlike C and C++, the Rust compiler includes special checks that ensure that borrowed @@ -29,10 +29,10 @@ a limit duration. Borrowed pointers never claim any kind of ownership over the data that they point at: instead, they are used for cases where you like to make use of data for a short time. -As an example, consider a simple record type `point`: +As an example, consider a simple struct type `Point`: ~~~ -type point = {x: float, y: float}; +struct Point {x: float, y: float} ~~~ We can use this simple definition to allocate points in many ways. For @@ -40,10 +40,10 @@ example, in this code, each of these three local variables contains a point, but allocated in a different place: ~~~ -# type point = {x: float, y: float}; -let on_the_stack : point = {x: 3.0, y: 4.0}; -let shared_box : @point = @{x: 5.0, y: 1.0}; -let unique_box : ~point = ~{x: 7.0, y: 9.0}; +# struct Point {x: float, y: float} +let on_the_stack : Point = Point {x: 3.0, y: 4.0}; +let shared_box : @Point = @Point {x: 5.0, y: 1.0}; +let unique_box : ~Point = ~Point {x: 7.0, y: 9.0}; ~~~ Suppose we wanted to write a procedure that computed the distance @@ -59,9 +59,9 @@ define a function that takes the points by pointer. We can use borrowed pointers to do this: ~~~ -# type point = {x: float, y: float}; +# struct Point {x: float, y: float} # fn sqrt(f: float) -> float { 0f } -fn compute_distance(p1: &point, p2: &point) -> float { +fn compute_distance(p1: &Point, p2: &Point) -> float { let x_d = p1.x - p2.x; let y_d = p1.y - p2.y; sqrt(x_d * x_d + y_d * y_d) @@ -71,26 +71,26 @@ fn compute_distance(p1: &point, p2: &point) -> float { Now we can call `compute_distance()` in various ways: ~~~ -# type point = {x: float, y: float}; -# let on_the_stack : point = {x: 3.0, y: 4.0}; -# let shared_box : @point = @{x: 5.0, y: 1.0}; -# let unique_box : ~point = ~{x: 7.0, y: 9.0}; -# fn compute_distance(p1: &point, p2: &point) -> float { 0f } +# struct Point {x: float, y: float} +# let on_the_stack : Point = Point{x: 3.0, y: 4.0}; +# let shared_box : @Point = @Point{x: 5.0, y: 1.0}; +# let unique_box : ~Point = ~Point{x: 7.0, y: 9.0}; +# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f } compute_distance(&on_the_stack, shared_box); compute_distance(shared_box, unique_box); ~~~ Here the `&` operator is used to take the address of the variable -`on_the_stack`; this is because `on_the_stack` has the type `point` -(that is, a record value) and we have to take its address to get a +`on_the_stack`; this is because `on_the_stack` has the type `Point` +(that is, a struct value) and we have to take its address to get a value. We also call this _borrowing_ the local variable `on_the_stack`, because we are created an alias: that is, another route to the same data. In the case of the boxes `shared_box` and `unique_box`, however, no explicit action is necessary. The compiler will automatically convert -a box like `@point` or `~point` to a borrowed pointer like -`&point`. This is another form of borrowing; in this case, the +a box like `@Point` or `~Point` to a borrowed pointer like +`&Point`. This is another form of borrowing; in this case, the contents of the shared/unique box is being lent out. Whenever a value is borrowed, there are some limitations on what you @@ -108,8 +108,8 @@ it again. In the previous example, the value `on_the_stack` was defined like so: ~~~ -# type point = {x: float, y: float}; -let on_the_stack : point = {x: 3.0, y: 4.0}; +# struct Point {x: float, y: float} +let on_the_stack: Point = Point {x: 3.0, y: 4.0}; ~~~ This results in a by-value variable. As a consequence, we had to @@ -118,20 +118,20 @@ pointer. Sometimes however it is more convenient to move the & operator into the definition of `on_the_stack`: ~~~ -# type point = {x: float, y: float}; -let on_the_stack2 : &point = &{x: 3.0, y: 4.0}; +# struct Point {x: float, y: float} +let on_the_stack2: &Point = &Point {x: 3.0, y: 4.0}; ~~~ Applying `&` to an rvalue (non-assignable location) is just a convenient shorthand for creating a temporary and taking its address: ~~~ -# type point = {x: float, y: float}; -let tmp = {x: 3.0, y: 4.0}; -let on_the_stack2 : &point = &tmp; +# struct Point {x: float, y: float} +let tmp = Point {x: 3.0, y: 4.0}; +let on_the_stack2 : &Point = &tmp; ~~~ -Taking the address of fields +# Taking the address of fields As in C, the `&` operator is not limited to taking the address of local variables. It can also be used to take the address of fields or @@ -139,39 +139,45 @@ individual array elements. For example, consider this type definition for `rectangle`: ~~~ -type point = {x: float, y: float}; // as before -type size = {w: float, h: float}; // as before -type rectangle = {origin: point, size: size}; +struct Point {x: float, y: float} // as before +struct Size {w: float, h: float} // as before +struct Rectangle {origin: Point, size: Size} ~~~ Now again I can define rectangles in a few different ways: ~~~ -let rect_stack = &{origin: {x: 1f, y: 2f}, size: {w: 3f, h: 4f}}; -let rect_shared = @{origin: {x: 3f, y: 4f}, size: {w: 3f, h: 4f}}; -let rect_unique = ~{origin: {x: 5f, y: 6f}, size: {w: 3f, h: 4f}}; +# struct Point {x: float, y: float} +# struct Size {w: float, h: float} // as before +# struct Rectangle {origin: Point, size: Size} +let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f}, + size: Size {w: 3f, h: 4f}}; +let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f}, + size: Size {w: 3f, h: 4f}}; +let rect_unique = ~Rectangle {origin: Point {x: 5f, y: 6f}, + size: Size {w: 3f, h: 4f}}; ~~~ In each case I can use the `&` operator to extact out individual subcomponents. For example, I could write: ~~~ -# type point = {x: float, y: float}; -# type size = {w: float, h: float}; // as before -# type rectangle = {origin: point, size: size}; -# let rect_stack = &{origin: {x: 1f, y: 2f}, size: {w: 3f, h: 4f}}; -# let rect_shared = @{origin: {x: 3f, y: 4f}, size: {w: 3f, h: 4f}}; -# let rect_unique = ~{origin: {x: 5f, y: 6f}, size: {w: 3f, h: 4f}}; -# fn compute_distance(p1: &point, p2: &point) -> float { 0f } -compute_distance(&rect_stack.origin, &rect_shared.origin); +# struct Point {x: float, y: float} // as before +# struct Size {w: float, h: float} // as before +# struct Rectangle {origin: Point, size: Size} +# let rect_stack = &{origin: Point {x: 1f, y: 2f}, size: Size {w: 3f, h: 4f}}; +# let rect_managed = @{origin: Point {x: 3f, y: 4f}, size: Size {w: 3f, h: 4f}}; +# let rect_unique = ~{origin: Point {x: 5f, y: 6f}, size: Size {w: 3f, h: 4f}}; +# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f } +compute_distance(&rect_stack.origin, &rect_managed.origin); ~~~ which would borrow the field `origin` from the rectangle on the stack -from the shared box and then compute the distance between them. +from the managed box and then compute the distance between them. -# Borrowing shared boxes and rooting +# Borrowing managed boxes and rooting -We’ve seen a few examples so far where heap boxes (both shared and +We’ve seen a few examples so far where heap boxes (both managed and unique) are borrowed. Up till this point, we’ve glossed over issues of safety. As stated in the introduction, at runtime a borrowed pointer is simply a pointer, nothing more. Therefore, if we wish to avoid the @@ -192,8 +198,9 @@ relatively easy, such as when taking the address of a local variable or a field that is stored on the stack: ~~~ +struct X { f: int } fn example1() { - let mut x = {f: 3}; + let mut x = X { f: 3 }; let y = &mut x.f; // -+ L ... // | } // -+ @@ -207,8 +214,9 @@ The situation gets more complex when borrowing data that resides in heap boxes: ~~~ +# struct X { f: int } fn example2() { - let mut x = @{f: 3}; + let mut x = @X { f: 3 }; let y = &x.f; // -+ L ... // | } // -+ @@ -218,20 +226,21 @@ In this example, the value `x` is in fact a heap box, and `y` is therefore a pointer into that heap box. Again the lifetime of `y` will be L, the remainder of the function body. But there is a crucial difference: suppose `x` were reassigned during the lifetime L? If -we’re not careful, that could mean that the shared box would become +we’re not careful, that could mean that the managed box would become unrooted and therefore be subject to garbage collection > ***Note:***In our current implementation, the garbage collector is > implemented using reference counting and cycle detection. -For this reason, whenever the interior of a shared box stored in a +For this reason, whenever the interior of a managed box stored in a mutable location is borrowed, the compiler will insert a temporary -that ensures that the shared box remains live for the entire +that ensures that the managed box remains live for the entire lifetime. So, the above example would be compiled as: ~~~ +# struct X { f: int } fn example2() { - let mut x = @{f: 3}; + let mut x = @X {f: 3}; let x1 = x; let y = &x1.f; // -+ L ... // | @@ -239,19 +248,19 @@ fn example2() { ~~~ Now if `x` is reassigned, the pointer `y` will still remain valid. This -process is called “rooting”. +process is called *rooting*. # Borrowing unique boxes -The previous example demonstrated `rooting`, the process by which the -compiler ensures that shared boxes remain live for the duration of a +The previous example demonstrated *rooting*, the process by which the +compiler ensures that managed boxes remain live for the duration of a borrow. Unfortunately, rooting does not work if the data being borrowed is a unique box, as it is not possible to have two references to a unique box. -For unique boxes, therefore, the compiler will only allow a borrow `if +For unique boxes, therefore, the compiler will only allow a borrow *if the compiler can guarantee that the unique box will not be reassigned -or moved for the lifetime of the pointer`. This does not necessarily +or moved for the lifetime of the pointer*. This does not necessarily mean that the unique box is stored in immutable memory. For example, the following function is legal: @@ -283,7 +292,7 @@ rejected by the compiler): ~~~ {.xfail-test} fn example3() -> int { - let mut x = ~{f: 3}; + let mut x = ~X {f: 3}; let y = &x.f; x = ~{f: 4}; // Error reported here. *y @@ -325,15 +334,18 @@ which has been freed. In fact, the compiler can apply this same kind of reasoning can be applied to any memory which is _(uniquely) owned by the stack frame_. So we could modify the previous example to introduce -additional unique pointers and records, and the compiler will still be +additional unique pointers and structs, and the compiler will still be able to detect possible mutations: ~~~ {.xfail-test} fn example3() -> int { - let mut x = ~{mut f: ~{g: 3}}; + struct R { g: int } + struct S { mut f: ~R } + + let mut x = ~S {mut f: ~R {g: 3}}; let y = &x.f.g; - x = ~{mut f: ~{g: 4}}; // Error reported here. - x.f = ~{g: 5}; // Error reported here. + x = ~S {mut f: ~R {g: 4}}; // Error reported here. + x.f = ~R {g: 5}; // Error reported here. *y } ~~~ @@ -346,17 +358,20 @@ Things get tricker when the unique box is not uniquely owned by the stack frame (or when the compiler doesn’t know who the owner is). Consider a program like this: -~~~ {.xfail-test} -fn example5a(x: @{mut f: ~{g: int}} ...) -> int { +~~~ +struct R { g: int } +struct S { mut f: ~R } +fn example5a(x: @S ...) -> int { let y = &x.f.g; // Error reported here. ... +# return 0; } ~~~ Here the heap looks something like: ~~~ {.notrust} - Stack Shared Heap Exchange Heap + Stack Managed Heap Exchange Heap x +------+ +-------------+ +------+ | @... | ----> | mut f: ~... | --+-> | g: 3 | @@ -368,7 +383,7 @@ Here the heap looks something like: In this case, the owning reference to the value being borrowed is in fact `x.f`. Moreover, `x.f` is both mutable and aliasable. Aliasable means that it is possible that there are other pointers to that same -shared box, so even if the compiler were to prevent `x.f` from being +managed box, so even if the compiler were to prevent `x.f` from being mutated, the field might still be changed through some alias of `x`. Therefore, to be safe, the compiler only accepts pure actions during the lifetime of `y`. We’ll have a final example on purity but @@ -379,7 +394,9 @@ unique found in aliasable memory is to ensure that it is stored within unique fields, as in the following example: ~~~ -fn example5b(x: @{f: ~{g: int}}) -> int { +struct R { g: int } +struct S { f: ~R } +fn example5b(x: @S) -> int { let y = &x.f.g; ... # return 0; @@ -394,21 +411,32 @@ If you do have a unique box in a mutable field, and you wish to borrow it, one option is to use the swap operator to bring that unique box onto your stack: -~~~ {.xfail-test} -fn example5c(x: @{mut f: ~int}) -> int { - let mut v = ~0; +~~~ +struct R { g: int } +struct S { mut f: ~R } +fn example5c(x: @S) -> int { + let mut v = ~R {g: 0}; v <-> x.f; // Swap v and x.f - let y = &v; - ... + { // Block constrains the scope of `y`: + let y = &v.g; + ... + } x.f <- v; // Replace x.f ... # return 0; } ~~~ -Of course, this has the side effect of modifying your shared box for -the duration of the borrow, so it works best when you know that you -won’t be accessing that same box again. +Of course, this has the side effect of modifying your managed box for +the duration of the borrow, so it only works when you know that you +won’t be accessing that same box for the duration of the loan. Note +also that sometimes it is necessary to introduce additional blocks to +constrain the scope of the loan. In this example, the borrowed +pointer `y` would still be in scope when you moved the value `v` back +into `x.f`, and hence moving `v` would be considered illegal. You +cannot move values if they are outstanding loans which are still +valid. By introducing the block, the scope of `y` is restricted and so +the move is legal. # Borrowing and enums @@ -422,11 +450,11 @@ As an example, let’s look at the following `shape` type that can represent both rectangles and circles: ~~~ -type point = {x: float, y: float}; // as before -type size = {w: float, h: float}; // as before -enum shape { - circle(point, float), // origin, radius - rectangle(point, size) // upper-left, dimensions +struct Point {x: float, y: float}; // as before +struct Size {w: float, h: float}; // as before +enum Shape { + Circle(Point, float), // origin, radius + Rectangle(Point, Size) // upper-left, dimensions } ~~~ @@ -435,17 +463,17 @@ function takes a borrowed pointer to a shape to avoid the need of copying them. ~~~ -# type point = {x: float, y: float}; // as before -# type size = {w: float, h: float}; // as before -# enum shape { -# circle(point, float), // origin, radius -# rectangle(point, size) // upper-left, dimensions +# struct Point {x: float, y: float}; // as before +# struct Size {w: float, h: float}; // as before +# enum Shape { +# Circle(Point, float), // origin, radius +# Rectangle(Point, Size) // upper-left, dimensions # } # const tau: float = 6.28f; -fn compute_area(shape: &shape) -> float { +fn compute_area(shape: &Shape) -> float { match *shape { - circle(_, radius) => 0.5 * tau * radius * radius, - rectangle(_, ref size) => size.w * size.h + Circle(_, radius) => 0.5 * tau * radius * radius, + Rectangle(_, ref size) => size.w * size.h } } ~~~ @@ -504,75 +532,82 @@ Stack Memory ~~~ As you can see, the `size` pointer would not be pointing at a `float` and -not a record. This is not good. +not a struct. This is not good. So, in fact, for every `ref` binding, the compiler will impose the same rules as the ones we saw for borrowing the interior of a unique box: it must be able to guarantee that the enum will not be overwritten for the duration of the borrow. In fact, the example I gave earlier would be considered safe. This is because the shape -pointer has type `&shape`, which means “borrowed pointer to immutable +pointer has type `&Shape`, which means “borrowed pointer to immutable memory containing a shape”. If however the type of that pointer were -`&const shape` or `&mut shape`, then the ref binding would not be +`&const Shape` or `&mut Shape`, then the ref binding would not be permitted. Just as with unique boxes, the compiler will permit ref bindings into data owned by the stack frame even if it is mutable, but otherwise it requires that the data reside in immutable memory. -> ***Note:*** Right now, all pattern bindings are by-reference. We -> expect this to change so that copies are the default and references -> must be noted explicitly. +> ***Note:*** Right now, pattern bindings not explicitly annotated +> with `ref` or `copy` use a special mode of "implicit by reference". +> This is changing as soon as we finish updating all the existing code +> in the compiler that relies on the current settings. # Returning borrowed pointers So far, all of the examples we’ve looked at use borrowed pointers in a “downward” direction. That is, the borrowed pointer is created and -then used during the method or code block which created it. In some -cases, it is also possible to return borrowed pointers to the caller, -but as we’ll see this is more limited. +then used during the method or code block which created it. It is also +possible to return borrowed pointers to the caller, but as we'll see +this requires some explicit annotation. For example, we could write a subroutine like this: -~~~ {.xfail-test} -type point = {x: float, y: float}; -fn get_x(p: &point) -> &float { &p.x } +~~~ +struct Point {x: float, y: float} +fn get_x(p: &r/Point) -> &r/float { &p.x } ~~~ Here, the function `get_x()` returns a pointer into the structure it was -given. You’ll note that _both_ the parameter and the return value are -borrowed pointers; this is important. In general, it is only possible -to return borrowed pointers if they are derived from a borrowed -pointer which was given as input to the procedure. +given. The type of the parameter (`&r/Point`) and return type (`&r/float`) both +make use of a new syntactic form that we have not seen so far. Here the identifier `r` +serves as an explicit name for the lifetime of the pointer. So in effect +this function is declaring that it takes in a pointer with lifetime `r` and returns +a pointer with that same lifetime. -In the example, `get_x()` took a borrowed pointer to a `point` as -input. In general, for all borrowed pointers that appear in the -signature of a function (such as the parameter and return types), the -compiler assigns the same symbolic lifetime L (we will see later that -there are ways to differentiate the lifetimes of different parameters -if that should be necessary). This means that, from the compiler’s -point of view, `get_x()` takes and returns two pointers with the same -lifetime. Now, unlike other lifetimes, this lifetime is a bit -abstract: it doesn’t refer to a specific expression within `get_x()`, -but rather to some expression within the caller. This is called a -_lifetime parameter_, because the lifetime L is effectively defined by -the caller to `get_x()`, just as the value for the parameter `p` is -defined by the caller. +In general, it is only possible to return borrowed pointers if they +are derived from a borrowed pointer which was given as input to the +procedure. In that case, they will always have the same lifetime as +one of the parameters; named lifetimes are used to indicate which +parameter that is. -In any case, whatever the lifetime L is, the pointer produced by +In the examples before, function parameter types did not include a +lifetime name. In this case, the compiler simply creates a new, +anonymous name, meaning that the parameter is assumed to have a +distinct lifetime from all other parameters. + +Named lifetimes that appear in function signatures are conceptually +the same as the other lifetimes we've seen before, but they are a bit +abstract: they don’t refer to a specific expression within `get_x()`, +but rather to some expression within the *caller of `get_x()`*. The +lifetime `r` is actually a kind of *lifetime parameter*: it is defined +by the caller to `get_x()`, just as the value for the parameter `p` is +defined by that caller. + +In any case, whatever the lifetime `r` is, the pointer produced by `&p.x` always has the same lifetime as `p` itself, as a pointer to a -field of a record is valid as long as the record is valid. Therefore, +field of a struct is valid as long as the struct is valid. Therefore, the compiler is satisfied with the function `get_x()`. To drill in this point, let’s look at a variation on the example, this time one which does not compile: ~~~ {.xfail-test} -type point = {x: float, y: float}; -fn get_x_sh(p: @point) -> &float { +struct Point {x: float, y: float} +fn get_x_sh(p: @Point) -> &float { &p.x // Error reported here } ~~~ -Here, the function `get_x_sh()` takes a shared box as input and +Here, the function `get_x_sh()` takes a managed box as input and returns a borrowed pointer. As before, the lifetime of the borrowed pointer that will be returned is a parameter (specified by the caller). That means that effectively `get_x_sh()` is promising to @@ -582,121 +617,114 @@ promised to return a pointer that was valid for as long as the pointer it was given. Within `get_x_sh()`, we see the expression `&p.x` which takes the -address of a field of a shared box. This implies that the compiler +address of a field of a managed box. This implies that the compiler must guarantee that, so long as the resulting pointer is valid, the -shared box will not be reclaimed by the garbage collector. But recall -that get_x_sh() also promised to return a pointer that was valid for +managed box will not be reclaimed by the garbage collector. But recall +that `get_x_sh()` also promised to return a pointer that was valid for as long as the caller wanted it to be. Clearly, `get_x_sh()` is not in a position to make both of these guarantees; in fact, it cannot guarantee that the pointer will remain valid at all once it returns, as the parameter `p` may or may not be live in the caller. Therefore, the compiler will report an error here. -In general, if you borrow a shared (or unique) box to create a +In general, if you borrow a managed (or unique) box to create a borrowed pointer, the pointer will only be valid within the function -and cannot be returned. Generally, the only way to return borrowed -pointers is to take borrowed pointers as input. +and cannot be returned. This is why the typical way to return borrowed +pointers is to take borrowed pointers as input (the only other case in +which it can be legal to return a borrowed pointer is if the pointer +points at a static constant). # Named lifetimes -So far we have always used the notation `&T` for a borrowed -pointer. However, sometimes if a function takes many parameters, it is -useful to be able to group those parameters by lifetime. For example, -consider this function: +Let's look at named lifetimes in more detail. In effect, the use of +named lifetimes allows you to group parameters by lifetime. For +example, consider this function: -~~~ {.xfail-test} -# type point = {x: float, y: float}; // as before -# type size = {w: float, h: float}; // as before -# enum shape { -# circle(point, float), // origin, radius -# rectangle(point, size) // upper-left, dimensions +~~~ +# struct Point {x: float, y: float}; // as before +# struct Size {w: float, h: float}; // as before +# enum Shape { +# Circle(Point, float), // origin, radius +# Rectangle(Point, Size) // upper-left, dimensions # } -# fn compute_area(shape: &shape) -> float { 0f } -fn select(shape: &shape, threshold: float, - a: &T, b: &T) -> &T { +# fn compute_area(shape: &Shape) -> float { 0f } +fn select(shape: &r/Shape, threshold: float, + a: &r/T, b: &r/T) -> &r/T { if compute_area(shape) > threshold {a} else {b} } ~~~ -This function takes three borrowed pointers. Because of the way that -the system works, each will be assigned the same lifetime: the default -lifetime parameter. In practice, this means that, in the caller, the -lifetime of the returned value will be the intersection of the -lifetime of the three region parameters. This may be overloy -conservative, as in this example: +This function takes three borrowed pointers and assigns each the same +lifetime `r`. In practice, this means that, in the caller, the +lifetime `r` will be the *intersection of the lifetime of the three +region parameters*. This may be overly conservative, as in this +example: -~~~ {.xfail-test} -# type point = {x: float, y: float}; // as before -# type size = {w: float, h: float}; // as before -# enum shape { -# circle(point, float), // origin, radius -# rectangle(point, size) // upper-left, dimensions +~~~ +# struct Point {x: float, y: float}; // as before +# struct Size {w: float, h: float}; // as before +# enum Shape { +# Circle(Point, float), // origin, radius +# Rectangle(Point, Size) // upper-left, dimensions # } -# fn compute_area(shape: &shape) -> float { 0f } -# fn select(shape: &shape, threshold: float, -# a: &T, b: &T) -> &T { +# fn compute_area(shape: &Shape) -> float { 0f } +# fn select(shape: &Shape, threshold: float, +# a: &r/T, b: &r/T) -> &r/T { # if compute_area(shape) > threshold {a} else {b} # } - - // -+ L -fn select_based_on_unit_circle( // |-+ B - threshold: float, a: &T, b: &T) -> &T { // | | - // | | - let shape = circle({x: 0, y: 0}, 1); // | | - select(&shape, threshold, a, b) // | | -} // |-+ - // -+ + // -+ r +fn select_based_on_unit_circle( // |-+ B + threshold: float, a: &r/T, b: &r/T) -> &r/T { // | | + // | | + let shape = Circle(Point {x: 0., y: 0.}, 1.); // | | + select(&shape, threshold, a, b) // | | +} // |-+ + // -+ ~~~ In this call to `select()`, the lifetime of the first parameter shape is B, the function body. Both of the second two parameters `a` and `b` -share the same lifetime, L, which is the lifetime parameter of +share the same lifetime, `r`, which is a lifetime parameter of `select_based_on_unit_circle()`. The caller will infer the -intersection of these three lifetimes as the lifetime of the returned +intersection of these two lifetimes as the lifetime of the returned value, and hence the return value of `shape()` will be assigned a -return value of B. This will in turn lead to a compilation error, -because `select_based_on_unit_circle()` is supposed to return a value -with the lifetime L. +lifetime of B. This will in turn lead to a compilation error, because +`select_based_on_unit_circle()` is supposed to return a value with the +lifetime `r`. -To address this, we could modify the definition of `select()` to +To address this, we can modify the definition of `select()` to distinguish the lifetime of the first parameter from the lifetime of the latter two. After all, the first parameter is not being -returned. To do so, we make use of the notation `</T`, which is a -borrowed pointer with an explicit lifetime. This effectively creates a -second lifetime parameter for the function; named lifetime parameters -do not need to be declared, you just use them. Here is how the new -`select()` might look: +returned. Here is how the new `select()` might look: -~~~ {.xfail-test} -# type point = {x: float, y: float}; // as before -# type size = {w: float, h: float}; // as before -# enum shape { -# circle(point, float), // origin, radius -# rectangle(point, size) // upper-left, dimensions +~~~ +# struct Point {x: float, y: float}; // as before +# struct Size {w: float, h: float}; // as before +# enum Shape { +# Circle(Point, float), // origin, radius +# Rectangle(Point, Size) // upper-left, dimensions # } -# fn compute_area(shape: &shape) -> float { 0f } -fn select(shape: &tmp/shape, threshold: float, - a: &T, b: &T) -> &T { +# fn compute_area(shape: &Shape) -> float { 0f } +fn select(shape: &tmp/Shape, threshold: float, + a: &r/T, b: &r/T) -> &r/T { if compute_area(shape) > threshold {a} else {b} } ~~~ Here you can see the lifetime of shape is now being called `tmp`. The -parameters `a`, `b`, and the return value all remain with the default -lifetime parameter. +parameters `a`, `b`, and the return value are all given the lifetime +`r`. However, since the lifetime `tmp` is not returned, it would be shorter +to just omit the named lifetime for `shape` altogether: -You could also write `select()` using all named lifetime parameters, -which might look like: - -~~~ {.xfail-test} -# type point = {x: float, y: float}; // as before -# type size = {w: float, h: float}; // as before -# enum shape { -# circle(point, float), // origin, radius -# rectangle(point, size) // upper-left, dimensions +~~~ +# struct Point {x: float, y: float}; // as before +# struct Size {w: float, h: float}; // as before +# enum Shape { +# Circle(Point, float), // origin, radius +# Rectangle(Point, Size) // upper-left, dimensions # } -# fn compute_area(shape: &shape) -> float { 0f } -fn select(shape: &tmp/shape, threshold: float, +# fn compute_area(shape: &Shape) -> float { 0f } +fn select(shape: &Shape, threshold: float, a: &r/T, b: &r/T) -> &r/T { if compute_area(shape) > threshold {a} else {b} } @@ -721,7 +749,9 @@ a unique box found in an aliasable, mutable location, only now we’ve replaced the `...` with some specific code: ~~~ -fn example5a(x: @{mut f: ~{g: int}} ...) -> int { +struct R { g: int } +struct S { mut f: ~R } +fn example5a(x: @S ...) -> int { let y = &x.f.g; // Unsafe *y + 1 } @@ -739,9 +769,11 @@ fn add_one(x: &int) -> int { *x + 1 } We can now update `example5a()` to use `add_one()`: -~~~ {.xfail-test} -# fn add_one(x: &int) -> int { *x + 1 } -fn example5a(x: @{mut f: ~{g: int}} ...) -> int { +~~~ +# struct R { g: int } +# struct S { mut f: ~R } +# pure fn add_one(x: &int) -> int { *x + 1 } +fn example5a(x: @S ...) -> int { let y = &x.f.g; add_one(y) // Error reported here } @@ -763,4 +795,4 @@ With this change, the modified version of `example5a()` will again compile. So there you have it. A (relatively) brief tour of borrowed pointer system. For more details, I refer to the (yet to be written) reference document on borrowed pointers, which will explain the full notation -and give more examples. \ No newline at end of file +and give more examples. diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index 42c5908b0497..463bd4746fee 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -1,4 +1,6 @@ -# Interacting with foreign code +% Rust Foreign Function Interface Tutorial + +# Introduction One of Rust's aims, as a system programming language, is to interoperate well with C code. @@ -38,7 +40,7 @@ fn main(args: ~[~str]) { } ~~~~ -## Foreign modules +# Foreign modules Before we can call `SHA1`, we have to declare it. That is what this part of the program is responsible for: @@ -68,7 +70,7 @@ extern mod something { } ~~~~ -## Foreign calling conventions +# Foreign calling conventions Most foreign code will be C code, which usually uses the `cdecl` calling convention, so that is what Rust uses by default when calling foreign @@ -88,7 +90,7 @@ The `"abi"` attribute applies to a foreign module (it can not be applied to a single function within a module), and must be either `"cdecl"` or `"stdcall"`. Other conventions may be defined in the future. -## Unsafe pointers +# Unsafe pointers The foreign `SHA1` function is declared to take three arguments, and return a pointer. @@ -118,7 +120,7 @@ caution—unlike Rust's other pointer types, unsafe pointers are completely unmanaged, so they might point at invalid memory, or be null pointers. -## Unsafe blocks +# Unsafe blocks The `sha1` function is the most obscure part of the program. @@ -159,7 +161,7 @@ unsafe fn kaboom() { ~"I'm harmless!"; } This function can only be called from an unsafe block or another unsafe function. -## Pointer fiddling +# Pointer fiddling The standard library defines a number of helper functions for dealing with unsafe data, casting between types, and generally subverting @@ -202,10 +204,10 @@ unsafe pointer that was returned by `SHA1`. SHA1 digests are always twenty bytes long, so we can pass `20u` for the length of the new vector. -## Passing structures +# Passing structures C functions often take pointers to structs as arguments. Since Rust -records are binary-compatible with C structs, Rust programs can call +structs are binary-compatible with C structs, Rust programs can call such functions directly. This program uses the POSIX function `gettimeofday` to get a @@ -215,15 +217,21 @@ microsecond-resolution timer. extern mod std; use libc::c_ulonglong; -type timeval = {mut tv_sec: c_ulonglong, - mut tv_usec: c_ulonglong}; +struct timeval { + mut tv_sec: c_ulonglong, + mut tv_usec: c_ulonglong +} + #[nolink] extern mod lib_c { fn gettimeofday(tv: *timeval, tz: *()) -> i32; } fn unix_time_in_microseconds() -> u64 unsafe { - let x = {mut tv_sec: 0 as c_ulonglong, mut tv_usec: 0 as c_ulonglong}; - lib_c::gettimeofday(ptr::addr_of(x), ptr::null()); + let x = timeval { + mut tv_sec: 0 as c_ulonglong, + mut tv_usec: 0 as c_ulonglong + }; + lib_c::gettimeofday(ptr::addr_of(&x), ptr::null()); return (x.tv_sec as u64) * 1000_000_u64 + (x.tv_usec as u64); } @@ -234,8 +242,8 @@ The `#[nolink]` attribute indicates that there's no foreign library to link in. The standard C library is already linked with Rust programs. A `timeval`, in C, is a struct with two 32-bit integers. Thus, we -define a record type with the same contents, and declare -`gettimeofday` to take a pointer to such a record. +define a struct type with the same contents, and declare +`gettimeofday` to take a pointer to such a struct. The second argument to `gettimeofday` (the time zone) is not used by this program, so it simply declares it to be a pointer to the nil diff --git a/doc/tutorial-macros.md b/doc/tutorial-macros.md index deb6252d0422..5cd5d79bd297 100644 --- a/doc/tutorial-macros.md +++ b/doc/tutorial-macros.md @@ -1,4 +1,6 @@ -# Macros +% Rust Macros Tutorial + +# Introduction Functions are the programmer's primary tool of abstraction, but there are cases in which they are insufficient, because the programmer wants to @@ -50,7 +52,7 @@ early_return!(input_2 special_b); Macros are defined in pattern-matching style: -## Invocation syntax +# Invocation syntax On the left-hand-side of the `=>` is the macro invocation syntax. It is free-form, excepting the following rules: @@ -69,7 +71,7 @@ rules of tokenization apply, So `($x:ident => (($e:expr)))`, though excessively fancy, would create a macro that could be invoked like `my_macro!(i=>(( 2+2 )))`. -## Transcription syntax +# Transcription syntax The right-hand side of the `=>` follows the same rules as the left-hand side, except that `$` need only be followed by the name of the syntactic fragment @@ -80,9 +82,9 @@ an expression; currently, user-defined macros can only be invoked in expression position (even though `macro_rules!` itself can be in item position). -## Multiplicity +# Multiplicity -### Invocation +## Invocation Going back to the motivating example, suppose that we wanted each invocation of `early_return` to potentially accept multiple "special" identifiers. The diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md index 2f540ef9ee6d..405f4ac73478 100644 --- a/doc/tutorial-tasks.md +++ b/doc/tutorial-tasks.md @@ -1,52 +1,165 @@ -% Tasks and communication in Rust +% Rust Tasks and Communication Tutorial -Rust supports a system of lightweight tasks, similar to what is found -in Erlang or other actor systems. Rust tasks communicate via messages -and do not share data. However, it is possible to send data without -copying it by making use of [the exchange heap](#unique-boxes), which -allow the sending task to release ownership of a value, so that the -receiving task can keep on using it. +# Introduction -> ***Note:*** As Rust evolves, we expect the task API to grow and -> change somewhat. The tutorial documents the API as it exists today. +The Rust language is designed from the ground up to support pervasive +and safe concurrency through lightweight, memory-isolated tasks and +message passing. -# Spawning a task +Rust tasks are not the same as traditional threads - they are what are +often referred to as _green threads_, cooperatively scheduled by the +Rust runtime onto a small number of operating system threads. Being +significantly cheaper to create than traditional threads, Rust can +create hundreds of thousands of concurrent tasks on a typical 32-bit +system. -Spawning a task is done using the various spawn functions in the -module `task`. Let's begin with the simplest one, `task::spawn()`: +Tasks provide failure isolation and recovery. When an exception occurs +in rust code (either by calling `fail` explicitly or by otherwise performing +an invalid operation) the entire task is destroyed - there is no way +to `catch` an exception as in other languages. Instead tasks may monitor +each other to detect when failure has occurred. + +Rust tasks have dynamically sized stacks. When a task is first created +it starts off with a small amount of stack (currently in the low +thousands of bytes, depending on platform) and more stack is acquired as +needed. A Rust task will never run off the end of the stack as is +possible in many other languages, but they do have a stack budget, and +if a Rust task exceeds its stack budget then it will fail safely. + +Tasks make use of Rust's type system to provide strong memory safety +guarantees, disallowing shared mutable state. Communication between +tasks is facilitated by the transfer of _owned_ data through the +global _exchange heap_. + +This tutorial will explain the basics of tasks and communication in Rust, +explore some typical patterns in concurrent Rust code, and finally +discuss some of the more exotic synchronization types in the standard +library. + +## A note about the libraries + +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 +and do not always present a consistent interface. + +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 +to `core::comm`. In this tutorial we will discuss `pipes` and ignore +the `comm` API. + +For your reference, these are the standard modules involved in Rust +concurrency at the moment. + +* [`core::task`] - All code relating to tasks and task scheduling +* [`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::arc`] - The ARC type, for safely sharing immutable data +* [`std::par`] - Some basic tools for implementing parallel algorithms + +[`core::task`]: core/task.html +[`core::comm`]: core/comm.html +[`core::pipes`]: core/pipes.html +[`std::comm`]: std/comm.html +[`std::sync`]: std/sync.html +[`std::arc`]: std/arc.html +[`std::par`]: std/par.html + +# Basics + +The programming interface for creating and managing tasks is contained +in the `task` module of the `core` library, making it available to all +Rust code by default. At it's simplest, creating a task is a matter of +calling the `spawn` function, passing a closure to run in the new +task. ~~~~ +# use io::println; use task::spawn; -use io::println; -let some_value = 22; +// Print something profound in a different task using a named function +fn print_message() { println("I am running in a different task!"); } +spawn(print_message); +// Print something more profound in a different task using a lambda expression +spawn( || println("I am also running in a different task!") ); + +// The canonical way to spawn is using `do` notation do spawn { - println(~"This executes in the child task."); - println(fmt!("%d", some_value)); + println("I too am running in a different task!"); } ~~~~ -The argument to `task::spawn()` is a [unique -closure](#unique-closures) of type `fn~()`, meaning that it takes no -arguments and generates no return value. The effect of `task::spawn()` -is to fire up a child task that will execute the closure in parallel -with the creator. +In Rust, there is nothing special about creating tasks - the language +itself doesn't know what a 'task' is. Instead, Rust provides in the +type system all the tools necessary to implement safe concurrency, +_owned types_ in particular, and leaves the dirty work up to the +core library. -# Communication +The `spawn` function has a very simple type signature: `fn spawn(f: +~fn())`. Because it accepts only owned closures, and owned closures +contained only owned data, `spawn` can safely move the entire closure +and all its associated state into an entirely different task for +execution. Like any closure, the function passed to spawn may capture +an environment that it carries across tasks. -Now that we have spawned a child task, it would be nice if we could -communicate with it. This is done using *pipes*. Pipes are simply a -pair of endpoints, with one for sending messages and another for -receiving messages. The easiest way to create a pipe is to use -`pipes::stream`. Imagine we wish to perform two expensive -computations in parallel. We might write something like: +~~~ +# use io::println; +# use task::spawn; +# fn generate_task_number() -> int { 0 } +// Generate some state locally +let child_task_number = generate_task_number(); + +do spawn { + // Capture it in the remote task + println(fmt!("I am child number %d", child_task_number)); +} +~~~ + +By default tasks will be multiplexed across the available cores, running +in parallel, thus on a multicore machine, running the following code +should interleave the output in vaguely random order. + +~~~ +# use io::print; +# use task::spawn; + +for int::range(0, 20) |child_task_number| { + do spawn { + print(fmt!("I am child number %d\n", child_task_number)); + } +} +~~~ + +## Communication + +Now that we have spawned a new task, it would be nice if we could +communicate with it. Recall that Rust does not have shared mutable +state, so one task may not manipulate variables owned by another task. +Instead we use *pipes*. + +Pipes are simply a pair of endpoints, with one for sending messages +and another for receiving messages. Pipes are low-level communication +building-blocks and so come in a variety of forms, appropriate for +different use cases, but there are just a few varieties that are most +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 +endpoint. Consider the following example of performing two calculations +concurrently. ~~~~ use task::spawn; use pipes::{stream, Port, Chan}; -let (chan, port) = stream(); +let (chan, port): (Chan, Port) = stream(); do spawn { let result = some_expensive_computation(); @@ -55,43 +168,45 @@ do spawn { some_other_expensive_computation(); let result = port.recv(); - # fn some_expensive_computation() -> int { 42 } # fn some_other_expensive_computation() {} ~~~~ -Let's walk through this code line-by-line. The first line creates a -stream for sending and receiving integers: +Let's examine this example in detail. The `let` statement first creates a +stream for sending and receiving integers (recall that `let` can be +used for destructuring patterns, in this case separating a tuple into +its component parts). -~~~~ {.ignore} -# use pipes::stream; -let (chan, port) = stream(); +~~~~ +# use pipes::{stream, Chan, Port}; +let (chan, port): (Chan, Port) = stream(); ~~~~ -This port is where we will receive the message from the child task -once it is complete. The channel will be used by the child to send a -message to the port. The next statement actually spawns the child: +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 +spawns the child task. ~~~~ # use task::{spawn}; -# use comm::{Port, Chan}; +# use task::spawn; +# use pipes::{stream, Port, Chan}; # fn some_expensive_computation() -> int { 42 } -# let port = Port(); -# let chan = port.chan(); +# let (chan, port) = stream(); do spawn { let result = some_expensive_computation(); chan.send(result); } ~~~~ -This child will perform the expensive computation send the result -over the channel. (Under the hood, `chan` was captured by the -closure that forms the body of the child task. This capture is -allowed because channels are sendable.) +Notice that `chan` was transferred to the child task implicitly by +capturing it in the task closure. Both `Chan` and `Port` are sendable +types and may be captured into tasks or otherwise transferred between +them. In the example, the child task performs an expensive computation +then sends the result over the captured channel. -Finally, the parent continues by performing -some other expensive computation and then waiting for the child's result -to arrive on the port: +Finally, the parent continues by performing some other expensive +computation and then waiting for the child's result to arrive on the +port: ~~~~ # use pipes::{stream, Port, Chan}; @@ -102,7 +217,248 @@ some_other_expensive_computation(); let result = port.recv(); ~~~~ -# Creating a task with a bi-directional communication path +The `Port` and `Chan` pair created by `stream` enable efficient +communication between a single sender and a single receiver, but +multiple senders cannot use a single `Chan`, nor can multiple +receivers use a single `Port`. What if our example needed to perform +multiple computations across a number of tasks? The following cannot +be written: + +~~~ {.xfail-test} +# use task::{spawn}; +# use pipes::{stream, Port, Chan}; +# fn some_expensive_computation() -> int { 42 } +let (chan, port) = stream(); + +do spawn { + chan.send(some_expensive_computation()); +} + +// ERROR! The previous spawn statement already owns the channel, +// so the compiler will not allow it to be captured again +do spawn { + chan.send(some_expensive_computation()); +} +~~~ + +Instead we can use a `SharedChan`, a type that allows a single +`Chan` to be shared by multiple senders. + +~~~ +# use task::spawn; +use pipes::{stream, SharedChan}; + +let (chan, port) = stream(); +let chan = SharedChan(move chan); + +for uint::range(0, 3) |init_val| { + // Create a new channel handle to distribute to the child task + let child_chan = chan.clone(); + do spawn { + child_chan.send(some_expensive_computation(init_val)); + } +} + +let result = port.recv() + port.recv() + port.recv(); +# fn some_expensive_computation(_i: uint) -> int { 42 } +~~~ + +Here we transfer ownership of the channel into a new `SharedChan` +value. Like `Chan`, `SharedChan` is a non-copyable, owned type +(sometimes also referred to as an 'affine' or 'linear' type). Unlike +`Chan` though, `SharedChan` may be duplicated with the `clone()` +method. A cloned `SharedChan` produces a new handle to the same +channel, allowing multiple tasks to send data to a single port. +Between `spawn`, `stream` and `SharedChan` we have enough tools +to implement many useful concurrency patterns. + +Note that the above `SharedChan` example is somewhat contrived since +you could also simply use three `stream` pairs, but it serves to +illustrate the point. For reference, written with multiple streams it +might look like the example below. + +~~~ +# use task::spawn; +# use pipes::{stream, Port, Chan}; + +// Create a vector of ports, one for each child task +let ports = do vec::from_fn(3) |init_val| { + let (chan, port) = stream(); + do spawn { + chan.send(some_expensive_computation(init_val)); + } + port +}; + +// Wait on each port, accumulating the results +let result = ports.foldl(0, |accum, port| *accum + port.recv() ); +# fn some_expensive_computation(_i: uint) -> int { 42 } +~~~ + +# TODO + +# Handling task failure + +Rust has a built-in mechanism for raising exceptions, written `fail` +(or `fail ~"reason"`, or sometimes `assert expr`), and it causes the +task to unwind its stack, running destructors and freeing memory along +the way, and then exit itself. Unlike C++, exceptions in Rust are +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. + +~~~ +# use task::spawn; +# fn do_some_work() { loop { task::yield() } } +# do task::try { +// Create a child task that fails +do spawn { fail } + +// This will also fail because the task we spawned failed +do_some_work(); +# }; +~~~ + +While it isn't possible for a task to recover from failure, +tasks may be notified when _other_ tasks fail. The simplest way +of handling task failure is with the `try` function, which is +similar to spawn, but immediately blocks waiting for the child +task to finish. + +~~~ +# fn some_condition() -> bool { false } +# fn calculate_result() -> int { 0 } +let result: Result = do task::try { + if some_condition() { + calculate_result() + } else { + fail ~"oops!"; + } +}; +assert result.is_err(); +~~~ + +Unlike `spawn`, the function spawned using `try` may return a value, +which `try` will dutifully propagate back to the caller in a [`Result`] +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 + +> ***Note:*** A failed task does not currently produce a useful error +> value (all error results from `try` are equal to `Err(())`). In the +> future it may be possible for tasks to intercept the value passed to +> `fail`. + +TODO: Need discussion of `future_result` in order to make failure +modes useful. + +But not all failure is created equal. In some cases you might need to +abort the entire program (perhaps you're writing an assert which, if +it trips, indicates an unrecoverable logic error); in other cases you +might want to contain the failure at a certain boundary (perhaps a +small piece of input from the outside world, which you happen to be +processing in parallel, is malformed and its processing task can't +proceed). Hence the need for different _linked failure modes_. + +## Failure modes + +By default, task failure is _bidirectionally linked_, which means if +either task dies, it kills the other one. + +~~~ +# fn sleep_forever() { loop { task::yield() } } +# do task::try { +do task::spawn { + do task::spawn { + fail; // All three tasks will die. + } + sleep_forever(); // Will get woken up by force, then fail +} +sleep_forever(); // Will get woken up by force, then fail +# }; +~~~ + +If you want parent tasks to kill their children, but not for a child +task's failure to kill the parent, you can call +`task::spawn_supervised` for _unidirectionally linked_ failure. The +function `task::try`, which we saw previously, uses `spawn_supervised` +internally, with additional logic to wait for the child task to finish +before returning. Hence: + +~~~ +# use pipes::{stream, Chan, Port}; +# use task::{spawn, try}; +# fn sleep_forever() { loop { task::yield() } } +# do task::try { +let (sender, receiver): (Chan, Port) = stream(); +do spawn { // Bidirectionally linked + // Wait for the supervised child task to exist. + let message = receiver.recv(); + // Kill both it and the parent task. + assert message != 42; +} +do try { // Unidirectionally linked + sender.send(42); + sleep_forever(); // Will get woken up by force +} +// Flow never reaches here -- parent task was killed too. +# }; +~~~ + +Supervised failure is useful in any situation where one task manages +multiple fallible child tasks, and the parent task can recover +if any child files. On the other hand, if the _parent_ (supervisor) fails +then there is nothing the children can do to recover, so they should +also fail. + +Supervised task failure propagates across multiple generations even if +an intermediate generation has already exited: + +~~~ +# fn sleep_forever() { loop { task::yield() } } +# fn wait_for_a_while() { for 1000.times { task::yield() } } +# do task::try:: { +do task::spawn_supervised { + do task::spawn_supervised { + sleep_forever(); // Will get woken up by force, then fail + } + // Intermediate task immediately exits +} +wait_for_a_while(); +fail; // Will kill grandchild even if child has already exited +# }; +~~~ + +Finally, tasks can be configured to not propagate failure to each +other at all, using `task::spawn_unlinked` for _isolated failure_. + +~~~ +# fn random() -> int { 100 } +# fn sleep_for(i: int) { for i.times { task::yield() } } +# do task::try::<()> { +let (time1, time2) = (random(), random()); +do task::spawn_unlinked { + sleep_for(time2); // Won't get forced awake + fail; +} +sleep_for(time1); // Won't get forced awake +fail; +// It will take MAX(time1,time2) for the program to finish. +# }; +~~~ + + +# Unfinished notes + +## Actor patterns + +## Linearity, option dancing, owned closures + +## Creating a task with a bi-directional communication path 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 @@ -171,3 +527,4 @@ assert from_child.recv() == ~"0"; The parent task first calls `DuplexStream` to create a pair of bidirectional endpoints. It then uses `task::spawn` to create the child task, which captures one end of the communication channel. As a result, both parent and child can send and receive data to and from the other. + diff --git a/doc/tutorial.md b/doc/tutorial.md index bf774a19ace3..7f60492e06ff 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -82,7 +82,7 @@ supported build environments that are most likely to work. > ***Note:*** Windows users should read the detailed > [getting started][wiki-start] notes on the wiki. Even when using -> the binary installer the windows build requires a MinGW installation, +> the binary installer the Windows build requires a MinGW installation, > the precise details of which are not discussed in this tutorial. To build from source you will also need the following prerequisite @@ -111,12 +111,9 @@ can be adjusted by passing a `--prefix` argument to `configure`. Various other options are also supported, pass `--help` for more information on them. -When complete, `make install` will place the following programs into -`/usr/local/bin`: - - * `rustc`, the Rust compiler - * `rustdoc`, the API-documentation tool - * `cargo`, the Rust package manager +When complete, `make install` will place several programs into +`/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the +API-documentation tool, and `cargo`, the Rust package manager. [wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust [tarball]: http://dl.rust-lang.org/dist/rust-0.4.tar.gz @@ -216,8 +213,8 @@ fn main() { } ~~~~ -The `let` keyword, introduces a local variable. By default, variables -are immutable. `let mut` can be used to introduce a local variable +The `let` keyword introduces a local variable. Variables are immutable +by default, so `let mut` can be used to introduce a local variable that can be reassigned. ~~~~ @@ -232,14 +229,17 @@ 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. Local variables may shadow earlier -declarations, making the earlier variables inaccessible. +a colon, then the type name. ~~~~ let my_favorite_value: float = 57.8; let my_favorite_value: int = my_favorite_value as int; ~~~~ +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. + 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 alphabetic characters, numbers, or underscores. The preferred style is to @@ -371,7 +371,7 @@ more detail later on (the `T`s here stand for any other type): `[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 -`@T`, `~T`, `&T` [Pointer types](#boxes-and-pointers) +`&T`, `~T`, `@T` [Pointer types](#boxes-and-pointers) ------------------------- ----------------------------------------------- Some types can only be manipulated by pointer, never directly. For instance, @@ -421,7 +421,7 @@ Rust will assume that an unsuffixed integer literal has type ~~~~ let a = 1; // a is an int let b = 10i; // b is an int, due to the 'i' suffix -let c = 100u; // c as a uint +let c = 100u; // c is a uint let d = 1000i32; // d is an i32 ~~~~ @@ -619,7 +619,7 @@ literals and most enum variants. `while` produces a loop that runs as long as its given condition (which must have type `bool`) evaluates to true. Inside a loop, the -keyword `break` can be used to abort the loop, and `again` can be used +keyword `break` can be used to abort the loop, and `loop` can be used to abort the current iteration and continue with the next. ~~~~ @@ -713,16 +713,16 @@ enum Shape { } ~~~~ -A value of this type is either a Circle, in which case it contains a -point struct and a float, or a Rectangle, in which case it contains -two point records. The run-time representation of such a value +A value of this type is either a `Circle`, in which case it contains a +`Point` struct and a float, or a `Rectangle`, in which case it contains +two `Point` structs. The run-time representation of such a value includes an identifier of the actual form that it holds, much like the 'tagged union' pattern in C, but with better ergonomics. -The above declaration will define a type `shape` that can be used to -refer to such shapes, and two functions, `circle` and `rectangle`, +The above declaration will define a type `Shape` that can be used to +refer to such shapes, and two functions, `Circle` and `Rectangle`, which can be used to construct values of the type (taking arguments of -the specified types). So `circle({x: 0f, y: 0f}, 10f)` is the way to +the specified types). So `Circle(Point {x: 0f, y: 0f}, 10f)` is the way to create a new circle. Enum variants need not have type parameters. This, for example, is @@ -820,7 +820,7 @@ fn point_from_direction(dir: Direction) -> Point { ## Tuples -Tuples in Rust behave exactly like records, except that their fields +Tuples in Rust behave exactly like structs, except that their fields do not have names (and can thus not be accessed with dot notation). Tuples can have any arity except for 0 or 1 (though you may consider nil, `()`, as the empty tuple if you like). @@ -957,7 +957,7 @@ Rust has three competing goals that inform its view of memory: Most languages that offer strong memory safety guarantees rely upon a garbage-collected heap to manage all of the objects. This approach is straightforward both in concept and in implementation, but has -significant costs. Languages that take this approach tend to +significant costs. Languages that follow this path tend to aggressively pursue ways to ameliorate allocation costs (think the Java Virtual Machine). Rust supports this strategy with _managed boxes_: memory allocated on the heap whose lifetime is managed @@ -982,7 +982,7 @@ tasks. Experience in other languages has proven that isolating each task's heap from the others is a reliable strategy and one that is 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 garbage-collect memory. +per-heap. Rust never "stops the world" to reclaim memory. Complete isolation of heaps between tasks implies that any data transferred between tasks must be copied. While this is a fine and @@ -995,27 +995,18 @@ _owned boxes_. All tasks may allocate objects on the exchange heap, then transfer ownership of those objects to other tasks, avoiding expensive copies. -## What to be aware of - -Rust has three "realms" in which objects can be allocated: the stack, -the local heap, and the exchange heap. These realms have corresponding -pointer types: the borrowed pointer (`&T`), the managed box (`@T`), -and the owned box (`~T`). These three sigils will appear -repeatedly as we explore the language. Learning the appropriate role -of each is key to using Rust effectively. - # Boxes and pointers -In contrast to a lot of modern languages, aggregate types like records +In contrast to a lot of modern languages, aggregate types like structs and enums are _not_ represented as pointers to allocated memory in Rust. They are, as in C and C++, represented directly. This means that -if you `let x = {x: 1f, y: 1f};`, you are creating a record on the -stack. If you then copy it into a data structure, the whole record is +if you `let x = Point {x: 1f, y: 1f};`, you are creating a struct on the +stack. If you then copy it into a data structure, the whole struct is copied, not just a pointer. -For small records like `point`, this is usually more efficient than -allocating memory and going through a pointer. But for big records, or -records with mutable fields, it can be useful to have a single copy on +For small structs like `Point`, this is usually more efficient than +allocating memory and going through a pointer. But for big structs, or +those with mutable fields, it can be useful to have a single copy on the heap, and refer to that through a pointer. Rust supports several types of pointers. The safe pointer types are @@ -1191,8 +1182,8 @@ compute_distance(shared_box, unique_box); ~~~ Here the `&` operator is used to take the address of the variable -`on_the_stack`; this is because `on_the_stack` has the type `point` -(that is, a record value) and we have to take its address to get a +`on_the_stack`; this is because `on_the_stack` has the type `Point` +(that is, a struct value) and we have to take its address to get a value. We also call this _borrowing_ the local variable `on_the_stack`, because we are created an alias: that is, another route to the same data. @@ -1517,7 +1508,7 @@ fn each(v: &[int], op: fn(v: &int)) { The reason we pass in a *pointer* to an integer rather than the integer itself is that this is how the actual `each()` function for vectors works. Using a pointer means that the function can be used -for vectors of any type, even large records that would be impractical +for vectors of any type, even large structs that would be impractical to copy out of the vector on each iteration. As a caller, if we use a closure to provide the final operator argument, we can write it in a way that has a pleasant, block-like structure. @@ -1576,7 +1567,7 @@ Empty argument lists can be omitted from `do` expressions. Most iteration in Rust is done with `for` loops. Like `do`, `for` is a nice syntax for doing control flow with closures. -Additionally, within a `for` loop, `break`, `again`, and `return` +Additionally, within a `for` loop, `break`, `loop`, and `return` work just as they do with `while` and `loop`. Consider again our `each` function, this time improved to @@ -1611,7 +1602,7 @@ With `for`, functions like `each` can be treated more like builtin looping structures. When calling `each` in a `for` loop, instead of returning `false` to break out of the loop, you just write `break`. To skip ahead -to the next iteration, write `again`. +to the next iteration, write `loop`. ~~~~ # use each = vec::each; @@ -1644,14 +1635,15 @@ fn contains(v: &[int], elt: int) -> bool { # Generics Throughout this tutorial, we've been defining functions that act only on -single data types. With type parameters we can also define functions that -may be invoked on multiple types. +specific data types. With type parameters we can also define functions whose +arguments represent generic types, and which can be invoked with a variety +of types. Consider a generic `map` function. ~~~~ fn map(vector: &[T], function: fn(v: &T) -> U) -> ~[U] { let mut accumulator = ~[]; for vec::each(vector) |element| { - vec::push(accumulator, function(element)); + accumulator.push(function(element)); } return accumulator; } @@ -1665,7 +1657,7 @@ each other. Inside a generic function, the names of the type parameters (capitalized by convention) stand for opaque types. You can't look inside them, but you can pass them around. Note that instances of -generic types are almost always passed by pointer. For example, the +generic types are often passed by pointer. For example, the parameter `function()` is supplied with a pointer to a value of type `T` and not a value of type `T` itself. This ensures that the function works with the broadest set of types possible, since some @@ -1691,11 +1683,11 @@ These declarations produce valid types like `Set`, `Stack` and `Maybe`. Generic functions in Rust are compiled to very efficient runtime code -through a process called _monomorphisation_. This big word just means -that, for each generic function you call, the compiler generates a -specialized version that is optimized specifically for the argument -types. In this respect Rust's generics have similar performance -characteristics to C++ templates. +through a process called _monomorphisation_. This is a fancy way of +saying that, for each generic function you call, the compiler +generates a specialized version that is optimized specifically for the +argument types. In this respect Rust's generics have similar +performance characteristics to C++ templates. ## Traits @@ -1760,13 +1752,10 @@ types by the compiler, and may not be overridden: ## Declaring and implementing traits -A trait consists of a set of methods, or may be empty, as is the case -with `Copy`, `Send`, and `Const`. A method is a function that -can be applied to a `self` value and a number of arguments, using the -dot notation: `self.foo(arg1, arg2)`. - -For example, we could declare the trait `Printable` for things that -can be printed to the console, with a single method: +A trait consists of a set of methods, without bodies, or may be empty, +as is the case with `Copy`, `Send`, and `Const`. For example, we could +declare the trait `Printable` for things that can be printed to the +console, with a single method: ~~~~ trait Printable { @@ -1774,9 +1763,12 @@ trait Printable { } ~~~~ -To actually implement a trait for a given type, the `impl` form is -used. This defines implementations of `Printable` for the `int` and -`~str` types. +Traits may be implemented for specific types with [impls]. An impl +that implements a trait includes the name of the trait at the start of +the definition, as in the following impls of `Printable` for `int` +and `~str`. + +[impls]: #functions-and-methods ~~~~ # trait Printable { fn print(); } @@ -1792,14 +1784,10 @@ impl ~str: Printable { # (~"foo").print(); ~~~~ -Given these, we may call `1.print()` to print `"1"`, or -`(~"foo").print()` to print `"foo"` again, as with . This is basically a form of -static overloading—when the Rust compiler sees the `print` method -call, it looks for an implementation that matches the type with a -method that matches the name, and simply calls that. - -Traits may themselves contain type parameters. A trait for -generalized sequence types might look like the following: +Methods defined in an implementation of a trait may be called just as +any other method, using dot notation, as in `1.print()`. Traits may +themselves contain type parameters. A trait for generalized sequence +types might look like the following: ~~~~ trait Seq { diff --git a/man/rustc.1 b/man/rustc.1 index f1a0a0131e13..f5888015944a 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -75,10 +75,7 @@ Write intermediate files (.bc, .opt.bc, .o) in addition to normal output .TP \fB\-\-static\fR -Use or produce static libraries or binaries -.TP -\fB\-\-stats\fR -Print compilation statistics +Use or produce static libraries or binaries (experimental) .TP \fB\-\-sysroot\fR Override the system root @@ -87,10 +84,9 @@ Override the system root Build a test harness .TP \fB\-\-target\fR -Target cpu\-manufacturer\-kernel[\-os] to compile for -(default: host triple) -(see http://sources.redhat.com/autobook/autobook/ -autobook_17.html for detail) +Target cpu\-manufacturer\-kernel[\-os] to compile for (default: host triple) +(see <\fBhttp://sources.redhat.com/autobook/autobook/autobook_17.html\fR> for +detail) .TP \fB\-W\fR enable warning @@ -121,7 +117,7 @@ To build either with a crate (.rc) file: $ rustc hello.rc .SH "BUGS" -See \fBhttps://github.com/mozilla/rust/issues\fR for a list of known bugs. +See <\fBhttps://github.com/mozilla/rust/issues\fR> for a list of known bugs. .SH "AUTHOR" See \fBAUTHORS.txt\fR in the rust source distribution. Graydon Hoare diff --git a/src/cargo/cargo.rc b/src/cargo/cargo.rc index ae0953188738..17ddacfd7eb7 100644 --- a/src/cargo/cargo.rc +++ b/src/cargo/cargo.rc @@ -24,6 +24,8 @@ #[allow(vecs_implicitly_copyable, non_implicitly_copyable_typarams)]; #[allow(non_camel_case_types)]; +#[allow(deprecated_mode)]; +#[allow(deprecated_pattern)]; extern mod core(vers = "0.4"); extern mod std(vers = "0.4"); diff --git a/src/cargo/cargo.rs b/src/cargo/cargo.rs index a9fa6ca899c6..211b048de7a3 100644 --- a/src/cargo/cargo.rs +++ b/src/cargo/cargo.rs @@ -11,13 +11,14 @@ use syntax::diagnostic; use result::{Ok, Err}; use io::WriterUtil; +use send_map::linear::LinearMap; use std::{map, json, tempfile, term, sort, getopts}; use map::HashMap; use to_str::to_str; use getopts::{optflag, optopt, opt_present}; use dvec::DVec; -type package = { +struct Package { name: ~str, uuid: ~str, url: ~str, @@ -26,10 +27,10 @@ type package = { reference: Option<~str>, tags: ~[~str], versions: ~[(~str, ~str)] -}; +} -impl package : cmp::Ord { - pure fn lt(other: &package) -> bool { +impl Package : cmp::Ord { + pure fn lt(other: &Package) -> bool { if self.name.lt(&(*other).name) { return true; } if (*other).name.lt(&self.name) { return false; } if self.uuid.lt(&(*other).uuid) { return true; } @@ -45,28 +46,21 @@ impl package : cmp::Ord { if self.versions.lt(&(*other).versions) { return true; } return false; } - pure fn le(other: &package) -> bool { !(*other).lt(&self) } - pure fn ge(other: &package) -> bool { !self.lt(other) } - pure fn gt(other: &package) -> bool { (*other).lt(&self) } + pure fn le(other: &Package) -> bool { !(*other).lt(&self) } + pure fn ge(other: &Package) -> bool { !self.lt(other) } + pure fn gt(other: &Package) -> bool { (*other).lt(&self) } } -type local_package = { - name: ~str, - metaname: ~str, - version: ~str, - files: ~[~str] -}; - -type source = @{ +struct Source { name: ~str, mut url: ~str, mut method: ~str, mut key: Option<~str>, mut keyfp: Option<~str>, - packages: DVec -}; + packages: DVec +} -type cargo = { +struct Cargo { pgp: bool, root: Path, installdir: Path, @@ -74,13 +68,13 @@ type cargo = { libdir: Path, workdir: Path, sourcedir: Path, - sources: map::HashMap<~str, source>, + sources: map::HashMap<~str, @Source>, mut current_install: ~str, dep_cache: map::HashMap<~str, bool>, - opts: options -}; + opts: Options +} -type crate = { +struct Crate { name: ~str, vers: ~str, uuid: ~str, @@ -88,22 +82,22 @@ type crate = { sigs: Option<~str>, crate_type: Option<~str>, deps: ~[~str] -}; +} -type options = { +struct Options { test: bool, - mode: mode, + mode: Mode, free: ~[~str], help: bool, -}; +} -enum mode { system_mode, user_mode, local_mode } +enum Mode { SystemMode, UserMode, LocalMode } -impl mode : cmp::Eq { - pure fn eq(other: &mode) -> bool { +impl Mode : cmp::Eq { + pure fn eq(other: &Mode) -> bool { (self as uint) == ((*other) as uint) } - pure fn ne(other: &mode) -> bool { !self.eq(other) } + pure fn ne(other: &Mode) -> bool { !self.eq(other) } } fn opts() -> ~[getopts::Opt] { @@ -150,7 +144,7 @@ fn is_uuid(id: ~str) -> bool { if vec::len(parts) == 5u { let mut correct = 0u; for vec::eachi(parts) |i, part| { - fn is_hex_digit(ch: char) -> bool { + fn is_hex_digit(+ch: char) -> bool { ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F') @@ -270,7 +264,7 @@ fn load_link(mis: ~[@ast::meta_item]) -> (Option<~str>, (name, vers, uuid) } -fn load_crate(filename: &Path) -> Option { +fn load_crate(filename: &Path) -> Option { let sess = parse::new_parse_sess(None); let c = parse::parse_crate_from_crate_file(filename, ~[], sess); @@ -351,7 +345,7 @@ fn load_crate(filename: &Path) -> Option { match *ps.interner.get(attr_name) { ~"std" | ~"core" => (), - _ => vec::push(e.deps, query) + _ => e.deps.push(query) } } _ => () @@ -375,7 +369,7 @@ fn load_crate(filename: &Path) -> Option { match (name, vers, uuid) { (Some(name0), Some(vers0), Some(uuid0)) => { - Some({ + Some(Crate { name: name0, vers: vers0, uuid: uuid0, @@ -407,8 +401,8 @@ fn need_dir(s: &Path) { } } -fn valid_pkg_name(s: ~str) -> bool { - fn is_valid_digit(c: char) -> bool { +fn valid_pkg_name(s: &str) -> bool { + fn is_valid_digit(+c: char) -> bool { ('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || @@ -419,33 +413,33 @@ fn valid_pkg_name(s: ~str) -> bool { s.all(is_valid_digit) } -fn parse_source(name: ~str, j: json::Json) -> source { +fn parse_source(name: ~str, j: &json::Json) -> @Source { if !valid_pkg_name(name) { fail fmt!("'%s' is an invalid source name", name); } - match j { - json::Dict(j) => { - let mut url = match j.find(~"url") { - Some(json::String(u)) => *u, + match *j { + json::Object(j) => { + let mut url = match j.find(&~"url") { + Some(json::String(u)) => u, _ => fail ~"needed 'url' field in source" }; - let method = match j.find(~"method") { - Some(json::String(u)) => *u, + let method = match j.find(&~"method") { + Some(json::String(u)) => u, _ => assume_source_method(url) }; - let key = match j.find(~"key") { - Some(json::String(u)) => Some(*u), + let key = match j.find(&~"key") { + Some(json::String(u)) => Some(u), _ => None }; - let keyfp = match j.find(~"keyfp") { - Some(json::String(u)) => Some(*u), + let keyfp = match j.find(&~"keyfp") { + Some(json::String(u)) => Some(u), _ => None }; if method == ~"file" { url = os::make_absolute(&Path(url)).to_str(); } - return @{ + return @Source { name: name, mut url: url, mut method: method, @@ -457,14 +451,14 @@ fn parse_source(name: ~str, j: json::Json) -> source { }; } -fn try_parse_sources(filename: &Path, sources: map::HashMap<~str, source>) { +fn try_parse_sources(filename: &Path, sources: map::HashMap<~str, @Source>) { if !os::path_exists(filename) { return; } let c = io::read_whole_file_str(filename); - match json::from_str(result::get(c)) { - Ok(json::Dict(j)) => { - for j.each |k, v| { - sources.insert(k, parse_source(k, v)); - debug!("source: %s", k); + match json::from_str(c.get()) { + Ok(json::Object(j)) => { + for j.each |k, v| { + sources.insert(copy *k, parse_source(*k, v)); + debug!("source: %s", *k); } } Ok(_) => fail ~"malformed sources.json", @@ -472,17 +466,17 @@ fn try_parse_sources(filename: &Path, sources: map::HashMap<~str, source>) { } } -fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) { - let name = match p.find(~"name") { +fn load_one_source_package(src: @Source, p: &json::Object) { + let name = match p.find(&~"name") { Some(json::String(n)) => { - if !valid_pkg_name(*n) { + if !valid_pkg_name(n) { warn(~"malformed source json: " - + src.name + ~", '" + *n + ~"'"+ + + src.name + ~", '" + n + ~"'"+ ~" is an invalid name (alphanumeric, underscores and" + ~" dashes only)"); return; } - *n + n } _ => { warn(~"malformed source json: " + src.name + ~" (missing name)"); @@ -490,15 +484,15 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) { } }; - let uuid = match p.find(~"uuid") { + let uuid = match p.find(&~"uuid") { Some(json::String(n)) => { - if !is_uuid(*n) { + if !is_uuid(n) { warn(~"malformed source json: " - + src.name + ~", '" + *n + ~"'"+ + + src.name + ~", '" + n + ~"'"+ ~" is an invalid uuid"); return; } - *n + n } _ => { warn(~"malformed source json: " + src.name + ~" (missing uuid)"); @@ -506,16 +500,16 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) { } }; - let url = match p.find(~"url") { - Some(json::String(n)) => *n, + let url = match p.find(&~"url") { + Some(json::String(n)) => n, _ => { warn(~"malformed source json: " + src.name + ~" (missing url)"); return; } }; - let method = match p.find(~"method") { - Some(json::String(n)) => *n, + let method = match p.find(&~"method") { + Some(json::String(n)) => n, _ => { warn(~"malformed source json: " + src.name + ~" (missing method)"); @@ -523,17 +517,17 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) { } }; - let reference = match p.find(~"ref") { - Some(json::String(n)) => Some(*n), + let reference = match p.find(&~"ref") { + Some(json::String(n)) => Some(n), _ => None }; let mut tags = ~[]; - match p.find(~"tags") { + match p.find(&~"tags") { Some(json::List(js)) => { - for (*js).each |j| { + for js.each |j| { match *j { - json::String(j) => vec::grow(tags, 1u, *j), + json::String(ref j) => tags.grow(1u, j), _ => () } } @@ -541,8 +535,8 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) { _ => () } - let description = match p.find(~"description") { - Some(json::String(n)) => *n, + let description = match p.find(&~"description") { + Some(json::String(n)) => n, _ => { warn(~"malformed source json: " + src.name + ~" (missing description)"); @@ -550,7 +544,7 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) { } }; - let newpkg = { + let newpkg = Package { name: name, uuid: uuid, url: url, @@ -574,14 +568,14 @@ fn load_one_source_package(src: source, p: map::HashMap<~str, json::Json>) { log(debug, ~" loaded package: " + src.name + ~"/" + name); } -fn load_source_info(c: &cargo, src: source) { +fn load_source_info(c: &Cargo, src: @Source) { let dir = c.sourcedir.push(src.name); let srcfile = dir.push("source.json"); if !os::path_exists(&srcfile) { return; } let srcstr = io::read_whole_file_str(&srcfile); - match json::from_str(result::get(srcstr)) { - Ok(json::Dict(s)) => { - let o = parse_source(src.name, json::Dict(s)); + match json::from_str(srcstr.get()) { + Ok(ref json @ json::Object(_)) => { + let o = parse_source(src.name, json); src.key = o.key; src.keyfp = o.keyfp; @@ -595,17 +589,17 @@ fn load_source_info(c: &cargo, src: source) { } }; } -fn load_source_packages(c: &cargo, src: source) { +fn load_source_packages(c: &Cargo, src: @Source) { log(debug, ~"loading source: " + src.name); let dir = c.sourcedir.push(src.name); let pkgfile = dir.push("packages.json"); if !os::path_exists(&pkgfile) { return; } let pkgstr = io::read_whole_file_str(&pkgfile); - match json::from_str(result::get(pkgstr)) { + match json::from_str(pkgstr.get()) { Ok(json::List(js)) => { - for (*js).each |j| { + for js.each |j| { match *j { - json::Dict(p) => { + json::Object(p) => { load_one_source_package(src, p); } _ => { @@ -625,7 +619,7 @@ fn load_source_packages(c: &cargo, src: source) { }; } -fn build_cargo_options(argv: ~[~str]) -> options { +fn build_cargo_options(argv: ~[~str]) -> Options { let matches = match getopts::getopts(argv, opts()) { result::Ok(m) => m, result::Err(f) => { @@ -649,34 +643,34 @@ fn build_cargo_options(argv: ~[~str]) -> options { } let mode = - if (!is_install && !is_uninstall) || g { user_mode } - else if G { system_mode } - else { local_mode }; + if (!is_install && !is_uninstall) || g { UserMode } + else if G { SystemMode } + else { LocalMode }; - {test: test, mode: mode, free: matches.free, help: help} + Options {test: test, mode: mode, free: matches.free, help: help} } -fn configure(opts: options) -> cargo { +fn configure(opts: Options) -> Cargo { let home = match get_cargo_root() { Ok(home) => home, - Err(_err) => result::get(get_cargo_sysroot()) + Err(_err) => get_cargo_sysroot().get() }; let get_cargo_dir = match opts.mode { - system_mode => get_cargo_sysroot, - user_mode => get_cargo_root, - local_mode => get_cargo_root_nearest + SystemMode => get_cargo_sysroot, + UserMode => get_cargo_root, + LocalMode => get_cargo_root_nearest }; - let p = result::get(get_cargo_dir()); + let p = get_cargo_dir().get(); - let sources = map::HashMap(); + let sources = HashMap(); try_parse_sources(&home.push("sources.json"), sources); try_parse_sources(&home.push("local-sources.json"), sources); - let dep_cache = map::HashMap(); + let dep_cache = HashMap(); - let mut c = { + let mut c = Cargo { pgp: pgp::supported(), root: home, installdir: p, @@ -714,10 +708,10 @@ fn configure(opts: options) -> cargo { c } -fn for_each_package(c: &cargo, b: fn(source, package)) { +fn for_each_package(c: &Cargo, b: fn(s: @Source, p: &Package)) { for c.sources.each_value |v| { for v.packages.each |p| { - b(v, *p); + b(v, p); } } } @@ -748,7 +742,7 @@ fn run_in_buildpath(what: &str, path: &Path, subdir: &Path, cf: &Path, Some(buildpath) } -fn test_one_crate(_c: &cargo, path: &Path, cf: &Path) { +fn test_one_crate(_c: &Cargo, path: &Path, cf: &Path) { let buildpath = match run_in_buildpath(~"testing", path, &Path("test"), cf, @@ -759,7 +753,7 @@ fn test_one_crate(_c: &cargo, path: &Path, cf: &Path) { run_programs(&buildpath); } -fn install_one_crate(c: &cargo, path: &Path, cf: &Path) { +fn install_one_crate(c: &Cargo, path: &Path, cf: &Path) { let buildpath = match run_in_buildpath(~"installing", path, &Path("build"), cf, ~[]) { @@ -776,7 +770,7 @@ fn install_one_crate(c: &cargo, path: &Path, cf: &Path) { ~"lib")) { debug!(" bin: %s", ct.to_str()); install_to_dir(*ct, &c.bindir); - if c.opts.mode == system_mode { + if c.opts.mode == SystemMode { // FIXME (#2662): Put this file in PATH / symlink it so it can // be used as a generic executable // `cargo install -G rustray` and `rustray file.obj` @@ -800,14 +794,14 @@ fn rustc_sysroot() -> ~str { } } -fn install_source(c: &cargo, path: &Path) { +fn install_source(c: &Cargo, path: &Path) { debug!("source: %s", path.to_str()); os::change_dir(path); let mut cratefiles = ~[]; for os::walk_dir(&Path(".")) |p| { if p.filetype() == Some(~".rc") { - vec::push(cratefiles, *p); + cratefiles.push(*p); } } @@ -839,7 +833,7 @@ fn install_source(c: &cargo, path: &Path) { } } -fn install_git(c: &cargo, wd: &Path, url: ~str, reference: Option<~str>) { +fn install_git(c: &Cargo, wd: &Path, url: ~str, reference: Option<~str>) { run::program_output(~"git", ~[~"clone", url, wd.to_str()]); if reference.is_some() { let r = reference.get(); @@ -850,7 +844,7 @@ fn install_git(c: &cargo, wd: &Path, url: ~str, reference: Option<~str>) { install_source(c, wd); } -fn install_curl(c: &cargo, wd: &Path, url: ~str) { +fn install_curl(c: &Cargo, wd: &Path, url: ~str) { let tarpath = wd.push("pkg.tar"); let p = run::program_output(~"curl", ~[~"-f", ~"-s", ~"-o", tarpath.to_str(), url]); @@ -863,14 +857,14 @@ fn install_curl(c: &cargo, wd: &Path, url: ~str) { install_source(c, wd); } -fn install_file(c: &cargo, wd: &Path, path: &Path) { +fn install_file(c: &Cargo, wd: &Path, path: &Path) { run::program_output(~"tar", ~[~"-x", ~"--strip-components=1", ~"-C", wd.to_str(), ~"-f", path.to_str()]); install_source(c, wd); } -fn install_package(c: &cargo, src: ~str, wd: &Path, pkg: package) { +fn install_package(c: &Cargo, src: ~str, wd: &Path, pkg: Package) { let url = copy pkg.url; let method = match pkg.method { ~"git" => ~"git", @@ -883,12 +877,12 @@ fn install_package(c: &cargo, src: ~str, wd: &Path, pkg: package) { match method { ~"git" => install_git(c, wd, url, copy pkg.reference), ~"file" => install_file(c, wd, &Path(url)), - ~"curl" => install_curl(c, wd, copy url), + ~"curl" => install_curl(c, wd, url), _ => () } } -fn cargo_suggestion(c: &cargo, fallback: fn()) +fn cargo_suggestion(c: &Cargo, fallback: fn()) { if c.sources.size() == 0u { error(~"no sources defined - you may wish to run " + @@ -898,11 +892,11 @@ fn cargo_suggestion(c: &cargo, fallback: fn()) fallback(); } -fn install_uuid(c: &cargo, wd: &Path, uuid: ~str) { +fn install_uuid(c: &Cargo, wd: &Path, uuid: ~str) { let mut ps = ~[]; for_each_package(c, |s, p| { if p.uuid == uuid { - vec::grow(ps, 1u, (s.name, copy p)); + vec::push(&mut ps, (s.name, copy *p)); } }); if vec::len(ps) == 1u { @@ -922,11 +916,11 @@ fn install_uuid(c: &cargo, wd: &Path, uuid: ~str) { } } -fn install_named(c: &cargo, wd: &Path, name: ~str) { +fn install_named(c: &Cargo, wd: &Path, name: ~str) { let mut ps = ~[]; for_each_package(c, |s, p| { if p.name == name { - vec::grow(ps, 1u, (s.name, copy p)); + vec::push(&mut ps, (s.name, copy *p)); } }); if vec::len(ps) == 1u { @@ -946,7 +940,7 @@ fn install_named(c: &cargo, wd: &Path, name: ~str) { } } -fn install_uuid_specific(c: &cargo, wd: &Path, src: ~str, uuid: ~str) { +fn install_uuid_specific(c: &Cargo, wd: &Path, src: ~str, uuid: ~str) { match c.sources.find(src) { Some(s) => { for s.packages.each |p| { @@ -961,7 +955,7 @@ fn install_uuid_specific(c: &cargo, wd: &Path, src: ~str, uuid: ~str) { error(~"can't find package: " + src + ~"/" + uuid); } -fn install_named_specific(c: &cargo, wd: &Path, src: ~str, name: ~str) { +fn install_named_specific(c: &Cargo, wd: &Path, src: ~str, name: ~str) { match c.sources.find(src) { Some(s) => { for s.packages.each |p| { @@ -976,7 +970,7 @@ fn install_named_specific(c: &cargo, wd: &Path, src: ~str, name: ~str) { error(~"can't find package: " + src + ~"/" + name); } -fn cmd_uninstall(c: &cargo) { +fn cmd_uninstall(c: &Cargo) { if vec::len(c.opts.free) < 3u { cmd_usage(); return; @@ -1028,7 +1022,7 @@ fn cmd_uninstall(c: &cargo) { } } -fn install_query(c: &cargo, wd: &Path, target: ~str) { +fn install_query(c: &Cargo, wd: &Path, target: ~str) { match c.dep_cache.find(target) { Some(inst) => { if inst { @@ -1088,7 +1082,7 @@ fn install_query(c: &cargo, wd: &Path, target: ~str) { } } -fn get_temp_workdir(c: &cargo) -> Path { +fn get_temp_workdir(c: &Cargo) -> Path { match tempfile::mkdtemp(&c.workdir, "cargo") { Some(wd) => wd, None => fail fmt!("needed temp dir: %s", @@ -1096,7 +1090,7 @@ fn get_temp_workdir(c: &cargo) -> Path { } } -fn cmd_install(c: &cargo) unsafe { +fn cmd_install(c: &Cargo) unsafe { let wd = get_temp_workdir(c); if vec::len(c.opts.free) == 2u { @@ -1120,7 +1114,7 @@ fn cmd_install(c: &cargo) unsafe { install_query(c, &wd, query); } -fn sync(c: &cargo) { +fn sync(c: &Cargo) { for c.sources.each_key |k| { let mut s = c.sources.get(k); sync_one(c, s); @@ -1128,7 +1122,7 @@ fn sync(c: &cargo) { } } -fn sync_one_file(c: &cargo, dir: &Path, src: source) -> bool { +fn sync_one_file(c: &Cargo, dir: &Path, src: @Source) -> bool { let name = src.name; let srcfile = dir.push("source.json.new"); let destsrcfile = dir.push("source.json"); @@ -1206,7 +1200,7 @@ fn sync_one_file(c: &cargo, dir: &Path, src: source) -> bool { return true; } -fn sync_one_git(c: &cargo, dir: &Path, src: source) -> bool { +fn sync_one_git(c: &Cargo, dir: &Path, src: @Source) -> bool { let name = src.name; let srcfile = dir.push("source.json"); let pkgfile = dir.push("packages.json"); @@ -1309,7 +1303,7 @@ fn sync_one_git(c: &cargo, dir: &Path, src: source) -> bool { return true; } -fn sync_one_curl(c: &cargo, dir: &Path, src: source) -> bool { +fn sync_one_curl(c: &Cargo, dir: &Path, src: @Source) -> bool { let name = src.name; let srcfile = dir.push("source.json.new"); let destsrcfile = dir.push("source.json"); @@ -1425,7 +1419,7 @@ fn sync_one_curl(c: &cargo, dir: &Path, src: source) -> bool { return true; } -fn sync_one(c: &cargo, src: source) { +fn sync_one(c: &Cargo, src: @Source) { let name = src.name; let dir = c.sourcedir.push(name); @@ -1445,7 +1439,7 @@ fn sync_one(c: &cargo, src: source) { } } -fn cmd_init(c: &cargo) { +fn cmd_init(c: &Cargo) { let srcurl = ~"http://www.rust-lang.org/cargo/sources.json"; let sigurl = ~"http://www.rust-lang.org/cargo/sources.json.sig"; @@ -1484,7 +1478,7 @@ fn cmd_init(c: &cargo) { info(fmt!("initialized .cargo in %s", c.root.to_str())); } -fn print_pkg(s: source, p: package) { +fn print_pkg(s: @Source, p: &Package) { let mut m = s.name + ~"/" + p.name + ~" (" + p.uuid + ~")"; if vec::len(p.tags) > 0u { m = m + ~" [" + str::connect(p.tags, ~", ") + ~"]"; @@ -1495,7 +1489,7 @@ fn print_pkg(s: source, p: package) { } } -fn print_source(s: source) { +fn print_source(s: @Source) { info(s.name + ~" (" + s.url + ~")"); let pks = sort::merge_sort(s.packages.get(), sys::shape_lt); @@ -1516,7 +1510,7 @@ fn print_source(s: source) { })); } -fn cmd_list(c: &cargo) { +fn cmd_list(c: &Cargo) { sync(c); if vec::len(c.opts.free) >= 3u { @@ -1542,7 +1536,7 @@ fn cmd_list(c: &cargo) { } } -fn cmd_search(c: &cargo) { +fn cmd_search(c: &Cargo) { if vec::len(c.opts.free) < 3u { cmd_usage(); return; @@ -1575,17 +1569,17 @@ fn install_to_dir(srcfile: &Path, destdir: &Path) { } } -fn dump_cache(c: &cargo) { +fn dump_cache(c: &Cargo) { need_dir(&c.root); let out = c.root.push("cache.json"); - let _root = json::Dict(map::HashMap()); + let _root = json::Object(~LinearMap()); if os::path_exists(&out) { copy_warn(&out, &c.root.push("cache.json.old")); } } -fn dump_sources(c: &cargo) { +fn dump_sources(c: &Cargo) { if c.sources.size() < 1u { return; } @@ -1600,33 +1594,31 @@ fn dump_sources(c: &cargo) { match io::buffered_file_writer(&out) { result::Ok(writer) => { - let hash = map::HashMap(); - let root = json::Dict(hash); + let mut hash = ~LinearMap(); - for c.sources.each |k, v| { - let chash = map::HashMap(); - let child = json::Dict(chash); + for c.sources.each |k, v| { + let mut chash = ~LinearMap(); - chash.insert(~"url", json::String(@v.url)); - chash.insert(~"method", json::String(@v.method)); + chash.insert(~"url", json::String(v.url)); + chash.insert(~"method", json::String(v.method)); match copy v.key { Some(key) => { - chash.insert(~"key", json::String(@key)); + chash.insert(~"key", json::String(copy key)); } _ => () } match copy v.keyfp { Some(keyfp) => { - chash.insert(~"keyfp", json::String(@keyfp)); + chash.insert(~"keyfp", json::String(copy keyfp)); } _ => () } - hash.insert(k, child); + hash.insert(copy k, json::Object(chash)); } - writer.write_str(json::to_str(root)); + json::to_writer(writer, &json::Object(hash)) } result::Err(e) => { error(fmt!("could not dump sources: %s", e)); @@ -1641,7 +1633,7 @@ fn copy_warn(srcfile: &Path, destfile: &Path) { } } -fn cmd_sources(c: &cargo) { +fn cmd_sources(c: &Cargo) { if vec::len(c.opts.free) < 3u { for c.sources.each_value |v| { info(fmt!("%s (%s) via %s", @@ -1677,7 +1669,7 @@ fn cmd_sources(c: &cargo) { if c.sources.contains_key(name) { error(fmt!("source already exists: %s", name)); } else { - c.sources.insert(name, @{ + c.sources.insert(name, @Source { name: name, mut url: url, mut method: assume_source_method(url), diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc index ce11245dba54..991d2d2cb0e3 100644 --- a/src/compiletest/compiletest.rc +++ b/src/compiletest/compiletest.rc @@ -5,6 +5,8 @@ #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; +#[allow(deprecated_mode)]; +#[allow(deprecated_pattern)]; extern mod core(vers = "0.4"); extern mod std(vers = "0.4"); diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 5bee7fb255dc..264ee61018bf 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -58,7 +58,7 @@ fn parse_config(args: ~[~str]) -> config { } else { option::None }, logfile: option::map(&getopts::opt_maybe_str(matches, ~"logfile"), - |s| Path(s)), + |s| Path(*s)), runtool: getopts::opt_maybe_str(matches, ~"runtool"), rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), jit: getopts::opt_present(matches, ~"jit"), @@ -141,7 +141,7 @@ fn make_tests(config: config) -> ~[test::TestDesc] { let file = copy *file; debug!("inspecting file %s", file.to_str()); if is_test(config, file) { - vec::push(tests, make_test(config, file)) + tests.push(make_test(config, file)) } } return tests; diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index e7d6593061d7..a8b69201a225 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -9,7 +9,7 @@ type expected_error = { line: uint, kind: ~str, msg: ~str }; // Load any test directives embedded in the file fn load_errors(testfile: &Path) -> ~[expected_error] { let mut error_patterns = ~[]; - let rdr = result::get(io::file_reader(testfile)); + let rdr = io::file_reader(testfile).get(); let mut line_num = 1u; while !rdr.eof() { let ln = rdr.read_line(); diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 4ff1b8e9c788..3071c9a70a1e 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -28,7 +28,7 @@ fn load_props(testfile: &Path) -> test_props { let mut pp_exact = option::None; for iter_header(testfile) |ln| { match parse_error_pattern(ln) { - option::Some(ep) => vec::push(error_patterns, ep), + option::Some(ep) => error_patterns.push(ep), option::None => () }; @@ -41,11 +41,11 @@ fn load_props(testfile: &Path) -> test_props { } do parse_aux_build(ln).iter |ab| { - vec::push(aux_builds, ab); + aux_builds.push(*ab); } do parse_exec_env(ln).iter |ee| { - vec::push(exec_env, ee); + exec_env.push(*ee); } }; return { @@ -73,7 +73,7 @@ fn is_test_ignored(config: config, testfile: &Path) -> bool { } fn iter_header(testfile: &Path, it: fn(~str) -> bool) -> bool { - let rdr = result::get(io::file_reader(testfile)); + let rdr = io::file_reader(testfile).get(); while !rdr.eof() { let ln = rdr.read_line(); @@ -103,7 +103,7 @@ fn parse_compile_flags(line: ~str) -> Option<~str> { fn parse_exec_env(line: ~str) -> Option<(~str, ~str)> { do parse_name_value_directive(line, ~"exec-env").map |nv| { // nv is either FOO or FOO=BAR - let strs = str::splitn_char(nv, '=', 1u); + let strs = str::splitn_char(*nv, '=', 1u); match strs.len() { 1u => (strs[0], ~""), 2u => (strs[0], strs[1]), diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index d62f2fe5837f..b03c3bbf42fa 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -14,12 +14,12 @@ fn target_env(lib_path: ~str, prog: ~str) -> ~[(~str,~str)] { let aux_path = prog.slice(0u, prog.len() - 4u) + ~".libaux"; env = do vec::map(env) |pair| { - let (k,v) = pair; + let (k,v) = *pair; if k == ~"PATH" { (~"PATH", v + ~";" + lib_path + ~";" + aux_path) } else { (k,v) } }; if str::ends_with(prog, ~"rustc.exe") { - vec::push(env, (~"RUST_THREADS", ~"1")); + env.push((~"RUST_THREADS", ~"1")); } return env; } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 1c69e5111375..ff695f64088f 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -109,7 +109,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) { let rounds = match props.pp_exact { option::Some(_) => 1, option::None => 2 }; - let mut srcs = ~[result::get(io::read_whole_file_str(testfile))]; + let mut srcs = ~[io::read_whole_file_str(testfile).get()]; let mut round = 0; while round < rounds { @@ -121,7 +121,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) { procres); } - vec::push(srcs, procres.stdout); + srcs.push(procres.stdout); round += 1; } @@ -129,7 +129,7 @@ fn run_pretty_test(config: config, props: test_props, testfile: &Path) { match props.pp_exact { option::Some(file) => { let filepath = testfile.dir_path().push_rel(&file); - result::get(io::read_whole_file_str(&filepath)) + io::read_whole_file_str(&filepath).get() } option::None => { srcs[vec::len(srcs) - 2u] } }; @@ -503,10 +503,7 @@ fn make_run_args(config: config, _props: test_props, testfile: &Path) -> fn split_maybe_args(argstr: Option<~str>) -> ~[~str] { fn rm_whitespace(v: ~[~str]) -> ~[~str] { - fn flt(&&s: ~str) -> Option<~str> { - if !str::is_whitespace(s) { option::Some(s) } else { option::None } - } - vec::filter_map(v, flt) + vec::filter(v, |s| !str::is_whitespace(*s)) } match argstr { @@ -561,8 +558,8 @@ fn dump_output(config: config, testfile: &Path, out: ~str, err: ~str) { fn dump_output_file(config: config, testfile: &Path, out: ~str, extension: ~str) { let outfile = make_out_name(config, testfile, extension); - let writer = result::get( - io::file_writer(&outfile, ~[io::Create, io::Truncate])); + let writer = + io::file_writer(&outfile, ~[io::Create, io::Truncate]).get(); writer.write_str(out); } diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py index 7bd3537a8b8c..7016713f2fee 100755 --- a/src/etc/combine-tests.py +++ b/src/etc/combine-tests.py @@ -30,7 +30,7 @@ for t in os.listdir(run_pass): "xfail-fast" in s or "xfail-win32" in s): stage2_tests.append(t) - if "main(args: ~[~str])" in s: + if "fn main(args:" in s or "fn main(++args:" in s: take_args[t] = True f.close() @@ -39,11 +39,13 @@ stage2_tests.sort() c = open("tmp/run_pass_stage2.rc", "w") i = 0 c.write("// AUTO-GENERATED FILE: DO NOT EDIT\n") +c.write("#[legacy_exports];\n") c.write("#[link(name=\"run_pass_stage2\", vers=\"0.1\")];\n") for t in stage2_tests: p = os.path.join(run_pass, t) p = p.replace("\\", "\\\\") c.write("#[path = \"%s\"]" % p); + c.write("#[legacy_exports]"); c.write("mod t_%d;\n" % i) i += 1 c.close() diff --git a/src/etc/emacs/rust-mode.el b/src/etc/emacs/rust-mode.el index 9a9b92dfb8ce..d9ee135ac47b 100644 --- a/src/etc/emacs/rust-mode.el +++ b/src/etc/emacs/rust-mode.el @@ -70,7 +70,7 @@ "let" "log" "loop" "move" "new" "pure" "pub" "priv" - "return" "static" + "ref" "return" "static" "unchecked" "unsafe" "while")) (puthash word t table)) diff --git a/src/fuzzer/cycles.rs b/src/fuzzer/cycles.rs index 17ed1c0fb960..ec263ead954f 100644 --- a/src/fuzzer/cycles.rs +++ b/src/fuzzer/cycles.rs @@ -62,7 +62,7 @@ fn test_cycles(r : rand::rng, k: uint, n: uint) // Create a graph with no edges range(0u, vlen) {|_i| - vec::push(v, empty_pointy()); + v.push(empty_pointy()); } // Fill in the graph with random edges, with density k/n @@ -77,7 +77,7 @@ fn test_cycles(r : rand::rng, k: uint, n: uint) // https://github.com/mozilla/rust/issues/1899 if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; } - if (likelihood(r, k, n)) { vec::push(v[i].n, mut p(choice(r, v))); } + if (likelihood(r, k, n)) { v[i].n.push(mut p(choice(r, v))); } if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; } } diff --git a/src/fuzzer/fuzzer.rc b/src/fuzzer/fuzzer.rc index 073335fbc728..640bcccc7a89 100644 --- a/src/fuzzer/fuzzer.rc +++ b/src/fuzzer/fuzzer.rc @@ -9,6 +9,8 @@ #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; +#[allow(deprecated_mode)]; +#[allow(deprecated_pattern)]; extern mod core(vers = "0.4"); extern mod std(vers = "0.4"); diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index 5e2cf689b7c5..cd312362d6a4 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -19,7 +19,7 @@ impl test_mode : cmp::Eq { fn write_file(filename: &Path, content: ~str) { result::get( - io::file_writer(filename, ~[io::Create, io::Truncate])) + &io::file_writer(filename, ~[io::Create, io::Truncate])) .write_str(content); } @@ -30,7 +30,7 @@ fn contains(haystack: ~str, needle: ~str) -> bool { fn find_rust_files(files: &mut ~[Path], path: &Path) { if path.filetype() == Some(~".rs") && !contains(path.to_str(), ~"utf8") { // ignoring "utf8" tests because something is broken - vec::push(*files, *path); + files.push(*path); } else if os::path_is_dir(path) && !contains(path.to_str(), ~"compile-fail") && !contains(path.to_str(), ~"build") { @@ -124,7 +124,7 @@ fn stash_ty_if(c: fn@(@ast::ty, test_mode)->bool, e: @ast::ty, tm: test_mode) { if c(e, tm) { - vec::push(*es,*e); + es.push(*e); } else {/* now my indices are wrong :( */ } } @@ -221,7 +221,7 @@ fn under(n: uint, it: fn(uint)) { while i < n { it(i); i += 1u; } } -fn as_str(f: fn@(io::Writer)) -> ~str { +fn as_str(f: fn@(+x: io::Writer)) -> ~str { io::with_str_writer(f) } @@ -229,7 +229,7 @@ fn check_variants_of_ast(crate: ast::crate, codemap: codemap::codemap, filename: &Path, cx: context) { let stolen = steal(crate, cx.mode); let extra_exprs = vec::filter(common_exprs(), - |a| safe_to_use_expr(a, cx.mode) ); + |a| safe_to_use_expr(*a, cx.mode) ); check_variants_T(crate, codemap, filename, ~"expr", extra_exprs + stolen.exprs, pprust::expr_to_str, replace_expr_in_crate, cx); @@ -243,7 +243,7 @@ fn check_variants_T( filename: &Path, thing_label: ~str, things: ~[T], - stringifier: fn@(@T, syntax::parse::token::ident_interner) -> ~str, + stringifier: fn@(@T, @syntax::parse::token::ident_interner) -> ~str, replacer: fn@(ast::crate, uint, T, test_mode) -> ast::crate, cx: context ) { @@ -543,7 +543,7 @@ fn check_convergence(files: &[Path]) { error!("pp convergence tests: %u files", vec::len(files)); for files.each |file| { if !file_might_not_converge(file) { - let s = @result::get(io::read_whole_file_str(file)); + let s = @result::get(&io::read_whole_file_str(file)); if !content_might_not_converge(*s) { error!("pp converge: %s", file.to_str()); // Change from 7u to 2u once @@ -563,7 +563,7 @@ fn check_variants(files: &[Path], cx: context) { loop; } - let s = @result::get(io::read_whole_file_str(file)); + let s = @result::get(&io::read_whole_file_str(file)); if contains(*s, ~"#") { loop; // Macros are confusing } diff --git a/src/fuzzer/ivec_fuzz.rs b/src/fuzzer/ivec_fuzz.rs index 9351e23acf08..49d34e769925 100644 --- a/src/fuzzer/ivec_fuzz.rs +++ b/src/fuzzer/ivec_fuzz.rs @@ -55,11 +55,11 @@ fn vec_edits(v: ~[T], xs: ~[T]) -> ~[~[T]] { if Lv != 1u { // When Lv == 1u, this is redundant with omit. - vec::push(edits, ~[]); + edits.push(~[]); } if Lv >= 3u { // When Lv == 2u, this is redundant with swap. - vec::push(edits, vec::reversed(v)); + edits.push(vec::reversed(v)); } ix(0u, 1u, Lv) {|i| edits += ~[vec_omit(v, i)]; } ix(0u, 1u, Lv) {|i| edits += ~[vec_dup(v, i)]; } @@ -69,10 +69,10 @@ fn vec_edits(v: ~[T], xs: ~[T]) -> ~[~[T]] { ix(0u, 1u, len(xs)) {|j| ix(0u, 1u, Lv) {|i| - vec::push(edits, vec_poke(v, i, xs[j])); + edits.push(vec_poke(v, i, xs[j])); } ix(0u, 0u, Lv) {|i| - vec::push(edits, vec_insert(v, i, xs[j])); + edits.push(vec_insert(v, i, xs[j])); } } diff --git a/src/fuzzer/rand_util.rs b/src/fuzzer/rand_util.rs index 39301d17a452..6745805e2d88 100644 --- a/src/fuzzer/rand_util.rs +++ b/src/fuzzer/rand_util.rs @@ -61,7 +61,7 @@ fn weighted_vec(v : ~[weighted]) -> ~[T] { for {weight: weight, item: item} in v { let i = 0u; while i < weight { - vec::push(r, item); + r.push(item); i += 1u; } } diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs index e35e6536410f..7d410c0337ad 100644 --- a/src/libcore/at_vec.rs +++ b/src/libcore/at_vec.rs @@ -1,14 +1,11 @@ //! Managed vectors -use ptr::addr_of; +// NB: transitionary, de-mode-ing. +// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_pattern)]; -export init_op; -export capacity; -export build_sized, build, build_sized_opt; -export map; -export from_fn, from_elem; -export raw; -export traits; +use cast::transmute; +use ptr::addr_of; /// Code for dealing with @-vectors. This is pretty incomplete, and /// contains a bunch of duplication from the code for ~-vectors. @@ -29,10 +26,10 @@ extern mod rusti { /// Returns the number of elements the vector can hold without reallocating #[inline(always)] -pure fn capacity(&&v: @[const T]) -> uint { +pub pure fn capacity(v: @[const T]) -> uint { unsafe { let repr: **raw::VecRepr = - ::cast::reinterpret_cast(&addr_of(v)); + ::cast::reinterpret_cast(&addr_of(&v)); (**repr).unboxed.alloc / sys::size_of::() } } @@ -50,12 +47,12 @@ pure fn capacity(&&v: @[const T]) -> uint { * onto the vector being constructed. */ #[inline(always)] -pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> @[A] { - let mut vec = @[]; - unsafe { raw::reserve(vec, size); } - builder(|+x| unsafe { raw::push(vec, move x) }); - return vec; +pub pure fn build_sized(size: uint, + builder: &fn(push: pure fn(v: A))) -> @[A] { + let mut vec: @[const A] = @[]; + unsafe { raw::reserve(&mut vec, size); } + builder(|+x| unsafe { raw::push(&mut vec, move x) }); + return unsafe { transmute(vec) }; } /** @@ -69,7 +66,7 @@ pure fn build_sized(size: uint, * onto the vector being constructed. */ #[inline(always)] -pure fn build(builder: fn(push: pure fn(+v: A))) -> @[A] { +pub pure fn build(builder: &fn(push: pure fn(v: A))) -> @[A] { build_sized(4, builder) } @@ -86,14 +83,14 @@ pure fn build(builder: fn(push: pure fn(+v: A))) -> @[A] { * onto the vector being constructed. */ #[inline(always)] -pure fn build_sized_opt(size: Option, - builder: fn(push: pure fn(+v: A))) -> @[A] { +pub pure fn build_sized_opt(size: Option, + builder: &fn(push: pure fn(v: A))) -> @[A] { build_sized(size.get_default(4), builder) } // Appending #[inline(always)] -pure fn append(lhs: @[T], rhs: &[const T]) -> @[T] { +pub pure fn append(lhs: @[T], rhs: &[const T]) -> @[T] { do build_sized(lhs.len() + rhs.len()) |push| { for vec::each(lhs) |x| { push(*x); } for uint::range(0, rhs.len()) |i| { push(rhs[i]); } @@ -102,10 +99,10 @@ pure fn append(lhs: @[T], rhs: &[const T]) -> @[T] { /// Apply a function to each element of a vector and return the results -pure fn map(v: &[T], f: fn(T) -> U) -> @[U] { +pub pure fn map(v: &[T], f: &fn(x: &T) -> U) -> @[U] { do build_sized(v.len()) |push| { for vec::each(v) |elem| { - push(f(*elem)); + push(f(elem)); } } } @@ -116,7 +113,7 @@ pure fn map(v: &[T], f: fn(T) -> U) -> @[U] { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -pure fn from_fn(n_elts: uint, op: iter::InitOp) -> @[T] { +pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> @[T] { do build_sized(n_elts) |push| { let mut i: uint = 0u; while i < n_elts { push(op(i)); i += 1u; } @@ -129,17 +126,17 @@ pure fn from_fn(n_elts: uint, op: iter::InitOp) -> @[T] { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value `t`. */ -pure fn from_elem(n_elts: uint, t: T) -> @[T] { +pub pure fn from_elem(n_elts: uint, t: T) -> @[T] { do build_sized(n_elts) |push| { let mut i: uint = 0u; - while i < n_elts { push(t); i += 1u; } + while i < n_elts { push(copy t); i += 1u; } } } #[cfg(notest)] -mod traits { +pub mod traits { #[legacy_exports]; - impl @[T] : Add<&[const T],@[T]> { + pub impl @[T] : Add<&[const T],@[T]> { #[inline(always)] pure fn add(rhs: & &[const T]) -> @[T] { append(self, (*rhs)) @@ -148,13 +145,12 @@ mod traits { } #[cfg(test)] -mod traits { +pub mod traits { #[legacy_exports];} -mod raw { - #[legacy_exports]; - type VecRepr = vec::raw::VecRepr; - type SliceRepr = vec::raw::SliceRepr; +pub mod raw { + pub type VecRepr = vec::raw::VecRepr; + pub type SliceRepr = vec::raw::SliceRepr; /** * Sets the length of a vector @@ -164,14 +160,14 @@ mod raw { * the vector is actually the specified size. */ #[inline(always)] - unsafe fn set_len(&&v: @[const T], new_len: uint) { - let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v)); + pub unsafe fn set_len(v: @[const T], new_len: uint) { + let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(&v)); (**repr).unboxed.fill = new_len * sys::size_of::(); } #[inline(always)] - unsafe fn push(&v: @[const T], +initval: T) { - let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v)); + pub unsafe fn push(v: &mut @[const T], initval: T) { + let repr: **VecRepr = ::cast::reinterpret_cast(&v); let fill = (**repr).unboxed.fill; if (**repr).unboxed.alloc > fill { push_fast(v, move initval); @@ -182,16 +178,16 @@ mod raw { } // This doesn't bother to make sure we have space. #[inline(always)] // really pretty please - unsafe fn push_fast(&v: @[const T], +initval: T) { - let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v)); + pub unsafe fn push_fast(v: &mut @[const T], initval: T) { + let repr: **VecRepr = ::cast::reinterpret_cast(&v); let fill = (**repr).unboxed.fill; (**repr).unboxed.fill += sys::size_of::(); - let p = ptr::addr_of((**repr).unboxed.data); + let p = addr_of(&((**repr).unboxed.data)); let p = ptr::offset(p, fill) as *mut T; rusti::move_val_init(*p, move initval); } - unsafe fn push_slow(&v: @[const T], +initval: T) { + pub unsafe fn push_slow(v: &mut @[const T], initval: T) { reserve_at_least(v, v.len() + 1u); push_fast(v, move initval); } @@ -207,10 +203,10 @@ mod raw { * * v - A vector * * n - The number of elements to reserve space for */ - unsafe fn reserve(&v: @[const T], n: uint) { + pub unsafe fn reserve(v: &mut @[const T], n: uint) { // Only make the (slow) call into the runtime if we have to - if capacity(v) < n { - let ptr = addr_of(v) as **VecRepr; + if capacity(*v) < n { + let ptr: **VecRepr = transmute(copy v); rustrt::vec_reserve_shared_actual(sys::get_type_desc::(), ptr, n as libc::size_t); } @@ -231,14 +227,14 @@ mod raw { * * v - A vector * * n - The number of elements to reserve space for */ - unsafe fn reserve_at_least(&v: @[const T], n: uint) { + pub unsafe fn reserve_at_least(v: &mut @[const T], n: uint) { reserve(v, uint::next_power_of_two(n)); } } #[test] -fn test() { +pub fn test() { // Some code that could use that, then: fn seq_range(lo: uint, hi: uint) -> @[uint] { do build |push| { @@ -254,7 +250,6 @@ fn test() { } #[test] -fn append_test() { +pub fn append_test() { assert @[1,2,3] + @[4,5,6] == @[1,2,3,4,5,6]; } - diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index 1419aac63696..9e7e257ee307 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -8,43 +8,39 @@ use cmp::Eq; -export not, and, or, xor, implies; -export eq, ne, is_true, is_false; -export from_str, to_str, all_values, to_bit; - /// Negation / inverse -pure fn not(v: bool) -> bool { !v } +pub pure fn not(v: bool) -> bool { !v } /// Conjunction -pure fn and(a: bool, b: bool) -> bool { a && b } +pub pure fn and(a: bool, b: bool) -> bool { a && b } /// Disjunction -pure fn or(a: bool, b: bool) -> bool { a || b } +pub pure fn or(a: bool, b: bool) -> bool { a || b } /** * Exclusive or * * Identical to `or(and(a, not(b)), and(not(a), b))` */ -pure fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) } +pub pure fn xor(a: bool, b: bool) -> bool { (a && !b) || (!a && b) } /// Implication in the logic, i.e. from `a` follows `b` -pure fn implies(a: bool, b: bool) -> bool { !a || b } +pub pure fn implies(a: bool, b: bool) -> bool { !a || b } /// true if truth values `a` and `b` are indistinguishable in the logic -pure fn eq(a: bool, b: bool) -> bool { a == b } +pub pure fn eq(a: bool, b: bool) -> bool { a == b } /// true if truth values `a` and `b` are distinguishable in the logic -pure fn ne(a: bool, b: bool) -> bool { a != b } +pub pure fn ne(a: bool, b: bool) -> bool { a != b } /// true if `v` represents truth in the logic -pure fn is_true(v: bool) -> bool { v } +pub pure fn is_true(v: bool) -> bool { v } /// true if `v` represents falsehood in the logic -pure fn is_false(v: bool) -> bool { !v } +pub pure fn is_false(v: bool) -> bool { !v } /// Parse logic value from `s` -pure fn from_str(s: &str) -> Option { +pub pure fn from_str(s: &str) -> Option { if s == "true" { Some(true) } else if s == "false" { @@ -55,19 +51,19 @@ pure fn from_str(s: &str) -> Option { } /// Convert `v` into a string -pure fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } } +pub pure fn to_str(v: bool) -> ~str { if v { ~"true" } else { ~"false" } } /** * Iterates over all truth values by passing them to `blk` in an unspecified * order */ -fn all_values(blk: fn(v: bool)) { +pub fn all_values(blk: fn(v: bool)) { blk(true); blk(false); } /// converts truth value to an 8 bit byte -pure fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } } +pub pure fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } } impl bool : cmp::Eq { pure fn eq(other: &bool) -> bool { self == (*other) } @@ -75,20 +71,20 @@ impl bool : cmp::Eq { } #[test] -fn test_bool_from_str() { +pub fn test_bool_from_str() { do all_values |v| { assert Some(v) == from_str(bool::to_str(v)) } } #[test] -fn test_bool_to_str() { +pub fn test_bool_to_str() { assert to_str(false) == ~"false"; assert to_str(true) == ~"true"; } #[test] -fn test_bool_to_bit() { +pub fn test_bool_to_bit() { do all_values |v| { assert to_bit(v) == if is_true(v) { 1u8 } else { 0u8 }; } diff --git a/src/libcore/box.rs b/src/libcore/box.rs index fd3715b457c4..d34679f2bd75 100644 --- a/src/libcore/box.rs +++ b/src/libcore/box.rs @@ -7,28 +7,24 @@ use cmp::{Eq, Ord}; use intrinsic::TyDesc; -export ptr_eq, raw; - -mod raw { - #[legacy_exports]; - - struct BoxHeaderRepr { +pub mod raw { + pub struct BoxHeaderRepr { ref_count: uint, type_desc: *TyDesc, prev: *BoxRepr, next: *BoxRepr, } - struct BoxRepr { + pub struct BoxRepr { header: BoxHeaderRepr, data: u8 } } -pure fn ptr_eq(a: @T, b: @T) -> bool { +pub pure fn ptr_eq(a: @T, b: @T) -> bool { //! Determine if two shared boxes point to the same object - unsafe { ptr::addr_of(*a) == ptr::addr_of(*b) } + unsafe { ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) } } impl @const T : Eq { diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs index 93467404868f..f4f0d7b61044 100644 --- a/src/libcore/cast.rs +++ b/src/libcore/cast.rs @@ -1,21 +1,14 @@ //! Unsafe operations -export reinterpret_cast, forget, bump_box_refcount, transmute; -export transmute_mut, transmute_immut, transmute_region, transmute_mut_region; -export transmute_mut_unsafe, transmute_immut_unsafe; - -export copy_lifetime, copy_lifetime_vec; - #[abi = "rust-intrinsic"] extern mod rusti { - #[legacy_exports]; fn forget(-x: T); - fn reinterpret_cast(e: T) -> U; + fn reinterpret_cast(&&e: T) -> U; } /// Casts the value at `src` to U. The two types must have the same length. #[inline(always)] -unsafe fn reinterpret_cast(src: &T) -> U { +pub unsafe fn reinterpret_cast(src: &T) -> U { rusti::reinterpret_cast(*src) } @@ -28,7 +21,7 @@ unsafe fn reinterpret_cast(src: &T) -> U { * reinterpret_cast on managed pointer types. */ #[inline(always)] -unsafe fn forget(-thing: T) { rusti::forget(move thing); } +pub unsafe fn forget(thing: T) { rusti::forget(move thing); } /** * Force-increment the reference count on a shared box. If used @@ -36,7 +29,7 @@ unsafe fn forget(-thing: T) { rusti::forget(move thing); } * and/or reinterpret_cast when such calls would otherwise scramble a box's * reference count */ -unsafe fn bump_box_refcount(+t: @T) { forget(move t); } +pub unsafe fn bump_box_refcount(t: @T) { forget(move t); } /** * Transform a value of one type into a value of another type. @@ -47,7 +40,7 @@ unsafe fn bump_box_refcount(+t: @T) { forget(move t); } * assert transmute("L") == ~[76u8, 0u8]; */ #[inline(always)] -unsafe fn transmute(-thing: L) -> G { +pub unsafe fn transmute(thing: L) -> G { let newthing: G = reinterpret_cast(&thing); forget(move thing); move newthing @@ -55,39 +48,45 @@ unsafe fn transmute(-thing: L) -> G { /// Coerce an immutable reference to be mutable. #[inline(always)] -unsafe fn transmute_mut(+ptr: &a/T) -> &a/mut T { transmute(move ptr) } +pub unsafe fn transmute_mut(ptr: &a/T) -> &a/mut T { transmute(move ptr) } /// Coerce a mutable reference to be immutable. #[inline(always)] -unsafe fn transmute_immut(+ptr: &a/mut T) -> &a/T { transmute(move ptr) } +pub unsafe fn transmute_immut(ptr: &a/mut T) -> &a/T { + transmute(move ptr) +} /// Coerce a borrowed pointer to have an arbitrary associated region. #[inline(always)] -unsafe fn transmute_region(+ptr: &a/T) -> &b/T { transmute(move ptr) } +pub unsafe fn transmute_region(ptr: &a/T) -> &b/T { transmute(move ptr) } /// Coerce an immutable reference to be mutable. #[inline(always)] -unsafe fn transmute_mut_unsafe(+ptr: *const T) -> *mut T { transmute(ptr) } +pub unsafe fn transmute_mut_unsafe(ptr: *const T) -> *mut T { + transmute(ptr) +} /// Coerce an immutable reference to be mutable. #[inline(always)] -unsafe fn transmute_immut_unsafe(+ptr: *const T) -> *T { transmute(ptr) } +pub unsafe fn transmute_immut_unsafe(ptr: *const T) -> *T { + transmute(ptr) +} /// Coerce a borrowed mutable pointer to have an arbitrary associated region. #[inline(always)] -unsafe fn transmute_mut_region(+ptr: &a/mut T) -> &b/mut T { +pub unsafe fn transmute_mut_region(ptr: &a/mut T) -> &b/mut T { transmute(move ptr) } /// Transforms lifetime of the second pointer to match the first. #[inline(always)] -unsafe fn copy_lifetime(_ptr: &a/S, ptr: &T) -> &a/T { +pub unsafe fn copy_lifetime(_ptr: &a/S, ptr: &T) -> &a/T { transmute_region(ptr) } /// Transforms lifetime of the second pointer to match the first. #[inline(always)] -unsafe fn copy_lifetime_vec(_ptr: &a/[S], ptr: &T) -> &a/T { +pub unsafe fn copy_lifetime_vec(_ptr: &a/[S], ptr: &T) -> &a/T { transmute_region(ptr) } @@ -97,16 +96,14 @@ unsafe fn copy_lifetime_vec(_ptr: &a/[S], ptr: &T) -> &a/T { ****************************************************************************/ #[cfg(test)] -mod tests { - #[legacy_exports]; - +pub mod tests { #[test] - fn test_reinterpret_cast() { + pub fn test_reinterpret_cast() { assert 1u == unsafe { reinterpret_cast(&1) }; } #[test] - fn test_bump_box_refcount() { + pub fn test_bump_box_refcount() { unsafe { let box = @~"box box box"; // refcount 1 bump_box_refcount(box); // refcount 2 @@ -121,7 +118,7 @@ mod tests { } #[test] - fn test_transmute() { + pub fn test_transmute() { unsafe { let x = @1; let x: *int = transmute(x); @@ -131,7 +128,7 @@ mod tests { } #[test] - fn test_transmute2() { + pub fn test_transmute2() { unsafe { assert ~[76u8, 0u8] == transmute(~"L"); } diff --git a/src/libcore/char.rs b/src/libcore/char.rs index e6fab268a5b1..b76571864e07 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -39,24 +39,16 @@ use cmp::Eq; Cn Unassigned a reserved unassigned code point or a noncharacter */ -export is_alphabetic, - is_XID_start, is_XID_continue, - is_lowercase, is_uppercase, - is_whitespace, is_alphanumeric, - is_ascii, is_digit, - to_digit, cmp, - escape_default, escape_unicode; - -use is_alphabetic = unicode::derived_property::Alphabetic; -use is_XID_start = unicode::derived_property::XID_Start; -use is_XID_continue = unicode::derived_property::XID_Continue; +pub use is_alphabetic = unicode::derived_property::Alphabetic; +pub use is_XID_start = unicode::derived_property::XID_Start; +pub use is_XID_continue = unicode::derived_property::XID_Continue; /** * Indicates whether a character is in lower case, defined * in terms of the Unicode General Category 'Ll' */ -pure fn is_lowercase(c: char) -> bool { +pub pure fn is_lowercase(c: char) -> bool { return unicode::general_category::Ll(c); } @@ -64,7 +56,7 @@ pure fn is_lowercase(c: char) -> bool { * Indicates whether a character is in upper case, defined * in terms of the Unicode General Category 'Lu'. */ -pure fn is_uppercase(c: char) -> bool { +pub pure fn is_uppercase(c: char) -> bool { return unicode::general_category::Lu(c); } @@ -73,7 +65,7 @@ pure fn is_uppercase(c: char) -> bool { * terms of the Unicode General Categories 'Zs', 'Zl', 'Zp' * additional 'Cc'-category control codes in the range [0x09, 0x0d] */ -pure fn is_whitespace(c: char) -> bool { +pub pure fn is_whitespace(c: char) -> bool { return ('\x09' <= c && c <= '\x0d') || unicode::general_category::Zs(c) || unicode::general_category::Zl(c) @@ -85,7 +77,7 @@ pure fn is_whitespace(c: char) -> bool { * defined in terms of the Unicode General Categories 'Nd', 'Nl', 'No' * and the Derived Core Property 'Alphabetic'. */ -pure fn is_alphanumeric(c: char) -> bool { +pub pure fn is_alphanumeric(c: char) -> bool { return unicode::derived_property::Alphabetic(c) || unicode::general_category::Nd(c) || unicode::general_category::Nl(c) || @@ -93,12 +85,12 @@ pure fn is_alphanumeric(c: char) -> bool { } /// Indicates whether the character is an ASCII character -pure fn is_ascii(c: char) -> bool { +pub pure fn is_ascii(c: char) -> bool { c - ('\x7F' & c) == '\x00' } /// Indicates whether the character is numeric (Nd, Nl, or No) -pure fn is_digit(c: char) -> bool { +pub pure fn is_digit(c: char) -> bool { return unicode::general_category::Nd(c) || unicode::general_category::Nl(c) || unicode::general_category::No(c); @@ -114,7 +106,7 @@ pure fn is_digit(c: char) -> bool { * 'b' or 'B', 11, etc. Returns none if the char does not * refer to a digit in the given radix. */ -pure fn to_digit(c: char, radix: uint) -> Option { +pub pure fn to_digit(c: char, radix: uint) -> Option { let val = match c { '0' .. '9' => c as uint - ('0' as uint), 'a' .. 'z' => c as uint + 10u - ('a' as uint), @@ -134,7 +126,7 @@ pure fn to_digit(c: char, radix: uint) -> Option { * - chars in [0x100,0xffff] get 4-digit escapes: `\\uNNNN` * - chars above 0x10000 get 8-digit escapes: `\\UNNNNNNNN` */ -fn escape_unicode(c: char) -> ~str { +pub fn escape_unicode(c: char) -> ~str { let s = u32::to_str(c as u32, 16u); let (c, pad) = (if c <= '\xff' { ('x', 2u) } else if c <= '\uffff' { ('u', 4u) } @@ -159,7 +151,7 @@ fn escape_unicode(c: char) -> ~str { * - Any other chars in the range [0x20,0x7e] are not escaped. * - Any other chars are given hex unicode escapes; see `escape_unicode`. */ -fn escape_default(c: char) -> ~str { +pub fn escape_default(c: char) -> ~str { match c { '\t' => ~"\\t", '\r' => ~"\\r", @@ -179,7 +171,7 @@ fn escape_default(c: char) -> ~str { * * -1 if a < b, 0 if a == b, +1 if a > b */ -pure fn cmp(a: char, b: char) -> int { +pub pure fn cmp(a: char, b: char) -> int { return if b > a { -1 } else if b < a { 1 } else { 0 } diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs index 064387dd6b85..df6074e32009 100644 --- a/src/libcore/cleanup.rs +++ b/src/libcore/cleanup.rs @@ -10,8 +10,6 @@ use repr::BoxRepr; use sys::TypeDesc; use cast::transmute; -export annihilate; - /** * Runtime structures * diff --git a/src/libcore/cmath.rs b/src/libcore/cmath.rs index 11f26c24b94f..9a9a7cb31121 100644 --- a/src/libcore/cmath.rs +++ b/src/libcore/cmath.rs @@ -3,10 +3,6 @@ #[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; -// uncomment once #1433 is fixed -// FIXME (#1433): export c_float_math_consts; -// FIXME (#1433): export c_double_math_consts; - use libc::c_int; use libc::c_float; use libc::c_double; @@ -193,66 +189,62 @@ pub mod c_double_targ_consts { FIXME use these once they can be parsed (see Issue #1433) -mod c_float_math_consts { - #[legacy_exports]; - const pi: c_float = 0x1.921fb6p+1_f32; - const div_1_pi: c_float = 0x1.45f306p-2_f32; - const div_2_pi: c_float = 0x1.45f306p-1_f32; - const div_pi_2: c_float = 0x1.921fb6p+0_f32; - const div_pi_4: c_float = 0x1.921fb6p-1_f32; - const div_2_sqrtpi: c_float = 0x1.20dd76p+0_f32; - const e: c_float = 0x1.5bf0a8p+1_f32; - const log2_e: c_float = 0x1.715476p+0_f32; - const log10_e: c_float = 0x1.bcb7b2p-2_f32; - const ln_2: c_float = 0x1.62e43p-1_f32; - const ln_10: c_float = 0x1.26bb1cp+1_f32; - const sqrt2: c_float = 0x1.6a09e6p+0_f32; - const div_1_sqrt2: c_float = 0x1.6a09e6p-1_f32; +pub mod c_float_math_consts { + pub const pi: c_float = 0x1.921fb6p+1_f32; + pub const div_1_pi: c_float = 0x1.45f306p-2_f32; + pub const div_2_pi: c_float = 0x1.45f306p-1_f32; + pub const div_pi_2: c_float = 0x1.921fb6p+0_f32; + pub const div_pi_4: c_float = 0x1.921fb6p-1_f32; + pub const div_2_sqrtpi: c_float = 0x1.20dd76p+0_f32; + pub const e: c_float = 0x1.5bf0a8p+1_f32; + pub const log2_e: c_float = 0x1.715476p+0_f32; + pub const log10_e: c_float = 0x1.bcb7b2p-2_f32; + pub const ln_2: c_float = 0x1.62e43p-1_f32; + pub const ln_10: c_float = 0x1.26bb1cp+1_f32; + pub const sqrt2: c_float = 0x1.6a09e6p+0_f32; + pub const div_1_sqrt2: c_float = 0x1.6a09e6p-1_f32; } -mod c_double_math_consts { - #[legacy_exports]; - const pi: c_double = 0x1.921fb54442d18p+1_f64; - const div_1_pi: c_double = 0x1.45f306dc9c883p-2_f64; - const div_2_pi: c_double = 0x1.45f306dc9c883p-1_f64; - const div_pi_2: c_double = 0x1.921fb54442d18p+0_f64; - const div_pi_4: c_double = 0x1.921fb54442d18p-1_f64; - const div_2_sqrtpi: c_double = 0x1.20dd750429b6dp+0_f64; - const e: c_double = 0x1.5bf0a8b145769p+1_f64; - const log2_e: c_double = 0x1.71547652b82fep+0_f64; - const log10_e: c_double = 0x1.bcb7b1526e50ep-2_f64; - const ln_2: c_double = 0x1.62e42fefa39efp-1_f64; - const ln_10: c_double = 0x1.26bb1bbb55516p+1_f64; - const sqrt2: c_double = 0x1.6a09e667f3bcdp+0_f64; - const div_1_sqrt2: c_double = 0x1.6a09e667f3bcdp-1_f64; +pub mod c_double_math_consts { + pub const pi: c_double = 0x1.921fb54442d18p+1_f64; + pub const div_1_pi: c_double = 0x1.45f306dc9c883p-2_f64; + pub const div_2_pi: c_double = 0x1.45f306dc9c883p-1_f64; + pub const div_pi_2: c_double = 0x1.921fb54442d18p+0_f64; + pub const div_pi_4: c_double = 0x1.921fb54442d18p-1_f64; + pub const div_2_sqrtpi: c_double = 0x1.20dd750429b6dp+0_f64; + pub const e: c_double = 0x1.5bf0a8b145769p+1_f64; + pub const log2_e: c_double = 0x1.71547652b82fep+0_f64; + pub const log10_e: c_double = 0x1.bcb7b1526e50ep-2_f64; + pub const ln_2: c_double = 0x1.62e42fefa39efp-1_f64; + pub const ln_10: c_double = 0x1.26bb1bbb55516p+1_f64; + pub const sqrt2: c_double = 0x1.6a09e667f3bcdp+0_f64; + pub const div_1_sqrt2: c_double = 0x1.6a09e667f3bcdp-1_f64; } -mod c_float_targ_consts { - #[legacy_exports]; - const radix: uint = 2u; - const mantissa_digits: uint = 24u; - const digits: uint = 6u; - const min_exp: int = -125; - const max_exp: int = 128; - const min_10_exp: int = -37; - const max_10_exp: int = 38; - const min_value: c_float = 0x1p-126_f32; - const max_value: c_float = 0x1.fffffep+127_f32; - const epsilon: c_float = 0x1p-23_f32; +pub mod c_float_targ_consts { + pub const radix: uint = 2u; + pub const mantissa_digits: uint = 24u; + pub const digits: uint = 6u; + pub const min_exp: int = -125; + pub const max_exp: int = 128; + pub const min_10_exp: int = -37; + pub const max_10_exp: int = 38; + pub const min_value: c_float = 0x1p-126_f32; + pub const max_value: c_float = 0x1.fffffep+127_f32; + pub const epsilon: c_float = 0x1p-23_f32; } -mod c_double_targ_consts { - #[legacy_exports]; - const radix: uint = 2u; - const mantissa_digits: uint = 53u; - const digits: uint = 15u; - const min_exp: int = -1021; - const max_exp: int = 1024; - const min_10_exp: int = -307; - const max_10_exp: int = 308; - const min_value: c_double = 0x1p-1022_f64; - const max_value: c_double = 0x1.fffffffffffffp+1023_f64; - const epsilon: c_double = 0x1p-52_f64; +pub mod c_double_targ_consts { + pub const radix: uint = 2u; + pub const mantissa_digits: uint = 53u; + pub const digits: uint = 15u; + pub const min_exp: int = -1021; + pub const max_exp: int = 1024; + pub const min_10_exp: int = -307; + pub const max_10_exp: int = 308; + pub const min_value: c_double = 0x1p-1022_f64; + pub const max_value: c_double = 0x1.fffffffffffffp+1023_f64; + pub const epsilon: c_double = 0x1p-52_f64; } */ diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 37a8f976d74a..c3630e9f857c 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -14,17 +14,14 @@ and `Eq` to overload the `==` and `!=` operators. #[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; -use nounittest::*; -use unittest::*; -export Ord; -export Eq; +pub use nounittest::*; +pub use unittest::*; /// Interfaces used for comparison. // Awful hack to work around duplicate lang items in core test. #[cfg(notest)] mod nounittest { - #[legacy_exports]; /** * Trait for values that can be compared for a sort-order. * @@ -33,7 +30,7 @@ mod nounittest { * default implementations. */ #[lang="ord"] - trait Ord { + pub trait Ord { pure fn lt(other: &self) -> bool; pure fn le(other: &self) -> bool; pure fn ge(other: &self) -> bool; @@ -50,7 +47,7 @@ mod nounittest { * a default implementation. */ #[lang="eq"] - trait Eq { + pub trait Eq { pure fn eq(other: &self) -> bool; pure fn ne(other: &self) -> bool; } @@ -63,14 +60,14 @@ mod nounittest { #[cfg(test)] mod unittest { #[legacy_exports]; - trait Ord { + pub trait Ord { pure fn lt(other: &self) -> bool; pure fn le(other: &self) -> bool; pure fn ge(other: &self) -> bool; pure fn gt(other: &self) -> bool; } - trait Eq { + pub trait Eq { pure fn eq(other: &self) -> bool; pure fn ne(other: &self) -> bool; } @@ -80,27 +77,27 @@ mod unittest { mod unittest { #[legacy_exports];} -pure fn lt(v1: &T, v2: &T) -> bool { +pub pure fn lt(v1: &T, v2: &T) -> bool { (*v1).lt(v2) } -pure fn le(v1: &T, v2: &T) -> bool { +pub pure fn le(v1: &T, v2: &T) -> bool { (*v1).lt(v2) || (*v1).eq(v2) } -pure fn eq(v1: &T, v2: &T) -> bool { +pub pure fn eq(v1: &T, v2: &T) -> bool { (*v1).eq(v2) } -pure fn ne(v1: &T, v2: &T) -> bool { +pub pure fn ne(v1: &T, v2: &T) -> bool { (*v1).ne(v2) } -pure fn ge(v1: &T, v2: &T) -> bool { +pub pure fn ge(v1: &T, v2: &T) -> bool { (*v1).ge(v2) } -pure fn gt(v1: &T, v2: &T) -> bool { +pub pure fn gt(v1: &T, v2: &T) -> bool { (*v1).gt(v2) } diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index b99eec8bb5b3..64c38d13e493 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -32,14 +32,13 @@ will once again be the preferred module for intertask communication. */ -// NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// NB: transitionary, de-mode-ing +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; use either::Either; use libc::size_t; - - +// After snapshot, change p2::addr_of => addr_of /** * A communication endpoint that can receive messages @@ -76,7 +75,7 @@ pub fn Port() -> Port { impl Port { fn chan() -> Chan { Chan(self) } - fn send(+v: T) { self.chan().send(move v) } + fn send(v: T) { self.chan().send(move v) } fn recv() -> T { recv(self) } fn peek() -> bool { peek(self) } @@ -85,7 +84,7 @@ impl Port { impl Chan { fn chan() -> Chan { self } - fn send(+v: T) { send(self, move v) } + fn send(v: T) { send(self, move v) } fn recv() -> T { recv_chan(self) } fn peek() -> bool { peek_chan(self) } @@ -104,7 +103,7 @@ struct PortPtr { // Once the port is detached it's guaranteed not to receive further // messages let yield = 0; - let yieldp = ptr::addr_of(yield); + let yieldp = ptr::addr_of(&yield); rustrt::rust_port_begin_detach(self.po, yieldp); if yield != 0 { // Need to wait for the port to be detached @@ -167,7 +166,7 @@ fn as_raw_port(ch: comm::Chan, f: fn(*rust_port) -> U) -> U { * Constructs a channel. The channel is bound to the port used to * construct it. */ -pub fn Chan(p: Port) -> Chan { +pub fn Chan(&&p: Port) -> Chan { Chan_(rustrt::get_port_id((**p).po)) } @@ -175,9 +174,9 @@ pub fn Chan(p: Port) -> Chan { * Sends data over a channel. The sent data is moved into the channel, * whereupon the caller loses access to it. */ -pub fn send(ch: Chan, +data: T) { +pub fn send(ch: Chan, data: T) { let Chan_(p) = ch; - let data_ptr = ptr::addr_of(data) as *(); + let data_ptr = ptr::addr_of(&data) as *(); let res = rustrt::rust_port_id_send(p, data_ptr); if res != 0 unsafe { // Data sent successfully @@ -207,10 +206,10 @@ fn peek_chan(ch: comm::Chan) -> bool { /// Receive on a raw port pointer fn recv_(p: *rust_port) -> T { let yield = 0; - let yieldp = ptr::addr_of(yield); + let yieldp = ptr::addr_of(&yield); let mut res; res = rusti::init::(); - rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp); + rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp); if yield != 0 { // Data isn't available yet, so res has not been initialized. @@ -234,12 +233,12 @@ fn peek_(p: *rust_port) -> bool { pub fn select2(p_a: Port, p_b: Port) -> Either { let ports = ~[(**p_a).po, (**p_b).po]; - let yield = 0, yieldp = ptr::addr_of(yield); + let yield = 0, yieldp = ptr::addr_of(&yield); let mut resport: *rust_port; resport = rusti::init::<*rust_port>(); do vec::as_imm_buf(ports) |ports, n_ports| { - rustrt::rust_port_select(ptr::addr_of(resport), ports, + rustrt::rust_port_select(ptr::addr_of(&resport), ports, n_ports as size_t, yieldp); } @@ -275,7 +274,6 @@ type port_id = int; #[abi = "cdecl"] extern mod rustrt { - #[legacy_exports]; fn rust_port_id_send(target_port: port_id, data: *()) -> libc::uintptr_t; fn new_port(unit_sz: libc::size_t) -> *rust_port; @@ -298,7 +296,6 @@ extern mod rustrt { #[abi = "rust-intrinsic"] extern mod rusti { - #[legacy_exports]; fn init() -> T; } @@ -459,7 +456,7 @@ fn test_recv_chan_wrong_task() { let po = Port(); let ch = Chan(po); send(ch, ~"flower"); - assert result::is_err(task::try(|| + assert result::is_err(&task::try(|| recv_chan(ch) )) } diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 9568294c7bab..818e1e890ec9 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -36,7 +36,10 @@ Implicitly, all crates behave as if they included the following prologue: // Don't link to core. We are core. #[no_core]; -#[legacy_modes]; +#[legacy_exports]; + +#[warn(deprecated_mode)]; +#[warn(deprecated_pattern)]; #[warn(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; @@ -85,242 +88,158 @@ export private; /// Operations and constants for `int` #[path = "int-template"] mod int { - #[legacy_exports]; - use inst::{ pow }; - export pow; + pub use inst::{ pow }; #[path = "int.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `i8` #[path = "int-template"] mod i8 { - #[legacy_exports]; #[path = "i8.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `i16` #[path = "int-template"] mod i16 { - #[legacy_exports]; #[path = "i16.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `i32` #[path = "int-template"] mod i32 { - #[legacy_exports]; #[path = "i32.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `i64` #[path = "int-template"] mod i64 { - #[legacy_exports]; #[path = "i64.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `uint` #[path = "uint-template"] mod uint { - #[legacy_exports]; - use inst::{ + pub use inst::{ div_ceil, div_round, div_floor, iterate, next_power_of_two }; - export div_ceil, div_round, div_floor, iterate, - next_power_of_two; - #[path = "uint.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `u8` #[path = "uint-template"] mod u8 { - #[legacy_exports]; - use inst::is_ascii; - export is_ascii; - + pub use inst::is_ascii; #[path = "u8.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `u16` #[path = "uint-template"] mod u16 { - #[legacy_exports]; #[path = "u16.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `u32` #[path = "uint-template"] mod u32 { - #[legacy_exports]; #[path = "u32.rs"] - #[legacy_exports] mod inst; } /// Operations and constants for `u64` #[path = "uint-template"] mod u64 { - #[legacy_exports]; #[path = "u64.rs"] - #[legacy_exports] mod inst; } -#[legacy_exports] mod box; -#[legacy_exports] mod char; -#[legacy_exports] mod float; -#[legacy_exports] mod f32; -#[legacy_exports] mod f64; -#[legacy_exports] mod str; -#[legacy_exports] mod ptr; -#[legacy_exports] mod vec; -#[legacy_exports] mod at_vec; -#[legacy_exports] mod bool; -#[legacy_exports] mod tuple; -#[legacy_exports] mod unit; -#[legacy_exports] mod uniq; // Ubiquitous-utility-type modules #[cfg(notest)] -#[legacy_exports] mod ops; -#[legacy_exports] mod cmp; -#[legacy_exports] mod num; -#[legacy_exports] mod hash; -#[legacy_exports] mod either; -#[legacy_exports] mod iter; -#[legacy_exports] mod logging; -#[legacy_exports] mod option; #[path="iter-trait"] mod option_iter { - #[legacy_exports]; #[path = "option.rs"] - #[legacy_exports] mod inst; } -#[legacy_exports] mod result; -#[legacy_exports] mod to_str; -#[legacy_exports] mod to_bytes; -#[legacy_exports] mod from_str; -#[legacy_exports] mod util; // Data structure modules -#[legacy_exports] mod dvec; #[path="iter-trait"] mod dvec_iter { - #[legacy_exports]; #[path = "dvec.rs"] - #[legacy_exports] mod inst; } -#[legacy_exports] mod dlist; #[path="iter-trait"] mod dlist_iter { - #[legacy_exports]; #[path ="dlist.rs"] - #[legacy_exports] mod inst; } -#[legacy_exports] mod send_map; // Concurrency -#[legacy_exports] mod comm; -#[legacy_exports] mod task { - #[legacy_exports]; - #[legacy_exports] - mod local_data; - #[legacy_exports] + pub mod local_data; mod local_data_priv; - #[legacy_exports] - mod spawn; - #[legacy_exports] - mod rt; + pub mod spawn; + pub mod rt; } -#[legacy_exports] mod future; -#[legacy_exports] mod pipes; // Runtime and language-primitive support -#[legacy_exports] mod gc; -#[legacy_exports] mod io; -#[legacy_exports] mod libc; -#[legacy_exports] mod os; -#[legacy_exports] mod path; -#[legacy_exports] mod rand; -#[legacy_exports] mod run; -#[legacy_exports] mod sys; -#[legacy_exports] mod cast; -#[legacy_exports] mod mutable; -#[legacy_exports] mod flate; -#[legacy_exports] mod repr; -#[legacy_exports] mod cleanup; -#[legacy_exports] mod reflect; // Modules supporting compiler-generated code @@ -336,9 +255,7 @@ mod rt; // For internal use, not exported -#[legacy_exports] mod unicode; -#[legacy_exports] mod private; mod cmath; mod stackwalk; diff --git a/src/libcore/core.rs b/src/libcore/core.rs index 8806131c9fb2..c7261aa8c29c 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -2,8 +2,6 @@ // Export various ubiquitous types, constructors, methods. -#[legacy_exports]; - use option::{Some, None}; use Option = option::Option; use result::{Result, Ok, Err}; @@ -17,6 +15,7 @@ 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; @@ -33,6 +32,7 @@ export Num, Times, TimesIx; 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; diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs index e997d1f13edb..17ddd6ea73b7 100644 --- a/src/libcore/dlist.rs +++ b/src/libcore/dlist.rs @@ -9,12 +9,9 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate. */ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; -export DList; -export new_dlist, from_elem, from_vec, extensions; - type DListLink = Option>; enum DListNode = @{ @@ -24,7 +21,7 @@ enum DListNode = @{ mut next: DListLink }; -enum DList { +pub enum DList { DList_(@{ mut size: uint, mut hd: DListLink, @@ -83,7 +80,7 @@ impl DListNode { } /// Creates a new dlist node with the given data. -pure fn new_dlist_node(+data: T) -> DListNode { +pure fn new_dlist_node(data: T) -> DListNode { DListNode(@{data: move data, mut linked: false, mut prev: None, mut next: None}) } @@ -94,15 +91,15 @@ pure fn DList() -> DList { } /// Creates a new dlist with a single element -pure fn from_elem(+data: T) -> DList { +pub pure fn from_elem(data: T) -> DList { let list = DList(); unsafe { list.push(move data); } list } -fn from_vec(+vec: &[T]) -> DList { +pub fn from_vec(vec: &[T]) -> DList { do vec::foldl(DList(), vec) |list,data| { - list.push(data); // Iterating left-to-right -- add newly to the tail. + list.push(*data); // Iterating left-to-right -- add newly to the tail. list } } @@ -118,7 +115,7 @@ fn concat(lists: DList>) -> DList { } priv impl DList { - pure fn new_link(-data: T) -> DListLink { + pure fn new_link(data: T) -> DListLink { Some(DListNode(@{data: move data, mut linked: true, mut prev: None, mut next: None})) } @@ -145,7 +142,7 @@ priv impl DList { // Link two nodes together. If either of them are 'none', also sets // the head and/or tail pointers appropriately. #[inline(always)] - fn link(+before: DListLink, +after: DListLink) { + fn link(before: DListLink, after: DListLink) { match before { Some(neighbour) => neighbour.next = after, None => self.hd = after @@ -166,12 +163,12 @@ priv impl DList { self.size -= 1; } - fn add_head(+nobe: DListLink) { + fn add_head(nobe: DListLink) { self.link(nobe, self.hd); // Might set tail too. self.hd = nobe; self.size += 1; } - fn add_tail(+nobe: DListLink) { + fn add_tail(nobe: DListLink) { self.link(self.tl, nobe); // Might set head too. self.tl = nobe; self.size += 1; @@ -201,27 +198,27 @@ impl DList { pure fn is_not_empty() -> bool { self.len() != 0 } /// Add data to the head of the list. O(1). - fn push_head(+data: T) { + fn push_head(data: T) { self.add_head(self.new_link(move data)); } /** * Add data to the head of the list, and get the new containing * node. O(1). */ - fn push_head_n(+data: T) -> DListNode { + fn push_head_n(data: T) -> DListNode { let mut nobe = self.new_link(move data); self.add_head(nobe); option::get(&nobe) } /// Add data to the tail of the list. O(1). - fn push(+data: T) { + fn push(data: T) { self.add_tail(self.new_link(move data)); } /** * Add data to the tail of the list, and get the new containing * node. O(1). */ - fn push_n(+data: T) -> DListNode { + fn push_n(data: T) -> DListNode { let mut nobe = self.new_link(move data); self.add_tail(nobe); option::get(&nobe) @@ -230,7 +227,7 @@ impl DList { * Insert data into the middle of the list, left of the given node. * O(1). */ - fn insert_before(+data: T, neighbour: DListNode) { + fn insert_before(data: T, neighbour: DListNode) { self.insert_left(self.new_link(move data), neighbour); } /** @@ -245,7 +242,7 @@ impl DList { * Insert data in the middle of the list, left of the given node, * and get its containing node. O(1). */ - fn insert_before_n(+data: T, neighbour: DListNode) -> DListNode { + fn insert_before_n(data: T, neighbour: DListNode) -> DListNode { let mut nobe = self.new_link(move data); self.insert_left(nobe, neighbour); option::get(&nobe) @@ -254,7 +251,7 @@ impl DList { * Insert data into the middle of the list, right of the given node. * O(1). */ - fn insert_after(+data: T, neighbour: DListNode) { + fn insert_after(data: T, neighbour: DListNode) { self.insert_right(neighbour, self.new_link(move data)); } /** @@ -269,7 +266,7 @@ impl DList { * Insert data in the middle of the list, right of the given node, * and get its containing node. O(1). */ - fn insert_after_n(+data: T, neighbour: DListNode) -> DListNode { + fn insert_after_n(data: T, neighbour: DListNode) -> DListNode { let mut nobe = self.new_link(move data); self.insert_right(neighbour, nobe); option::get(&nobe) @@ -278,13 +275,13 @@ impl DList { /// Remove a node from the head of the list. O(1). fn pop_n() -> Option> { let hd = self.peek_n(); - hd.map(|nobe| self.unlink(nobe)); + hd.map(|nobe| self.unlink(*nobe)); hd } /// Remove a node from the tail of the list. O(1). fn pop_tail_n() -> Option> { let tl = self.peek_tail_n(); - tl.map(|nobe| self.unlink(nobe)); + tl.map(|nobe| self.unlink(*nobe)); tl } /// Get the node at the list's head. O(1). @@ -678,7 +675,7 @@ mod tests { #[test] fn test_dlist_foldl() { let l = from_vec(vec::from_fn(101, |x|x)); - assert iter::foldl(l, 0, |accum,elem| accum+elem) == 5050; + assert iter::foldl(&l, 0, |accum,elem| *accum+*elem) == 5050; } #[test] fn test_dlist_break_early() { diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 82767112b395..a2a709087971 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -10,18 +10,12 @@ Note that recursive use is not permitted. */ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; use cast::reinterpret_cast; use ptr::null; -export DVec; -export from_elem; -export from_vec; -export extensions; -export unwrap; - /** * A growable, modifiable vector type that accumulates elements into a * unique vector. @@ -57,27 +51,27 @@ type DVec_ = { mut data: ~[A] }; -enum DVec { +pub enum DVec { DVec_(DVec_) } /// Creates a new, empty dvec -fn DVec() -> DVec { +pub fn DVec() -> DVec { DVec_({mut data: ~[]}) } /// Creates a new dvec with a single element -fn from_elem(+e: A) -> DVec { +pub fn from_elem(e: A) -> DVec { DVec_({mut data: ~[move e]}) } /// Creates a new dvec with the contents of a vector -fn from_vec(+v: ~[A]) -> DVec { +pub fn from_vec(v: ~[A]) -> DVec { DVec_({mut data: move v}) } /// Consumes the vector and returns its contents -fn unwrap(+d: DVec) -> ~[A] { +pub fn unwrap(d: DVec) -> ~[A] { let DVec_({data: v}) <- d; move v } @@ -93,7 +87,7 @@ priv impl DVec { } #[inline(always)] - fn check_out(f: fn(-v: ~[A]) -> B) -> B { + fn check_out(f: &fn(v: ~[A]) -> B) -> B { unsafe { let mut data = cast::reinterpret_cast(&null::<()>()); data <-> self.data; @@ -104,7 +98,7 @@ priv impl DVec { } #[inline(always)] - fn give_back(+data: ~[A]) { + fn give_back(data: ~[A]) { unsafe { self.data = move data; } @@ -126,7 +120,7 @@ impl DVec { * and return a new vector to replace it with. */ #[inline(always)] - fn swap(f: fn(-v: ~[A]) -> ~[A]) { + fn swap(f: &fn(v: ~[A]) -> ~[A]) { self.check_out(|v| self.give_back(f(move v))) } @@ -136,7 +130,7 @@ impl DVec { * and return a new vector to replace it with. */ #[inline(always)] - fn swap_mut(f: fn(-v: ~[mut A]) -> ~[mut A]) { + fn swap_mut(f: &fn(v: ~[mut A]) -> ~[mut A]) { do self.swap |v| { vec::from_mut(f(vec::to_mut(move v))) } @@ -154,7 +148,7 @@ impl DVec { } /// Overwrite the current contents - fn set(+w: ~[A]) { + fn set(w: ~[A]) { self.check_not_borrowed(); self.data <- w; } @@ -163,14 +157,14 @@ impl DVec { fn pop() -> A { do self.check_out |v| { let mut v <- v; - let result = vec::pop(v); + let result = v.pop(); self.give_back(move v); move result } } /// Insert a single item at the front of the list - fn unshift(-t: A) { + fn unshift(t: A) { unsafe { let mut data = cast::reinterpret_cast(&null::<()>()); data <-> self.data; @@ -178,22 +172,22 @@ impl DVec { if data_ptr.is_null() { fail ~"Recursive use of dvec"; } log(error, ~"a"); self.data <- ~[move t]; - vec::push_all_move(self.data, move data); + self.data.push_all_move(move data); log(error, ~"b"); } } /// Append a single item to the end of the list - fn push(+t: A) { + fn push(t: A) { self.check_not_borrowed(); - vec::push(self.data, move t); + self.data.push(move t); } /// Remove and return the first element fn shift() -> A { do self.check_out |v| { let mut v = move v; - let result = vec::shift(v); + let result = v.shift(); self.give_back(move v); move result } @@ -246,7 +240,7 @@ impl DVec { vec::reserve(&mut v, new_len); let mut i = from_idx; while i < to_idx { - vec::push(v, ts[i]); + v.push(ts[i]); i += 1u; } move v @@ -272,7 +266,7 @@ impl DVec { } }; - for ts.each |t| { vec::push(v, *t) }; + for ts.each |t| { v.push(*t) }; v } } @@ -311,10 +305,10 @@ impl DVec { * growing the vector if necessary. New elements will be initialized * with `initval` */ - fn grow_set_elt(idx: uint, initval: A, val: A) { + fn grow_set_elt(idx: uint, initval: &A, val: A) { do self.swap |v| { let mut v = move v; - vec::grow_set(v, idx, initval, val); + v.grow_set(idx, initval, val); move v } } @@ -325,11 +319,11 @@ impl DVec { self.check_not_borrowed(); let length = self.len(); - if length == 0u { + if length == 0 { fail ~"attempt to retrieve the last element of an empty vector"; } - return self.data[length - 1u]; + return self.data[length - 1]; } /// Iterates over the elements in reverse order @@ -360,7 +354,7 @@ impl DVec { } impl DVec: Index { - pure fn index(&&idx: uint) -> A { + pure fn index(idx: uint) -> A { self.get_elt(idx) } } diff --git a/src/libcore/either.rs b/src/libcore/either.rs index 55e22f7cfe97..c64cd25e4813 100644 --- a/src/libcore/either.rs +++ b/src/libcore/either.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; //! A type that represents one of two alternatives @@ -8,13 +8,13 @@ use cmp::Eq; use result::Result; /// The either type -enum Either { +pub enum Either { Left(T), Right(U) } -fn either(f_left: fn((&T)) -> V, - f_right: fn((&U)) -> V, value: &Either) -> V { +pub fn either(f_left: fn((&T)) -> V, + f_right: fn((&U)) -> V, value: &Either) -> V { /*! * Applies a function based on the given either value * @@ -29,33 +29,34 @@ fn either(f_left: fn((&T)) -> V, } } -fn lefts(eithers: &[Either]) -> ~[T] { +pub fn lefts(eithers: &[Either]) -> ~[T] { //! Extracts from a vector of either all the left values - let mut result: ~[T] = ~[]; - for vec::each(eithers) |elt| { - match *elt { - Left(l) => vec::push(result, l), - _ => { /* fallthrough */ } + do vec::build_sized(eithers.len()) |push| { + for vec::each(eithers) |elt| { + match *elt { + Left(ref l) => { push(*l); } + _ => { /* fallthrough */ } + } } } - move result } -fn rights(eithers: &[Either]) -> ~[U] { +pub fn rights(eithers: &[Either]) -> ~[U] { //! Extracts from a vector of either all the right values - let mut result: ~[U] = ~[]; - for vec::each(eithers) |elt| { - match *elt { - Right(r) => vec::push(result, r), - _ => { /* fallthrough */ } + do vec::build_sized(eithers.len()) |push| { + for vec::each(eithers) |elt| { + match *elt { + Right(ref r) => { push(*r); } + _ => { /* fallthrough */ } + } } } - move result } -fn partition(eithers: &[Either]) +// XXX bad copies. take arg by val +pub fn partition(eithers: &[Either]) -> {lefts: ~[T], rights: ~[U]} { /*! * Extracts from a vector of either all the left values and right values @@ -68,23 +69,26 @@ fn partition(eithers: &[Either]) let mut rights: ~[U] = ~[]; for vec::each(eithers) |elt| { match *elt { - Left(l) => vec::push(lefts, l), - Right(r) => vec::push(rights, r) + Left(copy l) => lefts.push(l), + Right(copy r) => rights.push(r) } } return {lefts: move lefts, rights: move rights}; } -pure fn flip(eith: &Either) -> Either { +// XXX bad copies +pub pure fn flip(eith: &Either) -> Either { //! Flips between left and right of a given either match *eith { - Right(r) => Left(r), - Left(l) => Right(l) + Right(copy r) => Left(r), + Left(copy l) => Right(l) } } -pure fn to_result(eith: &Either) -> Result { +// XXX bad copies +pub pure fn to_result(eith: &Either) + -> Result { /*! * Converts either::t to a result::t * @@ -93,24 +97,25 @@ pure fn to_result(eith: &Either) -> Result { */ match *eith { - Right(r) => result::Ok(r), - Left(l) => result::Err(l) + Right(copy r) => result::Ok(r), + Left(copy l) => result::Err(l) } } -pure fn is_left(eith: &Either) -> bool { +pub pure fn is_left(eith: &Either) -> bool { //! Checks whether the given value is a left match *eith { Left(_) => true, _ => false } } -pure fn is_right(eith: &Either) -> bool { +pub pure fn is_right(eith: &Either) -> bool { //! Checks whether the given value is a right match *eith { Right(_) => true, _ => false } } -pure fn unwrap_left(+eith: Either) -> T { +// tjc: fix the next two after a snapshot +pub pure fn unwrap_left(eith: Either) -> T { //! Retrieves the value in the left branch. Fails if the either is Right. match move eith { @@ -118,7 +123,7 @@ pure fn unwrap_left(+eith: Either) -> T { } } -pure fn unwrap_right(+eith: Either) -> U { +pub pure fn unwrap_right(eith: Either) -> U { //! Retrieves the value in the right branch. Fails if the either is Left. match move eith { @@ -129,16 +134,16 @@ pure fn unwrap_right(+eith: Either) -> U { impl Either : Eq { pure fn eq(other: &Either) -> bool { match self { - Left(a) => { + Left(ref a) => { match (*other) { - Left(ref b) => a.eq(b), + Left(ref b) => (*a).eq(b), Right(_) => false } } - Right(a) => { + Right(ref a) => { match (*other) { Left(_) => false, - Right(ref b) => a.eq(b) + Right(ref b) => (*a).eq(b) } } } diff --git a/src/libcore/extfmt.rs b/src/libcore/extfmt.rs index 9a992143a111..e10ff4bac714 100644 --- a/src/libcore/extfmt.rs +++ b/src/libcore/extfmt.rs @@ -81,16 +81,16 @@ mod ct { // A fragment of the output sequence enum Piece { PieceString(~str), PieceConv(Conv), } - type ErrorFn = fn@(~str) -> ! ; + type ErrorFn = fn@(&str) -> ! ; - fn parse_fmt_string(s: ~str, error: ErrorFn) -> ~[Piece] { + fn parse_fmt_string(s: &str, error: ErrorFn) -> ~[Piece] { let mut pieces: ~[Piece] = ~[]; let lim = str::len(s); let mut buf = ~""; - fn flush_buf(+buf: ~str, &pieces: ~[Piece]) -> ~str { - if str::len(buf) > 0 { + fn flush_buf(buf: ~str, pieces: &mut ~[Piece]) -> ~str { + if buf.len() > 0 { let piece = PieceString(move buf); - vec::push(pieces, move piece); + pieces.push(move piece); } return ~""; } @@ -108,17 +108,17 @@ mod ct { buf += curr2; i += 1; } else { - buf = flush_buf(move buf, pieces); + buf = flush_buf(move buf, &mut pieces); let rs = parse_conversion(s, i, lim, error); - vec::push(pieces, copy rs.piece); + pieces.push(copy rs.piece); i = rs.next; } } else { buf += curr; i += size; } } - flush_buf(move buf, pieces); + flush_buf(move buf, &mut pieces); move pieces } - fn peek_num(s: ~str, i: uint, lim: uint) -> + fn peek_num(s: &str, i: uint, lim: uint) -> Option<{num: uint, next: uint}> { let mut j = i; let mut accum = 0u; @@ -140,7 +140,7 @@ mod ct { None } } - fn parse_conversion(s: ~str, i: uint, lim: uint, error: ErrorFn) -> + 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 +155,7 @@ mod ct { ty: ty.ty}), next: ty.next}; } - fn parse_parameter(s: ~str, i: uint, lim: uint) -> + fn parse_parameter(s: &str, i: uint, lim: uint) -> {param: Option, next: uint} { if i >= lim { return {param: None, next: i}; } let num = peek_num(s, i, lim); @@ -170,12 +170,12 @@ mod ct { } }; } - fn parse_flags(s: ~str, i: uint, lim: uint) -> + 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}; } - fn more_(f: Flag, s: ~str, i: uint, lim: uint) -> + fn more(f: Flag, s: &str, i: uint, lim: uint) -> {flags: ~[Flag], next: uint} { let next = parse_flags(s, i + 1u, lim); let rest = copy next.flags; @@ -183,21 +183,22 @@ mod ct { let curr: ~[Flag] = ~[f]; return {flags: vec::append(move curr, rest), next: j}; } - let more = |x, copy s| more_(x, copy s, i, lim); + // Unfortunate, but because s is borrowed, can't use a closure + // fn more(f: Flag, s: &str) { more_(f, s, i, lim); } let f = s[i]; return if f == '-' as u8 { - more(FlagLeftJustify) + more(FlagLeftJustify, s, i, lim) } else if f == '0' as u8 { - more(FlagLeftZeroPad) + more(FlagLeftZeroPad, s, i, lim) } else if f == ' ' as u8 { - more(FlagSpaceForSign) + more(FlagSpaceForSign, s, i, lim) } else if f == '+' as u8 { - more(FlagSignAlways) + more(FlagSignAlways, s, i, lim) } else if f == '#' as u8 { - more(FlagAlternate) + more(FlagAlternate, s, i, lim) } else { {flags: move noflags, next: i} }; } - fn parse_count(s: ~str, i: uint, lim: uint) + fn parse_count(s: &str, i: uint, lim: uint) -> {count: Count, next: uint} { return if i >= lim { {count: CountImplied, next: i} @@ -219,7 +220,7 @@ mod ct { } }; } - fn parse_precision(s: ~str, i: uint, lim: uint) -> + fn parse_precision(s: &str, i: uint, lim: uint) -> {count: Count, next: uint} { return if i >= lim { {count: CountImplied, next: i} @@ -235,7 +236,7 @@ mod ct { } } else { {count: CountImplied, next: i} }; } - fn parse_type(s: ~str, i: uint, lim: uint, error: ErrorFn) -> + 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); @@ -288,7 +289,7 @@ mod rt { type Conv = {flags: u32, width: Count, precision: Count, ty: Ty}; pure fn conv_int(cv: Conv, i: int) -> ~str { - let radix = 10u; + let radix = 10; let prec = get_int_precision(cv); let mut s : ~str = int_to_str_prec(i, radix, prec); if 0 <= i { @@ -350,8 +351,8 @@ mod rt { } return unsafe { pad(cv, s, PadFloat) }; } - pure fn conv_poly(cv: Conv, v: T) -> ~str { - let s = sys::log_str(&v); + pure fn conv_poly(cv: Conv, v: &T) -> ~str { + let s = sys::log_str(v); return conv_str(cv, s); } @@ -404,16 +405,17 @@ mod rt { pure fn ne(other: &PadMode) -> bool { !self.eq(other) } } - fn pad(cv: Conv, &s: ~str, mode: PadMode) -> ~str { + fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { + let mut s = move s; // sadtimes let uwidth : uint = match cv.width { - CountImplied => return copy s, + 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 copy s; } + if uwidth <= strlen { return s; } let mut padchar = ' '; let diff = uwidth - strlen; if have_flag(cv.flags, flag_left_justify) { @@ -444,7 +446,7 @@ mod rt { // zeros. It may make sense to convert zero padding to a precision // instead. - if signed && zero_padding && str::len(s) > 0u { + 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)); @@ -461,7 +463,12 @@ mod rt { } } -// XXX remove after snapshots +// 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; @@ -477,7 +484,7 @@ mod rt2 { type Conv = {flags: u32, width: Count, precision: Count, ty: Ty}; pure fn conv_int(cv: Conv, i: int) -> ~str { - let radix = 10u; + let radix = 10; let prec = get_int_precision(cv); let mut s : ~str = int_to_str_prec(i, radix, prec); if 0 <= i { @@ -539,8 +546,8 @@ mod rt2 { } return unsafe { pad(cv, s, PadFloat) }; } - pure fn conv_poly(cv: Conv, v: T) -> ~str { - let s = sys::log_str(&v); + pure fn conv_poly(cv: Conv, v: &T) -> ~str { + let s = sys::log_str(v); return conv_str(cv, s); } @@ -593,16 +600,17 @@ mod rt2 { pure fn ne(other: &PadMode) -> bool { !self.eq(other) } } - fn pad(cv: Conv, &s: ~str, mode: PadMode) -> ~str { + fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str { + let mut s = move s; // sadtimes let uwidth : uint = match cv.width { - CountImplied => return copy s, + 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 copy s; } + if uwidth <= strlen { return s; } let mut padchar = ' '; let diff = uwidth - strlen; if have_flag(cv.flags, flag_left_justify) { @@ -633,7 +641,7 @@ mod rt2 { // zeros. It may make sense to convert zero padding to a precision // instead. - if signed && zero_padding && str::len(s) > 0u { + 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)); diff --git a/src/libcore/f32.rs b/src/libcore/f32.rs index a8ca15f6afc5..ec0e66734fa3 100644 --- a/src/libcore/f32.rs +++ b/src/libcore/f32.rs @@ -4,68 +4,51 @@ //! Operations and constants for `f32` -// PORT - -use cmath::c_float::*; -use cmath::c_float_targ_consts::*; - -export add, sub, mul, div, rem, lt, le, eq, ne, ge, gt; -export is_positive, is_negative, is_nonpositive, is_nonnegative; -export is_zero, is_infinite, is_finite; -export NaN, is_NaN, infinity, neg_infinity; -export consts; -export logarithm; -export acos, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, floor; -export erf, erfc, exp, expm1, exp2, abs, abs_sub; -export mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp; -export lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix; -export modf, pow, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc; -export signbit; - -export num; +pub use cmath::c_float::*; +pub use cmath::c_float_targ_consts::*; // These are not defined inside consts:: for consistency with // the integer types -const NaN: f32 = 0.0_f32/0.0_f32; +pub const NaN: f32 = 0.0_f32/0.0_f32; -const infinity: f32 = 1.0_f32/0.0_f32; +pub const infinity: f32 = 1.0_f32/0.0_f32; -const neg_infinity: f32 = -1.0_f32/0.0_f32; +pub const neg_infinity: f32 = -1.0_f32/0.0_f32; -pure fn is_NaN(f: f32) -> bool { f != f } +pub pure fn is_NaN(f: f32) -> bool { f != f } -pure fn add(x: f32, y: f32) -> f32 { return x + y; } +pub pure fn add(x: f32, y: f32) -> f32 { return x + y; } -pure fn sub(x: f32, y: f32) -> f32 { return x - y; } +pub pure fn sub(x: f32, y: f32) -> f32 { return x - y; } -pure fn mul(x: f32, y: f32) -> f32 { return x * y; } +pub pure fn mul(x: f32, y: f32) -> f32 { return x * y; } -pure fn div(x: f32, y: f32) -> f32 { return x / y; } +pub pure fn div(x: f32, y: f32) -> f32 { return x / y; } -pure fn rem(x: f32, y: f32) -> f32 { return x % y; } +pub pure fn rem(x: f32, y: f32) -> f32 { return x % y; } -pure fn lt(x: f32, y: f32) -> bool { return x < y; } +pub pure fn lt(x: f32, y: f32) -> bool { return x < y; } -pure fn le(x: f32, y: f32) -> bool { return x <= y; } +pub pure fn le(x: f32, y: f32) -> bool { return x <= y; } -pure fn eq(x: f32, y: f32) -> bool { return x == y; } +pub pure fn eq(x: f32, y: f32) -> bool { return x == y; } -pure fn ne(x: f32, y: f32) -> bool { return x != y; } +pub pure fn ne(x: f32, y: f32) -> bool { return x != y; } -pure fn ge(x: f32, y: f32) -> bool { return x >= y; } +pub pure fn ge(x: f32, y: f32) -> bool { return x >= y; } -pure fn gt(x: f32, y: f32) -> bool { return x > y; } +pub pure fn gt(x: f32, y: f32) -> bool { return x > y; } // FIXME (#1999): replace the predicates below with llvm intrinsics or // calls to the libmath macros in the rust runtime for performance. /// Returns true if `x` is a positive number, including +0.0f320 and +Infinity -pure fn is_positive(x: f32) -> bool +pub pure fn is_positive(x: f32) -> bool { return x > 0.0f32 || (1.0f32/x) == infinity; } /// Returns true if `x` is a negative number, including -0.0f320 and -Infinity -pure fn is_negative(x: f32) -> bool +pub pure fn is_negative(x: f32) -> bool { return x < 0.0f32 || (1.0f32/x) == neg_infinity; } /** @@ -73,7 +56,7 @@ pure fn is_negative(x: f32) -> bool * * This is the same as `f32::is_negative`. */ -pure fn is_nonpositive(x: f32) -> bool { +pub pure fn is_nonpositive(x: f32) -> bool { return x < 0.0f32 || (1.0f32/x) == neg_infinity; } @@ -82,87 +65,85 @@ pure fn is_nonpositive(x: f32) -> bool { * * This is the same as `f32::is_positive`.) */ -pure fn is_nonnegative(x: f32) -> bool { +pub pure fn is_nonnegative(x: f32) -> bool { return x > 0.0f32 || (1.0f32/x) == infinity; } /// Returns true if `x` is a zero number (positive or negative zero) -pure fn is_zero(x: f32) -> bool { +pub pure fn is_zero(x: f32) -> bool { return x == 0.0f32 || x == -0.0f32; } /// Returns true if `x`is an infinite number -pure fn is_infinite(x: f32) -> bool { +pub pure fn is_infinite(x: f32) -> bool { return x == infinity || x == neg_infinity; } /// Returns true if `x`is a finite number -pure fn is_finite(x: f32) -> bool { +pub pure fn is_finite(x: f32) -> bool { return !(is_NaN(x) || is_infinite(x)); } // FIXME (#1999): add is_normal, is_subnormal, and fpclassify. /* Module: consts */ -mod consts { - #[legacy_exports]; - +pub mod consts { // FIXME (requires Issue #1433 to fix): replace with mathematical // constants from cmath. /// Archimedes' constant - const pi: f32 = 3.14159265358979323846264338327950288_f32; + pub const pi: f32 = 3.14159265358979323846264338327950288_f32; /// pi/2.0 - const frac_pi_2: f32 = 1.57079632679489661923132169163975144_f32; + pub const frac_pi_2: f32 = 1.57079632679489661923132169163975144_f32; /// pi/4.0 - const frac_pi_4: f32 = 0.785398163397448309615660845819875721_f32; + pub const frac_pi_4: f32 = 0.785398163397448309615660845819875721_f32; /// 1.0/pi - const frac_1_pi: f32 = 0.318309886183790671537767526745028724_f32; + pub const frac_1_pi: f32 = 0.318309886183790671537767526745028724_f32; /// 2.0/pi - const frac_2_pi: f32 = 0.636619772367581343075535053490057448_f32; + pub const frac_2_pi: f32 = 0.636619772367581343075535053490057448_f32; /// 2.0/sqrt(pi) - const frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517_f32; + pub const frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517_f32; /// sqrt(2.0) - const sqrt2: f32 = 1.41421356237309504880168872420969808_f32; + pub const sqrt2: f32 = 1.41421356237309504880168872420969808_f32; /// 1.0/sqrt(2.0) - const frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039_f32; + pub const frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039_f32; /// Euler's number - const e: f32 = 2.71828182845904523536028747135266250_f32; + pub const e: f32 = 2.71828182845904523536028747135266250_f32; /// log2(e) - const log2_e: f32 = 1.44269504088896340735992468100189214_f32; + pub const log2_e: f32 = 1.44269504088896340735992468100189214_f32; /// log10(e) - const log10_e: f32 = 0.434294481903251827651128918916605082_f32; + pub const log10_e: f32 = 0.434294481903251827651128918916605082_f32; /// ln(2.0) - const ln_2: f32 = 0.693147180559945309417232121458176568_f32; + pub const ln_2: f32 = 0.693147180559945309417232121458176568_f32; /// ln(10.0) - const ln_10: f32 = 2.30258509299404568401799145468436421_f32; + pub const ln_10: f32 = 2.30258509299404568401799145468436421_f32; } -pure fn signbit(x: f32) -> int { +pub pure fn signbit(x: f32) -> int { if is_negative(x) { return 1; } else { return 0; } } -pure fn logarithm(n: f32, b: f32) -> f32 { +pub pure fn logarithm(n: f32, b: f32) -> f32 { return log2(n) / log2(b); } impl f32: num::Num { - pure fn add(&&other: f32) -> f32 { return self + other; } - pure fn sub(&&other: f32) -> f32 { return self - other; } - pure fn mul(&&other: f32) -> f32 { return self * other; } - pure fn div(&&other: f32) -> f32 { return self / other; } - pure fn modulo(&&other: f32) -> f32 { return self % other; } + pure fn add(other: &f32) -> f32 { return self + *other; } + pure fn sub(other: &f32) -> f32 { return self - *other; } + pure fn mul(other: &f32) -> f32 { return self * *other; } + pure fn div(other: &f32) -> f32 { return self / *other; } + pure fn modulo(other: &f32) -> f32 { return self % *other; } pure fn neg() -> f32 { return -self; } pure fn to_int() -> int { return self as int; } diff --git a/src/libcore/f64.rs b/src/libcore/f64.rs index 0be0a0591323..731d369649b1 100644 --- a/src/libcore/f64.rs +++ b/src/libcore/f64.rs @@ -4,95 +4,70 @@ //! Operations and constants for `f64` -// PORT +pub use cmath::c_double::*; +pub use cmath::c_double_targ_consts::*; -use cmath::c_double::*; -use cmath::c_double_targ_consts::*; - -// Even though this module exports everything defined in it, -// because it contains re-exports, we also have to explicitly -// export locally defined things. That's a bit annoying. -export add, sub, mul, div, rem, lt, le, eq, ne, ge, gt; -export is_positive, is_negative, is_nonpositive, is_nonnegative; -export is_zero, is_infinite, is_finite; -export NaN, is_NaN, infinity, neg_infinity; -export consts; -export logarithm; -export acos, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, floor; -export erf, erfc, exp, expm1, exp2, abs, abs_sub; -export mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp; -export lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix; -export modf, pow, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc; -export signbit; -export epsilon; - -export j0, j1, jn, y0, y1, yn; - -export num; +// FIXME (#1433): obtain these in a different way // These are not defined inside consts:: for consistency with // the integer types -// PORT check per architecture +pub const radix: uint = 2u; -// FIXME (#1433): obtain these in a different way +pub const mantissa_digits: uint = 53u; +pub const digits: uint = 15u; -const radix: uint = 2u; +pub const epsilon: f64 = 2.2204460492503131e-16_f64; -const mantissa_digits: uint = 53u; -const digits: uint = 15u; +pub const min_value: f64 = 2.2250738585072014e-308_f64; +pub const max_value: f64 = 1.7976931348623157e+308_f64; -const epsilon: f64 = 2.2204460492503131e-16_f64; +pub const min_exp: int = -1021; +pub const max_exp: int = 1024; -const min_value: f64 = 2.2250738585072014e-308_f64; -const max_value: f64 = 1.7976931348623157e+308_f64; +pub const min_10_exp: int = -307; +pub const max_10_exp: int = 308; -const min_exp: int = -1021; -const max_exp: int = 1024; +pub const NaN: f64 = 0.0_f64/0.0_f64; -const min_10_exp: int = -307; -const max_10_exp: int = 308; +pub const infinity: f64 = 1.0_f64/0.0_f64; -const NaN: f64 = 0.0_f64/0.0_f64; +pub const neg_infinity: f64 = -1.0_f64/0.0_f64; -const infinity: f64 = 1.0_f64/0.0_f64; +pub pure fn is_NaN(f: f64) -> bool { f != f } -const neg_infinity: f64 = -1.0_f64/0.0_f64; +pub pure fn add(x: f64, y: f64) -> f64 { return x + y; } -pure fn is_NaN(f: f64) -> bool { f != f } +pub pure fn sub(x: f64, y: f64) -> f64 { return x - y; } -pure fn add(x: f64, y: f64) -> f64 { return x + y; } +pub pure fn mul(x: f64, y: f64) -> f64 { return x * y; } -pure fn sub(x: f64, y: f64) -> f64 { return x - y; } +pub pure fn div(x: f64, y: f64) -> f64 { return x / y; } -pure fn mul(x: f64, y: f64) -> f64 { return x * y; } +pub pure fn rem(x: f64, y: f64) -> f64 { return x % y; } -pure fn div(x: f64, y: f64) -> f64 { return x / y; } +pub pure fn lt(x: f64, y: f64) -> bool { return x < y; } -pure fn rem(x: f64, y: f64) -> f64 { return x % y; } +pub pure fn le(x: f64, y: f64) -> bool { return x <= y; } -pure fn lt(x: f64, y: f64) -> bool { return x < y; } +pub pure fn eq(x: f64, y: f64) -> bool { return x == y; } -pure fn le(x: f64, y: f64) -> bool { return x <= y; } +pub pure fn ne(x: f64, y: f64) -> bool { return x != y; } -pure fn eq(x: f64, y: f64) -> bool { return x == y; } +pub pure fn ge(x: f64, y: f64) -> bool { return x >= y; } -pure fn ne(x: f64, y: f64) -> bool { return x != y; } +pub pure fn gt(x: f64, y: f64) -> bool { return x > y; } -pure fn ge(x: f64, y: f64) -> bool { return x >= y; } - -pure fn gt(x: f64, y: f64) -> bool { return x > y; } - -pure fn sqrt(x: f64) -> f64 { +pub pure fn sqrt(x: f64) -> f64 { cmath::c_double::sqrt(x as libc::c_double) as f64 } /// Returns true if `x` is a positive number, including +0.0f640 and +Infinity -pure fn is_positive(x: f64) -> bool +pub pure fn is_positive(x: f64) -> bool { return x > 0.0f64 || (1.0f64/x) == infinity; } /// Returns true if `x` is a negative number, including -0.0f640 and -Infinity -pure fn is_negative(x: f64) -> bool +pub pure fn is_negative(x: f64) -> bool { return x < 0.0f64 || (1.0f64/x) == neg_infinity; } /** @@ -100,7 +75,7 @@ pure fn is_negative(x: f64) -> bool * * This is the same as `f64::is_negative`. */ -pure fn is_nonpositive(x: f64) -> bool { +pub pure fn is_nonpositive(x: f64) -> bool { return x < 0.0f64 || (1.0f64/x) == neg_infinity; } @@ -109,87 +84,85 @@ pure fn is_nonpositive(x: f64) -> bool { * * This is the same as `f64::positive`. */ -pure fn is_nonnegative(x: f64) -> bool { +pub pure fn is_nonnegative(x: f64) -> bool { return x > 0.0f64 || (1.0f64/x) == infinity; } /// Returns true if `x` is a zero number (positive or negative zero) -pure fn is_zero(x: f64) -> bool { +pub pure fn is_zero(x: f64) -> bool { return x == 0.0f64 || x == -0.0f64; } /// Returns true if `x`is an infinite number -pure fn is_infinite(x: f64) -> bool { +pub pure fn is_infinite(x: f64) -> bool { return x == infinity || x == neg_infinity; } /// Returns true if `x`is a finite number -pure fn is_finite(x: f64) -> bool { +pub pure fn is_finite(x: f64) -> bool { return !(is_NaN(x) || is_infinite(x)); } // FIXME (#1999): add is_normal, is_subnormal, and fpclassify /* Module: consts */ -mod consts { - #[legacy_exports]; - +pub mod consts { // FIXME (requires Issue #1433 to fix): replace with mathematical // constants from cmath. /// Archimedes' constant - const pi: f64 = 3.14159265358979323846264338327950288_f64; + pub const pi: f64 = 3.14159265358979323846264338327950288_f64; /// pi/2.0 - const frac_pi_2: f64 = 1.57079632679489661923132169163975144_f64; + pub const frac_pi_2: f64 = 1.57079632679489661923132169163975144_f64; /// pi/4.0 - const frac_pi_4: f64 = 0.785398163397448309615660845819875721_f64; + pub const frac_pi_4: f64 = 0.785398163397448309615660845819875721_f64; /// 1.0/pi - const frac_1_pi: f64 = 0.318309886183790671537767526745028724_f64; + pub const frac_1_pi: f64 = 0.318309886183790671537767526745028724_f64; /// 2.0/pi - const frac_2_pi: f64 = 0.636619772367581343075535053490057448_f64; + pub const frac_2_pi: f64 = 0.636619772367581343075535053490057448_f64; /// 2.0/sqrt(pi) - const frac_2_sqrtpi: f64 = 1.12837916709551257389615890312154517_f64; + pub const frac_2_sqrtpi: f64 = 1.12837916709551257389615890312154517_f64; /// sqrt(2.0) - const sqrt2: f64 = 1.41421356237309504880168872420969808_f64; + pub const sqrt2: f64 = 1.41421356237309504880168872420969808_f64; /// 1.0/sqrt(2.0) - const frac_1_sqrt2: f64 = 0.707106781186547524400844362104849039_f64; + pub const frac_1_sqrt2: f64 = 0.707106781186547524400844362104849039_f64; /// Euler's number - const e: f64 = 2.71828182845904523536028747135266250_f64; + pub const e: f64 = 2.71828182845904523536028747135266250_f64; /// log2(e) - const log2_e: f64 = 1.44269504088896340735992468100189214_f64; + pub const log2_e: f64 = 1.44269504088896340735992468100189214_f64; /// log10(e) - const log10_e: f64 = 0.434294481903251827651128918916605082_f64; + pub const log10_e: f64 = 0.434294481903251827651128918916605082_f64; /// ln(2.0) - const ln_2: f64 = 0.693147180559945309417232121458176568_f64; + pub const ln_2: f64 = 0.693147180559945309417232121458176568_f64; /// ln(10.0) - const ln_10: f64 = 2.30258509299404568401799145468436421_f64; + pub const ln_10: f64 = 2.30258509299404568401799145468436421_f64; } -pure fn signbit(x: f64) -> int { +pub pure fn signbit(x: f64) -> int { if is_negative(x) { return 1; } else { return 0; } } -pure fn logarithm(n: f64, b: f64) -> f64 { +pub pure fn logarithm(n: f64, b: f64) -> f64 { return log2(n) / log2(b); } impl f64: num::Num { - pure fn add(&&other: f64) -> f64 { return self + other; } - pure fn sub(&&other: f64) -> f64 { return self - other; } - pure fn mul(&&other: f64) -> f64 { return self * other; } - pure fn div(&&other: f64) -> f64 { return self / other; } - pure fn modulo(&&other: f64) -> f64 { return self % other; } + pure fn add(other: &f64) -> f64 { return self + *other; } + pure fn sub(other: &f64) -> f64 { return self - *other; } + pure fn mul(other: &f64) -> f64 { return self * *other; } + pure fn div(other: &f64) -> f64 { return self / *other; } + pure fn modulo(other: &f64) -> f64 { return self % *other; } pure fn neg() -> f64 { return -self; } pure fn to_int() -> int { return self as int; } diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs index b75894e0c1b7..7c5176494a22 100644 --- a/src/libcore/flate.rs +++ b/src/libcore/flate.rs @@ -11,8 +11,6 @@ Simple compression use libc::{c_void, size_t, c_int}; extern mod rustrt { - #[legacy_exports]; - fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void, src_buf_len: size_t, pout_len: *size_t, @@ -29,14 +27,14 @@ const lz_fast : c_int = 0x1; // LZ with only one probe const lz_norm : c_int = 0x80; // LZ with 128 probes, "normal" const lz_best : c_int = 0xfff; // LZ with 4095 probes, "best" -fn deflate_bytes(bytes: &[const u8]) -> ~[u8] { +pub fn deflate_bytes(bytes: &[const u8]) -> ~[u8] { do vec::as_const_buf(bytes) |b, len| { unsafe { let mut outsz : size_t = 0; let res = rustrt::tdefl_compress_mem_to_heap(b as *c_void, len as size_t, - ptr::addr_of(outsz), + ptr::addr_of(&outsz), lz_norm); assert res as int != 0; let out = vec::raw::from_buf(res as *u8, @@ -47,14 +45,14 @@ fn deflate_bytes(bytes: &[const u8]) -> ~[u8] { } } -fn inflate_bytes(bytes: &[const u8]) -> ~[u8] { +pub fn inflate_bytes(bytes: &[const u8]) -> ~[u8] { do vec::as_const_buf(bytes) |b, len| { unsafe { let mut outsz : size_t = 0; let res = rustrt::tinfl_decompress_mem_to_heap(b as *c_void, len as size_t, - ptr::addr_of(outsz), + ptr::addr_of(&outsz), 0); assert res as int != 0; let out = vec::raw::from_buf(res as *u8, @@ -71,12 +69,12 @@ fn test_flate_round_trip() { let r = rand::Rng(); let mut words = ~[]; for 20.times { - vec::push(words, r.gen_bytes(r.gen_uint_range(1, 10))); + words.push(r.gen_bytes(r.gen_uint_range(1, 10))); } for 20.times { let mut in = ~[]; for 2000.times { - vec::push_all(in, r.choose(words)); + in.push_all(r.choose(words)); } debug!("de/inflate of %u bytes of random word-sequences", in.len()); diff --git a/src/libcore/float.rs b/src/libcore/float.rs index 2cd95269aaf0..098e82f5fad7 100644 --- a/src/libcore/float.rs +++ b/src/libcore/float.rs @@ -7,26 +7,10 @@ // Even though this module exports everything defined in it, // because it contains re-exports, we also have to explicitly // export locally defined things. That's a bit annoying. -export to_str_common, to_str_exact, to_str, from_str; -export add, sub, mul, div, rem, lt, le, eq, ne, ge, gt; -export is_positive, is_negative, is_nonpositive, is_nonnegative; -export is_zero, is_infinite, is_finite; -export NaN, is_NaN, infinity, neg_infinity; -export consts; -export logarithm; -export acos, asin, atan, atan2, cbrt, ceil, copysign, cos, cosh, floor; -export erf, erfc, exp, expm1, exp2, abs, abs_sub; -export mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp; -export lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix; -export modf, pow, round, sin, sinh, sqrt, tan, tanh, tgamma, trunc; -export signbit; -export pow_with_uint; -export num; // export when m_float == c_double -export j0, j1, jn, y0, y1, yn; // PORT this must match in width according to architecture @@ -44,56 +28,54 @@ use f64::{j0, j1, jn, y0, y1, yn}; use cmp::{Eq, Ord}; use num::from_int; -const NaN: float = 0.0/0.0; +pub const NaN: float = 0.0/0.0; -const infinity: float = 1.0/0.0; +pub const infinity: float = 1.0/0.0; -const neg_infinity: float = -1.0/0.0; +pub const neg_infinity: float = -1.0/0.0; /* Module: consts */ -mod consts { - #[legacy_exports]; - +pub mod consts { // FIXME (requires Issue #1433 to fix): replace with mathematical // constants from cmath. /// Archimedes' constant - const pi: float = 3.14159265358979323846264338327950288; + pub const pi: float = 3.14159265358979323846264338327950288; /// pi/2.0 - const frac_pi_2: float = 1.57079632679489661923132169163975144; + pub const frac_pi_2: float = 1.57079632679489661923132169163975144; /// pi/4.0 - const frac_pi_4: float = 0.785398163397448309615660845819875721; + pub const frac_pi_4: float = 0.785398163397448309615660845819875721; /// 1.0/pi - const frac_1_pi: float = 0.318309886183790671537767526745028724; + pub const frac_1_pi: float = 0.318309886183790671537767526745028724; /// 2.0/pi - const frac_2_pi: float = 0.636619772367581343075535053490057448; + pub const frac_2_pi: float = 0.636619772367581343075535053490057448; /// 2.0/sqrt(pi) - const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517; + pub const frac_2_sqrtpi: float = 1.12837916709551257389615890312154517; /// sqrt(2.0) - const sqrt2: float = 1.41421356237309504880168872420969808; + pub const sqrt2: float = 1.41421356237309504880168872420969808; /// 1.0/sqrt(2.0) - const frac_1_sqrt2: float = 0.707106781186547524400844362104849039; + pub const frac_1_sqrt2: float = 0.707106781186547524400844362104849039; /// Euler's number - const e: float = 2.71828182845904523536028747135266250; + pub const e: float = 2.71828182845904523536028747135266250; /// log2(e) - const log2_e: float = 1.44269504088896340735992468100189214; + pub const log2_e: float = 1.44269504088896340735992468100189214; /// log10(e) - const log10_e: float = 0.434294481903251827651128918916605082; + pub const log10_e: float = 0.434294481903251827651128918916605082; /// ln(2.0) - const ln_2: float = 0.693147180559945309417232121458176568; + pub const ln_2: float = 0.693147180559945309417232121458176568; /// ln(10.0) - const ln_10: float = 2.30258509299404568401799145468436421; + pub const ln_10: float = 2.30258509299404568401799145468436421; } /** @@ -109,7 +91,7 @@ mod consts { * * digits - The number of significant digits * * exact - Whether to enforce the exact number of significant digits */ -fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { +pub fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { if is_NaN(num) { return ~"NaN"; } if num == infinity { return ~"inf"; } if num == neg_infinity { return ~"-inf"; } @@ -139,11 +121,11 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { // while we still need digits // build stack of digits - while ii > 0u && (frac >= epsilon_prime || exact) { + while ii > 0 && (frac >= epsilon_prime || exact) { // store the next digit frac *= 10.0; let digit = frac as uint; - vec::push(fractionalParts, digit); + fractionalParts.push(digit); // calculate the next frac frac -= digit as float; @@ -153,25 +135,25 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { let mut acc; let mut racc = ~""; - let mut carry = if frac * 10.0 as uint >= 5u { 1u } else { 0u }; + let mut carry = if frac * 10.0 as uint >= 5 { 1 } else { 0 }; // turn digits into string // using stack of digits - while vec::len(fractionalParts) > 0u { - let mut adjusted_digit = carry + vec::pop(fractionalParts); + while fractionalParts.is_not_empty() { + let mut adjusted_digit = carry + fractionalParts.pop(); - if adjusted_digit == 10u { - carry = 1u; - adjusted_digit %= 10u + if adjusted_digit == 10 { + carry = 1; + adjusted_digit %= 10 } else { - carry = 0u + carry = 0; }; racc = uint::str(adjusted_digit) + racc; } // pad decimals with trailing zeroes - while str::len(racc) < digits && exact { + while racc.len() < digits && exact { racc += ~"0" } @@ -194,12 +176,12 @@ fn to_str_common(num: float, digits: uint, exact: bool) -> ~str { * * num - The float value * * digits - The number of significant digits */ -fn to_str_exact(num: float, digits: uint) -> ~str { +pub fn to_str_exact(num: float, digits: uint) -> ~str { to_str_common(num, digits, true) } #[test] -fn test_to_str_exact_do_decimal() { +pub fn test_to_str_exact_do_decimal() { let s = to_str_exact(5.0, 4u); assert s == ~"5.0000"; } @@ -214,7 +196,7 @@ fn test_to_str_exact_do_decimal() { * * num - The float value * * digits - The number of significant digits */ -fn to_str(num: float, digits: uint) -> ~str { +pub fn to_str(num: float, digits: uint) -> ~str { to_str_common(num, digits, false) } @@ -244,7 +226,7 @@ fn to_str(num: float, digits: uint) -> ~str { * `none` if the string did not represent a valid number. Otherwise, * `Some(n)` where `n` is the floating-point number represented by `[num]`. */ -fn from_str(num: &str) -> Option { +pub fn from_str(num: &str) -> Option { if num == "inf" { return Some(infinity as float); } else if num == "-inf" { @@ -379,7 +361,7 @@ fn from_str(num: &str) -> Option { * * `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow` */ -fn pow_with_uint(base: uint, pow: uint) -> float { +pub fn pow_with_uint(base: uint, pow: uint) -> float { if base == 0u { if pow == 0u { return NaN as float; @@ -399,40 +381,40 @@ fn pow_with_uint(base: uint, pow: uint) -> float { return total; } -pure fn is_positive(x: float) -> bool { f64::is_positive(x as f64) } -pure fn is_negative(x: float) -> bool { f64::is_negative(x as f64) } -pure fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) } -pure fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) } -pure fn is_zero(x: float) -> bool { f64::is_zero(x as f64) } -pure fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) } -pure fn is_finite(x: float) -> bool { f64::is_finite(x as f64) } -pure fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) } +pub pure fn is_positive(x: float) -> bool { f64::is_positive(x as f64) } +pub pure fn is_negative(x: float) -> bool { f64::is_negative(x as f64) } +pub pure fn is_nonpositive(x: float) -> bool { f64::is_nonpositive(x as f64) } +pub pure fn is_nonnegative(x: float) -> bool { f64::is_nonnegative(x as f64) } +pub pure fn is_zero(x: float) -> bool { f64::is_zero(x as f64) } +pub pure fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) } +pub pure fn is_finite(x: float) -> bool { f64::is_finite(x as f64) } +pub pure fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) } -pure fn abs(x: float) -> float { f64::abs(x as f64) as float } -pure fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float } -pure fn atan(x: float) -> float { f64::atan(x as f64) as float } -pure fn sin(x: float) -> float { f64::sin(x as f64) as float } -pure fn cos(x: float) -> float { f64::cos(x as f64) as float } -pure fn tan(x: float) -> float { f64::tan(x as f64) as float } +pub pure fn abs(x: float) -> float { f64::abs(x as f64) as float } +pub pure fn sqrt(x: float) -> float { f64::sqrt(x as f64) as float } +pub pure fn atan(x: float) -> float { f64::atan(x as f64) as float } +pub pure fn sin(x: float) -> float { f64::sin(x as f64) as float } +pub pure fn cos(x: float) -> float { f64::cos(x as f64) as float } +pub pure fn tan(x: float) -> float { f64::tan(x as f64) as float } impl float : Eq { - pure fn eq(other: &float) -> bool { self == (*other) } - pure fn ne(other: &float) -> bool { self != (*other) } + pub pure fn eq(other: &float) -> bool { self == (*other) } + pub pure fn ne(other: &float) -> bool { self != (*other) } } impl float : Ord { - pure fn lt(other: &float) -> bool { self < (*other) } - pure fn le(other: &float) -> bool { self <= (*other) } - pure fn ge(other: &float) -> bool { self >= (*other) } - pure fn gt(other: &float) -> bool { self > (*other) } + pub pure fn lt(other: &float) -> bool { self < (*other) } + pub pure fn le(other: &float) -> bool { self <= (*other) } + pub pure fn ge(other: &float) -> bool { self >= (*other) } + pub pure fn gt(other: &float) -> bool { self > (*other) } } impl float: num::Num { - pure fn add(&&other: float) -> float { return self + other; } - pure fn sub(&&other: float) -> float { return self - other; } - pure fn mul(&&other: float) -> float { return self * other; } - pure fn div(&&other: float) -> float { return self / other; } - pure fn modulo(&&other: float) -> float { return self % other; } + pub pure fn add(other: &float) -> float { return self + *other; } + pub pure fn sub(other: &float) -> float { return self - *other; } + pub pure fn mul(other: &float) -> float { return self * *other; } + pub pure fn div(other: &float) -> float { return self / *other; } + pure fn modulo(other: &float) -> float { return self % *other; } pure fn neg() -> float { return -self; } pure fn to_int() -> int { return self as int; } @@ -440,7 +422,7 @@ impl float: num::Num { } #[test] -fn test_from_str() { +pub fn test_from_str() { assert from_str(~"3") == Some(3.); assert from_str(~"3") == Some(3.); assert from_str(~"3.14") == Some(3.14); @@ -483,7 +465,7 @@ fn test_from_str() { } #[test] -fn test_positive() { +pub fn test_positive() { assert(is_positive(infinity)); assert(is_positive(1.)); assert(is_positive(0.)); @@ -494,7 +476,7 @@ fn test_positive() { } #[test] -fn test_negative() { +pub fn test_negative() { assert(!is_negative(infinity)); assert(!is_negative(1.)); assert(!is_negative(0.)); @@ -505,7 +487,7 @@ fn test_negative() { } #[test] -fn test_nonpositive() { +pub fn test_nonpositive() { assert(!is_nonpositive(infinity)); assert(!is_nonpositive(1.)); assert(!is_nonpositive(0.)); @@ -516,7 +498,7 @@ fn test_nonpositive() { } #[test] -fn test_nonnegative() { +pub fn test_nonnegative() { assert(is_nonnegative(infinity)); assert(is_nonnegative(1.)); assert(is_nonnegative(0.)); @@ -527,24 +509,24 @@ fn test_nonnegative() { } #[test] -fn test_to_str_inf() { +pub fn test_to_str_inf() { assert to_str(infinity, 10u) == ~"inf"; assert to_str(-infinity, 10u) == ~"-inf"; } #[test] -fn test_traits() { +pub fn test_traits() { fn test(ten: &U) { assert (ten.to_int() == 10); let two: U = from_int(2); assert (two.to_int() == 2); - assert (ten.add(two) == from_int(12)); - assert (ten.sub(two) == from_int(8)); - assert (ten.mul(two) == from_int(20)); - assert (ten.div(two) == from_int(5)); - assert (ten.modulo(two) == from_int(0)); + assert (ten.add(&two) == from_int(12)); + assert (ten.sub(&two) == from_int(8)); + assert (ten.mul(&two) == from_int(20)); + assert (ten.div(&two) == from_int(5)); + assert (ten.modulo(&two) == from_int(0)); } test(&10.0); diff --git a/src/libcore/from_str.rs b/src/libcore/from_str.rs index b9bd322a816b..c4dd2536e2cf 100644 --- a/src/libcore/from_str.rs +++ b/src/libcore/from_str.rs @@ -6,7 +6,7 @@ use option::Option; -trait FromStr { +pub trait FromStr { static fn from_str(s: &str) -> Option; } diff --git a/src/libcore/future.rs b/src/libcore/future.rs index 35b3ffe040c5..11b6a2c01354 100644 --- a/src/libcore/future.rs +++ b/src/libcore/future.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; /*! @@ -19,20 +19,8 @@ use either::Either; use pipes::recv; use cast::copy_lifetime; -export Future; -export extensions; -export from_value; -export from_port; -export from_fn; -export get; -export with; -export spawn; - -// for task.rs -export future_pipe; - #[doc = "The future type"] -struct Future { +pub struct Future { /*priv*/ mut state: FutureState, // FIXME(#2829) -- futures should not be copyable, because they close @@ -67,7 +55,7 @@ impl Future { } } -fn from_value(+val: A) -> Future { +pub fn from_value(val: A) -> Future { /*! * Create a future from a value * @@ -78,7 +66,8 @@ fn from_value(+val: A) -> Future { Future {state: Forced(~(move val))} } -fn from_port(+port: future_pipe::client::waiting) -> Future { +pub fn from_port(port: future_pipe::client::waiting) -> + Future { /*! * Create a future from a port * @@ -97,7 +86,7 @@ fn from_port(+port: future_pipe::client::waiting) -> Future { } } -fn from_fn(+f: ~fn() -> A) -> Future { +pub fn from_fn(+f: ~fn() -> A) -> Future { /*! * Create a future from a function. * @@ -109,7 +98,7 @@ fn from_fn(+f: ~fn() -> A) -> Future { Future {state: Pending(move f)} } -fn spawn(+blk: fn~() -> A) -> Future { +pub fn spawn(+blk: fn~() -> A) -> Future { /*! * Create a future from a unique closure. * @@ -122,7 +111,7 @@ fn spawn(+blk: fn~() -> A) -> Future { })) } -fn get_ref(future: &r/Future) -> &r/A { +pub fn get_ref(future: &r/Future) -> &r/A { /*! * Executes the future's closure and then returns a borrowed * pointer to the result. The borrowed pointer lasts as long as @@ -160,13 +149,13 @@ fn get_ref(future: &r/Future) -> &r/A { } } -fn get(future: &Future) -> A { +pub fn get(future: &Future) -> A { //! Get the value of the future *get_ref(future) } -fn with(future: &Future, blk: fn((&A)) -> B) -> B { +pub fn with(future: &Future, blk: fn((&A)) -> B) -> B { //! Work with the value without copying it blk(get_ref(future)) @@ -179,16 +168,15 @@ proto! future_pipe ( ) #[allow(non_implicitly_copyable_typarams)] -mod test { - #[legacy_exports]; +pub mod test { #[test] - fn test_from_value() { + pub fn test_from_value() { let f = from_value(~"snail"); assert get(&f) == ~"snail"; } #[test] - fn test_from_port() { + pub fn test_from_port() { let (po, ch) = future_pipe::init(); future_pipe::server::completed(ch, ~"whale"); let f = from_port(po); @@ -196,43 +184,43 @@ mod test { } #[test] - fn test_from_fn() { + pub fn test_from_fn() { let f = from_fn(|| ~"brail"); assert get(&f) == ~"brail"; } #[test] - fn test_interface_get() { + pub fn test_interface_get() { let f = from_value(~"fail"); assert f.get() == ~"fail"; } #[test] - fn test_with() { + pub fn test_with() { let f = from_value(~"nail"); assert with(&f, |v| copy *v) == ~"nail"; } #[test] - fn test_get_ref_method() { + pub fn test_get_ref_method() { let f = from_value(22); assert *f.get_ref() == 22; } #[test] - fn test_get_ref_fn() { + pub fn test_get_ref_fn() { let f = from_value(22); assert *get_ref(&f) == 22; } #[test] - fn test_interface_with() { + pub fn test_interface_with() { let f = from_value(~"kale"); assert f.with(|v| copy *v) == ~"kale"; } #[test] - fn test_spawn() { + pub fn test_spawn() { let f = spawn(|| ~"bale"); assert get(&f) == ~"bale"; } @@ -240,13 +228,13 @@ mod test { #[test] #[should_fail] #[ignore(cfg(target_os = "win32"))] - fn test_futurefail() { + pub fn test_futurefail() { let f = spawn(|| fail); let _x: ~str = get(&f); } #[test] - fn test_sendable_future() { + pub fn test_sendable_future() { let expected = ~"schlorf"; let f = do spawn |copy expected| { copy expected }; do task::spawn { diff --git a/src/libcore/gc.rs b/src/libcore/gc.rs index 4faffb0c9ad5..464600b94693 100644 --- a/src/libcore/gc.rs +++ b/src/libcore/gc.rs @@ -29,15 +29,11 @@ with destructors. #[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; -use stackwalk::Word; +pub use stackwalk::Word; use libc::size_t; use libc::uintptr_t; use send_map::linear::LinearMap; -export Word; -export gc; -export cleanup_stack_for_failure; - // Mirrors rust_stack.h stk_seg struct StackSegment { prev: *StackSegment, @@ -268,7 +264,7 @@ unsafe fn walk_gc_roots(mem: Memory, sentinel: **Word, visitor: Visitor) { } } -fn gc() { +pub fn gc() { unsafe { // Abort when GC is disabled. if get_safe_point_count() == 0 { @@ -301,7 +297,7 @@ fn expect_sentinel() -> bool { false } // This should only be called from fail, as it will drop the roots // which are *live* on the stack, rather than dropping those that are // dead. -fn cleanup_stack_for_failure() { +pub fn cleanup_stack_for_failure() { unsafe { // Abort when GC is disabled. if get_safe_point_count() == 0 { @@ -320,7 +316,7 @@ fn cleanup_stack_for_failure() { // own stack roots on the stack anyway. let sentinel_box = ~0; let sentinel: **Word = if expect_sentinel() { - cast::reinterpret_cast(&ptr::addr_of(sentinel_box)) + cast::reinterpret_cast(&ptr::addr_of(&sentinel_box)) } else { ptr::null() }; diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs index abc72ddfd31f..6703006650b0 100644 --- a/src/libcore/hash.rs +++ b/src/libcore/hash.rs @@ -17,9 +17,6 @@ use io::Writer; use io::WriterUtil; use to_bytes::IterBytes; -export Streaming, State, Hash, HashUtil; -export default_state; - /** * Types that can meaningfully be hashed should implement this. * @@ -32,7 +29,7 @@ export default_state; * the rest. This is the recommended approach, since constructing * good keyed hash functions is quite difficult. */ -trait Hash { +pub trait Hash { /** * Compute a "keyed" hash of the value implementing the trait, * taking `k0` and `k1` as "keying" parameters that randomize or @@ -49,7 +46,7 @@ trait Hash { } // When we have default methods, won't need this. -trait HashUtil { +pub trait HashUtil { pure fn hash() -> u64; } @@ -59,7 +56,7 @@ impl A: HashUtil { } /// Streaming hash-functions should implement this. -trait Streaming { +pub trait Streaming { fn input((&[const u8])); // These can be refactored some when we have default methods. fn result_bytes() -> ~[u8]; @@ -139,15 +136,15 @@ pure fn hash_keyed_5 State { +pub fn State(k0: u64, k1: u64) -> State { SipState(k0, k1) } #[inline(always)] -fn default_state() -> State { +pub fn default_state() -> State { State(0,0) } @@ -361,7 +358,7 @@ impl &SipState : Streaming { } #[test] -fn test_siphash() { +pub fn test_siphash() { let vecs : [[u8]/8]/64 = [ [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ]/_, [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ]/_, @@ -468,26 +465,26 @@ fn test_siphash() { } #[test] #[cfg(target_arch = "arm")] -fn test_hash_uint() { +pub fn test_hash_uint() { let val = 0xdeadbeef_deadbeef_u64; assert (val as u64).hash() != (val as uint).hash(); assert (val as u32).hash() == (val as uint).hash(); } #[test] #[cfg(target_arch = "x86_64")] -fn test_hash_uint() { +pub fn test_hash_uint() { let val = 0xdeadbeef_deadbeef_u64; assert (val as u64).hash() == (val as uint).hash(); assert (val as u32).hash() != (val as uint).hash(); } #[test] #[cfg(target_arch = "x86")] -fn test_hash_uint() { +pub fn test_hash_uint() { let val = 0xdeadbeef_deadbeef_u64; assert (val as u64).hash() != (val as uint).hash(); assert (val as u32).hash() == (val as uint).hash(); } #[test] -fn test_hash_idempotent() { +pub fn test_hash_idempotent() { let val64 = 0xdeadbeef_deadbeef_u64; val64.hash() == val64.hash(); let val32 = 0xdeadbeef_u32; @@ -495,7 +492,7 @@ fn test_hash_idempotent() { } #[test] -fn test_hash_no_bytes_dropped_64() { +pub fn test_hash_no_bytes_dropped_64() { let val = 0xdeadbeef_deadbeef_u64; assert val.hash() != zero_byte(val, 0).hash(); @@ -514,7 +511,7 @@ fn test_hash_no_bytes_dropped_64() { } #[test] -fn test_hash_no_bytes_dropped_32() { +pub fn test_hash_no_bytes_dropped_32() { let val = 0xdeadbeef_u32; assert val.hash() != zero_byte(val, 0).hash(); diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs index e1137e6d269c..6942d38d5d34 100644 --- a/src/libcore/int-template.rs +++ b/src/libcore/int-template.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; use T = inst::T; @@ -7,49 +7,36 @@ use cmp::{Eq, Ord}; use from_str::FromStr; use num::from_int; -export min_value, max_value; -export min, max; -export add, sub, mul, div, rem; -export lt, le, eq, ne, ge, gt; -export is_positive, is_negative; -export is_nonpositive, is_nonnegative; -export range; -export compl; -export abs; -export parse_bytes, from_str, to_str, to_str_bytes, str; -export num, ord, eq, times, timesi; -export bits, bytes; +pub const bits : uint = inst::bits; +pub const bytes : uint = (inst::bits / 8); -const bits : uint = inst::bits; -const bytes : uint = (inst::bits / 8); +pub const min_value: T = (-1 as T) << (bits - 1); +pub const max_value: T = min_value - 1 as T; -const min_value: T = (-1 as T) << (bits - 1); -const max_value: T = min_value - 1 as T; +pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } } +pub pure fn max(x: T, y: T) -> T { if x > y { x } else { y } } -pure fn min(x: T, y: T) -> T { if x < y { x } else { y } } -pure fn max(x: T, y: T) -> T { if x > y { x } else { y } } +pub pure fn add(x: T, y: T) -> T { x + y } +pub pure fn sub(x: T, y: T) -> T { x - y } +pub pure fn mul(x: T, y: T) -> T { x * y } +pub pure fn div(x: T, y: T) -> T { x / y } +pub pure fn rem(x: T, y: T) -> T { x % y } -pure fn add(x: T, y: T) -> T { x + y } -pure fn sub(x: T, y: T) -> T { x - y } -pure fn mul(x: T, y: T) -> T { x * y } -pure fn div(x: T, y: T) -> T { x / y } -pure fn rem(x: T, y: T) -> T { x % y } +pub pure fn lt(x: T, y: T) -> bool { x < y } +pub pure fn le(x: T, y: T) -> bool { x <= y } +pub pure fn eq(x: T, y: T) -> bool { x == y } +pub pure fn ne(x: T, y: T) -> bool { x != y } +pub pure fn ge(x: T, y: T) -> bool { x >= y } +pub pure fn gt(x: T, y: T) -> bool { x > y } -pure fn lt(x: T, y: T) -> bool { x < y } -pure fn le(x: T, y: T) -> bool { x <= y } -pure fn eq(x: T, y: T) -> bool { x == y } -pure fn ne(x: T, y: T) -> bool { x != y } -pure fn ge(x: T, y: T) -> bool { x >= y } -pure fn gt(x: T, y: T) -> bool { x > y } - -pure fn is_positive(x: T) -> bool { x > 0 as T } -pure fn is_negative(x: T) -> bool { x < 0 as T } -pure fn is_nonpositive(x: T) -> bool { x <= 0 as T } -pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } +pub pure fn is_positive(x: T) -> bool { x > 0 as T } +pub pure fn is_negative(x: T) -> bool { x < 0 as T } +pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T } +pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } #[inline(always)] /// Iterate over the range [`lo`..`hi`) -fn range(lo: T, hi: T, it: fn(T) -> bool) { +pub fn range(lo: T, hi: T, it: fn(T) -> bool) { let mut i = lo; while i < hi { if !it(i) { break } @@ -58,13 +45,13 @@ fn range(lo: T, hi: T, it: fn(T) -> bool) { } /// Computes the bitwise complement -pure fn compl(i: T) -> T { +pub pure fn compl(i: T) -> T { -1 as T ^ i } /// Computes the absolute value // FIXME: abs should return an unsigned int (#2353) -pure fn abs(i: T) -> T { +pub pure fn abs(i: T) -> T { if is_negative(i) { -i } else { i } } @@ -81,11 +68,11 @@ impl T : Eq { } impl T: num::Num { - pure fn add(&&other: T) -> T { return self + other; } - pure fn sub(&&other: T) -> T { return self - other; } - pure fn mul(&&other: T) -> T { return self * other; } - pure fn div(&&other: T) -> T { return self / other; } - pure fn modulo(&&other: T) -> T { return self % other; } + pure fn add(other: &T) -> T { return self + *other; } + pure fn sub(other: &T) -> T { return self - *other; } + pure fn mul(other: &T) -> T { return self * *other; } + pure fn div(other: &T) -> T { return self / *other; } + pure fn modulo(other: &T) -> T { return self % *other; } pure fn neg() -> T { return -self; } pure fn to_int() -> int { return self as int; } @@ -137,7 +124,7 @@ impl T: iter::TimesIx { * * buf - A byte buffer * * radix - The base of the number */ -fn parse_bytes(buf: &[u8], radix: uint) -> Option { +pub fn parse_bytes(buf: &[u8], radix: uint) -> Option { if vec::len(buf) == 0u { return None; } let mut i = vec::len(buf) - 1u; let mut start = 0u; @@ -160,14 +147,14 @@ fn parse_bytes(buf: &[u8], radix: uint) -> Option { } /// Parse a string to an int -fn from_str(s: &str) -> Option { parse_bytes(str::to_bytes(s), 10u) } +pub fn from_str(s: &str) -> Option { parse_bytes(str::to_bytes(s), 10u) } impl T : FromStr { static fn from_str(s: &str) -> Option { from_str(s) } } /// Convert to a string in a given base -fn to_str(n: T, radix: uint) -> ~str { +pub fn to_str(n: T, radix: uint) -> ~str { do to_str_bytes(n, radix) |slice| { do vec::as_imm_buf(slice) |p, len| { unsafe { str::raw::from_buf_len(p, len) } @@ -175,7 +162,7 @@ fn to_str(n: T, radix: uint) -> ~str { } } -fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { +pub fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { if n < 0 as T { uint::to_str_bytes(true, -n as uint, radix, f) } else { @@ -184,7 +171,7 @@ fn to_str_bytes(n: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { } /// Convert to a string -fn str(i: T) -> ~str { return to_str(i, 10u); } +pub fn str(i: T) -> ~str { return to_str(i, 10u); } // FIXME: Has alignment issues on windows and 32-bit linux (#2609) #[test] @@ -244,17 +231,17 @@ fn test_to_str() { #[test] fn test_interfaces() { - fn test(+ten: U) { + fn test(ten: U) { assert (ten.to_int() == 10); let two: U = from_int(2); assert (two.to_int() == 2); - assert (ten.add(two) == from_int(12)); - assert (ten.sub(two) == from_int(8)); - assert (ten.mul(two) == from_int(20)); - assert (ten.div(two) == from_int(5)); - assert (ten.modulo(two) == from_int(0)); + assert (ten.add(&two) == from_int(12)); + assert (ten.sub(&two) == from_int(8)); + assert (ten.mul(&two) == from_int(20)); + assert (ten.div(&two) == from_int(5)); + assert (ten.modulo(&two) == from_int(0)); assert (ten.neg() == from_int(-10)); } diff --git a/src/libcore/int-template/i16.rs b/src/libcore/int-template/i16.rs index 75a8409f6edd..9e7055c3e7a6 100644 --- a/src/libcore/int-template/i16.rs +++ b/src/libcore/int-template/i16.rs @@ -1,2 +1,2 @@ -type T = i16; -const bits: uint = u16::bits; \ No newline at end of file +pub type T = i16; +pub const bits: uint = u16::bits; \ No newline at end of file diff --git a/src/libcore/int-template/i32.rs b/src/libcore/int-template/i32.rs index 043ab95f579f..6545eaffdac9 100644 --- a/src/libcore/int-template/i32.rs +++ b/src/libcore/int-template/i32.rs @@ -1,2 +1,2 @@ -type T = i32; -const bits: uint = u32::bits; +pub type T = i32; +pub const bits: uint = u32::bits; diff --git a/src/libcore/int-template/i64.rs b/src/libcore/int-template/i64.rs index cea3c77c7f58..c6ed97e8162c 100644 --- a/src/libcore/int-template/i64.rs +++ b/src/libcore/int-template/i64.rs @@ -1,2 +1,2 @@ -type T = i64; -const bits: uint = u64::bits; \ No newline at end of file +pub type T = i64; +pub const bits: uint = u64::bits; \ No newline at end of file diff --git a/src/libcore/int-template/i8.rs b/src/libcore/int-template/i8.rs index 25614791ad63..0a2823e63c6e 100644 --- a/src/libcore/int-template/i8.rs +++ b/src/libcore/int-template/i8.rs @@ -1,2 +1,2 @@ -type T = i8; -const bits: uint = u8::bits; \ No newline at end of file +pub type T = i8; +pub const bits: uint = u8::bits; \ No newline at end of file diff --git a/src/libcore/int-template/int.rs b/src/libcore/int-template/int.rs index 7e7cddf9b300..8b898b173ac3 100644 --- a/src/libcore/int-template/int.rs +++ b/src/libcore/int-template/int.rs @@ -1,8 +1,8 @@ -type T = int; -const bits: uint = uint::bits; +pub type T = int; +pub const bits: uint = uint::bits; /// Returns `base` raised to the power of `exponent` -fn pow(base: int, exponent: uint) -> int { +pub fn pow(base: int, exponent: uint) -> int { if exponent == 0u { return 1; } //Not mathemtically true if ~[base == 0] if base == 0 { return 0; } let mut my_pow = exponent; diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 7c08e508d51e..2efc96933da8 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -17,7 +17,6 @@ type fd_t = c_int; #[abi = "cdecl"] extern mod rustrt { - #[legacy_exports]; fn rust_get_stdin() -> *libc::FILE; fn rust_get_stdout() -> *libc::FILE; fn rust_get_stderr() -> *libc::FILE; @@ -27,11 +26,11 @@ extern mod rustrt { // FIXME (#2004): This is all buffered. We might need an unbuffered variant // as well -enum SeekStyle { SeekSet, SeekEnd, SeekCur, } +pub enum SeekStyle { SeekSet, SeekEnd, SeekCur, } // The raw underlying reader trait. All readers must implement this. -trait Reader { +pub trait Reader { // FIXME (#2004): Seekable really should be orthogonal. // FIXME (#2982): This should probably return an error. @@ -45,19 +44,30 @@ trait Reader { // Generic utility functions defined on readers -trait ReaderUtil { +pub trait ReaderUtil { fn read_bytes(len: uint) -> ~[u8]; fn read_line() -> ~str; + + fn read_chars(n: uint) -> ~[char]; + fn read_char() -> char; + fn read_c_str() -> ~str; + fn read_le_uint(size: uint) -> uint; + fn read_le_int(size: uint) -> int; + fn read_be_uint(size: uint) -> uint; + fn read_whole_stream() -> ~[u8]; + fn each_byte(it: fn(int) -> bool); + fn each_char(it: fn(char) -> bool); + fn each_line(it: fn((&str)) -> bool); } impl T : ReaderUtil { fn read_bytes(len: uint) -> ~[u8] { let mut buf = vec::with_capacity(len); - unsafe { vec::raw::set_len(buf, len); } + unsafe { vec::raw::set_len(&mut buf, len); } let count = self.read(buf, len); - unsafe { vec::raw::set_len(buf, count); } + unsafe { vec::raw::set_len(&mut buf, count); } move buf } fn read_line() -> ~str { @@ -65,78 +75,78 @@ impl T : ReaderUtil { loop { let ch = self.read_byte(); if ch == -1 || ch == 10 { break; } - vec::push(buf, ch as u8); + buf.push(ch as u8); } str::from_bytes(buf) } -} -impl Reader { fn read_chars(n: uint) -> ~[char] { // returns the (consumed offset, n_req), appends characters to &chars - fn chars_from_bytes(buf: ~[u8], &chars: ~[char]) -> (uint, uint) { - let mut i = 0u; - while i < vec::len(buf) { + fn chars_from_bytes(buf: &~[u8], chars: &mut ~[char]) + -> (uint, uint) { + let mut i = 0; + let buf_len = buf.len(); + while i < buf_len { let b0 = buf[i]; let w = str::utf8_char_width(b0); let end = i + w; - i += 1u; - assert (w > 0u); - if w == 1u { - vec::push(chars, b0 as char ); + i += 1; + assert (w > 0); + if w == 1 { + chars.push(b0 as char); loop; } // can't satisfy this char with the existing data - if end > vec::len(buf) { - return (i - 1u, end - vec::len(buf)); + if end > buf_len { + return (i - 1, end - buf_len); } - let mut val = 0u; + let mut val = 0; while i < end { let next = buf[i] as int; - i += 1u; + i += 1; assert (next > -1); assert (next & 192 == 128); - val <<= 6u; + val <<= 6; val += (next & 63) as uint; } // See str::char_at - val += ((b0 << ((w + 1u) as u8)) as uint) - << (w - 1u) * 6u - w - 1u; - vec::push(chars, val as char ); + val += ((b0 << ((w + 1) as u8)) as uint) + << (w - 1) * 6 - w - 1u; + chars.push(val as char); } - return (i, 0u); + return (i, 0); } let mut buf: ~[u8] = ~[]; let mut chars: ~[char] = ~[]; // might need more bytes, but reading n will never over-read let mut nbread = n; - while nbread > 0u { + while nbread > 0 { let data = self.read_bytes(nbread); - if vec::len(data) == 0u { + if data.is_empty() { // eof - FIXME (#2004): should we do something if // we're split in a unicode char? break; } - vec::push_all(buf, data); - let (offset, nbreq) = chars_from_bytes(buf, chars); - let ncreq = n - vec::len(chars); + buf.push_all(data); + let (offset, nbreq) = chars_from_bytes::(&buf, &mut chars); + let ncreq = n - chars.len(); // again we either know we need a certain number of bytes // to complete a character, or we make sure we don't // over-read by reading 1-byte per char needed nbread = if ncreq > nbreq { ncreq } else { nbreq }; - if nbread > 0u { - buf = vec::slice(buf, offset, vec::len(buf)); + if nbread > 0 { + buf = vec::slice(buf, offset, buf.len()); } } move chars } fn read_char() -> char { - let c = self.read_chars(1u); - if vec::len(c) == 0u { + let c = self.read_chars(1); + if vec::len(c) == 0 { return -1 as char; // FIXME will this stay valid? // #2004 } - assert(vec::len(c) == 1u); + assert(vec::len(c) == 1); return c[0]; } @@ -144,7 +154,7 @@ impl Reader { let mut buf: ~[u8] = ~[]; loop { let ch = self.read_byte(); - if ch < 1 { break; } else { vec::push(buf, ch as u8); } + if ch < 1 { break; } else { buf.push(ch as u8); } } str::from_bytes(buf) } @@ -179,7 +189,7 @@ impl Reader { fn read_whole_stream() -> ~[u8] { let mut buf: ~[u8] = ~[]; - while !self.eof() { vec::push_all(buf, self.read_bytes(2048u)); } + while !self.eof() { buf.push_all(self.read_bytes(2048u)); } move buf } @@ -195,7 +205,7 @@ impl Reader { } } - fn each_line(it: fn(~str) -> bool) { + fn each_line(it: fn(s: &str) -> bool) { while !self.eof() { if !it(self.read_line()) { break; } } @@ -256,7 +266,7 @@ fn FILERes(f: *libc::FILE) -> FILERes { } } -fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader { +pub fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader { if cleanup { {base: f, cleanup: FILERes(f)} as Reader } else { @@ -268,9 +278,9 @@ fn FILE_reader(f: *libc::FILE, cleanup: bool) -> Reader { // top-level functions that take a reader, or a set of default methods on // reader (which can then be called reader) -fn stdin() -> Reader { rustrt::rust_get_stdin() as Reader } +pub fn stdin() -> Reader { rustrt::rust_get_stdin() as Reader } -fn file_reader(path: &Path) -> Result { +pub fn file_reader(path: &Path) -> Result { let f = os::as_c_charp(path.to_str(), |pathbuf| { os::as_c_charp("r", |modebuf| libc::fopen(pathbuf, modebuf) @@ -286,7 +296,7 @@ fn file_reader(path: &Path) -> Result { // Byte buffer readers -type ByteBuf = {buf: &[const u8], mut pos: uint}; +pub type ByteBuf = {buf: &[const u8], mut pos: uint}; impl ByteBuf: Reader { fn read(buf: &[mut u8], len: uint) -> uint { @@ -315,21 +325,21 @@ impl ByteBuf: Reader { fn tell() -> uint { self.pos } } -fn with_bytes_reader(bytes: &[u8], f: fn(Reader) -> t) -> t { +pub fn with_bytes_reader(bytes: &[u8], f: fn(Reader) -> t) -> t { f({buf: bytes, mut pos: 0u} as Reader) } -fn with_str_reader(s: &str, f: fn(Reader) -> T) -> T { +pub fn with_str_reader(s: &str, f: fn(Reader) -> T) -> T { str::byte_slice(s, |bytes| with_bytes_reader(bytes, f)) } // Writing -enum FileFlag { Append, Create, Truncate, NoFlag, } +pub enum FileFlag { Append, Create, Truncate, NoFlag, } // What type of writer are we? -enum WriterType { Screen, File } +pub enum WriterType { Screen, File } -impl WriterType : Eq { +pub impl WriterType : Eq { pure fn eq(other: &WriterType) -> bool { match (self, (*other)) { (Screen, Screen) | (File, File) => true, @@ -341,7 +351,7 @@ impl WriterType : Eq { // FIXME (#2004): Seekable really should be orthogonal. // FIXME (#2004): eventually u64 -trait Writer { +pub trait Writer { fn write(v: &[const u8]); fn seek(int, SeekStyle); fn tell() -> uint; @@ -382,7 +392,7 @@ impl *libc::FILE: Writer { } } -fn FILE_writer(f: *libc::FILE, cleanup: bool) -> Writer { +pub fn FILE_writer(f: *libc::FILE, cleanup: bool) -> Writer { if cleanup { {base: f, cleanup: FILERes(f)} as Writer } else { @@ -431,7 +441,7 @@ fn FdRes(fd: fd_t) -> FdRes { } } -fn fd_writer(fd: fd_t, cleanup: bool) -> Writer { +pub fn fd_writer(fd: fd_t, cleanup: bool) -> Writer { if cleanup { {base: fd, cleanup: FdRes(fd)} as Writer } else { @@ -440,7 +450,7 @@ fn fd_writer(fd: fd_t, cleanup: bool) -> Writer { } -fn mk_file_writer(path: &Path, flags: ~[FileFlag]) +pub fn mk_file_writer(path: &Path, flags: &[FileFlag]) -> Result { #[cfg(windows)] @@ -470,7 +480,8 @@ fn mk_file_writer(path: &Path, flags: ~[FileFlag]) } } -fn u64_to_le_bytes(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T { +pub fn u64_to_le_bytes(n: u64, size: uint, + f: fn(v: &[u8]) -> T) -> T { assert size <= 8u; match size { 1u => f(&[n as u8]), @@ -492,7 +503,7 @@ fn u64_to_le_bytes(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T { let mut bytes: ~[u8] = ~[], i = size, n = n; while i > 0u { - vec::push(bytes, (n & 255_u64) as u8); + bytes.push((n & 255_u64) as u8); n >>= 8_u64; i -= 1u; } @@ -501,7 +512,8 @@ fn u64_to_le_bytes(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T { } } -fn u64_to_be_bytes(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T { +pub fn u64_to_be_bytes(n: u64, size: uint, + f: fn(v: &[u8]) -> T) -> T { assert size <= 8u; match size { 1u => f(&[n as u8]), @@ -524,7 +536,7 @@ fn u64_to_be_bytes(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T { let mut i = size; while i > 0u { let shift = ((i - 1u) * 8u) as u64; - vec::push(bytes, (n >> shift) as u8); + bytes.push((n >> shift) as u8); i -= 1u; } f(bytes) @@ -532,7 +544,8 @@ fn u64_to_be_bytes(n: u64, size: uint, f: fn(v: &[u8]) -> T) -> T { } } -fn u64_from_be_bytes(data: &[const u8], start: uint, size: uint) -> u64 { +pub fn u64_from_be_bytes(data: &[const u8], + start: uint, size: uint) -> u64 { let mut sz = size; assert (sz <= 8u); let mut val = 0_u64; @@ -547,7 +560,7 @@ fn u64_from_be_bytes(data: &[const u8], start: uint, size: uint) -> u64 { // FIXME: #3048 combine trait+impl (or just move these to // default methods on writer) -trait WriterUtil { +pub trait WriterUtil { fn write_char(ch: char); fn write_str(s: &str); fn write_line(s: &str); @@ -644,13 +657,13 @@ impl T : WriterUtil { } #[allow(non_implicitly_copyable_typarams)] -fn file_writer(path: &Path, flags: ~[FileFlag]) -> Result { - result::chain(mk_file_writer(path, flags), |w| result::Ok(w)) +pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result { + mk_file_writer(path, flags).chain(|w| result::Ok(w)) } // FIXME: fileflags // #2004 -fn buffered_file_writer(path: &Path) -> Result { +pub fn buffered_file_writer(path: &Path) -> Result { let f = do os::as_c_charp(path.to_str()) |pathbuf| { do os::as_c_charp("w") |modebuf| { libc::fopen(pathbuf, modebuf) @@ -664,13 +677,13 @@ fn buffered_file_writer(path: &Path) -> Result { // FIXME (#2004) it would be great if this could be a const // FIXME (#2004) why are these different from the way stdin() is // implemented? -fn stdout() -> Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) } -fn stderr() -> Writer { fd_writer(libc::STDERR_FILENO as c_int, false) } +pub fn stdout() -> Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) } +pub fn stderr() -> Writer { fd_writer(libc::STDERR_FILENO as c_int, false) } -fn print(s: &str) { stdout().write_str(s); } -fn println(s: &str) { stdout().write_line(s); } +pub fn print(s: &str) { stdout().write_str(s); } +pub fn println(s: &str) { stdout().write_line(s); } -struct BytesWriter { +pub struct BytesWriter { buf: DVec, mut pos: uint, } @@ -684,10 +697,12 @@ impl BytesWriter: Writer { let count = uint::max(buf_len, self.pos + v_len); vec::reserve(&mut buf, count); - unsafe { vec::raw::set_len(buf, count); } + unsafe { vec::raw::set_len(&mut buf, count); } - let view = vec::mut_view(buf, self.pos, count); - vec::bytes::memcpy(view, v, v_len); + { + let view = vec::mut_view(buf, self.pos, count); + vec::bytes::memcpy(view, v, v_len); + } self.pos += v_len; @@ -712,28 +727,28 @@ impl @BytesWriter : Writer { fn get_type() -> WriterType { (*self).get_type() } } -fn BytesWriter() -> BytesWriter { +pub fn BytesWriter() -> BytesWriter { BytesWriter { buf: DVec(), mut pos: 0u } } -fn with_bytes_writer(f: fn(Writer)) -> ~[u8] { +pub fn with_bytes_writer(f: fn(Writer)) -> ~[u8] { let wr = @BytesWriter(); f(wr as Writer); wr.buf.check_out(|buf| buf) } -fn with_str_writer(f: fn(Writer)) -> ~str { +pub fn with_str_writer(f: fn(Writer)) -> ~str { let mut v = with_bytes_writer(f); // Make sure the vector has a trailing null and is proper utf8. - vec::push(v, 0); + v.push(0); assert str::is_utf8(v); unsafe { move ::cast::transmute(v) } } // Utility functions -fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) -> +pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) -> uint { let mut bpos = pos as int; let blen = len as int; @@ -747,7 +762,7 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) -> } #[allow(non_implicitly_copyable_typarams)] -fn read_whole_file_str(file: &Path) -> Result<~str, ~str> { +pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> { result::chain(read_whole_file(file), |bytes| { if str::is_utf8(bytes) { result::Ok(str::from_bytes(bytes)) @@ -760,7 +775,7 @@ fn read_whole_file_str(file: &Path) -> Result<~str, ~str> { // FIXME (#2004): implement this in a low-level way. Going through the // abstractions is pointless. #[allow(non_implicitly_copyable_typarams)] -fn read_whole_file(file: &Path) -> Result<~[u8], ~str> { +pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> { result::chain(file_reader(file), |rdr| { result::Ok(rdr.read_whole_stream()) }) @@ -768,10 +783,9 @@ fn read_whole_file(file: &Path) -> Result<~[u8], ~str> { // fsync related -mod fsync { - #[legacy_exports]; +pub mod fsync { - enum Level { + pub enum Level { // whatever fsync does on that platform FSync, @@ -786,7 +800,7 @@ mod fsync { // Artifacts that need to fsync on destruction - struct Res { + pub struct Res { arg: Arg, drop { match self.arg.opt_level { @@ -799,51 +813,51 @@ mod fsync { } } - fn Res(-arg: Arg) -> Res{ + pub fn Res(arg: Arg) -> Res{ Res { arg: move arg } } - type Arg = { + pub type Arg = { val: t, opt_level: Option, - fsync_fn: fn@(t, Level) -> int + fsync_fn: fn@(f: t, Level) -> int }; // fsync file after executing blk // FIXME (#2004) find better way to create resources within lifetime of // outer res - fn FILE_res_sync(&&file: FILERes, opt_level: Option, - blk: fn(&&v: Res<*libc::FILE>)) { - blk(Res({ + pub fn FILE_res_sync(file: &FILERes, opt_level: Option, + blk: fn(v: Res<*libc::FILE>)) { + blk(move Res({ val: file.f, opt_level: opt_level, - fsync_fn: fn@(&&file: *libc::FILE, l: Level) -> int { + fsync_fn: fn@(file: *libc::FILE, l: Level) -> int { return os::fsync_fd(libc::fileno(file), l) as int; } })); } // fsync fd after executing blk - fn fd_res_sync(&&fd: FdRes, opt_level: Option, - blk: fn(&&v: Res)) { - blk(Res({ + pub fn fd_res_sync(fd: &FdRes, opt_level: Option, + blk: fn(v: Res)) { + blk(move Res({ val: fd.fd, opt_level: opt_level, - fsync_fn: fn@(&&fd: fd_t, l: Level) -> int { + fsync_fn: fn@(fd: fd_t, l: Level) -> int { return os::fsync_fd(fd, l) as int; } })); } // Type of objects that may want to fsync - trait FSyncable { fn fsync(l: Level) -> int; } + pub trait FSyncable { fn fsync(l: Level) -> int; } // Call o.fsync after executing blk - fn obj_sync(&&o: FSyncable, opt_level: Option, - blk: fn(&&v: Res)) { + pub fn obj_sync(o: FSyncable, opt_level: Option, + blk: fn(v: Res)) { blk(Res({ val: o, opt_level: opt_level, - fsync_fn: fn@(&&o: FSyncable, l: Level) -> int { + fsync_fn: fn@(o: FSyncable, l: Level) -> int { return o.fsync(l); } })); @@ -852,7 +866,6 @@ mod fsync { #[cfg(test)] mod tests { - #[legacy_exports]; #[test] fn test_simple() { @@ -864,10 +877,10 @@ mod tests { { let out: io::Writer = result::get( - io::file_writer(tmpfile, ~[io::Create, io::Truncate])); + &io::file_writer(tmpfile, ~[io::Create, io::Truncate])); out.write_str(frood); } - let inp: io::Reader = result::get(io::file_reader(tmpfile)); + let inp: io::Reader = result::get(&io::file_reader(tmpfile)); let frood2: ~str = inp.read_c_str(); log(debug, frood2); assert frood == frood2; @@ -876,8 +889,8 @@ mod tests { #[test] fn test_readchars_empty() { do io::with_str_reader(~"") |inp| { - let res : ~[char] = inp.read_chars(128u); - assert(vec::len(res) == 0u); + let res : ~[char] = inp.read_chars(128); + assert(vec::len(res) == 0); } } @@ -890,7 +903,7 @@ mod tests { 104, 101, 108, 108, 111, 29983, 38152, 30340, 27748, 21273, 20999, 32905, 27748]; - fn check_read_ln(len : uint, s: ~str, ivals: ~[int]) { + fn check_read_ln(len : uint, s: &str, ivals: &[int]) { do io::with_str_reader(s) |inp| { let res : ~[char] = inp.read_chars(len); if (len <= vec::len(ivals)) { @@ -900,13 +913,13 @@ mod tests { vec::map(res, |x| *x as int)); } } - let mut i = 0u; - while i < 8u { + let mut i = 0; + while i < 8 { check_read_ln(i, wide_test, ivals); - i += 1u; + i += 1; } // check a long read for good measure - check_read_ln(128u, wide_test, ivals); + check_read_ln(128, wide_test, ivals); } #[test] @@ -928,7 +941,7 @@ mod tests { #[test] fn file_reader_not_exist() { match io::file_reader(&Path("not a file")) { - result::Err(e) => { + result::Err(copy e) => { assert e == ~"error opening not a file"; } result::Ok(_) => fail @@ -938,7 +951,7 @@ mod tests { #[test] fn file_writer_bad_name() { match io::file_writer(&Path("?/?"), ~[]) { - result::Err(e) => { + result::Err(copy e) => { assert str::starts_with(e, "error opening"); } result::Ok(_) => fail @@ -948,7 +961,7 @@ mod tests { #[test] fn buffered_file_writer_bad_name() { match io::buffered_file_writer(&Path("?/?")) { - result::Err(e) => { + result::Err(copy e) => { assert str::starts_with(e, "error opening"); } result::Ok(_) => fail diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs index b2bb53d395f5..09bfe2eff36a 100644 --- a/src/libcore/iter-trait.rs +++ b/src/libcore/iter-trait.rs @@ -2,51 +2,52 @@ // workaround our lack of traits and lack of macros. See core.{rc,rs} for // how this file is used. +#[warn(deprecated_mode)]; + use cmp::{Eq, Ord}; use inst::{IMPL_T, EACH, SIZE_HINT}; -export extensions; impl IMPL_T: iter::BaseIter { - pure fn each(blk: fn(v: &A) -> bool) { EACH(self, blk) } - pure fn size_hint() -> Option { SIZE_HINT(self) } + pure fn each(blk: fn(v: &A) -> bool) { EACH(&self, blk) } + pure fn size_hint() -> Option { SIZE_HINT(&self) } } impl IMPL_T: iter::ExtendedIter { - pure fn eachi(blk: fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) } - pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) } - pure fn foldl(+b0: B, blk: fn(B, A) -> B) -> B { - iter::foldl(self, move b0, blk) + pure fn eachi(blk: fn(uint, v: &A) -> bool) { iter::eachi(&self, blk) } + pure fn all(blk: fn(&A) -> bool) -> bool { iter::all(&self, blk) } + pure fn any(blk: fn(&A) -> bool) -> bool { iter::any(&self, blk) } + pure fn foldl(b0: B, blk: fn(&B, &A) -> B) -> B { + iter::foldl(&self, move b0, blk) } - pure fn position(f: fn(A) -> bool) -> Option { - iter::position(self, f) + pure fn position(f: fn(&A) -> bool) -> Option { + iter::position(&self, f) } } impl IMPL_T: iter::EqIter { - pure fn contains(x: A) -> bool { iter::contains(self, x) } - pure fn count(x: A) -> uint { iter::count(self, x) } + pure fn contains(x: &A) -> bool { iter::contains(&self, x) } + pure fn count(x: &A) -> uint { iter::count(&self, x) } } impl IMPL_T: iter::CopyableIter { - pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] { - iter::filter_to_vec(self, pred) + pure fn filter_to_vec(pred: fn(a: A) -> bool) -> ~[A] { + iter::filter_to_vec(&self, pred) } - pure fn map_to_vec(op: fn(v: &A) -> B) -> ~[B] { - iter::map_to_vec(self, op) + pure fn map_to_vec(op: fn(v: A) -> B) -> ~[B] { + iter::map_to_vec(&self, op) } - pure fn to_vec() -> ~[A] { iter::to_vec(self) } + pure fn to_vec() -> ~[A] { iter::to_vec(&self) } - // FIXME--bug in resolve prevents this from working (#2611) - // fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] { - // iter::flat_map_to_vec(self, op) - // } + pure fn flat_map_to_vec>(op: fn(a: A) -> IB) + -> ~[B] { + iter::flat_map_to_vec(&self, op) + } - pure fn find(p: fn(A) -> bool) -> Option { iter::find(self, p) } + pure fn find(p: fn(a: A) -> bool) -> Option { iter::find(&self, p) } } impl IMPL_T: iter::CopyableOrderedIter { - pure fn min() -> A { iter::min(self) } - pure fn max() -> A { iter::max(self) } + pure fn min() -> A { iter::min(&self) } + pure fn max() -> A { iter::max(&self) } } diff --git a/src/libcore/iter-trait/dlist.rs b/src/libcore/iter-trait/dlist.rs index b6bbc1f70c03..2a5bb59b0c1f 100644 --- a/src/libcore/iter-trait/dlist.rs +++ b/src/libcore/iter-trait/dlist.rs @@ -1,5 +1,5 @@ #[allow(non_camel_case_types)] -type IMPL_T = dlist::DList; +pub type IMPL_T = dlist::DList; /** * Iterates through the current contents. @@ -8,7 +8,7 @@ type IMPL_T = dlist::DList; * e.g. breadth-first search with in-place enqueues), but removing the current * node is forbidden. */ -pure fn EACH(self: IMPL_T, f: fn(v: &A) -> bool) { +pub pure fn EACH(self: &IMPL_T, f: fn(v: &A) -> bool) { let mut link = self.peek_n(); while option::is_some(&link) { let nobe = option::get(&link); @@ -29,6 +29,6 @@ pure fn EACH(self: IMPL_T, f: fn(v: &A) -> bool) { } } -pure fn SIZE_HINT(self: IMPL_T) -> Option { +pub pure fn SIZE_HINT(self: &IMPL_T) -> Option { Some(self.len()) } diff --git a/src/libcore/iter-trait/dvec.rs b/src/libcore/iter-trait/dvec.rs index 0f51df7b5455..f03f1a154e4d 100644 --- a/src/libcore/iter-trait/dvec.rs +++ b/src/libcore/iter-trait/dvec.rs @@ -1,12 +1,12 @@ #[allow(non_camel_case_types)] -type IMPL_T = dvec::DVec; +pub type IMPL_T = dvec::DVec; /** * Iterates through the current contents. * * Attempts to access this dvec during iteration will fail. */ -pure fn EACH(self: IMPL_T, f: fn(v: &A) -> bool) { +pub pure fn EACH(self: &IMPL_T, f: fn(v: &A) -> bool) { unsafe { do self.swap |v| { v.each(f); @@ -15,6 +15,6 @@ pure fn EACH(self: IMPL_T, f: fn(v: &A) -> bool) { } } -pure fn SIZE_HINT(self: IMPL_T) -> Option { +pub pure fn SIZE_HINT(self: &IMPL_T) -> Option { Some(self.len()) } diff --git a/src/libcore/iter-trait/option.rs b/src/libcore/iter-trait/option.rs index e1ffec0a7d77..44afe9f54f00 100644 --- a/src/libcore/iter-trait/option.rs +++ b/src/libcore/iter-trait/option.rs @@ -1,16 +1,16 @@ #[allow(non_camel_case_types)] -type IMPL_T = Option; +pub type IMPL_T = Option; -pure fn EACH(self: IMPL_T, f: fn(v: &A) -> bool) { - match self { +pub pure fn EACH(self: &IMPL_T, f: fn(v: &A) -> bool) { + match *self { None => (), Some(ref a) => { f(a); } } } -pure fn SIZE_HINT(self: IMPL_T) -> Option { - match self { - None => Some(0u), - Some(_) => Some(1u) +pub pure fn SIZE_HINT(self: &IMPL_T) -> Option { + match *self { + None => Some(0), + Some(_) => Some(1) } } diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 8af4ce3d0b1b..bf3e91f70719 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -7,48 +7,49 @@ The iteration traits and common implementation use cmp::{Eq, Ord}; /// A function used to initialize the elements of a sequence -type InitOp = fn(uint) -> T; +pub type InitOp = &fn(uint) -> T; -trait BaseIter { +pub trait BaseIter { pure fn each(blk: fn(v: &A) -> bool); pure fn size_hint() -> Option; } -trait ExtendedIter { +pub trait ExtendedIter { pure fn eachi(blk: fn(uint, v: &A) -> bool); - pure fn all(blk: fn(A) -> bool) -> bool; - pure fn any(blk: fn(A) -> bool) -> bool; - pure fn foldl(+b0: B, blk: fn(B, A) -> B) -> B; - pure fn position(f: fn(A) -> bool) -> Option; + pure fn all(blk: fn(&A) -> bool) -> bool; + pure fn any(blk: fn(&A) -> bool) -> bool; + pure fn foldl(b0: B, blk: fn(&B, &A) -> B) -> B; + pure fn position(f: fn(&A) -> bool) -> Option; } -trait EqIter { - pure fn contains(x: A) -> bool; - pure fn count(x: A) -> uint; +pub trait EqIter { + pure fn contains(x: &A) -> bool; + pure fn count(x: &A) -> uint; } -trait Times { +pub trait Times { pure fn times(it: fn() -> bool); } -trait TimesIx{ + +pub trait TimesIx{ pure fn timesi(it: fn(uint) -> bool); } -trait CopyableIter { - pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A]; - pure fn map_to_vec(op: fn(v: &A) -> B) -> ~[B]; +pub trait CopyableIter { + pure fn filter_to_vec(pred: fn(a: A) -> bool) -> ~[A]; + pure fn map_to_vec(op: fn(v: A) -> B) -> ~[B]; pure fn to_vec() -> ~[A]; - pure fn find(p: fn(A) -> bool) -> Option; + pure fn find(p: fn(a: A) -> bool) -> Option; } -trait CopyableOrderedIter { +pub trait CopyableOrderedIter { pure fn min() -> A; pure fn max() -> A; } // A trait for sequences that can be by imperatively pushing elements // onto them. -trait Buildable { +pub trait Buildable { /** * Builds a buildable sequence by calling a provided function with * an argument function that pushes an element onto the back of @@ -63,33 +64,36 @@ trait Buildable { * onto the sequence being constructed. */ static pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> self; + builder: fn(push: pure fn(v: A))) -> self; } -pure fn eachi>(self: IA, blk: fn(uint, v: &A) -> bool) { - let mut i = 0u; +pub pure fn eachi>(self: &IA, + blk: fn(uint, v: &A) -> bool) { + let mut i = 0; for self.each |a| { if !blk(i, a) { break; } - i += 1u; + i += 1; } } -pure fn all>(self: IA, blk: fn(A) -> bool) -> bool { +pub pure fn all>(self: &IA, + blk: fn(&A) -> bool) -> bool { for self.each |a| { - if !blk(*a) { return false; } + if !blk(a) { return false; } } return true; } -pure fn any>(self: IA, blk: fn(A) -> bool) -> bool { +pub pure fn any>(self: &IA, + blk: fn(&A) -> bool) -> bool { for self.each |a| { - if blk(*a) { return true; } + if blk(a) { return true; } } return false; } -pure fn filter_to_vec>(self: IA, - prd: fn(A) -> bool) -> ~[A] { +pub pure fn filter_to_vec>( + self: &IA, prd: fn(a: A) -> bool) -> ~[A] { do vec::build_sized_opt(self.size_hint()) |push| { for self.each |a| { if prd(*a) { push(*a); } @@ -97,18 +101,18 @@ pure fn filter_to_vec>(self: IA, } } -pure fn map_to_vec>(self: IA, op: fn(v: &A) -> B) +pub pure fn map_to_vec>(self: &IA, + op: fn(v: A) -> B) -> ~[B] { do vec::build_sized_opt(self.size_hint()) |push| { for self.each |a| { - push(op(a)); + push(op(*a)); } } } -pure fn flat_map_to_vec,IB:BaseIter>( - self: IA, op: fn(A) -> IB) -> ~[B] { - +pub pure fn flat_map_to_vec,IB:BaseIter>( + self: &IA, op: fn(a: A) -> IB) -> ~[B] { do vec::build |push| { for self.each |a| { for op(*a).each |b| { @@ -118,41 +122,43 @@ pure fn flat_map_to_vec,IB:BaseIter>( } } -pure fn foldl>(self: IA, +b0: B, blk: fn(B, A) -> B) -> B { +pub pure fn foldl>(self: &IA, b0: B, + blk: fn(&B, &A) -> B) + -> B { let mut b <- b0; for self.each |a| { - b = blk(b, *a); + b = blk(&b, a); } move b } -pure fn to_vec>(self: IA) -> ~[A] { - foldl::(self, ~[], |r, a| vec::append(copy r, ~[a])) +pub pure fn to_vec>(self: &IA) -> ~[A] { + foldl::(self, ~[], |r, a| vec::append(copy (*r), ~[*a])) } -pure fn contains>(self: IA, x: A) -> bool { +pub pure fn contains>(self: &IA, x: &A) -> bool { for self.each |a| { - if *a == x { return true; } + if *a == *x { return true; } } return false; } -pure fn count>(self: IA, x: A) -> uint { - do foldl(self, 0u) |count, value| { - if value == x { - count + 1u +pub pure fn count>(self: &IA, x: &A) -> uint { + do foldl(self, 0) |count, value| { + if *value == *x { + *count + 1 } else { - count + *count } } } -pure fn position>(self: IA, f: fn(A) -> bool) +pub pure fn position>(self: &IA, f: fn(&A) -> bool) -> Option { let mut i = 0; for self.each |a| { - if f(*a) { return Some(i); } + if f(a) { return Some(i); } i += 1; } return None; @@ -162,48 +168,44 @@ pure fn position>(self: IA, f: fn(A) -> bool) // iter interface, such as would provide "reach" in addition to "each". as is, // it would have to be implemented with foldr, which is too inefficient. -pure fn repeat(times: uint, blk: fn() -> bool) { - let mut i = 0u; +pub pure fn repeat(times: uint, blk: fn() -> bool) { + let mut i = 0; while i < times { if !blk() { break } - i += 1u; + i += 1; } } -pure fn min>(self: IA) -> A { +pub pure fn min>(self: &IA) -> A { match do foldl::,IA>(self, None) |a, b| { match a { - Some(a_) if a_ < b => { - // FIXME (#2005): Not sure if this is successfully optimized to - // a move - a + &Some(ref a_) if *a_ < *b => { + *(move a) } - _ => Some(b) + _ => Some(*b) } } { - Some(val) => val, + Some(move val) => val, None => fail ~"min called on empty iterator" } } -pure fn max>(self: IA) -> A { +pub pure fn max>(self: &IA) -> A { match do foldl::,IA>(self, None) |a, b| { match a { - Some(a_) if a_ > b => { - // FIXME (#2005): Not sure if this is successfully optimized to - // a move. - a + &Some(ref a_) if *a_ > *b => { + *(move a) } - _ => Some(b) + _ => Some(*b) } } { - Some(val) => val, + Some(move val) => val, None => fail ~"max called on empty iterator" } } -pure fn find>(self: IA, - p: fn(A) -> bool) -> Option { +pub pure fn find>(self: &IA, + p: fn(a: A) -> bool) -> Option { for self.each |i| { if p(*i) { return Some(*i) } } @@ -223,7 +225,8 @@ pure fn find>(self: IA, * onto the sequence being constructed. */ #[inline(always)] -pure fn build>(builder: fn(push: pure fn(+v: A))) -> B { +pub pure fn build>(builder: fn(push: pure fn(v: A))) + -> B { build_sized(4, builder) } @@ -241,9 +244,9 @@ pure fn build>(builder: fn(push: pure fn(+v: A))) -> B { * onto the sequence being constructed. */ #[inline(always)] -pure fn build_sized_opt>( +pub pure fn build_sized_opt>( size: Option, - builder: fn(push: pure fn(+v: A))) -> B { + builder: fn(push: pure fn(v: A))) -> B { build_sized(size.get_default(4), builder) } @@ -251,10 +254,11 @@ pure fn build_sized_opt>( // Functions that combine iteration and building /// Apply a function to each element of an iterable and return the results -fn map,U,BU: Buildable>(v: IT, f: fn(T) -> U) -> BU { +pub fn map,U,BU: Buildable>(v: &IT, f: fn(&T) -> U) + -> BU { do build_sized_opt(v.size_hint()) |push| { for v.each() |elem| { - push(f(*elem)); + push(f(elem)); } } } @@ -265,7 +269,8 @@ fn map,U,BU: Buildable>(v: IT, f: fn(T) -> U) -> BU { * Creates a generic sequence of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -pure fn from_fn>(n_elts: uint, op: InitOp) -> BT { +pub pure fn from_fn>(n_elts: uint, + op: InitOp) -> BT { do build_sized(n_elts) |push| { let mut i: uint = 0u; while i < n_elts { push(op(i)); i += 1u; } @@ -278,19 +283,20 @@ pure fn from_fn>(n_elts: uint, op: InitOp) -> BT { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value `t`. */ -pure fn from_elem>(n_elts: uint, t: T) -> BT { +pub pure fn from_elem>(n_elts: uint, + t: T) -> BT { do build_sized(n_elts) |push| { - let mut i: uint = 0u; - while i < n_elts { push(t); i += 1u; } + let mut i: uint = 0; + while i < n_elts { push(t); i += 1; } } } /// Appending two generic sequences #[inline(always)] -pure fn append,BT: Buildable>( - lhs: IT, rhs: IT) -> BT { - let size_opt = lhs.size_hint().chain( - |sz1| rhs.size_hint().map(|sz2| sz1+sz2)); +pub pure fn append,BT: Buildable>( + lhs: &IT, rhs: &IT) -> BT { + let size_opt = lhs.size_hint().chain_ref( + |sz1| rhs.size_hint().map(|sz2| *sz1+*sz2)); do build_sized_opt(size_opt) |push| { for lhs.each |x| { push(*x); } for rhs.each |x| { push(*x); } @@ -300,8 +306,8 @@ pure fn append,BT: Buildable>( /// Copies a generic sequence, possibly converting it to a different /// type of sequence. #[inline(always)] -pure fn copy_seq,BT: Buildable>( - v: IT) -> BT { +pub pure fn copy_seq,BT: Buildable>( + v: &IT) -> BT { do build_sized_opt(v.size_hint()) |push| { for v.each |x| { push(*x); } } diff --git a/src/libcore/libc.rs b/src/libcore/libc.rs index f99bc4554661..3665128bf3ca 100644 --- a/src/libcore/libc.rs +++ b/src/libcore/libc.rs @@ -2,40 +2,40 @@ #[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; /*! - * Bindings for libc. - * - * We consider the following specs reasonably normative with respect - * to interoperating with the C standard library (libc/msvcrt): - * - * * ISO 9899:1990 ('C95', 'ANSI C', 'Standard C'), NA1, 1995. - * * ISO 9899:1999 ('C99' or 'C9x'). - * * ISO 9945:1988 / IEEE 1003.1-1988 ('POSIX.1'). - * * ISO 9945:2001 / IEEE 1003.1-2001 ('POSIX:2001', 'SUSv3'). - * * ISO 9945:2008 / IEEE 1003.1-2008 ('POSIX:2008', 'SUSv4'). - * - * Despite having several names each, these are *reasonably* coherent - * point-in-time, list-of-definition sorts of specs. You can get each under a - * variety of names but will wind up with the same definition in each case. - * - * Our interface to these libraries is complicated by the non-universality of - * conformance to any of them. About the only thing universally supported is - * the first (C95), beyond that definitions quickly become absent on various - * platforms. - * - * We therefore wind up dividing our module-space up (mostly for the sake of - * sanity while editing, filling-in-details and eliminating duplication) into - * definitions common-to-all (held in modules named c95, c99, posix88, posix01 - * and posix08) and definitions that appear only on *some* platforms (named - * 'extra'). This would be things like significant OSX foundation kit, or - * win32 library kernel32.dll, or various fancy glibc, linux or BSD - * extensions. - * - * In addition to the per-platform 'extra' modules, we define a module of - * 'common BSD' libc routines that never quite made it into POSIX but show up - * in multiple derived systems. This is the 4.4BSD r2 / 1995 release, the - * final one from Berkeley after the lawsuits died down and the CSRG - * dissolved. - */ +* Bindings for libc. +* +* We consider the following specs reasonably normative with respect +* to interoperating with the C standard library (libc/msvcrt): +* +* * ISO 9899:1990 ('C95', 'ANSI C', 'Standard C'), NA1, 1995. +* * ISO 9899:1999 ('C99' or 'C9x'). +* * ISO 9945:1988 / IEEE 1003.1-1988 ('POSIX.1'). +* * ISO 9945:2001 / IEEE 1003.1-2001 ('POSIX:2001', 'SUSv3'). +* * ISO 9945:2008 / IEEE 1003.1-2008 ('POSIX:2008', 'SUSv4'). +* +* Despite having several names each, these are *reasonably* coherent +* point-in-time, list-of-definition sorts of specs. You can get each under a +* variety of names but will wind up with the same definition in each case. +* +* Our interface to these libraries is complicated by the non-universality of +* conformance to any of them. About the only thing universally supported is +* the first (C95), beyond that definitions quickly become absent on various +* platforms. +* +* We therefore wind up dividing our module-space up (mostly for the sake of +* sanity while editing, filling-in-details and eliminating duplication) into +* definitions common-to-all (held in modules named c95, c99, posix88, posix01 +* and posix08) and definitions that appear only on *some* platforms (named +* 'extra'). This would be things like significant OSX foundation kit, or +* win32 library kernel32.dll, or various fancy glibc, linux or BSD +* extensions. +* +* In addition to the per-platform 'extra' modules, we define a module of +* 'common BSD' libc routines that never quite made it into POSIX but show up +* in multiple derived systems. This is the 4.4BSD r2 / 1995 release, the +* final one from Berkeley after the lawsuits died down and the CSRG +* dissolved. +*/ #[allow(non_camel_case_types)]; @@ -44,795 +44,721 @@ // FIXME (#2006): change these to glob-exports when sufficiently supported. -use types::common::c95::*; -use types::common::c99::*; -use types::common::posix88::*; -use types::common::posix01::*; -use types::common::posix08::*; -use types::common::bsd44::*; -use types::os::arch::c95::*; -use types::os::arch::c99::*; -use types::os::arch::posix88::*; -use types::os::arch::posix01::*; -use types::os::arch::posix08::*; -use types::os::arch::bsd44::*; -use types::os::arch::extra::*; +pub use types::common::c95::*; +pub use types::common::c99::*; +pub use types::common::posix88::*; +pub use types::common::posix01::*; +pub use types::common::posix08::*; +pub use types::common::bsd44::*; +pub use types::os::arch::c95::*; +pub use types::os::arch::c99::*; +pub use types::os::arch::posix88::*; +pub use types::os::arch::posix01::*; +pub use types::os::arch::posix08::*; +pub use types::os::arch::bsd44::*; +pub use types::os::arch::extra::*; -use consts::os::c95::*; -use consts::os::c99::*; -use consts::os::posix88::*; -use consts::os::posix01::*; -use consts::os::posix08::*; -use consts::os::bsd44::*; -use consts::os::extra::*; +pub use consts::os::c95::*; +pub use consts::os::c99::*; +pub use consts::os::posix88::*; +pub use consts::os::posix01::*; +pub use consts::os::posix08::*; +pub use consts::os::bsd44::*; +pub use consts::os::extra::*; -use funcs::c95::ctype::*; -use funcs::c95::stdio::*; -use funcs::c95::stdlib::*; -use funcs::c95::string::*; +pub use funcs::c95::ctype::*; +pub use funcs::c95::stdio::*; +pub use funcs::c95::stdlib::*; +pub use funcs::c95::string::*; -use funcs::posix88::stat::*; -use funcs::posix88::stdio::*; -use funcs::posix88::fcntl::*; -use funcs::posix88::dirent::*; -use funcs::posix88::unistd::*; +pub use funcs::posix88::stat::*; +pub use funcs::posix88::stdio::*; +pub use funcs::posix88::fcntl::*; +pub use funcs::posix88::dirent::*; +pub use funcs::posix88::unistd::*; -use funcs::posix01::unistd::*; -use funcs::posix08::unistd::*; +pub use funcs::posix01::unistd::*; +pub use funcs::posix08::unistd::*; -use funcs::bsd44::*; -use funcs::extra::*; - -// FIXME (#2006): remove these 3 exports (and their uses next door in os::) -// when export globs work. They provide access (for now) for os:: to dig -// around in the rest of the platform-specific definitions. - -export types, funcs, consts; +pub use funcs::bsd44::*; +pub use funcs::extra::*; // Explicit export lists for the intersection (provided here) mean that // you can write more-platform-agnostic code if you stick to just these // symbols. -export c_float, c_double, c_void, FILE, fpos_t; -export DIR, dirent; -export c_char, c_schar, c_uchar; -export c_short, c_ushort, c_int, c_uint, c_long, c_ulong; -export size_t, ptrdiff_t, clock_t, time_t; -export c_longlong, c_ulonglong, intptr_t, uintptr_t; -export off_t, dev_t, ino_t, pid_t, mode_t, ssize_t; +pub use size_t; +pub use c_float, c_double, c_void, FILE, fpos_t; +pub use DIR, dirent; +pub use c_char, c_schar, c_uchar; +pub use c_short, c_ushort, c_int, c_uint, c_long, c_ulong; +pub use size_t, ptrdiff_t, clock_t, time_t; +pub use c_longlong, c_ulonglong, intptr_t, uintptr_t; +pub use off_t, dev_t, ino_t, pid_t, mode_t, ssize_t; -export EXIT_FAILURE, EXIT_SUCCESS, RAND_MAX, - EOF, SEEK_SET, SEEK_CUR, SEEK_END, _IOFBF, _IONBF, _IOLBF, - BUFSIZ, FOPEN_MAX, FILENAME_MAX, L_tmpnam, TMP_MAX, - O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, O_CREAT, O_EXCL, O_TRUNC, - S_IFIFO, S_IFCHR, S_IFBLK, S_IFDIR, S_IFREG, S_IFMT, S_IEXEC, - S_IWRITE, S_IREAD, S_IRWXU, S_IXUSR, S_IWUSR, S_IRUSR, F_OK, R_OK, - W_OK, X_OK, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO; +pub use EXIT_FAILURE, EXIT_SUCCESS, RAND_MAX, +EOF, SEEK_SET, SEEK_CUR, SEEK_END, _IOFBF, _IONBF, _IOLBF, +BUFSIZ, FOPEN_MAX, FILENAME_MAX, L_tmpnam, TMP_MAX, +O_RDONLY, O_WRONLY, O_RDWR, O_APPEND, O_CREAT, O_EXCL, O_TRUNC, +S_IFIFO, S_IFCHR, S_IFBLK, S_IFDIR, S_IFREG, S_IFMT, S_IEXEC, +S_IWRITE, S_IREAD, S_IRWXU, S_IXUSR, S_IWUSR, S_IRUSR, F_OK, R_OK, +W_OK, X_OK, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO; -export isalnum, isalpha, iscntrl, isdigit, islower, isprint, ispunct, - isspace, isupper, isxdigit, tolower, toupper; +pub use isalnum, isalpha, iscntrl, isdigit, islower, isprint, ispunct, +isspace, isupper, isxdigit, tolower, toupper; -export fopen, freopen, fflush, fclose, remove, tmpfile, setvbuf, setbuf, - fgetc, fgets, fputc, fputs, puts, ungetc, fread, fwrite, fseek, ftell, - rewind, fgetpos, fsetpos, feof, ferror, perror; +pub use fopen, freopen, fflush, fclose, remove, tmpfile, setvbuf, setbuf, +fgetc, fgets, fputc, fputs, puts, ungetc, fread, fwrite, fseek, ftell, +rewind, fgetpos, fsetpos, feof, ferror, perror; -export abs, labs, atof, atoi, strtod, strtol, strtoul, calloc, malloc, - realloc, free, abort, exit, system, getenv, rand, srand; +pub use abs, labs, atof, atoi, strtod, strtol, strtoul, calloc, malloc, +realloc, free, abort, exit, system, getenv, rand, srand; -export strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcoll, strchr, - strrchr, strspn, strcspn, strpbrk, strstr, strlen, strerror, strtok, - strxfrm, memcpy, memmove, memcmp, memchr, memset; +pub use strcpy, strncpy, strcat, strncat, strcmp, strncmp, strcoll, strchr, +strrchr, strspn, strcspn, strpbrk, strstr, strlen, strerror, strtok, +strxfrm, memcpy, memmove, memcmp, memchr, memset; -export chmod, mkdir; -export popen, pclose, fdopen, fileno; -export open, creat; -export access, chdir, close, dup, dup2, execv, execve, execvp, getcwd, - getpid, isatty, lseek, pipe, read, rmdir, unlink, write; +pub use chmod, mkdir; +pub use popen, pclose, fdopen, fileno; +pub use open, creat; +pub use access, chdir, close, dup, dup2, execv, execve, execvp, getcwd, +getpid, isatty, lseek, pipe, read, rmdir, unlink, write; mod types { - #[legacy_exports]; // Types tend to vary *per architecture* so we pull their definitions out // into this module. // Standard types that are opaque or common, so are not per-target. - mod common { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - enum c_void {} - enum FILE {} - enum fpos_t {} + pub mod common { + pub mod c95 { + pub enum c_void {} + pub enum FILE {} + pub enum fpos_t {} } - mod c99 { - #[legacy_exports]; - type int8_t = i8; - type int16_t = i16; - type int32_t = i32; - type int64_t = i64; - type uint8_t = u8; - type uint16_t = u16; - type uint32_t = u32; - type uint64_t = u64; + pub mod c99 { + pub type int8_t = i8; + pub type int16_t = i16; + pub type int32_t = i32; + pub type int64_t = i64; + pub type uint8_t = u8; + pub type uint16_t = u16; + pub type uint32_t = u32; + pub type uint64_t = u64; } - mod posix88 { - #[legacy_exports]; - enum DIR {} - enum dirent {} + pub mod posix88 { + pub enum DIR {} + pub enum dirent {} } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } + pub mod posix01 {} + pub mod posix08 {} + pub mod bsd44 {} } // Standard types that are scalar but vary by OS and arch. #[cfg(target_os = "linux")] - mod os { - #[legacy_exports]; + pub mod os { #[cfg(target_arch = "x86")] - mod arch { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - type c_char = i8; - type c_schar = i8; - type c_uchar = u8; - type c_short = i16; - type c_ushort = u16; - type c_int = i32; - type c_uint = u32; - type c_long = i32; - type c_ulong = u32; - type c_float = f32; - type c_double = f64; - type size_t = u32; - type ptrdiff_t = i32; - type clock_t = i32; - type time_t = i32; - type wchar_t = i32; + pub mod arch { + pub mod c95 { + pub type c_char = i8; + pub type c_schar = i8; + pub type c_uchar = u8; + pub type c_short = i16; + pub type c_ushort = u16; + pub type c_int = i32; + pub type c_uint = u32; + pub type c_long = i32; + pub type c_ulong = u32; + pub type c_float = f32; + pub type c_double = f64; + pub type size_t = u32; + pub type ptrdiff_t = i32; + pub type clock_t = i32; + pub type time_t = i32; + pub type wchar_t = i32; } - mod c99 { - #[legacy_exports]; - type c_longlong = i64; - type c_ulonglong = u64; - type intptr_t = int; - type uintptr_t = uint; + pub mod c99 { + pub type c_longlong = i64; + pub type c_ulonglong = u64; + pub type intptr_t = int; + pub type uintptr_t = uint; } - mod posix88 { - #[legacy_exports]; - type off_t = i32; - type dev_t = u64; - type ino_t = u32; - type pid_t = i32; - type uid_t = u32; - type gid_t = u32; - type useconds_t = u32; - type mode_t = u32; - type ssize_t = i32; - } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; + pub mod posix88 { + pub type off_t = i32; + pub type dev_t = u64; + pub type ino_t = u32; + pub type pid_t = i32; + pub type uid_t = u32; + pub type gid_t = u32; + pub type useconds_t = u32; + pub type mode_t = u32; + pub type ssize_t = i32; } + pub mod posix01 {} + pub mod posix08 {} + pub mod bsd44 {} + pub mod extra {} } #[cfg(target_arch = "x86_64")] - mod arch { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - type c_char = i8; - type c_schar = i8; - type c_uchar = u8; - type c_short = i16; - type c_ushort = u16; - type c_int = i32; - type c_uint = u32; - type c_long = i64; - type c_ulong = u64; - type c_float = f32; - type c_double = f64; - type size_t = u64; - type ptrdiff_t = i64; - type clock_t = i64; - type time_t = i64; - type wchar_t = i32; + pub mod arch { + pub mod c95 { + pub type c_char = i8; + pub type c_schar = i8; + pub type c_uchar = u8; + pub type c_short = i16; + pub type c_ushort = u16; + pub type c_int = i32; + pub type c_uint = u32; + pub type c_long = i64; + pub type c_ulong = u64; + pub type c_float = f32; + pub type c_double = f64; + pub type size_t = u64; + pub type ptrdiff_t = i64; + pub type clock_t = i64; + pub type time_t = i64; + pub type wchar_t = i32; } - mod c99 { - #[legacy_exports]; - type c_longlong = i64; - type c_ulonglong = u64; - type intptr_t = int; - type uintptr_t = uint; + pub mod c99 { + pub type c_longlong = i64; + pub type c_ulonglong = u64; + pub type intptr_t = int; + pub type uintptr_t = uint; } - mod posix88 { - #[legacy_exports]; - type off_t = i64; - type dev_t = u64; - type ino_t = u64; - type pid_t = i32; - type uid_t = u32; - type gid_t = u32; - type useconds_t = u32; - type mode_t = u32; - type ssize_t = i64; + pub mod posix88 { + pub type off_t = i64; + pub type dev_t = u64; + pub type ino_t = u64; + pub type pid_t = i32; + pub type uid_t = u32; + pub type gid_t = u32; + pub type useconds_t = u32; + pub type mode_t = u32; + pub type ssize_t = i64; } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { } } } #[cfg(target_os = "freebsd")] - mod os { - #[legacy_exports]; + pub mod os { #[cfg(target_arch = "x86_64")] - mod arch { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - type c_char = i8; - type c_schar = i8; - type c_uchar = u8; - type c_short = i16; - type c_ushort = u16; - type c_int = i32; - type c_uint = u32; - type c_long = i64; - type c_ulong = u64; - type c_float = f32; - type c_double = f64; - type size_t = u64; - type ptrdiff_t = i64; - type clock_t = i32; - type time_t = i64; - type wchar_t = i32; + pub mod arch { + pub mod c95 { + pub type c_char = i8; + pub type c_schar = i8; + pub type c_uchar = u8; + pub type c_short = i16; + pub type c_ushort = u16; + pub type c_int = i32; + pub type c_uint = u32; + pub type c_long = i64; + pub type c_ulong = u64; + pub type c_float = f32; + pub type c_double = f64; + pub type size_t = u64; + pub type ptrdiff_t = i64; + pub type clock_t = i32; + pub type time_t = i64; + pub type wchar_t = i32; } - mod c99 { - #[legacy_exports]; - type c_longlong = i64; - type c_ulonglong = u64; - type intptr_t = int; - type uintptr_t = uint; + pub mod c99 { + pub type c_longlong = i64; + pub type c_ulonglong = u64; + pub type intptr_t = int; + pub type uintptr_t = uint; } - mod posix88 { - #[legacy_exports]; - type off_t = i64; - type dev_t = u32; - type ino_t = u32; - type pid_t = i32; - type uid_t = u32; - type gid_t = u32; - type useconds_t = u32; - type mode_t = u16; - type ssize_t = i64; + pub mod posix88 { + pub type off_t = i64; + pub type dev_t = u32; + pub type ino_t = u32; + pub type pid_t = i32; + pub type uid_t = u32; + pub type gid_t = u32; + pub type useconds_t = u32; + pub type mode_t = u16; + pub type ssize_t = i64; } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { } } } #[cfg(target_os = "win32")] - mod os { - #[legacy_exports]; + pub mod os { #[cfg(target_arch = "x86")] - mod arch { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - type c_char = i8; - type c_schar = i8; - type c_uchar = u8; - type c_short = i16; - type c_ushort = u16; - type c_int = i32; - type c_uint = u32; - type c_long = i32; - type c_ulong = u32; - type c_float = f32; - type c_double = f64; - type size_t = u32; - type ptrdiff_t = i32; - type clock_t = i32; - type time_t = i32; - type wchar_t = u16; + pub mod arch { + pub mod c95 { + pub type c_char = i8; + pub type c_schar = i8; + pub type c_uchar = u8; + pub type c_short = i16; + pub type c_ushort = u16; + pub type c_int = i32; + pub type c_uint = u32; + pub type c_long = i32; + pub type c_ulong = u32; + pub type c_float = f32; + pub type c_double = f64; + pub type size_t = u32; + pub type ptrdiff_t = i32; + pub type clock_t = i32; + pub type time_t = i32; + pub type wchar_t = u16; } - mod c99 { - #[legacy_exports]; - type c_longlong = i64; - type c_ulonglong = u64; - type intptr_t = int; - type uintptr_t = uint; + pub mod c99 { + pub type c_longlong = i64; + pub type c_ulonglong = u64; + pub type intptr_t = int; + pub type uintptr_t = uint; } - mod posix88 { - #[legacy_exports]; - type off_t = i32; - type dev_t = u32; - type ino_t = i16; - type pid_t = i32; - type useconds_t = u32; - type mode_t = u16; - type ssize_t = i32; + pub mod posix88 { + pub type off_t = i32; + pub type dev_t = u32; + pub type ino_t = i16; + pub type pid_t = i32; + pub type useconds_t = u32; + pub type mode_t = u16; + pub type ssize_t = i32; } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; - type BOOL = c_int; - type BYTE = u8; - type CCHAR = c_char; - type CHAR = c_char; + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { + pub type BOOL = c_int; + pub type BYTE = u8; + pub type CCHAR = c_char; + pub type CHAR = c_char; - type DWORD = c_ulong; - type DWORDLONG = c_ulonglong; + pub type DWORD = c_ulong; + pub type DWORDLONG = c_ulonglong; - type HANDLE = LPVOID; - type HMODULE = c_uint; + pub type HANDLE = LPVOID; + pub type HMODULE = c_uint; - type LONG_PTR = c_long; + pub type LONG_PTR = c_long; - type LPCWSTR = *WCHAR; - type LPCSTR = *CHAR; + pub type LPCWSTR = *WCHAR; + pub type LPCSTR = *CHAR; - type LPWSTR = *mut WCHAR; - type LPSTR = *mut CHAR; + pub type LPWSTR = *mut WCHAR; + pub type LPSTR = *mut CHAR; // Not really, but opaque to us. - type LPSECURITY_ATTRIBUTES = LPVOID; + pub type LPSECURITY_ATTRIBUTES = LPVOID; - type LPVOID = *mut c_void; - type LPWORD = *mut WORD; + pub type LPVOID = *mut c_void; + pub type LPWORD = *mut WORD; - type LRESULT = LONG_PTR; - type PBOOL = *mut BOOL; - type WCHAR = wchar_t; - type WORD = u16; + pub type LRESULT = LONG_PTR; + pub type PBOOL = *mut BOOL; + pub type WCHAR = wchar_t; + pub type WORD = u16; } } } #[cfg(target_os = "macos")] - mod os { - #[legacy_exports]; + pub mod os { #[cfg(target_arch = "x86")] - mod arch { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - type c_char = i8; - type c_schar = i8; - type c_uchar = u8; - type c_short = i16; - type c_ushort = u16; - type c_int = i32; - type c_uint = u32; - type c_long = i32; - type c_ulong = u32; - type c_float = f32; - type c_double = f64; - type size_t = u32; - type ptrdiff_t = i32; - type clock_t = u32; - type time_t = i32; - type wchar_t = i32; + pub mod arch { + pub mod c95 { + pub type c_char = i8; + pub type c_schar = i8; + pub type c_uchar = u8; + pub type c_short = i16; + pub type c_ushort = u16; + pub type c_int = i32; + pub type c_uint = u32; + pub type c_long = i32; + pub type c_ulong = u32; + pub type c_float = f32; + pub type c_double = f64; + pub type size_t = u32; + pub type ptrdiff_t = i32; + pub type clock_t = u32; + pub type time_t = i32; + pub type wchar_t = i32; } - mod c99 { - #[legacy_exports]; - type c_longlong = i64; - type c_ulonglong = u64; - type intptr_t = int; - type uintptr_t = uint; + pub mod c99 { + pub type c_longlong = i64; + pub type c_ulonglong = u64; + pub type intptr_t = int; + pub type uintptr_t = uint; } - mod posix88 { - #[legacy_exports]; - type off_t = i64; - type dev_t = i32; - type ino_t = u64; - type pid_t = i32; - type uid_t = u32; - type gid_t = u32; - type useconds_t = u32; - type mode_t = u16; - type ssize_t = i32; + pub mod posix88 { + pub type off_t = i64; + pub type dev_t = i32; + pub type ino_t = u64; + pub type pid_t = i32; + pub type uid_t = u32; + pub type gid_t = u32; + pub type useconds_t = u32; + pub type mode_t = u16; + pub type ssize_t = i32; } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { } } #[cfg(target_arch = "x86_64")] - mod arch { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - type c_char = i8; - type c_schar = i8; - type c_uchar = u8; - type c_short = i16; - type c_ushort = u16; - type c_int = i32; - type c_uint = u32; - type c_long = i64; - type c_ulong = u64; - type c_float = f32; - type c_double = f64; - type size_t = u64; - type ptrdiff_t = i64; - type clock_t = u64; - type time_t = i64; - type wchar_t = i32; + pub mod arch { + pub mod c95 { + pub type c_char = i8; + pub type c_schar = i8; + pub type c_uchar = u8; + pub type c_short = i16; + pub type c_ushort = u16; + pub type c_int = i32; + pub type c_uint = u32; + pub type c_long = i64; + pub type c_ulong = u64; + pub type c_float = f32; + pub type c_double = f64; + pub type size_t = u64; + pub type ptrdiff_t = i64; + pub type clock_t = u64; + pub type time_t = i64; + pub type wchar_t = i32; } - mod c99 { - #[legacy_exports]; - type c_longlong = i64; - type c_ulonglong = u64; - type intptr_t = int; - type uintptr_t = uint; + pub mod c99 { + pub type c_longlong = i64; + pub type c_ulonglong = u64; + pub type intptr_t = int; + pub type uintptr_t = uint; } - mod posix88 { - #[legacy_exports]; - type off_t = i64; - type dev_t = i32; - type ino_t = u64; - type pid_t = i32; - type uid_t = u32; - type gid_t = u32; - type useconds_t = u32; - type mode_t = u16; - type ssize_t = i64; + pub mod posix88 { + pub type off_t = i64; + pub type dev_t = i32; + pub type ino_t = u64; + pub type pid_t = i32; + pub type uid_t = u32; + pub type gid_t = u32; + pub type useconds_t = u32; + pub type mode_t = u16; + pub type ssize_t = i64; } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { } } } } -mod consts { - #[legacy_exports]; - +pub mod consts { // Consts tend to vary per OS so we pull their definitions out // into this module. #[cfg(target_os = "win32")] - mod os { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - const EXIT_FAILURE : int = 1; - const EXIT_SUCCESS : int = 0; - const RAND_MAX : int = 32767; - const EOF : int = -1; - const SEEK_SET : int = 0; - const SEEK_CUR : int = 1; - const SEEK_END : int = 2; - const _IOFBF : int = 0; - const _IONBF : int = 4; - const _IOLBF : int = 64; - const BUFSIZ : uint = 512_u; - const FOPEN_MAX : uint = 20_u; - const FILENAME_MAX : uint = 260_u; - const L_tmpnam : uint = 16_u; - const TMP_MAX : uint = 32767_u; + pub mod os { + pub mod c95 { + pub const EXIT_FAILURE : int = 1; + pub const EXIT_SUCCESS : int = 0; + pub const RAND_MAX : int = 32767; + pub const EOF : int = -1; + pub const SEEK_SET : int = 0; + pub const SEEK_CUR : int = 1; + pub const SEEK_END : int = 2; + pub const _IOFBF : int = 0; + pub const _IONBF : int = 4; + pub const _IOLBF : int = 64; + pub const BUFSIZ : uint = 512_u; + pub const FOPEN_MAX : uint = 20_u; + pub const FILENAME_MAX : uint = 260_u; + pub const L_tmpnam : uint = 16_u; + pub const TMP_MAX : uint = 32767_u; } - mod c99 { - #[legacy_exports]; } - mod posix88 { - #[legacy_exports]; - const O_RDONLY : int = 0; - const O_WRONLY : int = 1; - const O_RDWR : int = 2; - const O_APPEND : int = 8; - const O_CREAT : int = 256; - const O_EXCL : int = 1024; - const O_TRUNC : int = 512; - const S_IFIFO : int = 4096; - const S_IFCHR : int = 8192; - const S_IFBLK : int = 12288; - const S_IFDIR : int = 16384; - const S_IFREG : int = 32768; - const S_IFMT : int = 61440; - const S_IEXEC : int = 64; - const S_IWRITE : int = 128; - const S_IREAD : int = 256; - const S_IRWXU : int = 448; - const S_IXUSR : int = 64; - const S_IWUSR : int = 128; - const S_IRUSR : int = 256; - const F_OK : int = 0; - const R_OK : int = 4; - const W_OK : int = 2; - const X_OK : int = 1; - const STDIN_FILENO : int = 0; - const STDOUT_FILENO : int = 1; - const STDERR_FILENO : int = 2; + pub mod c99 { } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; - const O_TEXT : int = 16384; - const O_BINARY : int = 32768; - const O_NOINHERIT: int = 128; + pub mod posix88 { + pub const O_RDONLY : int = 0; + pub const O_WRONLY : int = 1; + pub const O_RDWR : int = 2; + pub const O_APPEND : int = 8; + pub const O_CREAT : int = 256; + pub const O_EXCL : int = 1024; + pub const O_TRUNC : int = 512; + pub const S_IFIFO : int = 4096; + pub const S_IFCHR : int = 8192; + pub const S_IFBLK : int = 12288; + pub const S_IFDIR : int = 16384; + pub const S_IFREG : int = 32768; + pub const S_IFMT : int = 61440; + pub const S_IEXEC : int = 64; + pub const S_IWRITE : int = 128; + pub const S_IREAD : int = 256; + pub const S_IRWXU : int = 448; + pub const S_IXUSR : int = 64; + pub const S_IWUSR : int = 128; + pub const S_IRUSR : int = 256; + pub const F_OK : int = 0; + pub const R_OK : int = 4; + pub const W_OK : int = 2; + pub const X_OK : int = 1; + pub const STDIN_FILENO : int = 0; + pub const STDOUT_FILENO : int = 1; + pub const STDERR_FILENO : int = 2; + } + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { + pub const O_TEXT : int = 16384; + pub const O_BINARY : int = 32768; + pub const O_NOINHERIT: int = 128; - const ERROR_SUCCESS : int = 0; - const ERROR_INSUFFICIENT_BUFFER : int = 122; + pub const ERROR_SUCCESS : int = 0; + pub const ERROR_INSUFFICIENT_BUFFER : int = 122; } } #[cfg(target_os = "linux")] - mod os { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - const EXIT_FAILURE : int = 1; - const EXIT_SUCCESS : int = 0; - const RAND_MAX : int = 2147483647; - const EOF : int = -1; - const SEEK_SET : int = 0; - const SEEK_CUR : int = 1; - const SEEK_END : int = 2; - const _IOFBF : int = 0; - const _IONBF : int = 2; - const _IOLBF : int = 1; - const BUFSIZ : uint = 8192_u; - const FOPEN_MAX : uint = 16_u; - const FILENAME_MAX : uint = 4096_u; - const L_tmpnam : uint = 20_u; - const TMP_MAX : uint = 238328_u; + pub mod os { + pub mod c95 { + pub const EXIT_FAILURE : int = 1; + pub const EXIT_SUCCESS : int = 0; + pub const RAND_MAX : int = 2147483647; + pub const EOF : int = -1; + pub const SEEK_SET : int = 0; + pub const SEEK_CUR : int = 1; + pub const SEEK_END : int = 2; + pub const _IOFBF : int = 0; + pub const _IONBF : int = 2; + pub const _IOLBF : int = 1; + pub const BUFSIZ : uint = 8192_u; + pub const FOPEN_MAX : uint = 16_u; + pub const FILENAME_MAX : uint = 4096_u; + pub const L_tmpnam : uint = 20_u; + pub const TMP_MAX : uint = 238328_u; } - mod c99 { - #[legacy_exports]; } - mod posix88 { - #[legacy_exports]; - const O_RDONLY : int = 0; - const O_WRONLY : int = 1; - const O_RDWR : int = 2; - const O_APPEND : int = 1024; - const O_CREAT : int = 64; - const O_EXCL : int = 128; - const O_TRUNC : int = 512; - const S_IFIFO : int = 4096; - const S_IFCHR : int = 8192; - const S_IFBLK : int = 24576; - const S_IFDIR : int = 16384; - const S_IFREG : int = 32768; - const S_IFMT : int = 61440; - const S_IEXEC : int = 64; - const S_IWRITE : int = 128; - const S_IREAD : int = 256; - const S_IRWXU : int = 448; - const S_IXUSR : int = 64; - const S_IWUSR : int = 128; - const S_IRUSR : int = 256; - const F_OK : int = 0; - const R_OK : int = 4; - const W_OK : int = 2; - const X_OK : int = 1; - const STDIN_FILENO : int = 0; - const STDOUT_FILENO : int = 1; - const STDERR_FILENO : int = 2; - const F_LOCK : int = 1; - const F_TEST : int = 3; - const F_TLOCK : int = 2; - const F_ULOCK : int = 0; + pub mod c99 { } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; - const O_RSYNC : int = 1052672; - const O_DSYNC : int = 4096; - const O_SYNC : int = 1052672; + pub mod posix88 { + pub const O_RDONLY : int = 0; + pub const O_WRONLY : int = 1; + pub const O_RDWR : int = 2; + pub const O_APPEND : int = 1024; + pub const O_CREAT : int = 64; + pub const O_EXCL : int = 128; + pub const O_TRUNC : int = 512; + pub const S_IFIFO : int = 4096; + pub const S_IFCHR : int = 8192; + pub const S_IFBLK : int = 24576; + pub const S_IFDIR : int = 16384; + pub const S_IFREG : int = 32768; + pub const S_IFMT : int = 61440; + pub const S_IEXEC : int = 64; + pub const S_IWRITE : int = 128; + pub const S_IREAD : int = 256; + pub const S_IRWXU : int = 448; + pub const S_IXUSR : int = 64; + pub const S_IWUSR : int = 128; + pub const S_IRUSR : int = 256; + pub const F_OK : int = 0; + pub const R_OK : int = 4; + pub const W_OK : int = 2; + pub const X_OK : int = 1; + pub const STDIN_FILENO : int = 0; + pub const STDOUT_FILENO : int = 1; + pub const STDERR_FILENO : int = 2; + pub const F_LOCK : int = 1; + pub const F_TEST : int = 3; + pub const F_TLOCK : int = 2; + pub const F_ULOCK : int = 0; + } + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { + pub const O_RSYNC : int = 1052672; + pub const O_DSYNC : int = 4096; + pub const O_SYNC : int = 1052672; } } #[cfg(target_os = "freebsd")] - mod os { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - const EXIT_FAILURE : int = 1; - const EXIT_SUCCESS : int = 0; - const RAND_MAX : int = 2147483647; - const EOF : int = -1; - const SEEK_SET : int = 0; - const SEEK_CUR : int = 1; - const SEEK_END : int = 2; - const _IOFBF : int = 0; - const _IONBF : int = 2; - const _IOLBF : int = 1; - const BUFSIZ : uint = 1024_u; - const FOPEN_MAX : uint = 20_u; - const FILENAME_MAX : uint = 1024_u; - const L_tmpnam : uint = 1024_u; - const TMP_MAX : uint = 308915776_u; + pub mod os { + pub mod c95 { + pub const EXIT_FAILURE : int = 1; + pub const EXIT_SUCCESS : int = 0; + pub const RAND_MAX : int = 2147483647; + pub const EOF : int = -1; + pub const SEEK_SET : int = 0; + pub const SEEK_CUR : int = 1; + pub const SEEK_END : int = 2; + pub const _IOFBF : int = 0; + pub const _IONBF : int = 2; + pub const _IOLBF : int = 1; + pub const BUFSIZ : uint = 1024_u; + pub const FOPEN_MAX : uint = 20_u; + pub const FILENAME_MAX : uint = 1024_u; + pub const L_tmpnam : uint = 1024_u; + pub const TMP_MAX : uint = 308915776_u; } - mod c99 { - #[legacy_exports]; } - mod posix88 { - #[legacy_exports]; - const O_RDONLY : int = 0; - const O_WRONLY : int = 1; - const O_RDWR : int = 2; - const O_APPEND : int = 8; - const O_CREAT : int = 512; - const O_EXCL : int = 2048; - const O_TRUNC : int = 1024; - const S_IFIFO : int = 4096; - const S_IFCHR : int = 8192; - const S_IFBLK : int = 24576; - const S_IFDIR : int = 16384; - const S_IFREG : int = 32768; - const S_IFMT : int = 61440; - const S_IEXEC : int = 64; - const S_IWRITE : int = 128; - const S_IREAD : int = 256; - const S_IRWXU : int = 448; - const S_IXUSR : int = 64; - const S_IWUSR : int = 128; - const S_IRUSR : int = 256; - const F_OK : int = 0; - const R_OK : int = 4; - const W_OK : int = 2; - const X_OK : int = 1; - const STDIN_FILENO : int = 0; - const STDOUT_FILENO : int = 1; - const STDERR_FILENO : int = 2; - const F_LOCK : int = 1; - const F_TEST : int = 3; - const F_TLOCK : int = 2; - const F_ULOCK : int = 0; + pub mod c99 { } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; - const O_SYNC : int = 128; - const CTL_KERN: int = 1; - const KERN_PROC: int = 14; - const KERN_PROC_PATHNAME: int = 12; + pub mod posix88 { + pub const O_RDONLY : int = 0; + pub const O_WRONLY : int = 1; + pub const O_RDWR : int = 2; + pub const O_APPEND : int = 8; + pub const O_CREAT : int = 512; + pub const O_EXCL : int = 2048; + pub const O_TRUNC : int = 1024; + pub const S_IFIFO : int = 4096; + pub const S_IFCHR : int = 8192; + pub const S_IFBLK : int = 24576; + pub const S_IFDIR : int = 16384; + pub const S_IFREG : int = 32768; + pub const S_IFMT : int = 61440; + pub const S_IEXEC : int = 64; + pub const S_IWRITE : int = 128; + pub const S_IREAD : int = 256; + pub const S_IRWXU : int = 448; + pub const S_IXUSR : int = 64; + pub const S_IWUSR : int = 128; + pub const S_IRUSR : int = 256; + pub const F_OK : int = 0; + pub const R_OK : int = 4; + pub const W_OK : int = 2; + pub const X_OK : int = 1; + pub const STDIN_FILENO : int = 0; + pub const STDOUT_FILENO : int = 1; + pub const STDERR_FILENO : int = 2; + pub const F_LOCK : int = 1; + pub const F_TEST : int = 3; + pub const F_TLOCK : int = 2; + pub const F_ULOCK : int = 0; + } + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { + pub const O_SYNC : int = 128; + pub const CTL_KERN: int = 1; + pub const KERN_PROC: int = 14; + pub const KERN_PROC_PATHNAME: int = 12; } } #[cfg(target_os = "macos")] - mod os { - #[legacy_exports]; - mod c95 { - #[legacy_exports]; - const EXIT_FAILURE : int = 1; - const EXIT_SUCCESS : int = 0; - const RAND_MAX : int = 2147483647; - const EOF : int = -1; - const SEEK_SET : int = 0; - const SEEK_CUR : int = 1; - const SEEK_END : int = 2; - const _IOFBF : int = 0; - const _IONBF : int = 2; - const _IOLBF : int = 1; - const BUFSIZ : uint = 1024_u; - const FOPEN_MAX : uint = 20_u; - const FILENAME_MAX : uint = 1024_u; - const L_tmpnam : uint = 1024_u; - const TMP_MAX : uint = 308915776_u; + pub mod os { + pub mod c95 { + pub const EXIT_FAILURE : int = 1; + pub const EXIT_SUCCESS : int = 0; + pub const RAND_MAX : int = 2147483647; + pub const EOF : int = -1; + pub const SEEK_SET : int = 0; + pub const SEEK_CUR : int = 1; + pub const SEEK_END : int = 2; + pub const _IOFBF : int = 0; + pub const _IONBF : int = 2; + pub const _IOLBF : int = 1; + pub const BUFSIZ : uint = 1024_u; + pub const FOPEN_MAX : uint = 20_u; + pub const FILENAME_MAX : uint = 1024_u; + pub const L_tmpnam : uint = 1024_u; + pub const TMP_MAX : uint = 308915776_u; } - mod c99 { - #[legacy_exports]; } - mod posix88 { - #[legacy_exports]; - const O_RDONLY : int = 0; - const O_WRONLY : int = 1; - const O_RDWR : int = 2; - const O_APPEND : int = 8; - const O_CREAT : int = 512; - const O_EXCL : int = 2048; - const O_TRUNC : int = 1024; - const S_IFIFO : int = 4096; - const S_IFCHR : int = 8192; - const S_IFBLK : int = 24576; - const S_IFDIR : int = 16384; - const S_IFREG : int = 32768; - const S_IFMT : int = 61440; - const S_IEXEC : int = 64; - const S_IWRITE : int = 128; - const S_IREAD : int = 256; - const S_IRWXU : int = 448; - const S_IXUSR : int = 64; - const S_IWUSR : int = 128; - const S_IRUSR : int = 256; - const F_OK : int = 0; - const R_OK : int = 4; - const W_OK : int = 2; - const X_OK : int = 1; - const STDIN_FILENO : int = 0; - const STDOUT_FILENO : int = 1; - const STDERR_FILENO : int = 2; - const F_LOCK : int = 1; - const F_TEST : int = 3; - const F_TLOCK : int = 2; - const F_ULOCK : int = 0; + pub mod c99 { } - mod posix01 { - #[legacy_exports]; } - mod posix08 { - #[legacy_exports]; } - mod bsd44 { - #[legacy_exports]; } - mod extra { - #[legacy_exports]; - const O_DSYNC : int = 4194304; - const O_SYNC : int = 128; - const F_FULLFSYNC : int = 51; + pub mod posix88 { + pub const O_RDONLY : int = 0; + pub const O_WRONLY : int = 1; + pub const O_RDWR : int = 2; + pub const O_APPEND : int = 8; + pub const O_CREAT : int = 512; + pub const O_EXCL : int = 2048; + pub const O_TRUNC : int = 1024; + pub const S_IFIFO : int = 4096; + pub const S_IFCHR : int = 8192; + pub const S_IFBLK : int = 24576; + pub const S_IFDIR : int = 16384; + pub const S_IFREG : int = 32768; + pub const S_IFMT : int = 61440; + pub const S_IEXEC : int = 64; + pub const S_IWRITE : int = 128; + pub const S_IREAD : int = 256; + pub const S_IRWXU : int = 448; + pub const S_IXUSR : int = 64; + pub const S_IWUSR : int = 128; + pub const S_IRUSR : int = 256; + pub const F_OK : int = 0; + pub const R_OK : int = 4; + pub const W_OK : int = 2; + pub const X_OK : int = 1; + pub const STDIN_FILENO : int = 0; + pub const STDOUT_FILENO : int = 1; + pub const STDERR_FILENO : int = 2; + pub const F_LOCK : int = 1; + pub const F_TEST : int = 3; + pub const F_TLOCK : int = 2; + pub const F_ULOCK : int = 0; + } + pub mod posix01 { + } + pub mod posix08 { + } + pub mod bsd44 { + } + pub mod extra { + pub const O_DSYNC : int = 4194304; + pub const O_SYNC : int = 128; + pub const F_FULLFSYNC : int = 51; } } } -mod funcs { - #[legacy_exports]; - +pub mod funcs { // Thankfull most of c95 is universally available and does not vary by OS // or anything. The same is not true of POSIX. - mod c95 { - #[legacy_exports]; - + pub mod c95 { #[nolink] #[abi = "cdecl"] - extern mod ctype { - #[legacy_exports]; + pub extern mod ctype { fn isalnum(c: c_int) -> c_int; fn isalpha(c: c_int) -> c_int; fn iscntrl(c: c_int) -> c_int; @@ -850,9 +776,7 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod stdio { - #[legacy_exports]; - + pub extern mod stdio { fn fopen(filename: *c_char, mode: *c_char) -> *FILE; fn freopen(filename: *c_char, mode: *c_char, file: *FILE) -> *FILE; @@ -882,7 +806,8 @@ mod funcs { nobj: size_t, stream: *FILE) -> size_t; fn fwrite(ptr: *c_void, size: size_t, nobj: size_t, stream: *FILE) -> size_t; - fn fseek(stream: *FILE, offset: c_long, whence: c_int) -> c_int; + fn fseek(stream: *FILE, offset: c_long, + whence: c_int) -> c_int; fn ftell(stream: *FILE) -> c_long; fn rewind(stream: *FILE); fn fgetpos(stream: *FILE, ptr: *fpos_t) -> c_int; @@ -895,16 +820,16 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod stdlib { - #[legacy_exports]; + pub extern mod stdlib { fn abs(i: c_int) -> c_int; fn labs(i: c_long) -> c_long; - // Omitted: div, ldiv (return type incomplete). + // Omitted: div, ldiv (return pub type incomplete). fn atof(s: *c_char) -> c_double; fn atoi(s: *c_char) -> c_int; fn strtod(s: *c_char, endp: **c_char) -> c_double; fn strtol(s: *c_char, endp: **c_char, base: c_int) -> c_long; - fn strtoul(s: *c_char, endp: **c_char, base: c_int) -> c_ulong; + fn strtoul(s: *c_char, endp: **c_char, + base: c_int) -> c_ulong; fn calloc(nobj: size_t, size: size_t) -> *c_void; fn malloc(size: size_t) -> *c_void; fn realloc(p: *c_void, size: size_t) -> *c_void; @@ -921,9 +846,7 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod string { - #[legacy_exports]; - + pub extern mod string { fn strcpy(dst: *c_char, src: *c_char) -> *c_char; fn strncpy(dst: *c_char, src: *c_char, n: size_t) -> *c_char; fn strcat(s: *c_char, ct: *c_char) -> *c_char; @@ -956,13 +879,10 @@ mod funcs { // with the same POSIX functions and types as other platforms. #[cfg(target_os = "win32")] - mod posix88 { - #[legacy_exports]; - + pub mod posix88 { #[nolink] #[abi = "cdecl"] - extern mod stat { - #[legacy_exports]; + pub extern mod stat { #[link_name = "_chmod"] fn chmod(path: *c_char, mode: c_int) -> c_int; @@ -972,8 +892,7 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod stdio { - #[legacy_exports]; + pub extern mod stdio { #[link_name = "_popen"] fn popen(command: *c_char, mode: *c_char) -> *FILE; @@ -989,8 +908,7 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod fcntl { - #[legacy_exports]; + pub extern mod fcntl { #[link_name = "_open"] fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int; @@ -1000,15 +918,13 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod dirent { - #[legacy_exports]; + pub extern mod dirent { // Not supplied at all. } #[nolink] #[abi = "cdecl"] - extern mod unistd { - #[legacy_exports]; + pub extern mod unistd { #[link_name = "_access"] fn access(path: *c_char, amode: c_int) -> c_int; @@ -1035,7 +951,8 @@ mod funcs { fn execvp(c: *c_char, argv: **c_char) -> c_int; #[link_name = "_execvpe"] - fn execvpe(c: *c_char, argv: **c_char, envp: **c_char) -> c_int; + fn execvpe(c: *c_char, argv: **c_char, + envp: **c_char) -> c_int; #[link_name = "_getcwd"] fn getcwd(buf: *c_char, size: size_t) -> *c_char; @@ -1072,13 +989,10 @@ mod funcs { #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] - mod posix88 { - #[legacy_exports]; - + pub mod posix88 { #[nolink] #[abi = "cdecl"] - extern mod stat { - #[legacy_exports]; + pub extern mod stat { fn chmod(path: *c_char, mode: mode_t) -> c_int; fn fchmod(fd: c_int, mode: mode_t) -> c_int; fn mkdir(path: *c_char, mode: mode_t) -> c_int; @@ -1087,8 +1001,7 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod stdio { - #[legacy_exports]; + pub extern mod stdio { fn popen(command: *c_char, mode: *c_char) -> *FILE; fn pclose(stream: *FILE) -> c_int; fn fdopen(fd: c_int, mode: *c_char) -> *FILE; @@ -1097,8 +1010,7 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod fcntl { - #[legacy_exports]; + pub extern mod fcntl { fn open(path: *c_char, oflag: c_int, mode: c_int) -> c_int; fn creat(path: *c_char, mode: mode_t) -> c_int; fn fcntl(fd: c_int, cmd: c_int) -> c_int; @@ -1106,8 +1018,7 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod dirent { - #[legacy_exports]; + pub extern mod dirent { fn opendir(dirname: *c_char) -> *DIR; fn closedir(dirp: *DIR) -> c_int; fn readdir(dirp: *DIR) -> *dirent; @@ -1118,8 +1029,7 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod unistd { - #[legacy_exports]; + pub extern mod unistd { fn access(path: *c_char, amode: c_int) -> c_int; fn alarm(seconds: c_uint) -> c_uint; fn chdir(dir: *c_char) -> c_int; @@ -1128,7 +1038,8 @@ mod funcs { fn dup(fd: c_int) -> c_int; fn dup2(src: c_int, dst: c_int) -> c_int; fn execv(prog: *c_char, argv: **c_char) -> c_int; - fn execve(prog: *c_char, argv: **c_char, envp: **c_char) -> c_int; + fn execve(prog: *c_char, argv: **c_char, + envp: **c_char) -> c_int; fn execvp(c: *c_char, argv: **c_char) -> c_int; fn fork() -> pid_t; fn fpathconf(filedes: c_int, name: c_int) -> c_long; @@ -1138,7 +1049,8 @@ mod funcs { fn getgid() -> gid_t ; fn getgroups(ngroups_max: c_int, groups: *mut gid_t) -> c_int; fn getlogin() -> *c_char; - fn getopt(argc: c_int, argv: **c_char, optstr: *c_char) -> c_int; + fn getopt(argc: c_int, argv: **c_char, + optstr: *c_char) -> c_int; fn getpgrp() -> pid_t; fn getpid() -> pid_t; fn getppid() -> pid_t; @@ -1168,13 +1080,10 @@ mod funcs { #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] - mod posix01 { - #[legacy_exports]; - + pub mod posix01 { #[nolink] #[abi = "cdecl"] - extern mod unistd { - #[legacy_exports]; + pub extern mod unistd { fn readlink(path: *c_char, buf: *mut c_char, bufsz: size_t) -> ssize_t; @@ -1191,19 +1100,17 @@ mod funcs { #[nolink] #[abi = "cdecl"] - extern mod wait { - #[legacy_exports]; + pub extern mod wait { fn waitpid(pid: pid_t, status: *mut c_int, options: c_int) -> pid_t; } } #[cfg(target_os = "win32")] - mod posix01 { - #[legacy_exports]; + pub mod posix01 { #[nolink] - extern mod unistd { - #[legacy_exports]; } + pub extern mod unistd { + } } @@ -1211,11 +1118,10 @@ mod funcs { #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] - mod posix08 { - #[legacy_exports]; + pub mod posix08 { #[nolink] - extern mod unistd { - #[legacy_exports]; } + pub extern mod unistd { + } } @@ -1223,9 +1129,7 @@ mod funcs { #[cfg(target_os = "freebsd")] #[nolink] #[abi = "cdecl"] - extern mod bsd44 { - #[legacy_exports]; - + pub extern mod bsd44 { fn sysctl(name: *c_int, namelen: c_uint, oldp: *mut c_void, oldlenp: *mut size_t, newp: *c_void, newlen: size_t) -> c_int; @@ -1241,37 +1145,35 @@ mod funcs { #[cfg(target_os = "linux")] #[cfg(target_os = "win32")] - mod bsd44 { - #[legacy_exports]; + pub mod bsd44 { } #[cfg(target_os = "macos")] #[nolink] #[abi = "cdecl"] - extern mod extra { - #[legacy_exports]; + pub extern mod extra { fn _NSGetExecutablePath(buf: *mut c_char, bufsize: *mut u32) -> c_int; } #[cfg(target_os = "freebsd")] - mod extra { - #[legacy_exports]; } + pub mod extra { + } #[cfg(target_os = "linux")] - mod extra { - #[legacy_exports]; } + pub mod extra { + } #[cfg(target_os = "win32")] - mod extra { - #[legacy_exports]; + pub mod extra { use types::os::arch::extra::*; + pub use kernel32::*; + pub use msvcrt::*; #[abi = "stdcall"] - extern mod kernel32 { - #[legacy_exports]; + pub extern mod kernel32 { fn GetEnvironmentVariableW(n: LPCWSTR, v: LPWSTR, nsize: DWORD) -> DWORD; @@ -1295,8 +1197,7 @@ mod funcs { #[abi = "cdecl"] #[nolink] - extern mod msvcrt { - #[legacy_exports]; + pub extern mod msvcrt { #[link_name = "_commit"] fn commit(fd: c_int) -> c_int; } diff --git a/src/libcore/logging.rs b/src/libcore/logging.rs index a9f63b57fa5f..d4f3c0ea272e 100644 --- a/src/libcore/logging.rs +++ b/src/libcore/logging.rs @@ -6,18 +6,15 @@ use cast::transmute; -export console_on, console_off, log_type; - #[nolink] extern mod rustrt { - #[legacy_exports]; fn rust_log_console_on(); fn rust_log_console_off(); fn rust_log_str(level: u32, string: *libc::c_char, size: libc::size_t); } /// Turns on logging to stdout globally -fn console_on() { +pub fn console_on() { rustrt::rust_log_console_on(); } @@ -28,7 +25,7 @@ fn console_on() { * runtime environment's logging spec, e.g. by setting * the RUST_LOG environment variable */ -fn console_off() { +pub fn console_off() { rustrt::rust_log_console_off(); } diff --git a/src/libcore/mutable.rs b/src/libcore/mutable.rs index 506da9d3909c..5948c630cd85 100644 --- a/src/libcore/mutable.rs +++ b/src/libcore/mutable.rs @@ -8,15 +8,12 @@ dynamic checks: your program will fail if you attempt to perform mutation when the data structure should be immutable. */ - -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; use util::with; use cast::transmute_immut; -export Mut; - enum Mode { ReadOnly, Mutable, Immutable } struct Data { @@ -24,18 +21,18 @@ struct Data { priv mut mode: Mode } -type Mut = Data; +pub type Mut = Data; -fn Mut(+t: T) -> Mut { +pub fn Mut(t: T) -> Mut { Data {value: t, mode: ReadOnly} } -fn unwrap(+m: Mut) -> T { +pub fn unwrap(m: Mut) -> T { // Borrowck should prevent us from calling unwrap while the value // is in use, as that would be a move from a borrowed value. assert (m.mode as uint) == (ReadOnly as uint); - let Data {value, mode: _} <- m; - return move value; + let Data {value: move value, mode: _} = move m; + return value; } impl Data { @@ -71,7 +68,7 @@ impl Data { #[test] #[ignore(cfg(windows))] #[should_fail] -fn test_mut_in_imm() { +pub fn test_mut_in_imm() { let m = @Mut(1); do m.borrow_imm |_p| { do m.borrow_mut |_q| { @@ -83,7 +80,7 @@ fn test_mut_in_imm() { #[test] #[ignore(cfg(windows))] #[should_fail] -fn test_imm_in_mut() { +pub fn test_imm_in_mut() { let m = @Mut(1); do m.borrow_mut |_p| { do m.borrow_imm |_q| { @@ -93,7 +90,7 @@ fn test_imm_in_mut() { } #[test] -fn test_const_in_mut() { +pub fn test_const_in_mut() { let m = @Mut(1); do m.borrow_mut |p| { do m.borrow_const |q| { @@ -105,7 +102,7 @@ fn test_const_in_mut() { } #[test] -fn test_mut_in_const() { +pub fn test_mut_in_const() { let m = @Mut(1); do m.borrow_const |p| { do m.borrow_mut |q| { @@ -117,7 +114,7 @@ fn test_mut_in_const() { } #[test] -fn test_imm_in_const() { +pub fn test_imm_in_const() { let m = @Mut(1); do m.borrow_const |p| { do m.borrow_imm |q| { @@ -127,7 +124,7 @@ fn test_imm_in_const() { } #[test] -fn test_const_in_imm() { +pub fn test_const_in_imm() { let m = @Mut(1); do m.borrow_imm |p| { do m.borrow_const |q| { @@ -140,7 +137,7 @@ fn test_const_in_imm() { #[test] #[ignore(cfg(windows))] #[should_fail] -fn test_mut_in_imm_in_const() { +pub fn test_mut_in_imm_in_const() { let m = @Mut(1); do m.borrow_const |_p| { do m.borrow_imm |_q| { @@ -149,3 +146,4 @@ fn test_mut_in_imm_in_const() { } } } + diff --git a/src/libcore/num.rs b/src/libcore/num.rs index d5872933953a..d84f97c96393 100644 --- a/src/libcore/num.rs +++ b/src/libcore/num.rs @@ -1,12 +1,12 @@ //! An interface for numeric types -trait Num { +pub trait Num { // FIXME: Trait composition. (#2616) - pure fn add(&&other: self) -> self; - pure fn sub(&&other: self) -> self; - pure fn mul(&&other: self) -> self; - pure fn div(&&other: self) -> self; - pure fn modulo(&&other: self) -> self; + pure fn add(other: &self) -> self; + pure fn sub(other: &self) -> self; + pure fn mul(other: &self) -> self; + pure fn div(other: &self) -> self; + pure fn modulo(other: &self) -> self; pure fn neg() -> self; pure fn to_int() -> int; diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 28f7d21f5743..038c117b8bed 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -1,82 +1,82 @@ // Core operators and kinds. #[lang="const"] -trait Const { +pub trait Const { // Empty. } #[lang="copy"] -trait Copy { +pub trait Copy { // Empty. } #[lang="send"] -trait Send { +pub trait Send { // Empty. } #[lang="owned"] -trait Owned { +pub trait Owned { // Empty. } #[lang="add"] -trait Add { +pub trait Add { pure fn add(rhs: &RHS) -> Result; } #[lang="sub"] -trait Sub { +pub trait Sub { pure fn sub(rhs: &RHS) -> Result; } #[lang="mul"] -trait Mul { +pub trait Mul { pure fn mul(rhs: &RHS) -> Result; } #[lang="div"] -trait Div { +pub trait Div { pure fn div(rhs: &RHS) -> Result; } #[lang="modulo"] -trait Modulo { +pub trait Modulo { pure fn modulo(rhs: &RHS) -> Result; } #[lang="neg"] -trait Neg { +pub trait Neg { pure fn neg() -> Result; } #[lang="bitand"] -trait BitAnd { +pub trait BitAnd { pure fn bitand(rhs: &RHS) -> Result; } #[lang="bitor"] -trait BitOr { +pub trait BitOr { pure fn bitor(rhs: &RHS) -> Result; } #[lang="bitxor"] -trait BitXor { +pub trait BitXor { pure fn bitxor(rhs: &RHS) -> Result; } #[lang="shl"] -trait Shl { +pub trait Shl { pure fn shl(rhs: &RHS) -> Result; } #[lang="shr"] -trait Shr { +pub trait Shr { pure fn shr(rhs: &RHS) -> Result; } #[lang="index"] -trait Index { +pub trait Index { pure fn index(index: Index) -> Result; } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 6ab9a86d8f3d..6bd326186cb4 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -9,18 +9,18 @@ */ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +#[warn(deprecated_mode)]; #[forbid(deprecated_pattern)]; use cmp::Eq; /// The option type -enum Option { +pub enum Option { None, Some(T), } -pure fn get(opt: &Option) -> T { +pub pure fn get(opt: &Option) -> T { /*! * Gets the value out of an option * @@ -30,12 +30,12 @@ pure fn get(opt: &Option) -> T { */ match *opt { - Some(x) => return x, + Some(copy x) => return x, None => fail ~"option::get none" } } -pure fn get_ref(opt: &r/Option) -> &r/T { +pub pure fn get_ref(opt: &r/Option) -> &r/T { /*! * Gets an immutable reference to the value inside an option. * @@ -49,7 +49,7 @@ pure fn get_ref(opt: &r/Option) -> &r/T { } } -pure fn expect(opt: &Option, +reason: ~str) -> T { +pub pure fn expect(opt: &Option, reason: ~str) -> T { /*! * Gets the value out of an option, printing a specified message on * failure @@ -58,22 +58,17 @@ pure fn expect(opt: &Option, +reason: ~str) -> T { * * Fails if the value equals `none` */ - match *opt { Some(x) => x, None => fail reason } + match *opt { Some(copy x) => x, None => fail reason } } -pure fn map(opt: &Option, f: fn(T) -> U) -> Option { - //! Maps a `some` value from one type to another - - match *opt { Some(x) => Some(f(x)), None => None } -} - -pure fn map_ref(opt: &Option, f: fn(x: &T) -> U) -> Option { +pub pure fn map(opt: &Option, f: fn(x: &T) -> U) -> Option { //! Maps a `some` value by reference from one type to another match *opt { Some(ref x) => Some(f(x)), None => None } } -pure fn map_consume(+opt: Option, f: fn(+v: T) -> U) -> Option { +pub pure fn map_consume(opt: Option, + f: fn(v: T) -> U) -> Option { /*! * As `map`, but consumes the option and gives `f` ownership to avoid * copying. @@ -81,17 +76,23 @@ pure fn map_consume(+opt: Option, f: fn(+v: T) -> U) -> Option { if opt.is_some() { Some(f(option::unwrap(move opt))) } else { None } } -pure fn chain(opt: &Option, f: fn(T) -> Option) -> Option { +pub pure fn chain(opt: Option, + f: fn(t: T) -> Option) -> Option { /*! * Update an optional value by optionally running its content through a * function that returns an option. */ - match *opt { Some(x) => f(x), None => None } + // XXX write with move match + if opt.is_some() { + f(unwrap(opt)) + } else { + None + } } -pure fn chain_ref(opt: &Option, - f: fn(x: &T) -> Option) -> Option { +pub pure fn chain_ref(opt: &Option, + f: fn(x: &T) -> Option) -> Option { /*! * Update an optional value by optionally running its content by reference * through a function that returns an option. @@ -100,7 +101,7 @@ pure fn chain_ref(opt: &Option, match *opt { Some(ref x) => f(x), None => None } } -pure fn or(+opta: Option, +optb: Option) -> Option { +pub pure fn or(opta: Option, optb: Option) -> Option { /*! * Returns the leftmost some() value, or none if both are none. */ @@ -111,7 +112,7 @@ pure fn or(+opta: Option, +optb: Option) -> Option { } #[inline(always)] -pure fn while_some(+x: Option, blk: fn(+v: T) -> Option) { +pub pure fn while_some(x: Option, blk: fn(v: T) -> Option) { //! Applies a function zero or more times until the result is none. let mut opt <- x; @@ -120,54 +121,38 @@ pure fn while_some(+x: Option, blk: fn(+v: T) -> Option) { } } -pure fn is_none(opt: &Option) -> bool { +pub pure fn is_none(opt: &Option) -> bool { //! Returns true if the option equals `none` match *opt { None => true, Some(_) => false } } -pure fn is_some(opt: &Option) -> bool { +pub pure fn is_some(opt: &Option) -> bool { //! Returns true if the option contains some value !is_none(opt) } -pure fn get_default(opt: &Option, +def: T) -> T { +pub pure fn get_default(opt: &Option, def: T) -> T { //! Returns the contained value or a default - match *opt { Some(x) => x, None => def } + match *opt { Some(copy x) => x, None => def } } -pure fn map_default(opt: &Option, +def: U, f: fn(T) -> U) -> U { - //! Applies a function to the contained value or returns a default - - match *opt { None => move def, Some(t) => f(t) } -} - -// This should replace map_default. -pure fn map_default_ref(opt: &Option, +def: U, +pub pure fn map_default(opt: &Option, def: U, f: fn(x: &T) -> U) -> U { //! Applies a function to the contained value or returns a default match *opt { None => move def, Some(ref t) => f(t) } } -// This should change to by-copy mode; use iter_ref below for by reference -pure fn iter(opt: &Option, f: fn(T)) { - //! Performs an operation on the contained value or does nothing - - match *opt { None => (), Some(t) => f(t) } -} - -pure fn iter_ref(opt: &Option, f: fn(x: &T)) { +pub pure fn iter(opt: &Option, f: fn(x: &T)) { //! Performs an operation on the contained value by reference match *opt { None => (), Some(ref t) => f(t) } } -// tjc: shouldn't this be - instead of +? -// then could get rid of some superfluous moves #[inline(always)] -pure fn unwrap(+opt: Option) -> T { +pub pure fn unwrap(opt: Option) -> T { /*! * Moves a value out of an option type and returns it. * @@ -182,12 +167,12 @@ pure fn unwrap(+opt: Option) -> T { /// The ubiquitous option dance. #[inline(always)] -fn swap_unwrap(opt: &mut Option) -> T { +pub fn swap_unwrap(opt: &mut Option) -> T { if opt.is_none() { fail ~"option::swap_unwrap none" } unwrap(util::replace(opt, None)) } -pure fn unwrap_expect(+opt: Option, reason: &str) -> T { +pub pure fn unwrap_expect(opt: Option, reason: &str) -> T { //! As unwrap, but with a specified failure message. if opt.is_none() { fail reason.to_unique(); } unwrap(move opt) @@ -195,22 +180,10 @@ pure fn unwrap_expect(+opt: Option, reason: &str) -> T { // Some of these should change to be &Option, some should not. See below. impl Option { - /** - * Update an optional value by optionally running its content through a - * function that returns an option. - */ - pure fn chain(f: fn(T) -> Option) -> Option { chain(&self, f) } - /// Applies a function to the contained value or returns a default - pure fn map_default(+def: U, f: fn(T) -> U) -> U - { map_default(&self, move def, f) } - /// Performs an operation on the contained value or does nothing - pure fn iter(f: fn(T)) { iter(&self, f) } /// Returns true if the option equals `none` pure fn is_none() -> bool { is_none(&self) } /// Returns true if the option contains some value pure fn is_some() -> bool { is_some(&self) } - /// Maps a `some` value from one type to another - pure fn map(f: fn(T) -> U) -> Option { map(&self, f) } } impl &Option { @@ -222,12 +195,12 @@ impl &Option { chain_ref(self, f) } /// Applies a function to the contained value or returns a default - pure fn map_default_ref(+def: U, f: fn(x: &T) -> U) -> U - { map_default_ref(self, move def, f) } + pure fn map_default(def: U, f: fn(x: &T) -> U) -> U + { map_default(self, move def, f) } /// Performs an operation on the contained value by reference - pure fn iter_ref(f: fn(x: &T)) { iter_ref(self, f) } + pure fn iter(f: fn(x: &T)) { iter(self, f) } /// Maps a `some` value from one type to another by reference - pure fn map_ref(f: fn(x: &T) -> U) -> Option { map_ref(self, f) } + pure fn map(f: fn(x: &T) -> U) -> Option { map(self, f) } /// Gets an immutable reference to the value inside a `some`. pure fn get_ref() -> &self/T { get_ref(self) } } @@ -241,7 +214,7 @@ impl Option { * Fails if the value equals `none` */ pure fn get() -> T { get(&self) } - pure fn get_default(+def: T) -> T { get_default(&self, def) } + pure fn get_default(def: T) -> T { get_default(&self, def) } /** * Gets the value out of an option, printing a specified message on * failure @@ -250,9 +223,9 @@ impl Option { * * Fails if the value equals `none` */ - pure fn expect(+reason: ~str) -> T { expect(&self, reason) } + pure fn expect(reason: ~str) -> T { expect(&self, reason) } /// Applies a function zero or more times until the result is none. - pure fn while_some(blk: fn(+v: T) -> Option) { while_some(self, blk) } + pure fn while_some(blk: fn(v: T) -> Option) { while_some(self, blk) } } impl Option : Eq { @@ -264,11 +237,11 @@ impl Option : Eq { Some(_) => false } } - Some(self_contents) => { + Some(ref self_contents) => { match (*other) { None => false, Some(ref other_contents) => - self_contents.eq(other_contents) + (*self_contents).eq(other_contents) } } } @@ -279,20 +252,20 @@ impl Option : Eq { #[test] fn test_unwrap_ptr() { let x = ~0; - let addr_x = ptr::addr_of(*x); + let addr_x = ptr::p2::addr_of(&(*x)); let opt = Some(x); let y = unwrap(opt); - let addr_y = ptr::addr_of(*y); + let addr_y = ptr::p2::addr_of(&(*y)); assert addr_x == addr_y; } #[test] fn test_unwrap_str() { let x = ~"test"; - let addr_x = str::as_buf(x, |buf, _len| ptr::addr_of(buf)); - let opt = Some(x); - let y = unwrap(opt); - let addr_y = str::as_buf(y, |buf, _len| ptr::addr_of(buf)); + let addr_x = str::as_buf(x, |buf, _len| buf); + let opt = Some(move x); + let y = unwrap(move opt); + let addr_y = str::as_buf(y, |buf, _len| buf); assert addr_x == addr_y; } diff --git a/src/libcore/os.rs b/src/libcore/os.rs index b4c284cbd821..68571da3a1e9 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid #[forbid(deprecated_pattern)]; /*! @@ -21,34 +21,23 @@ */ use libc::{c_char, c_void, c_int, c_uint, size_t, ssize_t, - mode_t, pid_t, FILE}; -use libc::{close, fclose}; + mode_t, pid_t, FILE}; +pub use libc::{close, fclose}; use option::{Some, None}; -use consts::*; +pub use consts::*; use task::TaskBuilder; -export close, fclose, fsync_fd, waitpid; -export env, getenv, setenv, fdopen, pipe; -export getcwd, dll_filename, self_exe_path; -export exe_suffix, dll_suffix, sysname, arch, family; -export homedir, tmpdir, list_dir, list_dir_path, path_is_dir, path_exists, - make_absolute, make_dir, remove_dir, change_dir, remove_file, - copy_file; -export last_os_error; -export set_exit_status; -export walk_dir; - // FIXME: move these to str perhaps? #2620 -export as_c_charp, fill_charp_buf; extern mod rustrt { - #[legacy_exports]; + fn rust_get_argc() -> c_int; + fn rust_get_argv() -> **c_char; fn rust_getcwd() -> ~str; fn rust_path_is_dir(path: *libc::c_char) -> c_int; fn rust_path_exists(path: *libc::c_char) -> c_int; - fn rust_list_files(path: ~str) -> ~[~str]; + fn rust_list_files2(&&path: ~str) -> ~[~str]; fn rust_process_wait(handle: c_int) -> c_int; fn last_os_error() -> ~str; fn rust_set_exit_status(code: libc::intptr_t); @@ -57,15 +46,15 @@ extern mod rustrt { const tmpbuf_sz : uint = 1000u; -fn getcwd() -> Path { +pub fn getcwd() -> Path { Path(rustrt::rust_getcwd()) } -fn as_c_charp(s: &str, f: fn(*c_char) -> T) -> T { +pub fn as_c_charp(s: &str, f: fn(*c_char) -> T) -> T { str::as_c_str(s, |b| f(b as *c_char)) } -fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool) +pub fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool) -> Option<~str> { let buf = vec::to_mut(vec::from_elem(tmpbuf_sz, 0u8 as c_char)); do vec::as_mut_buf(buf) |b, sz| { @@ -79,29 +68,23 @@ fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool) #[cfg(windows)] mod win32 { - #[legacy_exports]; - use dword = libc::types::os::arch::extra::DWORD; + use libc::DWORD; - fn fill_utf16_buf_and_decode(f: fn(*mut u16, dword) -> dword) + pub fn fill_utf16_buf_and_decode(f: fn(*mut u16, DWORD) -> DWORD) -> Option<~str> { - - // FIXME: remove these when export globs work properly. #1238 - use libc::funcs::extra::kernel32::*; - use libc::consts::os::extra::*; - - let mut n = tmpbuf_sz as dword; + let mut n = tmpbuf_sz as DWORD; let mut res = None; let mut done = false; while !done { let buf = vec::to_mut(vec::from_elem(n as uint, 0u16)); do vec::as_mut_buf(buf) |b, _sz| { - let k : dword = f(b, tmpbuf_sz as dword); - if k == (0 as dword) { + let k : DWORD = f(b, tmpbuf_sz as DWORD); + if k == (0 as DWORD) { done = true; } else if (k == n && - GetLastError() == - ERROR_INSUFFICIENT_BUFFER as dword) { - n *= (2 as dword); + libc::GetLastError() == + libc::ERROR_INSUFFICIENT_BUFFER as DWORD) { + n *= (2 as DWORD); } else { let sub = vec::slice(buf, 0u, k as uint); res = option::Some(str::from_utf16(sub)); @@ -112,7 +95,7 @@ mod win32 { return res; } - fn as_utf16_p(s: &str, f: fn(*u16) -> T) -> T { + pub fn as_utf16_p(s: &str, f: fn(*u16) -> T) -> T { let mut t = str::to_utf16(s); // Null terminate before passing on. t += ~[0u16]; @@ -120,28 +103,22 @@ mod win32 { } } -fn getenv(n: &str) -> Option<~str> { +pub fn getenv(n: &str) -> Option<~str> { global_env::getenv(n) } -fn setenv(n: &str, v: &str) { +pub fn setenv(n: &str, v: &str) { global_env::setenv(n, v) } -fn env() -> ~[(~str,~str)] { +pub fn env() -> ~[(~str,~str)] { global_env::env() } mod global_env { - #[legacy_exports]; //! Internal module for serializing access to getenv/setenv - export getenv; - export setenv; - export env; - extern mod rustrt { - #[legacy_exports]; fn rust_global_env_chan_ptr() -> *libc::uintptr_t; } @@ -151,7 +128,7 @@ mod global_env { MsgEnv(comm::Chan<~[(~str,~str)]>) } - fn getenv(n: &str) -> Option<~str> { + pub fn getenv(n: &str) -> Option<~str> { let env_ch = get_global_env_chan(); let po = comm::Port(); comm::send(env_ch, MsgGetEnv(str::from_slice(n), @@ -159,7 +136,7 @@ mod global_env { comm::recv(po) } - fn setenv(n: &str, v: &str) { + pub fn setenv(n: &str, v: &str) { let env_ch = get_global_env_chan(); let po = comm::Port(); comm::send(env_ch, MsgSetEnv(str::from_slice(n), @@ -168,7 +145,7 @@ mod global_env { comm::recv(po) } - fn env() -> ~[(~str,~str)] { + pub fn env() -> ~[(~str,~str)] { let env_ch = get_global_env_chan(); let po = comm::Port(); comm::send(env_ch, MsgEnv(comm::Chan(po))); @@ -191,11 +168,11 @@ mod global_env { do private::weaken_task |weak_po| { loop { match comm::select2(msg_po, weak_po) { - either::Left(MsgGetEnv(n, resp_ch)) => { - comm::send(resp_ch, impl_::getenv(n)) + either::Left(MsgGetEnv(ref n, resp_ch)) => { + comm::send(resp_ch, impl_::getenv(*n)) } - either::Left(MsgSetEnv(n, v, resp_ch)) => { - comm::send(resp_ch, impl_::setenv(n, v)) + either::Left(MsgSetEnv(ref n, ref v, resp_ch)) => { + comm::send(resp_ch, impl_::setenv(*n, *v)) } either::Left(MsgEnv(resp_ch)) => { comm::send(resp_ch, impl_::env()) @@ -208,24 +185,22 @@ mod global_env { } mod impl_ { - #[legacy_exports]; extern mod rustrt { - #[legacy_exports]; fn rust_env_pairs() -> ~[~str]; } - fn env() -> ~[(~str,~str)] { + pub fn env() -> ~[(~str,~str)] { let mut pairs = ~[]; for vec::each(rustrt::rust_env_pairs()) |p| { let vs = str::splitn_char(*p, '=', 1u); assert vec::len(vs) == 2u; - vec::push(pairs, (copy vs[0], copy vs[1])); + pairs.push((copy vs[0], copy vs[1])); } move pairs } #[cfg(unix)] - fn getenv(n: &str) -> Option<~str> { + pub fn getenv(n: &str) -> Option<~str> { unsafe { let s = str::as_c_str(n, libc::getenv); return if ptr::null::() == cast::reinterpret_cast(&s) { @@ -238,39 +213,32 @@ mod global_env { } #[cfg(windows)] - fn getenv(n: &str) -> Option<~str> { - use libc::types::os::arch::extra::*; - use libc::funcs::extra::kernel32::*; + pub fn getenv(n: &str) -> Option<~str> { use win32::*; do as_utf16_p(n) |u| { do fill_utf16_buf_and_decode() |buf, sz| { - GetEnvironmentVariableW(u, buf, sz) + libc::GetEnvironmentVariableW(u, buf, sz) } } } #[cfg(unix)] - fn setenv(n: &str, v: &str) { - - // FIXME: remove this when export globs work properly. #1238 - use libc::funcs::posix01::unistd::setenv; + pub fn setenv(n: &str, v: &str) { do str::as_c_str(n) |nbuf| { do str::as_c_str(v) |vbuf| { - setenv(nbuf, vbuf, 1i32); + libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1i32); } } } #[cfg(windows)] - fn setenv(n: &str, v: &str) { - // FIXME: remove imports when export globs work properly. #1238 - use libc::funcs::extra::kernel32::*; + pub fn setenv(n: &str, v: &str) { use win32::*; do as_utf16_p(n) |nbuf| { do as_utf16_p(v) |vbuf| { - SetEnvironmentVariableW(nbuf, vbuf); + libc::SetEnvironmentVariableW(nbuf, vbuf); } } } @@ -278,7 +246,7 @@ mod global_env { } } -fn fdopen(fd: c_int) -> *FILE { +pub fn fdopen(fd: c_int) -> *FILE { return do as_c_charp("r") |modebuf| { libc::fdopen(fd, modebuf) }; @@ -288,13 +256,13 @@ fn fdopen(fd: c_int) -> *FILE { // fsync related #[cfg(windows)] -fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int { +pub fn fsync_fd(fd: c_int, _level: io::fsync::Level) -> c_int { use libc::funcs::extra::msvcrt::*; return commit(fd); } #[cfg(target_os = "linux")] -fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int { +pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int { use libc::funcs::posix01::unistd::*; match level { io::fsync::FSync @@ -304,7 +272,7 @@ fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int { } #[cfg(target_os = "macos")] -fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int { +pub fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int { use libc::consts::os::extra::*; use libc::funcs::posix88::fcntl::*; use libc::funcs::posix01::unistd::*; @@ -321,52 +289,50 @@ fn fsync_fd(fd: c_int, level: io::fsync::Level) -> c_int { } #[cfg(target_os = "freebsd")] -fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int { +pub fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int { use libc::funcs::posix01::unistd::*; return fsync(fd); } #[cfg(windows)] -fn waitpid(pid: pid_t) -> c_int { +pub fn waitpid(pid: pid_t) -> c_int { return rustrt::rust_process_wait(pid); } #[cfg(unix)] -fn waitpid(pid: pid_t) -> c_int { +pub fn waitpid(pid: pid_t) -> c_int { use libc::funcs::posix01::wait::*; let status = 0 as c_int; - assert (waitpid(pid, ptr::mut_addr_of(status), + assert (waitpid(pid, ptr::mut_addr_of(&status), 0 as c_int) != (-1 as c_int)); return status; } #[cfg(unix)] -fn pipe() -> {in: c_int, out: c_int} { +pub fn pipe() -> {in: c_int, out: c_int} { let fds = {mut in: 0 as c_int, mut out: 0 as c_int }; - assert (libc::pipe(ptr::mut_addr_of(fds.in)) == (0 as c_int)); + assert (libc::pipe(ptr::mut_addr_of(&(fds.in))) == (0 as c_int)); return {in: fds.in, out: fds.out}; } #[cfg(windows)] -fn pipe() -> {in: c_int, out: c_int} { - // FIXME: remove this when export globs work properly. #1238 - use libc::consts::os::extra::*; +pub fn pipe() -> {in: c_int, out: c_int} { // Windows pipes work subtly differently than unix pipes, and their // inheritance has to be handled in a different way that I do not fully // understand. Here we explicitly make the pipe non-inheritable, which // means to pass it to a subprocess they need to be duplicated first, as // in rust_run_program. let fds = { mut in: 0 as c_int, - mut out: 0 as c_int }; - let res = libc::pipe(ptr::mut_addr_of(fds.in), + mut out: 0 as c_int }; + let res = libc::pipe(ptr::mut_addr_of(&(fds.in)), 1024 as c_uint, - (O_BINARY | O_NOINHERIT) as c_int); + (libc::O_BINARY | libc::O_NOINHERIT) as c_int); assert (res == 0 as c_int); assert (fds.in != -1 as c_int && fds.in != 0 as c_int); assert (fds.out != -1 as c_int && fds.in != 0 as c_int); @@ -378,7 +344,7 @@ fn dup2(src: c_int, dst: c_int) -> c_int { } -fn dll_filename(base: &str) -> ~str { +pub fn dll_filename(base: &str) -> ~str { return pre() + str::from_slice(base) + dll_suffix(); #[cfg(unix)] @@ -389,7 +355,7 @@ fn dll_filename(base: &str) -> ~str { } -fn self_exe_path() -> Option { +pub fn self_exe_path() -> Option { #[cfg(target_os = "freebsd")] fn load_self() -> Option<~str> { @@ -401,7 +367,7 @@ fn self_exe_path() -> Option { KERN_PROC as c_int, KERN_PROC_PATHNAME as c_int, -1 as c_int]; sysctl(vec::raw::to_ptr(mib), vec::len(mib) as c_uint, - buf as *mut c_void, ptr::mut_addr_of(sz), + buf as *mut c_void, ptr::mut_addr_of(&sz), ptr::null(), 0u as size_t) == (0 as c_int) } } @@ -419,27 +385,22 @@ fn self_exe_path() -> Option { #[cfg(target_os = "macos")] fn load_self() -> Option<~str> { - // FIXME: remove imports when export globs work properly. #1238 - use libc::funcs::extra::*; do fill_charp_buf() |buf, sz| { - _NSGetExecutablePath(buf, ptr::mut_addr_of(sz as u32)) - == (0 as c_int) + libc::funcs::extra::_NSGetExecutablePath( + buf, ptr::mut_addr_of(&(sz as u32))) == (0 as c_int) } } #[cfg(windows)] fn load_self() -> Option<~str> { - // FIXME: remove imports when export globs work properly. #1238 - use libc::types::os::arch::extra::*; - use libc::funcs::extra::kernel32::*; use win32::*; do fill_utf16_buf_and_decode() |buf, sz| { - GetModuleFileNameW(0u as dword, buf, sz) + libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz) } } do load_self().map |pth| { - Path(pth).dir_path() + Path(*pth).dir_path() } } @@ -457,10 +418,10 @@ fn self_exe_path() -> Option { * * Otherwise, homedir returns option::none. */ -fn homedir() -> Option { +pub fn homedir() -> Option { return match getenv(~"HOME") { - Some(p) => if !str::is_empty(p) { - Some(Path(p)) + Some(ref p) => if !str::is_empty(*p) { + Some(Path(*p)) } else { secondary() }, @@ -474,7 +435,7 @@ fn homedir() -> Option { #[cfg(windows)] fn secondary() -> Option { - do option::chain(&getenv(~"USERPROFILE")) |p| { + do option::chain(getenv(~"USERPROFILE")) |p| { if !str::is_empty(p) { Some(Path(p)) } else { @@ -494,12 +455,12 @@ fn homedir() -> Option { * 'USERPROFILE' environment variable if any are set and not the empty * string. Otherwise, tmpdir returns the path to the Windows directory. */ -fn tmpdir() -> Path { +pub fn tmpdir() -> Path { return lookup(); fn getenv_nonempty(v: &str) -> Option { match getenv(v) { - Some(x) => + Some(move x) => if str::is_empty(x) { None } else { @@ -528,7 +489,7 @@ fn tmpdir() -> Path { } } /// Recursively walk a directory structure -fn walk_dir(p: &Path, f: fn((&Path)) -> bool) { +pub fn walk_dir(p: &Path, f: fn((&Path)) -> bool) { walk_dir_(p, f); @@ -557,21 +518,19 @@ fn walk_dir(p: &Path, f: fn((&Path)) -> bool) { } /// Indicates whether a path represents a directory -fn path_is_dir(p: &Path) -> bool { +pub fn path_is_dir(p: &Path) -> bool { do str::as_c_str(p.to_str()) |buf| { rustrt::rust_path_is_dir(buf) != 0 as c_int } } /// Indicates whether a path exists -fn path_exists(p: &Path) -> bool { +pub fn path_exists(p: &Path) -> bool { do str::as_c_str(p.to_str()) |buf| { rustrt::rust_path_exists(buf) != 0 as c_int } } -// FIXME (#2622): under Windows, we should prepend the current drive letter -// to paths that start with a slash. /** * Convert a relative path to an absolute path * @@ -582,7 +541,7 @@ fn path_exists(p: &Path) -> bool { // NB: this is here rather than in path because it is a form of environment // querying; what it does depends on the process working directory, not just // the input paths. -fn make_absolute(p: &Path) -> Path { +pub fn make_absolute(p: &Path) -> Path { if p.is_absolute { copy *p } else { @@ -592,19 +551,18 @@ fn make_absolute(p: &Path) -> Path { /// Creates a directory at the specified path -fn make_dir(p: &Path, mode: c_int) -> bool { +pub fn make_dir(p: &Path, mode: c_int) -> bool { return mkdir(p, mode); #[cfg(windows)] fn mkdir(p: &Path, _mode: c_int) -> bool { - // FIXME: remove imports when export globs work properly. #1238 - use libc::types::os::arch::extra::*; - use libc::funcs::extra::kernel32::*; use win32::*; // FIXME: turn mode into something useful? #2623 do as_utf16_p(p.to_str()) |buf| { - CreateDirectoryW(buf, unsafe { cast::reinterpret_cast(&0) }) - != (0 as BOOL) + libc::CreateDirectoryW(buf, unsafe { + cast::reinterpret_cast(&0) + }) + != (0 as libc::BOOL) } } @@ -618,7 +576,7 @@ fn make_dir(p: &Path, mode: c_int) -> bool { /// Lists the contents of a directory #[allow(non_implicitly_copyable_typarams)] -fn list_dir(p: &Path) -> ~[~str] { +pub fn list_dir(p: &Path) -> ~[~str] { #[cfg(unix)] fn star(p: &Path) -> Path { copy *p } @@ -626,8 +584,8 @@ fn list_dir(p: &Path) -> ~[~str] { #[cfg(windows)] fn star(p: &Path) -> Path { p.push("*") } - do rustrt::rust_list_files(star(p).to_str()).filter |filename| { - filename != ~"." && filename != ~".." + do rustrt::rust_list_files2(star(p).to_str()).filter |filename| { + *filename != ~"." && *filename != ~".." } } @@ -636,22 +594,19 @@ fn list_dir(p: &Path) -> ~[~str] { * * This version prepends each entry with the directory. */ -fn list_dir_path(p: &Path) -> ~[~Path] { +pub fn list_dir_path(p: &Path) -> ~[~Path] { os::list_dir(p).map(|f| ~p.push(*f)) } /// Removes a directory at the specified path -fn remove_dir(p: &Path) -> bool { +pub fn remove_dir(p: &Path) -> bool { return rmdir(p); #[cfg(windows)] fn rmdir(p: &Path) -> bool { - // FIXME: remove imports when export globs work properly. #1238 - use libc::funcs::extra::kernel32::*; - use libc::types::os::arch::extra::*; use win32::*; return do as_utf16_p(p.to_str()) |buf| { - RemoveDirectoryW(buf) != (0 as BOOL) + libc::RemoveDirectoryW(buf) != (0 as libc::BOOL) }; } @@ -663,17 +618,14 @@ fn remove_dir(p: &Path) -> bool { } } -fn change_dir(p: &Path) -> bool { +pub fn change_dir(p: &Path) -> bool { return chdir(p); #[cfg(windows)] fn chdir(p: &Path) -> bool { - // FIXME: remove imports when export globs work properly. #1238 - use libc::funcs::extra::kernel32::*; - use libc::types::os::arch::extra::*; use win32::*; return do as_utf16_p(p.to_str()) |buf| { - SetCurrentDirectoryW(buf) != (0 as BOOL) + libc::SetCurrentDirectoryW(buf) != (0 as libc::BOOL) }; } @@ -686,18 +638,16 @@ fn change_dir(p: &Path) -> bool { } /// Copies a file from one location to another -fn copy_file(from: &Path, to: &Path) -> bool { +pub fn copy_file(from: &Path, to: &Path) -> bool { return do_copy_file(from, to); #[cfg(windows)] fn do_copy_file(from: &Path, to: &Path) -> bool { - // FIXME: remove imports when export globs work properly. #1238 - use libc::funcs::extra::kernel32::*; - use libc::types::os::arch::extra::*; use win32::*; return do as_utf16_p(from.to_str()) |fromp| { do as_utf16_p(to.to_str()) |top| { - CopyFileW(fromp, top, (0 as BOOL)) != (0 as BOOL) + libc::CopyFileW(fromp, top, (0 as libc::BOOL)) != + (0 as libc::BOOL) } } } @@ -748,18 +698,14 @@ fn copy_file(from: &Path, to: &Path) -> bool { } /// Deletes an existing file -fn remove_file(p: &Path) -> bool { +pub fn remove_file(p: &Path) -> bool { return unlink(p); #[cfg(windows)] fn unlink(p: &Path) -> bool { - // FIXME (similar to Issue #2006): remove imports when export globs - // work properly. - use libc::funcs::extra::kernel32::*; - use libc::types::os::arch::extra::*; use win32::*; return do as_utf16_p(p.to_str()) |buf| { - DeleteFileW(buf) != (0 as BOOL) + libc::DeleteFileW(buf) != (0 as libc::BOOL) }; } @@ -772,7 +718,7 @@ fn remove_file(p: &Path) -> bool { } /// Get a string representing the platform-dependent last error -fn last_os_error() -> ~str { +pub fn last_os_error() -> ~str { rustrt::last_os_error() } @@ -784,67 +730,175 @@ fn last_os_error() -> ~str { * and is supervised by the scheduler then any user-specified exit status is * ignored and the process exits with the default failure status */ -fn set_exit_status(code: int) { +pub fn set_exit_status(code: int) { rustrt::rust_set_exit_status(code as libc::intptr_t); } -#[cfg(unix)] -fn family() -> ~str { ~"unix" } +unsafe fn load_argc_and_argv(argc: c_int, argv: **c_char) -> ~[~str] { + let mut args = ~[]; + for uint::range(0, argc as uint) |i| { + vec::push(&mut args, str::raw::from_c_str(*argv.offset(i))); + } + return args; +} + +/** + * Returns the command line arguments + * + * Returns a list of the command line arguments. + */ +#[cfg(target_os = "macos")] +fn real_args() -> ~[~str] { + unsafe { + let (argc, argv) = (*_NSGetArgc() as c_int, + *_NSGetArgv() as **c_char); + load_argc_and_argv(argc, argv) + } +} + +#[cfg(target_os = "linux")] +#[cfg(target_os = "freebsd")] +fn real_args() -> ~[~str] { + unsafe { + let argc = rustrt::rust_get_argc(); + let argv = rustrt::rust_get_argv(); + load_argc_and_argv(argc, argv) + } +} #[cfg(windows)] -fn family() -> ~str { ~"windows" } +fn real_args() -> ~[~str] { + let mut nArgs: c_int = 0; + let lpArgCount = ptr::to_mut_unsafe_ptr(&mut nArgs); + let lpCmdLine = GetCommandLineW(); + let szArgList = CommandLineToArgvW(lpCmdLine, lpArgCount); + + let mut args = ~[]; + for uint::range(0, nArgs as uint) |i| { + unsafe { + // Determine the length of this argument. + let ptr = *szArgList.offset(i); + let mut len = 0; + while *ptr.offset(len) != 0 { len += 1; } + + // Push it onto the list. + vec::push(&mut args, + vec::raw::buf_as_slice(ptr, len, + str::from_utf16)); + } + } + + unsafe { + LocalFree(cast::transmute(szArgList)); + } + + return args; +} + +type LPCWSTR = *u16; + +#[cfg(windows)] +#[link_name="kernel32"] +#[abi="stdcall"] +extern { + fn GetCommandLineW() -> LPCWSTR; + fn LocalFree(ptr: *c_void); +} + +#[cfg(windows)] +#[link_name="shell32"] +#[abi="stdcall"] +extern { + fn CommandLineToArgvW(lpCmdLine: LPCWSTR, pNumArgs: *mut c_int) -> **u16; +} + +struct OverriddenArgs { + val: ~[~str] +} + +fn overridden_arg_key(_v: @OverriddenArgs) {} + +pub fn args() -> ~[~str] { + unsafe { + match task::local_data::local_data_get(overridden_arg_key) { + None => real_args(), + Some(args) => copy args.val + } + } +} + +pub fn set_args(new_args: ~[~str]) { + unsafe { + let overridden_args = @OverriddenArgs { val: copy new_args }; + task::local_data::local_data_set(overridden_arg_key, overridden_args); + } +} + +#[cfg(target_os = "macos")] +extern { + // These functions are in crt_externs.h. + pub fn _NSGetArgc() -> *c_int; + pub fn _NSGetArgv() -> ***c_char; +} + +#[cfg(unix)] +pub fn family() -> ~str { ~"unix" } + +#[cfg(windows)] +pub fn family() -> ~str { ~"windows" } #[cfg(target_os = "macos")] mod consts { - #[legacy_exports]; - fn sysname() -> ~str { ~"macos" } - fn exe_suffix() -> ~str { ~"" } - fn dll_suffix() -> ~str { ~".dylib" } + pub fn sysname() -> ~str { ~"macos" } + pub fn exe_suffix() -> ~str { ~"" } + pub fn dll_suffix() -> ~str { ~".dylib" } } #[cfg(target_os = "freebsd")] mod consts { - #[legacy_exports]; - fn sysname() -> ~str { ~"freebsd" } - fn exe_suffix() -> ~str { ~"" } - fn dll_suffix() -> ~str { ~".so" } + pub fn sysname() -> ~str { ~"freebsd" } + pub fn exe_suffix() -> ~str { ~"" } + pub fn dll_suffix() -> ~str { ~".so" } } #[cfg(target_os = "linux")] mod consts { - #[legacy_exports]; - fn sysname() -> ~str { ~"linux" } - fn exe_suffix() -> ~str { ~"" } - fn dll_suffix() -> ~str { ~".so" } + pub fn sysname() -> ~str { ~"linux" } + pub fn exe_suffix() -> ~str { ~"" } + pub fn dll_suffix() -> ~str { ~".so" } } #[cfg(target_os = "win32")] mod consts { - #[legacy_exports]; - fn sysname() -> ~str { ~"win32" } - fn exe_suffix() -> ~str { ~".exe" } - fn dll_suffix() -> ~str { ~".dll" } + pub fn sysname() -> ~str { ~"win32" } + pub fn exe_suffix() -> ~str { ~".exe" } + pub fn dll_suffix() -> ~str { ~".dll" } } #[cfg(target_arch = "x86")] -fn arch() -> ~str { ~"x86" } +pub fn arch() -> ~str { ~"x86" } #[cfg(target_arch = "x86_64")] -fn arch() -> ~str { ~"x86_64" } +pub fn arch() -> ~str { ~"x86_64" } #[cfg(target_arch = "arm")] -fn arch() -> str { ~"arm" } +pub fn arch() -> str { ~"arm" } #[cfg(test)] #[allow(non_implicitly_copyable_typarams)] mod tests { - #[legacy_exports]; #[test] - fn last_os_error() { + pub fn last_os_error() { log(debug, last_os_error()); } + #[test] + pub fn test_args() { + let a = real_args(); + assert a.len() >= 1; + } + fn make_rand_name() -> ~str { let rng: rand::Rng = rand::Rng(); let n = ~"TEST" + rng.gen_str(10u); @@ -919,10 +973,10 @@ mod tests { let mut e = env(); setenv(n, ~"VALUE"); - assert !vec::contains(e, (copy n, ~"VALUE")); + assert !vec::contains(e, &(copy n, ~"VALUE")); e = env(); - assert vec::contains(e, (n, ~"VALUE")); + assert vec::contains(e, &(n, ~"VALUE")); } #[test] @@ -946,7 +1000,7 @@ mod tests { setenv(~"HOME", ~""); assert os::homedir().is_none(); - oldhome.iter(|s| setenv(~"HOME", s)); + oldhome.iter(|s| setenv(~"HOME", *s)); } #[test] @@ -973,9 +1027,9 @@ mod tests { setenv(~"USERPROFILE", ~"/home/PaloAlto"); assert os::homedir() == Some(Path("/home/MountainView")); - option::iter(&oldhome, |s| setenv(~"HOME", s)); + option::iter(&oldhome, |s| setenv(~"HOME", *s)); option::iter(&olduserprofile, - |s| setenv(~"USERPROFILE", s)); + |s| setenv(~"USERPROFILE", *s)); } #[test] diff --git a/src/libcore/path.rs b/src/libcore/path.rs index ab847702d68a..6d023ed1bfb7 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -10,19 +10,19 @@ Cross-platform file path handling use cmp::Eq; -struct WindowsPath { +pub struct WindowsPath { host: Option<~str>, device: Option<~str>, is_absolute: bool, components: ~[~str], } -struct PosixPath { +pub struct PosixPath { is_absolute: bool, components: ~[~str], } -trait GenericPath { +pub trait GenericPath { static pure fn from_str((&str)) -> self; @@ -45,18 +45,18 @@ trait GenericPath { } #[cfg(windows)] -type Path = WindowsPath; +pub type Path = WindowsPath; #[cfg(windows)] -pure fn Path(s: &str) -> Path { +pub pure fn Path(s: &str) -> Path { from_str::(s) } #[cfg(unix)] -type Path = PosixPath; +pub type Path = PosixPath; #[cfg(unix)] -pure fn Path(s: &str) -> Path { +pub pure fn Path(s: &str) -> Path { from_str::(s) } @@ -167,7 +167,7 @@ impl PosixPath : GenericPath { if t.len() == 0 { match self.filestem() { None => copy self, - Some(s) => self.with_filename(s) + Some(ref s) => self.with_filename(*s) } } else { let t = ~"." + str::from_slice(t); @@ -206,7 +206,7 @@ impl PosixPath : GenericPath { let mut ss = str::split_nonempty( *e, |c| windows::is_sep(c as u8)); - unsafe { vec::push_all_move(v, move ss); } + unsafe { v.push_all_move(move ss); } } PosixPath { components: move v, ..self } } @@ -214,14 +214,14 @@ impl PosixPath : GenericPath { pure fn push(s: &str) -> PosixPath { let mut v = copy self.components; let mut ss = str::split_nonempty(s, |c| windows::is_sep(c as u8)); - unsafe { vec::push_all_move(v, move ss); } + unsafe { v.push_all_move(move ss); } PosixPath { components: move v, ..self } } pure fn pop() -> PosixPath { let mut cs = copy self.components; if cs.len() != 0 { - unsafe { vec::pop(cs); } + unsafe { cs.pop(); } } return PosixPath { components: move cs, ..self } } @@ -239,11 +239,11 @@ impl WindowsPath : ToStr { fn to_str() -> ~str { let mut s = ~""; match self.host { - Some(h) => { s += "\\\\"; s += h; } + Some(ref h) => { s += "\\\\"; s += *h; } None => { } } match self.device { - Some(d) => { s += d; s += ":"; } + Some(ref d) => { s += *d; s += ":"; } None => { } } if self.is_absolute { @@ -358,7 +358,7 @@ impl WindowsPath : GenericPath { if t.len() == 0 { match self.filestem() { None => copy self, - Some(s) => self.with_filename(s) + Some(ref s) => self.with_filename(*s) } } else { let t = ~"." + str::from_slice(t); @@ -400,7 +400,7 @@ impl WindowsPath : GenericPath { let mut ss = str::split_nonempty( *e, |c| windows::is_sep(c as u8)); - unsafe { vec::push_all_move(v, move ss); } + unsafe { v.push_all_move(move ss); } } return WindowsPath { components: move v, ..self } } @@ -408,14 +408,14 @@ impl WindowsPath : GenericPath { pure fn push(s: &str) -> WindowsPath { let mut v = copy self.components; let mut ss = str::split_nonempty(s, |c| windows::is_sep(c as u8)); - unsafe { vec::push_all_move(v, move ss); } + unsafe { v.push_all_move(move ss); } return WindowsPath { components: move v, ..self } } pure fn pop() -> WindowsPath { let mut cs = copy self.components; if cs.len() != 0 { - unsafe { vec::pop(cs); } + unsafe { cs.pop(); } } return WindowsPath { components: move cs, ..self } } @@ -429,7 +429,7 @@ impl WindowsPath : GenericPath { } -pure fn normalize(components: &[~str]) -> ~[~str] { +pub pure fn normalize(components: &[~str]) -> ~[~str] { let mut cs = ~[]; unsafe { for components.each |c| { @@ -437,10 +437,10 @@ pure fn normalize(components: &[~str]) -> ~[~str] { if *c == ~"." && components.len() > 1 { loop; } if *c == ~"" { loop; } if *c == ~".." && cs.len() != 0 { - vec::pop(cs); + cs.pop(); loop; } - vec::push(cs, copy *c); + cs.push(copy *c); } } } @@ -462,7 +462,6 @@ fn test_double_slash_collapsing() } mod posix { - #[legacy_exports]; #[cfg(test)] fn mk(s: &str) -> PosixPath { from_str::(s) } @@ -553,14 +552,13 @@ mod posix { // Various windows helpers, and tests for the impl. mod windows { - #[legacy_exports]; #[inline(always)] - pure fn is_sep(u: u8) -> bool { + pub pure fn is_sep(u: u8) -> bool { u == '/' as u8 || u == '\\' as u8 } - pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> { + pub pure fn extract_unc_prefix(s: &str) -> Option<(~str,~str)> { if (s.len() > 1 && s[0] == '\\' as u8 && s[1] == '\\' as u8) { @@ -577,7 +575,7 @@ mod windows { None } - pure fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> { + pub pure fn extract_drive_prefix(s: &str) -> Option<(~str,~str)> { unsafe { if (s.len() > 1 && libc::isalpha(s[0] as libc::c_int) != 0 && diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 7321829f6b61..e34c0db35e9d 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -73,7 +73,7 @@ bounded and unbounded protocols allows for less code duplication. */ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; use cmp::Eq; @@ -81,31 +81,11 @@ use cast::{forget, reinterpret_cast, transmute}; use either::{Either, Left, Right}; use option::unwrap; -// Things used by code generated by the pipe compiler. -export entangle, get_buffer, drop_buffer; -export SendPacketBuffered, RecvPacketBuffered; -export Packet, packet, mk_packet, entangle_buffer, HasBuffer, BufferHeader; - -// export these so we can find them in the buffer_resource -// destructor. This is probably a symptom of #3005. -export atomic_add_acq, atomic_sub_rel; - -// User-level things -export SendPacket, RecvPacket, send, recv, try_recv, peek; -export select, select2, selecti, select2i, selectable; -export spawn_service, spawn_service_recv; -export stream, Port, Chan, SharedChan, PortSet, Channel; -export oneshot, ChanOne, PortOne; -export recv_one, try_recv_one, send_one, try_send_one; - -// Functions used by the protocol compiler -export rt; - #[doc(hidden)] const SPIN_COUNT: uint = 0; macro_rules! move_it ( - { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); move y } } + { $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); move y } } ) #[doc(hidden)] @@ -123,7 +103,7 @@ impl State : Eq { pure fn ne(other: &State) -> bool { !self.eq(other) } } -struct BufferHeader { +pub struct BufferHeader { // Tracks whether this buffer needs to be freed. We can probably // get away with restricting it to 0 or 1, if we're careful. mut ref_count: int, @@ -132,7 +112,7 @@ struct BufferHeader { // thing along. } -fn BufferHeader() -> BufferHeader{ +pub fn BufferHeader() -> BufferHeader{ BufferHeader { ref_count: 0 } @@ -195,13 +175,13 @@ impl PacketHeader { } #[doc(hidden)] -type Packet = { +pub type Packet = { header: PacketHeader, mut payload: Option, }; #[doc(hidden)] -trait HasBuffer { +pub trait HasBuffer { // XXX This should not have a trailing underscore fn set_buffer_(b: *libc::c_void); } @@ -213,7 +193,7 @@ impl Packet: HasBuffer { } #[doc(hidden)] -fn mk_packet() -> Packet { +pub fn mk_packet() -> Packet { { header: PacketHeader(), mut payload: None @@ -237,17 +217,17 @@ fn unibuffer() -> ~Buffer> { } #[doc(hidden)] -fn packet() -> *Packet { +pub fn packet() -> *Packet { let b = unibuffer(); - let p = ptr::addr_of(b.data); + let p = ptr::addr_of(&(b.data)); // We'll take over memory management from here. unsafe { forget(move b) } p } #[doc(hidden)] -fn entangle_buffer( - +buffer: ~Buffer, +pub fn entangle_buffer( + buffer: ~Buffer, init: fn(*libc::c_void, x: &T) -> *Packet) -> (SendPacketBuffered, RecvPacketBuffered) { @@ -256,52 +236,36 @@ fn entangle_buffer( (SendPacketBuffered(p), RecvPacketBuffered(p)) } -#[cfg(stage0)] #[abi = "rust-intrinsic"] #[doc(hidden)] extern mod rusti { - #[legacy_exports]; - fn atomic_xchg(dst: &mut int, ++src: int) -> int; - fn atomic_xchg_acq(dst: &mut int, ++src: int) -> int; - fn atomic_xchg_rel(dst: &mut int, ++src: int) -> int; + fn atomic_xchg(dst: &mut int, src: int) -> int; + fn atomic_xchg_acq(dst: &mut int, src: int) -> int; + fn atomic_xchg_rel(dst: &mut int, src: int) -> int; - fn atomic_xadd_acq(dst: &mut int, ++src: int) -> int; - fn atomic_xsub_rel(dst: &mut int, ++src: int) -> int; -} - -#[cfg(stage1)] -#[cfg(stage2)] -#[abi = "rust-intrinsic"] -#[doc(hidden)] -extern mod rusti { - #[legacy_exports]; - fn atomic_xchg(dst: &mut int, +src: int) -> int; - fn atomic_xchg_acq(dst: &mut int, +src: int) -> int; - fn atomic_xchg_rel(dst: &mut int, +src: int) -> int; - - fn atomic_xadd_acq(dst: &mut int, +src: int) -> int; - fn atomic_xsub_rel(dst: &mut int, +src: int) -> int; + fn atomic_xadd_acq(dst: &mut int, src: int) -> int; + fn atomic_xsub_rel(dst: &mut int, src: int) -> int; } // If I call the rusti versions directly from a polymorphic function, // I get link errors. This is a bug that needs investigated more. #[doc(hidden)] -fn atomic_xchng_rel(dst: &mut int, src: int) -> int { +pub fn atomic_xchng_rel(dst: &mut int, src: int) -> int { rusti::atomic_xchg_rel(dst, src) } #[doc(hidden)] -fn atomic_add_acq(dst: &mut int, src: int) -> int { +pub fn atomic_add_acq(dst: &mut int, src: int) -> int { rusti::atomic_xadd_acq(dst, src) } #[doc(hidden)] -fn atomic_sub_rel(dst: &mut int, src: int) -> int { +pub fn atomic_sub_rel(dst: &mut int, src: int) -> int { rusti::atomic_xsub_rel(dst, src) } #[doc(hidden)] -fn swap_task(+dst: &mut *rust_task, src: *rust_task) -> *rust_task { +pub fn swap_task(dst: &mut *rust_task, src: *rust_task) -> *rust_task { // It might be worth making both acquire and release versions of // this. unsafe { @@ -315,7 +279,6 @@ type rust_task = libc::c_void; #[doc(hidden)] extern mod rustrt { - #[legacy_exports]; #[rust_stack] fn rust_get_task() -> *rust_task; #[rust_stack] @@ -341,21 +304,21 @@ fn wait_event(this: *rust_task) -> *libc::c_void { } #[doc(hidden)] -fn swap_state_acq(+dst: &mut State, src: State) -> State { +fn swap_state_acq(dst: &mut State, src: State) -> State { unsafe { transmute(rusti::atomic_xchg_acq(transmute(move dst), src as int)) } } #[doc(hidden)] -fn swap_state_rel(+dst: &mut State, src: State) -> State { +fn swap_state_rel(dst: &mut State, src: State) -> State { unsafe { transmute(rusti::atomic_xchg_rel(transmute(move dst), src as int)) } } #[doc(hidden)] -unsafe fn get_buffer(p: *PacketHeader) -> ~Buffer { +pub unsafe fn get_buffer(p: *PacketHeader) -> ~Buffer { transmute((*p).buf_header()) } @@ -380,7 +343,7 @@ struct BufferResource { } } -fn BufferResource(+b: ~Buffer) -> BufferResource { +fn BufferResource(b: ~Buffer) -> BufferResource { //let p = ptr::addr_of(*b); //error!("take %?", p); atomic_add_acq(&mut b.header.ref_count, 1); @@ -391,12 +354,12 @@ fn BufferResource(+b: ~Buffer) -> BufferResource { } #[doc(hidden)] -fn send(+p: SendPacketBuffered, - +payload: T) -> bool { +pub fn send(p: SendPacketBuffered, + payload: T) -> bool { let header = p.header(); let p_ = p.unwrap(); let p = unsafe { &*p_ }; - assert ptr::addr_of(p.header) == header; + assert ptr::addr_of(&(p.header)) == header; assert p.payload.is_none(); p.payload <- Some(move payload); let old_state = swap_state_rel(&mut p.header.state, Full); @@ -414,7 +377,7 @@ fn send(+p: SendPacketBuffered, let old_task = swap_task(&mut p.header.blocked_task, ptr::null()); if !old_task.is_null() { rustrt::task_signal_event( - old_task, ptr::addr_of(p.header) as *libc::c_void); + old_task, ptr::addr_of(&(p.header)) as *libc::c_void); rustrt::rust_task_deref(old_task); } @@ -435,7 +398,7 @@ fn send(+p: SendPacketBuffered, Fails if the sender closes the connection. */ -fn recv(+p: RecvPacketBuffered) -> T { +pub fn recv(p: RecvPacketBuffered) -> T { option::unwrap_expect(try_recv(move p), "connection closed") } @@ -445,7 +408,7 @@ Returns `none` if the sender has closed the connection without sending a message, or `Some(T)` if a message was received. */ -fn try_recv(+p: RecvPacketBuffered) +pub fn try_recv(p: RecvPacketBuffered) -> Option { let p_ = p.unwrap(); @@ -539,7 +502,7 @@ fn try_recv(+p: RecvPacketBuffered) } /// Returns true if messages are available. -pure fn peek(p: &RecvPacketBuffered) -> bool { +pub pure fn peek(p: &RecvPacketBuffered) -> bool { match unsafe {(*p.header()).state} { Empty => false, Blocked => fail ~"peeking on blocked packet", @@ -566,7 +529,7 @@ fn sender_terminate(p: *Packet) { if !old_task.is_null() { rustrt::task_signal_event( old_task, - ptr::addr_of(p.header) as *libc::c_void); + ptr::addr_of(&(p.header)) as *libc::c_void); rustrt::rust_task_deref(old_task); } // The receiver will eventually clean up. @@ -691,9 +654,9 @@ Sometimes messages will be available on both endpoints at once. In this case, `select2` may return either `left` or `right`. */ -fn select2( - +a: RecvPacketBuffered, - +b: RecvPacketBuffered) +pub fn select2( + a: RecvPacketBuffered, + b: RecvPacketBuffered) -> Either<(Option, RecvPacketBuffered), (RecvPacketBuffered, Option)> { @@ -716,12 +679,13 @@ impl *PacketHeader: Selectable { } /// Returns the index of an endpoint that is ready to receive. -fn selecti(endpoints: &[T]) -> uint { +pub fn selecti(endpoints: &[T]) -> uint { wait_many(endpoints) } /// Returns 0 or 1 depending on which endpoint is ready to receive -fn select2i(a: &A, b: &B) -> Either<(), ()> { +pub fn select2i(a: &A, b: &B) -> + Either<(), ()> { match wait_many([a.header(), b.header()]/_) { 0 => Left(()), 1 => Right(()), @@ -733,12 +697,12 @@ fn select2i(a: &A, b: &B) -> Either<(), ()> { list of the remaining endpoints. */ -fn select(+endpoints: ~[RecvPacketBuffered]) +pub fn select(endpoints: ~[RecvPacketBuffered]) -> (uint, Option, ~[RecvPacketBuffered]) { let ready = wait_many(endpoints.map(|p| p.header())); let mut remaining <- endpoints; - let port = vec::swap_remove(remaining, ready); + let port = remaining.swap_remove(ready); let result = try_recv(move port); (ready, move result, move remaining) } @@ -747,14 +711,14 @@ fn select(+endpoints: ~[RecvPacketBuffered]) message. */ -type SendPacket = SendPacketBuffered>; +pub type SendPacket = SendPacketBuffered>; #[doc(hidden)] -fn SendPacket(p: *Packet) -> SendPacket { +pub fn SendPacket(p: *Packet) -> SendPacket { SendPacketBuffered(p) } -struct SendPacketBuffered { +pub struct SendPacketBuffered { mut p: Option<*Packet>, mut buffer: Option>, drop { @@ -773,14 +737,14 @@ struct SendPacketBuffered { } } -fn SendPacketBuffered(p: *Packet) +pub fn SendPacketBuffered(p: *Packet) -> SendPacketBuffered { //debug!("take send %?", p); SendPacketBuffered { p: Some(p), buffer: unsafe { Some(BufferResource( - get_buffer(ptr::addr_of((*p).header)))) + get_buffer(ptr::addr_of(&((*p).header))))) } } } @@ -796,7 +760,7 @@ impl SendPacketBuffered { match self.p { Some(packet) => unsafe { let packet = &*packet; - let header = ptr::addr_of(packet.header); + let header = ptr::addr_of(&(packet.header)); //forget(packet); header }, @@ -814,14 +778,14 @@ impl SendPacketBuffered { /// Represents the receive end of a pipe. It can receive exactly one /// message. -type RecvPacket = RecvPacketBuffered>; +pub type RecvPacket = RecvPacketBuffered>; #[doc(hidden)] -fn RecvPacket(p: *Packet) -> RecvPacket { +pub fn RecvPacket(p: *Packet) -> RecvPacket { RecvPacketBuffered(p) } -struct RecvPacketBuffered { +pub struct RecvPacketBuffered { mut p: Option<*Packet>, mut buffer: Option>, drop { @@ -851,7 +815,7 @@ impl RecvPacketBuffered : Selectable { match self.p { Some(packet) => unsafe { let packet = &*packet; - let header = ptr::addr_of(packet.header); + let header = ptr::addr_of(&(packet.header)); //forget(packet); header }, @@ -867,20 +831,20 @@ impl RecvPacketBuffered : Selectable { } } -fn RecvPacketBuffered(p: *Packet) +pub fn RecvPacketBuffered(p: *Packet) -> RecvPacketBuffered { //debug!("take recv %?", p); RecvPacketBuffered { p: Some(p), buffer: unsafe { Some(BufferResource( - get_buffer(ptr::addr_of((*p).header)))) + get_buffer(ptr::addr_of(&((*p).header))))) } } } #[doc(hidden)] -fn entangle() -> (SendPacket, RecvPacket) { +pub fn entangle() -> (SendPacket, RecvPacket) { let p = packet(); (SendPacket(p), RecvPacket(p)) } @@ -892,10 +856,10 @@ endpoint. The send endpoint is returned to the caller and the receive endpoint is passed to the new task. */ -fn spawn_service( +pub fn spawn_service( init: extern fn() -> (SendPacketBuffered, RecvPacketBuffered), - +service: fn~(+v: RecvPacketBuffered)) + +service: fn~(v: RecvPacketBuffered)) -> SendPacketBuffered { let (client, server) = init(); @@ -916,10 +880,10 @@ fn spawn_service( receive state. */ -fn spawn_service_recv( +pub fn spawn_service_recv( init: extern fn() -> (RecvPacketBuffered, SendPacketBuffered), - +service: fn~(+v: SendPacketBuffered)) + +service: fn~(v: SendPacketBuffered)) -> RecvPacketBuffered { let (client, server) = init(); @@ -945,19 +909,19 @@ proto! streamp ( ) /// A trait for things that can send multiple messages. -trait Channel { +pub trait Channel { // It'd be nice to call this send, but it'd conflict with the // built in send kind. /// Sends a message. - fn send(+x: T); + fn send(x: T); /// Sends a message, or report if the receiver has closed the connection. - fn try_send(+x: T) -> bool; + fn try_send(x: T) -> bool; } /// A trait for things that can receive multiple messages. -trait Recv { +pub trait Recv { /// Receives a message, or fails if the connection closes. fn recv() -> T; @@ -978,7 +942,7 @@ trait Recv { type Chan_ = { mut endp: Option> }; /// An endpoint that can send many messages. -enum Chan { +pub enum Chan { Chan_(Chan_) } @@ -986,7 +950,7 @@ enum Chan { type Port_ = { mut endp: Option> }; /// An endpoint that can receive many messages. -enum Port { +pub enum Port { Port_(Port_) } @@ -995,21 +959,21 @@ enum Port { These allow sending or receiving an unlimited number of messages. */ -fn stream() -> (Chan, Port) { +pub fn stream() -> (Chan, Port) { let (c, s) = streamp::init(); (Chan_({ mut endp: Some(move c) }), Port_({ mut endp: Some(move s) })) } impl Chan: Channel { - fn send(+x: T) { + fn send(x: T) { let mut endp = None; endp <-> self.endp; self.endp = Some( streamp::client::data(unwrap(move endp), move x)) } - fn try_send(+x: T) -> bool { + fn try_send(x: T) -> bool { let mut endp = None; endp <-> self.endp; match move streamp::client::try_data(unwrap(move endp), move x) { @@ -1047,7 +1011,7 @@ impl Port: Recv { let mut endp = None; endp <-> self.endp; let peek = match endp { - Some(endp) => pipes::peek(&endp), + Some(ref endp) => pipes::peek(endp), None => fail ~"peeking empty stream" }; self.endp <-> endp; @@ -1058,18 +1022,18 @@ impl Port: Recv { impl Port: Selectable { pure fn header() -> *PacketHeader unsafe { match self.endp { - Some(endp) => endp.header(), + Some(ref endp) => endp.header(), None => fail ~"peeking empty stream" } } } /// Treat many ports as one. -struct PortSet { +pub struct PortSet { mut ports: ~[pipes::Port], } -fn PortSet() -> PortSet{ +pub fn PortSet() -> PortSet{ PortSet { ports: ~[] } @@ -1077,8 +1041,8 @@ fn PortSet() -> PortSet{ impl PortSet : Recv { - fn add(+port: pipes::Port) { - vec::push(self.ports, move port) + fn add(port: pipes::Port) { + self.ports.push(move port) } fn chan() -> Chan { @@ -1101,7 +1065,7 @@ impl PortSet : Recv { } None => { // Remove this port. - let _ = vec::swap_remove(ports, i); + let _ = ports.swap_remove(i); } } } @@ -1124,10 +1088,10 @@ impl PortSet : Recv { } /// A channel that can be shared between many senders. -type SharedChan = private::Exclusive>; +pub type SharedChan = private::Exclusive>; impl SharedChan: Channel { - fn send(+x: T) { + fn send(x: T) { let mut xx = Some(move x); do self.with_imm |chan| { let mut x = None; @@ -1136,7 +1100,7 @@ impl SharedChan: Channel { } } - fn try_send(+x: T) -> bool { + fn try_send(x: T) -> bool { let mut xx = Some(move x); do self.with_imm |chan| { let mut x = None; @@ -1147,12 +1111,12 @@ impl SharedChan: Channel { } /// Converts a `chan` into a `shared_chan`. -fn SharedChan(+c: Chan) -> SharedChan { +pub fn SharedChan(c: Chan) -> SharedChan { private::exclusive(move c) } /// Receive a message from one of two endpoints. -trait Select2 { +pub trait Select2 { /// Receive a message or return `none` if a connection closes. fn try_select() -> Either, Option>; /// Receive a message or fail if a connection closes. @@ -1164,7 +1128,7 @@ impl, Right: Selectable Recv> fn select() -> Either { match self { - (lp, rp) => match select2i(&lp, &rp) { + (ref lp, ref rp) => match select2i(lp, rp) { Left(()) => Left (lp.recv()), Right(()) => Right(rp.recv()) } @@ -1173,7 +1137,7 @@ impl, Right: Selectable Recv> fn try_select() -> Either, Option> { match self { - (lp, rp) => match select2i(&lp, &rp) { + (ref lp, ref rp) => match select2i(lp, rp) { Left(()) => Left (lp.try_recv()), Right(()) => Right(rp.try_recv()) } @@ -1188,12 +1152,12 @@ proto! oneshot ( ) /// The send end of a oneshot pipe. -type ChanOne = oneshot::client::Oneshot; +pub type ChanOne = oneshot::client::Oneshot; /// The receive end of a oneshot pipe. -type PortOne = oneshot::server::Oneshot; +pub type PortOne = oneshot::server::Oneshot; /// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair. -fn oneshot() -> (ChanOne, PortOne) { +pub fn oneshot() -> (ChanOne, PortOne) { oneshot::init() } @@ -1201,13 +1165,13 @@ fn oneshot() -> (ChanOne, PortOne) { * Receive a message from a oneshot pipe, failing if the connection was * closed. */ -fn recv_one(+port: PortOne) -> T { +pub fn recv_one(port: PortOne) -> T { let oneshot::send(message) = recv(move port); move message } /// Receive a message from a oneshot pipe unless the connection was closed. -fn try_recv_one (+port: PortOne) -> Option { +pub fn try_recv_one (port: PortOne) -> Option { let message = try_recv(move port); if message.is_none() { None } @@ -1218,7 +1182,7 @@ fn try_recv_one (+port: PortOne) -> Option { } /// Send a message on a oneshot pipe, failing if the connection was closed. -fn send_one(+chan: ChanOne, +data: T) { +pub fn send_one(chan: ChanOne, data: T) { oneshot::client::send(move chan, move data); } @@ -1226,24 +1190,22 @@ fn send_one(+chan: ChanOne, +data: T) { * Send a message on a oneshot pipe, or return false if the connection was * closed. */ -fn try_send_one(+chan: ChanOne, +data: T) +pub fn try_send_one(chan: ChanOne, data: T) -> bool { oneshot::client::try_send(move chan, move data).is_some() } -mod rt { - #[legacy_exports]; +pub mod rt { // These are used to hide the option constructors from the // compiler because their names are changing - fn make_some(+val: T) -> Option { Some(move val) } - fn make_none() -> Option { None } + pub fn make_some(val: T) -> Option { Some(move val) } + pub fn make_none() -> Option { None } } #[cfg(test)] -mod test { - #[legacy_exports]; +pub mod test { #[test] - fn test_select2() { + pub fn test_select2() { let (c1, p1) = pipes::stream(); let (c2, p2) = pipes::stream(); @@ -1258,7 +1220,7 @@ mod test { } #[test] - fn test_oneshot() { + pub fn test_oneshot() { let (c, p) = oneshot::init(); oneshot::client::send(c, ()); diff --git a/src/libcore/private.rs b/src/libcore/private.rs index 777aea7320c6..c1b2b32edafc 100644 --- a/src/libcore/private.rs +++ b/src/libcore/private.rs @@ -1,16 +1,9 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; #[doc(hidden)]; -export chan_from_global_ptr, weaken_task; - -export SharedMutableState, shared_mutable_state, clone_shared_mutable_state; -export get_shared_mutable_state, get_shared_immutable_state; -export unwrap_shared_mutable_state; -export Exclusive, exclusive, unwrap_exclusive; - use compare_and_swap = rustrt::rust_compare_and_swap_ptr; use task::TaskBuilder; use task::atomically; @@ -49,7 +42,7 @@ type GlobalPtr = *libc::uintptr_t; * or, if no channel exists creates and installs a new channel and sets up a * new task to receive from it. */ -unsafe fn chan_from_global_ptr( +pub unsafe fn chan_from_global_ptr( global: GlobalPtr, task_fn: fn() -> task::TaskBuilder, +f: fn~(comm::Port) @@ -110,13 +103,13 @@ unsafe fn chan_from_global_ptr( } #[test] -fn test_from_global_chan1() { +pub fn test_from_global_chan1() { // This is unreadable, right? // The global channel - let globchan = 0u; - let globchanp = ptr::addr_of(globchan); + let globchan = 0; + let globchanp = ptr::p2::addr_of(&globchan); // Create the global channel, attached to a new task let ch = unsafe { @@ -147,25 +140,25 @@ fn test_from_global_chan1() { } #[test] -fn test_from_global_chan2() { +pub fn test_from_global_chan2() { - for iter::repeat(100u) { + for iter::repeat(100) { // The global channel - let globchan = 0u; - let globchanp = ptr::addr_of(globchan); + let globchan = 0; + let globchanp = ptr::p2::addr_of(&globchan); let resultpo = comm::Port(); let resultch = comm::Chan(resultpo); // Spawn a bunch of tasks that all want to compete to // create the global channel - for uint::range(0u, 10u) |i| { + for uint::range(0, 10) |i| { do task::spawn { let ch = unsafe { do chan_from_global_ptr( globchanp, task::task) |po| { - for uint::range(0u, 10u) |_j| { + for uint::range(0, 10) |_j| { let ch = comm::recv(po); comm::send(ch, {i}); } @@ -208,7 +201,7 @@ fn test_from_global_chan2() { * * Weak tasks must not be supervised. A supervised task keeps * a reference to its parent, so the parent will not die. */ -unsafe fn weaken_task(f: fn(comm::Port<()>)) { +pub unsafe fn weaken_task(f: fn(comm::Port<()>)) { let po = comm::Port(); let ch = comm::Chan(po); unsafe { @@ -232,7 +225,7 @@ unsafe fn weaken_task(f: fn(comm::Port<()>)) { } #[test] -fn test_weaken_task_then_unweaken() { +pub fn test_weaken_task_then_unweaken() { do task::try { unsafe { do weaken_task |_po| { @@ -242,7 +235,7 @@ fn test_weaken_task_then_unweaken() { } #[test] -fn test_weaken_task_wait() { +pub fn test_weaken_task_wait() { do task::spawn_unlinked { unsafe { do weaken_task |po| { @@ -253,7 +246,7 @@ fn test_weaken_task_wait() { } #[test] -fn test_weaken_task_stress() { +pub fn test_weaken_task_stress() { // Create a bunch of weak tasks for iter::repeat(100u) { do task::spawn { @@ -275,7 +268,7 @@ fn test_weaken_task_stress() { #[test] #[ignore(cfg(windows))] -fn test_weaken_task_fail() { +pub fn test_weaken_task_fail() { let res = do task::try { unsafe { do weaken_task |_po| { @@ -283,7 +276,7 @@ fn test_weaken_task_fail() { } } }; - assert result::is_err(res); + assert result::is_err(&res); } /**************************************************************************** @@ -347,7 +340,7 @@ fn ArcDestruct(data: *libc::c_void) -> ArcDestruct { } } -unsafe fn unwrap_shared_mutable_state(+rc: SharedMutableState) +pub unsafe fn unwrap_shared_mutable_state(rc: SharedMutableState) -> T { struct DeathThroes { mut ptr: Option<~ArcData>, @@ -418,9 +411,10 @@ unsafe fn unwrap_shared_mutable_state(+rc: SharedMutableState) * Data races between tasks can result in crashes and, with sufficient * cleverness, arbitrary type coercion. */ -type SharedMutableState = ArcDestruct; +pub type SharedMutableState = ArcDestruct; -unsafe fn shared_mutable_state(+data: T) -> SharedMutableState { +pub unsafe fn shared_mutable_state(data: T) -> + SharedMutableState { let data = ~ArcData { count: 1, unwrapper: 0, data: Some(move data) }; unsafe { let ptr = cast::transmute(move data); @@ -429,7 +423,7 @@ unsafe fn shared_mutable_state(+data: T) -> SharedMutableState { } #[inline(always)] -unsafe fn get_shared_mutable_state(rc: &a/SharedMutableState) +pub unsafe fn get_shared_mutable_state(rc: &a/SharedMutableState) -> &a/mut T { unsafe { let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); @@ -441,8 +435,8 @@ unsafe fn get_shared_mutable_state(rc: &a/SharedMutableState) } } #[inline(always)] -unsafe fn get_shared_immutable_state(rc: &a/SharedMutableState) - -> &a/T { +pub unsafe fn get_shared_immutable_state( + rc: &a/SharedMutableState) -> &a/T { unsafe { let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); assert ptr.count > 0; @@ -453,7 +447,7 @@ unsafe fn get_shared_immutable_state(rc: &a/SharedMutableState) } } -unsafe fn clone_shared_mutable_state(rc: &SharedMutableState) +pub unsafe fn clone_shared_mutable_state(rc: &SharedMutableState) -> SharedMutableState { unsafe { let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); @@ -506,9 +500,9 @@ struct ExData { lock: LittleLock, mut failed: bool, mut data: T, } /** * An arc over mutable data that is protected by a lock. For library use only. */ -struct Exclusive { x: SharedMutableState> } +pub struct Exclusive { x: SharedMutableState> } -fn exclusive(+user_data: T) -> Exclusive { +pub fn exclusive(user_data: T) -> Exclusive { let data = ExData { lock: LittleLock(), mut failed: false, mut data: user_data }; @@ -550,7 +544,7 @@ impl Exclusive { } // FIXME(#2585) make this a by-move method on the exclusive -fn unwrap_exclusive(+arc: Exclusive) -> T { +pub fn unwrap_exclusive(arc: Exclusive) -> T { let Exclusive { x: x } <- arc; let inner = unsafe { unwrap_shared_mutable_state(move x) }; let ExData { data: data, _ } <- inner; @@ -558,11 +552,9 @@ fn unwrap_exclusive(+arc: Exclusive) -> T { } #[cfg(test)] -mod tests { - #[legacy_exports]; - +pub mod tests { #[test] - fn exclusive_arc() { + pub fn exclusive_arc() { let mut futures = ~[]; let num_tasks = 10u; @@ -572,7 +564,7 @@ mod tests { for uint::range(0u, num_tasks) |_i| { let total = total.clone(); - vec::push(futures, future::spawn(|| { + futures.push(future::spawn(|| { for uint::range(0u, count) |_i| { do total.with |count| { **count += 1u; @@ -589,7 +581,7 @@ mod tests { } #[test] #[should_fail] #[ignore(cfg(windows))] - fn exclusive_poison() { + pub fn exclusive_poison() { // Tests that if one task fails inside of an exclusive, subsequent // accesses will also fail. let x = exclusive(1); @@ -605,13 +597,13 @@ mod tests { } #[test] - fn exclusive_unwrap_basic() { + pub fn exclusive_unwrap_basic() { let x = exclusive(~~"hello"); assert unwrap_exclusive(x) == ~~"hello"; } #[test] - fn exclusive_unwrap_contended() { + pub fn exclusive_unwrap_contended() { let x = exclusive(~~"hello"); let x2 = ~mut Some(x.clone()); do task::spawn { @@ -636,7 +628,7 @@ mod tests { } #[test] #[should_fail] #[ignore(cfg(windows))] - fn exclusive_unwrap_conflict() { + pub fn exclusive_unwrap_conflict() { let x = exclusive(~~"hello"); let x2 = ~mut Some(x.clone()); let mut res = None; @@ -650,7 +642,7 @@ mod tests { } #[test] #[ignore(cfg(windows))] - fn exclusive_unwrap_deadlock() { + pub fn exclusive_unwrap_deadlock() { // This is not guaranteed to get to the deadlock before being killed, // but it will show up sometimes, and if the deadlock were not there, // the test would nondeterministically fail. diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 7a31f42d8c4f..fad7eddd2d8d 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1,33 +1,11 @@ //! Unsafe pointer utility functions -export addr_of; -export to_unsafe_ptr; -export to_const_unsafe_ptr; -export to_mut_unsafe_ptr; -export mut_addr_of; -export offset; -export const_offset; -export mut_offset; -export null; -export mut_null; -export is_null; -export is_not_null; -export memcpy; -export memmove; -export memset; -export to_uint; -export ref_eq; -export buf_len; -export position; -export Ptr; - use cmp::{Eq, Ord}; use libc::{c_void, size_t}; #[nolink] #[abi = "cdecl"] extern mod libc_ { - #[legacy_exports]; #[rust_stack] fn memcpy(dest: *mut c_void, src: *const c_void, n: libc::size_t) -> *c_void; @@ -43,25 +21,30 @@ extern mod libc_ { #[abi = "rust-intrinsic"] extern mod rusti { - #[legacy_exports]; - fn addr_of(val: T) -> *T; + fn addr_of(&&val: T) -> *T; } /// Get an unsafe pointer to a value #[inline(always)] -pure fn addr_of(val: T) -> *T { unsafe { rusti::addr_of(val) } } +pub pure fn addr_of(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(val: &T) -> *T { unsafe { rusti::addr_of(*val) } } +} /// Get an unsafe mut pointer to a value #[inline(always)] -pure fn mut_addr_of(val: T) -> *mut T { +pub pure fn mut_addr_of(val: &T) -> *mut T { unsafe { - cast::reinterpret_cast(&rusti::addr_of(val)) + cast::reinterpret_cast(&rusti::addr_of(*val)) } } /// Calculate the offset from a pointer #[inline(always)] -fn offset(ptr: *T, count: uint) -> *T { +pub pure fn offset(ptr: *T, count: uint) -> *T { unsafe { (ptr as uint + count * sys::size_of::()) as *T } @@ -69,7 +52,7 @@ fn offset(ptr: *T, count: uint) -> *T { /// Calculate the offset from a const pointer #[inline(always)] -fn const_offset(ptr: *const T, count: uint) -> *const T { +pub pure fn const_offset(ptr: *const T, count: uint) -> *const T { unsafe { (ptr as uint + count * sys::size_of::()) as *T } @@ -77,39 +60,39 @@ fn const_offset(ptr: *const T, count: uint) -> *const T { /// Calculate the offset from a mut pointer #[inline(always)] -fn mut_offset(ptr: *mut T, count: uint) -> *mut T { +pub pure fn mut_offset(ptr: *mut T, count: uint) -> *mut T { (ptr as uint + count * sys::size_of::()) as *mut T } /// Return the offset of the first null pointer in `buf`. #[inline(always)] -unsafe fn buf_len(buf: **T) -> uint { - position(buf, |i| i == null()) +pub unsafe fn buf_len(buf: **T) -> uint { + position(buf, |i| *i == null()) } /// Return the first offset `i` such that `f(buf[i]) == true`. #[inline(always)] -unsafe fn position(buf: *T, f: fn(T) -> bool) -> uint { - let mut i = 0u; +pub unsafe fn position(buf: *T, f: fn(&T) -> bool) -> uint { + let mut i = 0; loop { - if f(*offset(buf, i)) { return i; } - else { i += 1u; } + if f(&(*offset(buf, i))) { return i; } + else { i += 1; } } } /// Create an unsafe null pointer #[inline(always)] -pure fn null() -> *T { unsafe { cast::reinterpret_cast(&0u) } } +pub pure fn null() -> *T { unsafe { cast::reinterpret_cast(&0u) } } /// Create an unsafe mutable null pointer #[inline(always)] -pure fn mut_null() -> *mut T { unsafe { cast::reinterpret_cast(&0u) } } +pub pure fn mut_null() -> *mut T { unsafe { cast::reinterpret_cast(&0u) } } /// Returns true if the pointer is equal to the null pointer. -pure fn is_null(ptr: *const T) -> bool { ptr == null() } +pub pure fn is_null(ptr: *const T) -> bool { ptr == null() } /// Returns true if the pointer is not equal to the null pointer. -pure fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } +pub pure fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } /** * Copies data from one location to another @@ -118,7 +101,7 @@ pure fn is_not_null(ptr: *const T) -> bool { !is_null(ptr) } * and destination may not overlap. */ #[inline(always)] -unsafe fn memcpy(dst: *mut T, src: *const T, count: uint) { +pub unsafe fn memcpy(dst: *mut T, src: *const T, count: uint) { let n = count * sys::size_of::(); libc_::memcpy(dst as *mut c_void, src as *c_void, n as size_t); } @@ -130,13 +113,13 @@ unsafe fn memcpy(dst: *mut T, src: *const T, count: uint) { * and destination may overlap. */ #[inline(always)] -unsafe fn memmove(dst: *mut T, src: *const T, count: uint) { +pub unsafe fn memmove(dst: *mut T, src: *const T, count: uint) { let n = count * sys::size_of::(); libc_::memmove(dst as *mut c_void, src as *c_void, n as size_t); } #[inline(always)] -unsafe fn memset(dst: *mut T, c: int, count: uint) { +pub unsafe fn memset(dst: *mut T, c: int, count: uint) { let n = count * sys::size_of::(); libc_::memset(dst as *mut c_void, c as libc::c_int, n as size_t); } @@ -148,7 +131,7 @@ unsafe fn memset(dst: *mut T, c: int, count: uint) { reinterpret_cast. */ #[inline(always)] -fn to_unsafe_ptr(thing: &T) -> *T { +pub pure fn to_unsafe_ptr(thing: &T) -> *T { unsafe { cast::reinterpret_cast(&thing) } } @@ -158,7 +141,7 @@ fn to_unsafe_ptr(thing: &T) -> *T { reinterpret_cast. */ #[inline(always)] -fn to_const_unsafe_ptr(thing: &const T) -> *const T { +pub pure fn to_const_unsafe_ptr(thing: &const T) -> *const T { unsafe { cast::reinterpret_cast(&thing) } } @@ -168,7 +151,7 @@ fn to_const_unsafe_ptr(thing: &const T) -> *const T { reinterpret_cast. */ #[inline(always)] -fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { +pub pure fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { unsafe { cast::reinterpret_cast(&thing) } } @@ -180,28 +163,35 @@ fn to_mut_unsafe_ptr(thing: &mut T) -> *mut T { (I couldn't think of a cutesy name for this one.) */ #[inline(always)] -fn to_uint(thing: &T) -> uint unsafe { +pub fn to_uint(thing: &T) -> uint unsafe { cast::reinterpret_cast(&thing) } /// Determine if two borrowed pointers point to the same thing. #[inline(always)] -fn ref_eq(thing: &a/T, other: &b/T) -> bool { +pub fn ref_eq(thing: &a/T, other: &b/T) -> bool { to_uint(thing) == to_uint(other) } -trait Ptr { +pub trait Ptr { pure fn is_null() -> bool; pure fn is_not_null() -> bool; + pure fn offset(count: uint) -> self; } /// Extension methods for pointers -impl *T: Ptr { +impl *T: Ptr { /// Returns true if the pointer is equal to the null pointer. + #[inline(always)] pure fn is_null() -> bool { is_null(self) } /// Returns true if the pointer is not equal to the null pointer. + #[inline(always)] pure fn is_not_null() -> bool { is_not_null(self) } + + /// Calculates the offset from a pointer. + #[inline(always)] + pure fn offset(count: uint) -> *T { offset(self, count) } } // Equality for pointers @@ -253,11 +243,11 @@ impl &const T : Ord { } #[test] -fn test() { +pub fn test() { unsafe { type Pair = {mut fst: int, mut snd: int}; let p = {mut fst: 10, mut snd: 20}; - let pptr: *mut Pair = mut_addr_of(p); + let pptr: *mut Pair = mut_addr_of(&p); let iptr: *mut int = cast::reinterpret_cast(&pptr); assert (*iptr == 10);; *iptr = 30; @@ -285,20 +275,20 @@ fn test() { } #[test] -fn test_position() { +pub fn test_position() { use str::as_c_str; use libc::c_char; let s = ~"hello"; unsafe { - assert 2u == as_c_str(s, |p| position(p, |c| c == 'l' as c_char)); - assert 4u == as_c_str(s, |p| position(p, |c| c == 'o' as c_char)); - assert 5u == as_c_str(s, |p| position(p, |c| c == 0 as c_char)); + assert 2u == as_c_str(s, |p| position(p, |c| *c == 'l' as c_char)); + assert 4u == as_c_str(s, |p| position(p, |c| *c == 'o' as c_char)); + assert 5u == as_c_str(s, |p| position(p, |c| *c == 0 as c_char)); } } #[test] -fn test_buf_len() { +pub fn test_buf_len() { let s0 = ~"hello"; let s1 = ~"there"; let s2 = ~"thing"; @@ -316,7 +306,7 @@ fn test_buf_len() { } #[test] -fn test_is_null() { +pub fn test_is_null() { let p: *int = ptr::null(); assert p.is_null(); assert !p.is_not_null(); diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 1b9aba6e391e..32f77a533a67 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -1,29 +1,29 @@ //! Random number generation -export Rng, seed, seeded_rng, Weighted, extensions; -export xorshift, seeded_xorshift; +// NB: transitional, de-mode-ing. +#[warn(deprecated_mode)]; +#[forbid(deprecated_pattern)]; #[allow(non_camel_case_types)] // runtime type enum rctx {} #[abi = "cdecl"] extern mod rustrt { - #[legacy_exports]; fn rand_seed() -> ~[u8]; fn rand_new() -> *rctx; - fn rand_new_seeded(seed: ~[u8]) -> *rctx; + fn rand_new_seeded2(&&seed: ~[u8]) -> *rctx; fn rand_next(c: *rctx) -> u32; fn rand_free(c: *rctx); } /// A random number generator -trait Rng { +pub trait Rng { /// Return the next random integer fn next() -> u32; } /// A value with a particular weight compared to other values -type Weighted = { weight: uint, item: T }; +pub type Weighted = { weight: uint, item: T }; /// Extension methods for random number generators impl Rng { @@ -123,7 +123,7 @@ impl Rng { /** * Return a char randomly chosen from chars, failing if chars is empty */ - fn gen_char_from(chars: ~str) -> char { + fn gen_char_from(chars: &str) -> char { assert !chars.is_empty(); self.choose(str::chars(chars)) } @@ -218,7 +218,7 @@ impl Rng { let mut r = ~[]; for v.each |item| { for uint::range(0u, item.weight) |_i| { - vec::push(r, item.item); + r.push(item.item); } } move r @@ -260,12 +260,12 @@ impl @RandRes: Rng { } /// Create a new random seed for seeded_rng -fn seed() -> ~[u8] { +pub fn seed() -> ~[u8] { rustrt::rand_seed() } /// Create a random number generator with a system specified seed -fn Rng() -> Rng { +pub fn Rng() -> Rng { @RandRes(rustrt::rand_new()) as Rng } @@ -275,8 +275,8 @@ fn Rng() -> Rng { * all other generators constructed with the same seed. The seed may be any * length. */ -fn seeded_rng(seed: ~[u8]) -> Rng { - @RandRes(rustrt::rand_new_seeded(seed)) as Rng +pub fn seeded_rng(seed: &~[u8]) -> Rng { + @RandRes(rustrt::rand_new_seeded2(*seed)) as Rng } type XorShiftState = { @@ -299,40 +299,72 @@ impl XorShiftState: Rng { } } -fn xorshift() -> Rng { +pub fn xorshift() -> Rng { // constants taken from http://en.wikipedia.org/wiki/Xorshift seeded_xorshift(123456789u32, 362436069u32, 521288629u32, 88675123u32) } -fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng { +pub fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng { {mut x: x, mut y: y, mut z: z, mut w: w} as Rng } -#[cfg(test)] -mod tests { - #[legacy_exports]; +// used to make space in TLS for a random number generator +fn tls_rng_state(+_v: @RandRes) {} + +/** + * Gives back a lazily initialized task-local random number generator, + * seeded by the system. Intended to be used in method chaining style, ie + * task_rng().gen_int(). + */ +pub fn task_rng() -> Rng { + let r : Option<@RandRes>; + unsafe { + r = task::local_data::local_data_get(tls_rng_state); + } + match r { + None => { + let rng = @RandRes(rustrt::rand_new()); + unsafe { + task::local_data::local_data_set(tls_rng_state, rng); + } + rng as Rng + } + Some(rng) => rng as Rng + } +} + +/** + * Returns a random uint, using the task's based random number generator. + */ +pub fn random() -> uint { + task_rng().gen_uint() +} + + +#[cfg(test)] +pub mod tests { #[test] - fn rng_seeded() { + pub fn rng_seeded() { let seed = rand::seed(); - let ra = rand::seeded_rng(seed); - let rb = rand::seeded_rng(seed); + let ra = rand::seeded_rng(&seed); + let rb = rand::seeded_rng(&seed); assert ra.gen_str(100u) == rb.gen_str(100u); } #[test] - fn rng_seeded_custom_seed() { + pub fn rng_seeded_custom_seed() { // much shorter than generated seeds which are 1024 bytes let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8]; - let ra = rand::seeded_rng(seed); - let rb = rand::seeded_rng(seed); + let ra = rand::seeded_rng(&seed); + let rb = rand::seeded_rng(&seed); assert ra.gen_str(100u) == rb.gen_str(100u); } #[test] - fn rng_seeded_custom_seed2() { + pub fn rng_seeded_custom_seed2() { let seed = ~[2u8, 32u8, 4u8, 32u8, 51u8]; - let ra = rand::seeded_rng(seed); + let ra = rand::seeded_rng(&seed); // Regression test that isaac is actually using the above vector let r = ra.next(); error!("%?", r); @@ -341,7 +373,7 @@ mod tests { } #[test] - fn gen_int_range() { + pub fn gen_int_range() { let r = rand::Rng(); let a = r.gen_int_range(-3, 42); assert a >= -3 && a < 42; @@ -352,12 +384,12 @@ mod tests { #[test] #[should_fail] #[ignore(cfg(windows))] - fn gen_int_from_fail() { + pub fn gen_int_from_fail() { rand::Rng().gen_int_range(5, -2); } #[test] - fn gen_uint_range() { + pub fn gen_uint_range() { let r = rand::Rng(); let a = r.gen_uint_range(3u, 42u); assert a >= 3u && a < 42u; @@ -368,12 +400,12 @@ mod tests { #[test] #[should_fail] #[ignore(cfg(windows))] - fn gen_uint_range_fail() { + pub fn gen_uint_range_fail() { rand::Rng().gen_uint_range(5u, 2u); } #[test] - fn gen_float() { + pub fn gen_float() { let r = rand::Rng(); let a = r.gen_float(); let b = r.gen_float(); @@ -381,14 +413,14 @@ mod tests { } #[test] - fn gen_weighted_bool() { + pub fn gen_weighted_bool() { let r = rand::Rng(); assert r.gen_weighted_bool(0u) == true; assert r.gen_weighted_bool(1u) == true; } #[test] - fn gen_str() { + pub fn gen_str() { let r = rand::Rng(); log(debug, r.gen_str(10u)); log(debug, r.gen_str(10u)); @@ -399,7 +431,7 @@ mod tests { } #[test] - fn gen_bytes() { + pub fn gen_bytes() { let r = rand::Rng(); assert r.gen_bytes(0u).len() == 0u; assert r.gen_bytes(10u).len() == 10u; @@ -407,13 +439,13 @@ mod tests { } #[test] - fn choose() { + pub fn choose() { let r = rand::Rng(); assert r.choose([1, 1, 1]) == 1; } #[test] - fn choose_option() { + pub fn choose_option() { let r = rand::Rng(); let x: Option = r.choose_option([]); assert x.is_none(); @@ -421,7 +453,7 @@ mod tests { } #[test] - fn choose_weighted() { + pub fn choose_weighted() { let r = rand::Rng(); assert r.choose_weighted(~[{weight: 1u, item: 42}]) == 42; assert r.choose_weighted(~[ @@ -431,7 +463,7 @@ mod tests { } #[test] - fn choose_weighted_option() { + pub fn choose_weighted_option() { let r = rand::Rng(); assert r.choose_weighted_option(~[{weight: 1u, item: 42}]) == Some(42); @@ -444,7 +476,7 @@ mod tests { } #[test] - fn weighted_vec() { + pub fn weighted_vec() { let r = rand::Rng(); let empty: ~[int] = ~[]; assert r.weighted_vec(~[]) == empty; @@ -456,12 +488,26 @@ mod tests { } #[test] - fn shuffle() { + pub fn shuffle() { let r = rand::Rng(); let empty: ~[int] = ~[]; assert r.shuffle(~[]) == empty; assert r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]; } + + #[test] + pub fn task_rng() { + let r = rand::task_rng(); + r.gen_int(); + assert r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]; + assert r.gen_uint_range(0u, 1u) == 0u; + } + + #[test] + pub fn random() { + // not sure how to test this aside from just getting a number + let _n : uint = rand::random(); + } } diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs index b7c718b3420b..41006e1dfb5e 100644 --- a/src/libcore/reflect.rs +++ b/src/libcore/reflect.rs @@ -13,7 +13,7 @@ use libc::c_void; * data structure, and implement both `MovePtr` for it as well as `TyVisitor`; * then build a MovePtrAdaptor wrapped around your struct. */ -trait MovePtr { +pub trait MovePtr { fn move_ptr(adjustment: fn(*c_void) -> *c_void); } @@ -27,7 +27,7 @@ fn align(size: uint, align: uint) -> uint { struct MovePtrAdaptor { inner: V } -pub fn MovePtrAdaptor(+v: V) -> MovePtrAdaptor { +pub fn MovePtrAdaptor(v: V) -> MovePtrAdaptor { MovePtrAdaptor { inner: move v } } diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index 30b43dd7f849..ff82ed3fb419 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -13,7 +13,8 @@ use cast::transmute; use intrinsic::{TyDesc, TyVisitor, visit_tydesc}; use reflect::{MovePtr, MovePtrAdaptor}; use vec::raw::{VecRepr, UnboxedVecRepr, SliceRepr}; -use box::raw::{BoxRepr, BoxHeaderRepr}; +pub use box::raw::BoxRepr; +use box::raw::BoxHeaderRepr; /// Helpers diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 205d375e9db8..e61690d5b2c0 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1,10 +1,14 @@ //! A type representing either success or failure +// NB: transitionary, de-mode-ing. +// tjc: re-forbid deprecated modes after snapshot +#[forbid(deprecated_pattern)]; + use cmp::Eq; use either::Either; /// The result type -enum Result { +pub enum Result { /// Contains the successful result value Ok(T), /// Contains the error value @@ -18,11 +22,11 @@ enum Result { * * If the result is an error */ -pure fn get(res: Result) -> T { - match res { - Ok(t) => t, - Err(the_err) => unsafe { - fail fmt!("get called on error result: %?", the_err) +pub pure fn get(res: &Result) -> T { + match *res { + Ok(copy t) => t, + Err(ref the_err) => unsafe { + fail fmt!("get called on error result: %?", *the_err) } } } @@ -34,11 +38,11 @@ pure fn get(res: Result) -> T { * * If the result is an error */ -pure fn get_ref(res: &a/Result) -> &a/T { +pub pure fn get_ref(res: &a/Result) -> &a/T { match *res { Ok(ref t) => t, Err(ref the_err) => unsafe { - fail fmt!("get_ref called on error result: %?", the_err) + fail fmt!("get_ref called on error result: %?", *the_err) } } } @@ -50,23 +54,23 @@ pure fn get_ref(res: &a/Result) -> &a/T { * * If the result is not an error */ -pure fn get_err(res: Result) -> U { - match res { - Err(u) => u, +pub pure fn get_err(res: &Result) -> U { + match *res { + Err(copy u) => u, Ok(_) => fail ~"get_err called on ok result" } } /// Returns true if the result is `ok` -pure fn is_ok(res: Result) -> bool { - match res { +pub pure fn is_ok(res: &Result) -> bool { + match *res { Ok(_) => true, Err(_) => false } } /// Returns true if the result is `err` -pure fn is_err(res: Result) -> bool { +pub pure fn is_err(res: &Result) -> bool { !is_ok(res) } @@ -76,10 +80,11 @@ pure fn is_err(res: Result) -> bool { * `ok` result variants are converted to `either::right` variants, `err` * result variants are converted to `either::left`. */ -pure fn to_either(res: Result) -> Either { - match res { - Ok(res) => either::Right(res), - Err(fail_) => either::Left(fail_) +pub pure fn to_either(res: &Result) + -> Either { + match *res { + Ok(copy res) => either::Right(res), + Err(copy fail_) => either::Left(fail_) } } @@ -97,11 +102,13 @@ pure fn to_either(res: Result) -> Either { * ok(parse_bytes(buf)) * } */ -fn chain(res: Result, op: fn(T) -> Result) - -> Result { - match res { - Ok(t) => op(t), - Err(e) => Err(e) +pub fn chain(res: Result, op: fn(t: T) + -> Result) -> Result { + // XXX: Should be writable with move + match + if res.is_ok() { + op(unwrap(res)) + } else { + Err(unwrap_err(res)) } } @@ -113,13 +120,13 @@ fn chain(res: Result, op: fn(T) -> Result) * immediately returned. This function can be used to pass through a * successful result while handling an error. */ -fn chain_err( +pub fn chain_err( res: Result, - op: fn(V) -> Result) + op: fn(t: V) -> Result) -> Result { - match res { - Ok(t) => Ok(t), - Err(v) => op(v) + match move res { + Ok(move t) => Ok(t), + Err(move v) => op(v) } } @@ -137,9 +144,9 @@ fn chain_err( * print_buf(buf) * } */ -fn iter(res: Result, f: fn(T)) { - match res { - Ok(t) => f(t), +pub fn iter(res: &Result, f: fn((&T))) { + match *res { + Ok(ref t) => f(t), Err(_) => () } } @@ -152,10 +159,10 @@ fn iter(res: Result, f: fn(T)) { * This function can be used to pass through a successful result while * handling an error. */ -fn iter_err(res: Result, f: fn(E)) { - match res { +pub fn iter_err(res: &Result, f: fn((&E))) { + match *res { Ok(_) => (), - Err(e) => f(e) + Err(ref e) => f(e) } } @@ -173,11 +180,11 @@ fn iter_err(res: Result, f: fn(E)) { * parse_bytes(buf) * } */ -fn map(res: Result, op: fn(T) -> U) +pub fn map(res: &Result, op: fn((&T)) -> U) -> Result { - match res { - Ok(t) => Ok(op(t)), - Err(e) => Err(e) + match *res { + Ok(ref t) => Ok(op(t)), + Err(copy e) => Err(e) } } @@ -189,63 +196,65 @@ fn map(res: Result, op: fn(T) -> U) * is immediately returned. This function can be used to pass through a * successful result while handling an error. */ -fn map_err(res: Result, op: fn(E) -> F) +pub fn map_err(res: &Result, op: fn((&E)) -> F) -> Result { - match res { - Ok(t) => Ok(t), - Err(e) => Err(op(e)) + match *res { + Ok(copy t) => Ok(t), + Err(ref e) => Err(op(e)) } } impl Result { - fn is_ok() -> bool { is_ok(self) } + fn is_ok() -> bool { is_ok(&self) } - fn is_err() -> bool { is_err(self) } + fn is_err() -> bool { is_err(&self) } - fn iter(f: fn(T)) { + fn iter(f: fn((&T))) { match self { - Ok(t) => f(t), + Ok(ref t) => f(t), Err(_) => () } } - fn iter_err(f: fn(E)) { + fn iter_err(f: fn((&E))) { match self { Ok(_) => (), - Err(e) => f(e) + Err(ref e) => f(e) } } } impl Result { - fn get() -> T { get(self) } + fn get() -> T { get(&self) } - fn map_err(op: fn(E) -> F) -> Result { + fn map_err(op: fn((&E)) -> F) -> Result { match self { - Ok(t) => Ok(t), - Err(e) => Err(op(e)) + Ok(copy t) => Ok(t), + Err(ref e) => Err(op(e)) } } } impl Result { - fn get_err() -> E { get_err(self) } + fn get_err() -> E { get_err(&self) } - fn map(op: fn(T) -> U) -> Result { + fn map(op: fn((&T)) -> U) -> Result { match self { - Ok(t) => Ok(op(t)), - Err(e) => Err(e) + Ok(ref t) => Ok(op(t)), + Err(copy e) => Err(e) } } } impl Result { - fn chain(op: fn(T) -> Result) -> Result { - chain(self, op) + fn chain(op: fn(t: T) -> Result) -> Result { + // XXX: Bad copy + chain(copy self, op) } - fn chain_err(op: fn(E) -> Result) -> Result { - chain_err(self, op) + fn chain_err(op: fn(t: E) -> Result) -> Result { + // XXX: Bad copy + chain_err(copy self, op) } } @@ -266,27 +275,27 @@ impl Result { * assert incd == ~[2u, 3u, 4u]; * } */ -fn map_vec( +pub fn map_vec( ts: &[T], op: fn((&T)) -> Result) -> Result<~[V],U> { let mut vs: ~[V] = vec::with_capacity(vec::len(ts)); for vec::each(ts) |t| { match op(t) { - Ok(v) => vec::push(vs, v), - Err(u) => return Err(u) + Ok(copy v) => vs.push(v), + Err(copy u) => return Err(u) } } return Ok(move vs); } -fn map_opt( - o_t: Option, op: fn(T) -> Result) -> Result,U> { +pub fn map_opt( + o_t: &Option, op: fn((&T)) -> Result) -> Result,U> { - match o_t { + match *o_t { None => Ok(None), - Some(t) => match op(t) { - Ok(v) => Ok(Some(v)), - Err(e) => Err(e) + Some(ref t) => match op(t) { + Ok(copy v) => Ok(Some(v)), + Err(copy e) => Err(e) } } } @@ -300,17 +309,17 @@ fn map_opt( * used in 'careful' code contexts where it is both appropriate and easy * to accommodate an error like the vectors being of different lengths. */ -fn map_vec2(ss: &[S], ts: &[T], - op: fn(S,T) -> Result) -> Result<~[V],U> { +pub fn map_vec2(ss: &[S], ts: &[T], + op: fn((&S),(&T)) -> Result) -> Result<~[V],U> { assert vec::same_length(ss, ts); let n = vec::len(ts); let mut vs = vec::with_capacity(n); let mut i = 0u; while i < n { - match op(ss[i],ts[i]) { - Ok(v) => vec::push(vs, v), - Err(u) => return Err(u) + match op(&ss[i],&ts[i]) { + Ok(copy v) => vs.push(v), + Err(copy u) => return Err(u) } i += 1u; } @@ -322,16 +331,16 @@ fn map_vec2(ss: &[S], ts: &[T], * error. This could be implemented using `map2()` but it is more efficient * on its own as no result vector is built. */ -fn iter_vec2(ss: &[S], ts: &[T], - op: fn(S,T) -> Result<(),U>) -> Result<(),U> { +pub fn iter_vec2(ss: &[S], ts: &[T], + op: fn((&S),(&T)) -> Result<(),U>) -> Result<(),U> { assert vec::same_length(ss, ts); let n = vec::len(ts); let mut i = 0u; while i < n { - match op(ss[i],ts[i]) { + match op(&ss[i],&ts[i]) { Ok(()) => (), - Err(u) => return Err(u) + Err(copy u) => return Err(u) } i += 1u; } @@ -339,7 +348,7 @@ fn iter_vec2(ss: &[S], ts: &[T], } /// Unwraps a result, assuming it is an `ok(T)` -fn unwrap(+res: Result) -> T { +pub fn unwrap(res: Result) -> T { match move res { Ok(move t) => move t, Err(_) => fail ~"unwrap called on an err result" @@ -347,7 +356,7 @@ fn unwrap(+res: Result) -> T { } /// Unwraps a result, assuming it is an `err(U)` -fn unwrap_err(+res: Result) -> U { +pub fn unwrap_err(res: Result) -> U { match move res { Err(move u) => move u, Ok(_) => fail ~"unwrap called on an ok result" @@ -357,15 +366,15 @@ fn unwrap_err(+res: Result) -> U { impl Result : Eq { pure fn eq(other: &Result) -> bool { match self { - Ok(e0a) => { + Ok(ref e0a) => { match (*other) { - Ok(e0b) => e0a == e0b, + Ok(ref e0b) => *e0a == *e0b, _ => false } } - Err(e0a) => { + Err(ref e0a) => { match (*other) { - Err(e0b) => e0a == e0b, + Err(ref e0b) => *e0a == *e0b, _ => false } } @@ -380,7 +389,7 @@ mod tests { #[legacy_exports]; fn op1() -> result::Result { result::Ok(666) } - fn op2(&&i: int) -> result::Result { + fn op2(i: int) -> result::Result { result::Ok(i as uint + 1u) } @@ -388,12 +397,12 @@ mod tests { #[test] fn chain_success() { - assert get(chain(op1(), op2)) == 667u; + assert get(&chain(op1(), op2)) == 667u; } #[test] fn chain_failure() { - assert get_err(chain(op3(), op2)) == ~"sadface"; + assert get_err(&chain(op3(), op2)) == ~"sadface"; } #[test] diff --git a/src/libcore/rt.rs b/src/libcore/rt.rs index 644edb69d562..9bc83a5f9043 100644 --- a/src/libcore/rt.rs +++ b/src/libcore/rt.rs @@ -11,10 +11,9 @@ use libc::uintptr_t; use gc::{cleanup_stack_for_failure, gc, Word}; #[allow(non_camel_case_types)] -type rust_task = c_void; +pub type rust_task = c_void; extern mod rustrt { - #[legacy_exports]; #[rust_stack] fn rust_upcall_fail(expr: *c_char, file: *c_char, line: size_t); @@ -35,13 +34,23 @@ extern mod rustrt { // 'rt_', otherwise the compiler won't find it. To fix this, see // gather_rust_rtcalls. #[rt(fail_)] -fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) { +pub fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) { cleanup_stack_for_failure(); rustrt::rust_upcall_fail(expr, file, line); } +#[rt(fail_bounds_check)] +pub fn rt_fail_bounds_check(file: *c_char, line: size_t, + index: size_t, len: size_t) { + let msg = fmt!("index out of bounds: the len is %d but the index is %d", + len as int, index as int); + do str::as_buf(msg) |p, _len| { + rt_fail_(p as *c_char, file, line); + } +} + #[rt(exchange_malloc)] -fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { +pub fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { return rustrt::rust_upcall_exchange_malloc(td, size); } @@ -49,12 +58,12 @@ fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char { // inside a landing pad may corrupt the state of the exception handler. If a // problem occurs, call exit instead. #[rt(exchange_free)] -fn rt_exchange_free(ptr: *c_char) { +pub fn rt_exchange_free(ptr: *c_char) { rustrt::rust_upcall_exchange_free(ptr); } #[rt(malloc)] -fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char { +pub fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char { return rustrt::rust_upcall_malloc(td, size); } @@ -62,7 +71,7 @@ fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char { // inside a landing pad may corrupt the state of the exception handler. If a // problem occurs, call exit instead. #[rt(free)] -fn rt_free(ptr: *c_char) { +pub fn rt_free(ptr: *c_char) { rustrt::rust_upcall_free(ptr); } diff --git a/src/libcore/run.rs b/src/libcore/run.rs index 2496ad51a416..f3e98f6ba827 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; //! Process spawning @@ -7,16 +7,8 @@ use option::{Some, None}; use libc::{pid_t, c_void, c_int}; use io::ReaderUtil; -export Program; -export run_program; -export start_program; -export program_output; -export spawn_process; -export waitpid; - #[abi = "cdecl"] extern mod rustrt { - #[legacy_exports]; fn rust_run_program(argv: **libc::c_char, envp: *c_void, dir: *libc::c_char, in_fd: c_int, out_fd: c_int, err_fd: c_int) @@ -24,7 +16,7 @@ extern mod rustrt { } /// A value representing a child process -trait Program { +pub trait Program { /// Returns the process id of the program fn get_id() -> pid_t; @@ -68,7 +60,7 @@ trait Program { * * The process id of the spawned process */ -fn spawn_process(prog: &str, args: &[~str], +pub fn spawn_process(prog: &str, args: &[~str], env: &Option<~[(~str,~str)]>, dir: &Option<~str>, in_fd: c_int, out_fd: c_int, err_fd: c_int) @@ -89,10 +81,10 @@ fn with_argv(prog: &str, args: &[~str], let mut tmps = ~[]; for vec::each(args) |arg| { let t = @copy *arg; - vec::push(tmps, t); - vec::push_all(argptrs, str::as_c_str(*t, |b| ~[b])); + tmps.push(t); + argptrs.push_all(str::as_c_str(*t, |b| ~[b])); } - vec::push(argptrs, ptr::null()); + argptrs.push(ptr::null()); vec::as_imm_buf(argptrs, |buf, _len| cb(buf)) } @@ -102,17 +94,17 @@ fn with_envp(env: &Option<~[(~str,~str)]>, // On posixy systems we can pass a char** for envp, which is // a null-terminated array of "k=v\n" strings. match *env { - Some(es) if !vec::is_empty(es) => { + Some(ref es) if !vec::is_empty(*es) => { let mut tmps = ~[]; let mut ptrs = ~[]; - for vec::each(es) |e| { + for vec::each(*es) |e| { let (k,v) = copy *e; let t = @(fmt!("%s=%s", k, v)); - vec::push(tmps, t); - vec::push_all(ptrs, str::as_c_str(*t, |b| ~[b])); + tmps.push(t); + ptrs.push_all(str::as_c_str(*t, |b| ~[b])); } - vec::push(ptrs, ptr::null()); + ptrs.push(ptr::null()); vec::as_imm_buf(ptrs, |p, _len| unsafe { cb(::cast::reinterpret_cast(&p)) } ) @@ -149,7 +141,7 @@ fn with_envp(env: &Option<~[(~str,~str)]>, fn with_dirp(d: &Option<~str>, cb: fn(*libc::c_char) -> T) -> T { match *d { - Some(dir) => str::as_c_str(dir, cb), + Some(ref dir) => str::as_c_str(*dir, cb), None => cb(ptr::null()) } } @@ -166,7 +158,7 @@ fn with_dirp(d: &Option<~str>, * * The process id */ -fn run_program(prog: &str, args: &[~str]) -> int { +pub fn run_program(prog: &str, args: &[~str]) -> int { let pid = spawn_process(prog, args, &None, &None, 0i32, 0i32, 0i32); if pid == -1 as pid_t { fail; } @@ -189,7 +181,7 @@ fn run_program(prog: &str, args: &[~str]) -> int { * * A class with a field */ -fn start_program(prog: &str, args: &[~str]) -> Program { +pub fn start_program(prog: &str, args: &[~str]) -> Program { let pipe_input = os::pipe(); let pipe_output = os::pipe(); let pipe_err = os::pipe(); @@ -232,7 +224,7 @@ fn start_program(prog: &str, args: &[~str]) -> Program { drop { destroy_repr(&self.r); } } - fn ProgRes(+r: ProgRepr) -> ProgRes { + fn ProgRes(r: ProgRepr) -> ProgRes { ProgRes { r: r } @@ -278,7 +270,7 @@ fn read_all(rd: io::Reader) -> ~str { * A record, {status: int, out: str, err: str} containing the exit code, * the contents of stdout and the contents of stderr. */ -fn program_output(prog: &str, args: &[~str]) -> +pub fn program_output(prog: &str, args: &[~str]) -> {status: int, out: ~str, err: ~str} { let pipe_in = os::pipe(); @@ -320,11 +312,11 @@ fn program_output(prog: &str, args: &[~str]) -> while count > 0 { let stream = comm::recv(p); match stream { - (1, s) => { - outs = copy s; + (1, copy s) => { + outs = s; } - (2, s) => { - errs = copy s; + (2, copy s) => { + errs = s; } (n, _) => { fail(fmt!("program_output received an unexpected file \ @@ -336,7 +328,7 @@ fn program_output(prog: &str, args: &[~str]) -> return {status: status, out: move outs, err: move errs}; } -fn writeclose(fd: c_int, s: &str) { +fn writeclose(fd: c_int, s: ~str) { use io::WriterUtil; error!("writeclose %d, %s", fd as int, s); @@ -359,7 +351,7 @@ fn readclose(fd: c_int) -> ~str { } /// Waits for a process to exit and returns the exit code -fn waitpid(pid: pid_t) -> int { +pub fn waitpid(pid: pid_t) -> int { return waitpid_os(pid); #[cfg(windows)] @@ -402,20 +394,19 @@ fn waitpid(pid: pid_t) -> int { #[cfg(test)] mod tests { - #[legacy_exports]; - use io::WriterUtil; // Regression test for memory leaks #[ignore(cfg(windows))] // FIXME (#2626) - fn test_leaks() { + pub fn test_leaks() { run::run_program("echo", []); run::start_program("echo", []); run::program_output("echo", []); } #[test] - fn test_pipes() { + #[allow(non_implicitly_copyable_typarams)] + pub fn test_pipes() { let pipe_in = os::pipe(); let pipe_out = os::pipe(); let pipe_err = os::pipe(); @@ -430,7 +421,7 @@ mod tests { if pid == -1i32 { fail; } let expected = ~"test"; - writeclose(pipe_in.out, expected); + writeclose(pipe_in.out, copy expected); let actual = readclose(pipe_out.in); readclose(pipe_err.in); os::waitpid(pid); @@ -441,7 +432,7 @@ mod tests { } #[test] - fn waitpid() { + pub fn waitpid() { let pid = run::spawn_process("false", [], &None, &None, 0i32, 0i32, 0i32); diff --git a/src/libcore/send_map.rs b/src/libcore/send_map.rs index 53dcff2e3158..4a56ee5b8968 100644 --- a/src/libcore/send_map.rs +++ b/src/libcore/send_map.rs @@ -12,10 +12,10 @@ use cmp::Eq; use hash::Hash; use to_bytes::IterBytes; -trait SendMap { +pub trait SendMap { // FIXME(#3148) ^^^^ once find_ref() works, we can drop V:copy - fn insert(&mut self, +k: K, +v: V) -> bool; + fn insert(&mut self, k: K, +v: V) -> bool; fn remove(&mut self, k: &K) -> bool; fn clear(&mut self); pure fn len(&const self) -> uint; @@ -31,17 +31,15 @@ trait SendMap { } /// Open addressing with linear probing. -mod linear { - #[legacy_exports]; - export LinearMap, linear_map, linear_map_with_capacity, public_methods; - +pub mod linear { const initial_capacity: uint = 32u; // 2^5 + struct Bucket { hash: uint, key: K, value: V, } - struct LinearMap { + pub struct LinearMap { k0: u64, k1: u64, resize_at: uint, @@ -60,11 +58,11 @@ mod linear { ((capacity as float) * 3. / 4.) as uint } - fn LinearMap() -> LinearMap { + pub fn LinearMap() -> LinearMap { linear_map_with_capacity(32) } - fn linear_map_with_capacity( + pub fn linear_map_with_capacity( initial_capacity: uint) -> LinearMap { let r = rand::Rng(); linear_map_with_capacity_and_keys(r.gen_u64(), r.gen_u64(), @@ -137,7 +135,7 @@ mod linear { k: &K) -> SearchResult { let _ = for self.bucket_sequence(hash) |i| { match buckets[i] { - Some(bkt) => if bkt.hash == hash && *k == bkt.key { + Some(ref bkt) => if bkt.hash == hash && *k == bkt.key { return FoundEntry(i); }, None => return FoundHole(i) @@ -163,7 +161,7 @@ mod linear { } } - fn insert_opt_bucket(&mut self, +bucket: Option>) { + fn insert_opt_bucket(&mut self, bucket: Option>) { match move bucket { Some(Bucket {hash: move hash, key: move key, @@ -177,7 +175,7 @@ mod linear { /// Inserts the key value pair into the buckets. /// Assumes that there will be a bucket. /// True if there was no previous entry with that key - fn insert_internal(&mut self, hash: uint, +k: K, +v: V) -> bool { + fn insert_internal(&mut self, hash: uint, k: K, v: V) -> bool { match self.bucket_for_key_with_hash(self.buckets, hash, &k) { TableFull => { fail ~"Internal logic error"; } FoundHole(idx) => { @@ -208,7 +206,7 @@ mod linear { } impl LinearMap { - fn insert(&mut self, +k: K, +v: V) -> bool { + fn insert(&mut self, k: K, v: V) -> bool { if self.size >= self.resize_at { // n.b.: We could also do this after searching, so // that we do not resize if this call to insert is @@ -285,18 +283,9 @@ mod linear { FoundEntry(idx) => { match self.buckets[idx] { Some(ref bkt) => { - let ptr = unsafe { - // FIXME(#3148)--region inference - // fails to capture needed deps. - // Here, the bucket value is known to - // live as long as self, because self - // is immutable. But the region - // inference stupidly infers a - // lifetime for `ref bkt` that is - // shorter than it needs to be. - cast::copy_lifetime(self, &bkt.value) - }; - Some(ptr) + // FIXME(#3148)---should be inferred + let bkt: &self/Bucket = bkt; + Some(&bkt.value) } None => { fail ~"LinearMap::find: internal logic error" @@ -344,7 +333,7 @@ mod linear { // FIXME (#3148): Once we rewrite found_entry, this // failure case won't be necessary match self.buckets[idx] { - Some(bkt) => {Some(copy bkt.value)} + Some(Bucket {value: copy value, _}) => {Some(value)} None => fail ~"LinearMap::find: internal logic error" } } @@ -366,13 +355,11 @@ mod linear { } #[test] -mod test { - #[legacy_exports]; - +pub mod test { use linear::LinearMap; #[test] - fn inserts() { + pub fn inserts() { let mut m = ~LinearMap(); assert m.insert(1, 2); assert m.insert(2, 4); @@ -381,7 +368,7 @@ mod test { } #[test] - fn overwrite() { + pub fn overwrite() { let mut m = ~LinearMap(); assert m.insert(1, 2); assert m.get(&1) == 2; @@ -390,7 +377,7 @@ mod test { } #[test] - fn conflicts() { + pub fn conflicts() { let mut m = linear::linear_map_with_capacity(4); assert m.insert(1, 2); assert m.insert(5, 3); @@ -401,7 +388,7 @@ mod test { } #[test] - fn conflict_remove() { + pub fn conflict_remove() { let mut m = linear::linear_map_with_capacity(4); assert m.insert(1, 2); assert m.insert(5, 3); @@ -412,7 +399,7 @@ mod test { } #[test] - fn empty() { + pub fn empty() { let mut m = linear::linear_map_with_capacity(4); assert m.insert(1, 2); assert !m.is_empty(); @@ -421,7 +408,7 @@ mod test { } #[test] - fn iterate() { + pub fn iterate() { let mut m = linear::linear_map_with_capacity(4); for uint::range(0, 32) |i| { assert m.insert(i, i*2); @@ -435,7 +422,7 @@ mod test { } #[test] - fn find_ref() { + pub fn find_ref() { let mut m = ~LinearMap(); assert m.find_ref(&1).is_none(); m.insert(1, 2); diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 4cc91b8b425f..09973148c8c8 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -1,7 +1,10 @@ #[doc(hidden)]; // FIXME #3538 +#[legacy_modes]; // tjc: remove after snapshot + // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// XXX: Can't do this because frame_address needs a deprecated mode. +//#[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; use cast::reinterpret_cast; @@ -74,7 +77,7 @@ fn breakpoint() { rustrt::rust_dbg_breakpoint() } -fn frame_address(f: fn(*u8)) { +fn frame_address(f: fn(++x: *u8)) { rusti::frame_address(f) } @@ -86,5 +89,5 @@ extern mod rustrt { #[abi = "rust-intrinsic"] extern mod rusti { #[legacy_exports]; - fn frame_address(f: fn(*u8)); + fn frame_address(f: fn(++x: *u8)); } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 737cd4d9d505..cf996a8b254c 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -15,115 +15,6 @@ use libc::size_t; use io::WriterUtil; use to_str::ToStr; -export - // Creating a string - from_bytes, - from_byte, - from_slice, - from_char, - from_chars, - append, - concat, - connect, - - // Reinterpretation - as_bytes, - as_bytes_slice, - as_buf, - as_c_str, - - // Adding things to and removing things from a string - push_str_no_overallocate, - push_str, - push_char, - pop_char, - shift_char, - view_shift_char, - unshift_char, - trim_left, - trim_right, - trim, - trim_left_chars, - trim_right_chars, - trim_chars, - - // Transforming strings - to_bytes, - byte_slice, - chars, - substr, - slice, - view, - split, splitn, split_nonempty, - split_char, splitn_char, split_char_nonempty, - split_str, split_str_nonempty, - lines, - lines_any, - words, - to_lower, - to_upper, - replace, - - // Comparing strings - eq, - eq_slice, - le, - hash, - - // Iterating through strings - all, any, - all_between, any_between, - map, - each, eachi, - each_char, each_chari, - bytes_each, - chars_each, - split_char_each, - splitn_char_each, - words_each, - lines_each, - - // Searching - find, find_from, find_between, - rfind, rfind_from, rfind_between, - find_char, find_char_from, find_char_between, - rfind_char, rfind_char_from, rfind_char_between, - find_str, find_str_from, find_str_between, - contains, contains_char, - starts_with, - ends_with, - - // String properties - is_ascii, - is_empty, - is_not_empty, - is_whitespace, - len, - char_len, - - // Misc - is_utf8, - is_utf16, - to_utf16, - from_utf16, - utf16_chars, - count_chars, count_bytes, - utf8_char_width, - char_range_at, - is_char_boundary, - char_at, - reserve, - reserve_at_least, - capacity, - escape_default, - escape_unicode, - - raw, - extensions, - StrSlice, - UniqueStr, - traits; - /* Section: Creating a string */ @@ -135,13 +26,13 @@ Section: Creating a string * * Fails if invalid UTF-8 */ -pure fn from_bytes(vv: &[const u8]) -> ~str { +pub pure fn from_bytes(vv: &[const u8]) -> ~str { assert is_utf8(vv); return unsafe { raw::from_bytes(vv) }; } /// Copy a slice into a new unique str -pure fn from_slice(s: &str) -> ~str { +pub pure fn from_slice(s: &str) -> ~str { unsafe { raw::slice_bytes(s, 0, len(s)) } } @@ -152,13 +43,13 @@ pure fn from_slice(s: &str) -> ~str { * * Fails if invalid UTF-8 */ -pure fn from_byte(b: u8) -> ~str { +pub pure fn from_byte(b: u8) -> ~str { assert b < 128u8; unsafe { ::cast::transmute(~[b, 0u8]) } } /// Appends a character at the end of a string -fn push_char(s: &const ~str, ch: char) { +pub fn push_char(s: &const ~str, ch: char) { unsafe { let code = ch as uint; let nb = if code < max_one_b { 1u } @@ -229,14 +120,14 @@ fn push_char(s: &const ~str, ch: char) { } /// Convert a char to a string -pure fn from_char(ch: char) -> ~str { +pub pure fn from_char(ch: char) -> ~str { let mut buf = ~""; unsafe { push_char(&mut buf, ch); } move buf } /// Convert a vector of chars to a string -pure fn from_chars(chs: &[char]) -> ~str { +pub pure fn from_chars(chs: &[char]) -> ~str { let mut buf = ~""; unsafe { reserve(&mut buf, chs.len()); @@ -249,7 +140,7 @@ pure fn from_chars(chs: &[char]) -> ~str { /// Appends a string slice to the back of a string, without overallocating #[inline(always)] -fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) { +pub fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) { unsafe { let llen = lhs.len(); let rlen = rhs.len(); @@ -266,7 +157,7 @@ fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) { } /// Appends a string slice to the back of a string #[inline(always)] -fn push_str(lhs: &const ~str, rhs: &str) { +pub fn push_str(lhs: &const ~str, rhs: &str) { unsafe { let llen = lhs.len(); let rlen = rhs.len(); @@ -284,7 +175,7 @@ fn push_str(lhs: &const ~str, rhs: &str) { /// Concatenate two strings together #[inline(always)] -pure fn append(+lhs: ~str, rhs: &str) -> ~str { +pub pure fn append(lhs: ~str, rhs: &str) -> ~str { let mut v <- lhs; unsafe { push_str_no_overallocate(&mut v, rhs); @@ -294,7 +185,7 @@ pure fn append(+lhs: ~str, rhs: &str) -> ~str { /// Concatenate a vector of strings -pure fn concat(v: &[~str]) -> ~str { +pub pure fn concat(v: &[~str]) -> ~str { let mut s: ~str = ~""; for vec::each(v) |ss| { unsafe { push_str(&mut s, *ss) }; @@ -303,7 +194,7 @@ pure fn concat(v: &[~str]) -> ~str { } /// Concatenate a vector of strings, placing a given separator between each -pure fn connect(v: &[~str], sep: &str) -> ~str { +pub pure fn connect(v: &[~str], sep: &str) -> ~str { let mut s = ~"", first = true; for vec::each(v) |ss| { if first { first = false; } else { unsafe { push_str(&mut s, sep); } } @@ -323,7 +214,7 @@ Section: Adding to and removing from a string * * If the string does not contain any characters */ -fn pop_char(s: &const ~str) -> char { +pub fn pop_char(s: &const ~str) -> char { let end = len(*s); assert end > 0u; let {ch, prev} = char_range_at_reverse(*s, end); @@ -338,7 +229,7 @@ fn pop_char(s: &const ~str) -> char { * * If the string does not contain any characters */ -fn shift_char(s: &mut ~str) -> char { +pub fn shift_char(s: &mut ~str) -> char { let {ch, next} = char_range_at(*s, 0u); *s = unsafe { raw::slice_bytes(*s, next, len(*s)) }; return ch; @@ -354,14 +245,14 @@ fn shift_char(s: &mut ~str) -> char { * If the string does not contain any characters */ #[inline] -fn view_shift_char(s: &a/str) -> (char, &a/str) { +pub fn view_shift_char(s: &a/str) -> (char, &a/str) { let {ch, next} = char_range_at(s, 0u); let next_s = unsafe { raw::view_bytes(s, next, len(s)) }; return (ch, next_s); } /// Prepend a char to a string -fn unshift_char(s: &mut ~str, ch: char) { +pub fn unshift_char(s: &mut ~str, ch: char) { *s = from_char(ch) + *s; } @@ -374,10 +265,10 @@ fn unshift_char(s: &mut ~str, ch: char) { * * chars_to_trim - A vector of chars * */ -pure fn trim_left_chars(s: &str, chars_to_trim: &[char]) -> ~str { +pub pure fn trim_left_chars(s: &str, chars_to_trim: &[char]) -> ~str { if chars_to_trim.is_empty() { return from_slice(s); } - match find(s, |c| !chars_to_trim.contains(c)) { + match find(s, |c| !chars_to_trim.contains(&c)) { None => ~"", Some(first) => unsafe { raw::slice_bytes(s, first, s.len()) } } @@ -392,10 +283,10 @@ pure fn trim_left_chars(s: &str, chars_to_trim: &[char]) -> ~str { * * chars_to_trim - A vector of chars * */ -pure fn trim_right_chars(s: &str, chars_to_trim: &[char]) -> ~str { +pub pure fn trim_right_chars(s: &str, chars_to_trim: &[char]) -> ~str { if chars_to_trim.is_empty() { return str::from_slice(s); } - match rfind(s, |c| !chars_to_trim.contains(c)) { + match rfind(s, |c| !chars_to_trim.contains(&c)) { None => ~"", Some(last) => { let {next, _} = char_range_at(s, last); @@ -413,12 +304,12 @@ pure fn trim_right_chars(s: &str, chars_to_trim: &[char]) -> ~str { * * chars_to_trim - A vector of chars * */ -pure fn trim_chars(s: &str, chars_to_trim: &[char]) -> ~str { +pub pure fn trim_chars(s: &str, chars_to_trim: &[char]) -> ~str { trim_left_chars(trim_right_chars(s, chars_to_trim), chars_to_trim) } /// Returns a string with leading whitespace removed -pure fn trim_left(s: &str) -> ~str { +pub pure fn trim_left(s: &str) -> ~str { match find(s, |c| !char::is_whitespace(c)) { None => ~"", Some(first) => unsafe { raw::slice_bytes(s, first, len(s)) } @@ -426,7 +317,7 @@ pure fn trim_left(s: &str) -> ~str { } /// Returns a string with trailing whitespace removed -pure fn trim_right(s: &str) -> ~str { +pub pure fn trim_right(s: &str) -> ~str { match rfind(s, |c| !char::is_whitespace(c)) { None => ~"", Some(last) => { @@ -437,7 +328,7 @@ pure fn trim_right(s: &str) -> ~str { } /// Returns a string with leading and trailing whitespace removed -pure fn trim(s: &str) -> ~str { trim_left(trim_right(s)) } +pub pure fn trim(s: &str) -> ~str { trim_left(trim_right(s)) } /* Section: Transforming strings @@ -448,27 +339,27 @@ Section: Transforming strings * * The result vector is not null-terminated. */ -pure fn to_bytes(s: &str) -> ~[u8] unsafe { +pub pure fn to_bytes(s: &str) -> ~[u8] unsafe { let mut v: ~[u8] = ::cast::transmute(from_slice(s)); - vec::raw::set_len(v, len(s)); + vec::raw::set_len(&mut v, len(s)); move v } /// Work with the string as a byte slice, not including trailing null. #[inline(always)] -pure fn byte_slice(s: &str, f: fn(v: &[u8]) -> T) -> T { +pub pure fn byte_slice(s: &str, f: fn(v: &[u8]) -> T) -> T { do as_buf(s) |p,n| { - unsafe { vec::raw::form_slice(p, n-1u, f) } + unsafe { vec::raw::buf_as_slice(p, n-1u, f) } } } /// Convert a string to a vector of characters -pure fn chars(s: &str) -> ~[char] { - let mut buf = ~[], i = 0u; +pub pure fn chars(s: &str) -> ~[char] { + let mut buf = ~[], i = 0; let len = len(s); while i < len { let {ch, next} = char_range_at(s, i); - unsafe { vec::push(buf, ch); } + unsafe { buf.push(ch); } i = next; } move buf @@ -480,7 +371,7 @@ pure fn chars(s: &str) -> ~[char] { * Returns a string containing `n` characters starting at byte offset * `begin`. */ -pure fn substr(s: &str, begin: uint, n: uint) -> ~str { +pub pure fn substr(s: &str, begin: uint, n: uint) -> ~str { slice(s, begin, begin + count_bytes(s, begin, n)) } @@ -490,7 +381,7 @@ pure fn substr(s: &str, begin: uint, n: uint) -> ~str { * Fails when `begin` and `end` do not point to valid characters or * beyond the last character of the string */ -pure fn slice(s: &str, begin: uint, end: uint) -> ~str { +pub pure fn slice(s: &str, begin: uint, end: uint) -> ~str { assert is_char_boundary(s, begin); assert is_char_boundary(s, end); unsafe { raw::slice_bytes(s, begin, end) } @@ -502,14 +393,14 @@ pure fn slice(s: &str, begin: uint, end: uint) -> ~str { * Fails when `begin` and `end` do not point to valid characters or beyond * the last character of the string */ -pure fn view(s: &a/str, begin: uint, end: uint) -> &a/str { +pub pure fn view(s: &a/str, begin: uint, end: uint) -> &a/str { assert is_char_boundary(s, begin); assert is_char_boundary(s, end); unsafe { raw::view_bytes(s, begin, end) } } /// Splits a string into substrings at each occurrence of a given character -pure fn split_char(s: &str, sep: char) -> ~[~str] { +pub pure fn split_char(s: &str, sep: char) -> ~[~str] { split_char_inner(s, sep, len(s), true) } @@ -519,12 +410,12 @@ pure fn split_char(s: &str, sep: char) -> ~[~str] { * * The byte must be a valid UTF-8/ASCII byte */ -pure fn splitn_char(s: &str, sep: char, count: uint) -> ~[~str] { +pub pure fn splitn_char(s: &str, sep: char, count: uint) -> ~[~str] { split_char_inner(s, sep, count, true) } /// Like `split_char`, but omits empty strings from the returned vector -pure fn split_char_nonempty(s: &str, sep: char) -> ~[~str] { +pub pure fn split_char_nonempty(s: &str, sep: char) -> ~[~str] { split_char_inner(s, sep, len(s), false) } @@ -537,8 +428,7 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool) while i < l && done < count { if s[i] == b { if allow_empty || start < i unsafe { - vec::push(result, - unsafe { raw::slice_bytes(s, start, i) }); + result.push(unsafe { raw::slice_bytes(s, start, i) }); } start = i + 1u; done += 1u; @@ -546,7 +436,7 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool) i += 1u; } if allow_empty || start < l { - unsafe { vec::push(result, raw::slice_bytes(s, start, l) ) }; + unsafe { result.push(raw::slice_bytes(s, start, l) ) }; } move result } else { @@ -556,7 +446,7 @@ pure fn split_char_inner(s: &str, sep: char, count: uint, allow_empty: bool) /// Splits a string into substrings using a character function -pure fn split(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { +pub pure fn split(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { split_inner(s, sepfn, len(s), true) } @@ -564,12 +454,12 @@ pure fn split(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { * Splits a string into substrings using a character function, cutting at * most `count` times. */ -pure fn splitn(s: &str, sepfn: fn(char) -> bool, count: uint) -> ~[~str] { +pub pure fn splitn(s: &str, sepfn: fn(char) -> bool, count: uint) -> ~[~str] { split_inner(s, sepfn, count, true) } /// Like `split`, but omits empty strings from the returned vector -pure fn split_nonempty(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { +pub pure fn split_nonempty(s: &str, sepfn: fn(char) -> bool) -> ~[~str] { split_inner(s, sepfn, len(s), false) } @@ -581,7 +471,7 @@ pure fn split_inner(s: &str, sepfn: fn(cc: char) -> bool, count: uint, let {ch, next} = char_range_at(s, i); if sepfn(ch) { if allow_empty || start < i unsafe { - vec::push(result, unsafe { raw::slice_bytes(s, start, i)}); + result.push(unsafe { raw::slice_bytes(s, start, i)}); } start = next; done += 1u; @@ -589,7 +479,7 @@ pure fn split_inner(s: &str, sepfn: fn(cc: char) -> bool, count: uint, i = next; } if allow_empty || start < l unsafe { - vec::push(result, unsafe { raw::slice_bytes(s, start, l) }); + result.push(unsafe { raw::slice_bytes(s, start, l) }); } move result } @@ -640,19 +530,19 @@ pure fn iter_between_matches(s: &a/str, sep: &b/str, f: fn(uint, uint)) { * assert ["", "XXX", "YYY", ""] == split_str(".XXX.YYY.", ".") * ~~~ */ -pure fn split_str(s: &a/str, sep: &b/str) -> ~[~str] { +pub pure fn split_str(s: &a/str, sep: &b/str) -> ~[~str] { let mut result = ~[]; do iter_between_matches(s, sep) |from, to| { - unsafe { vec::push(result, raw::slice_bytes(s, from, to)); } + unsafe { result.push(raw::slice_bytes(s, from, to)); } } move result } -pure fn split_str_nonempty(s: &a/str, sep: &b/str) -> ~[~str] { +pub pure fn split_str_nonempty(s: &a/str, sep: &b/str) -> ~[~str] { let mut result = ~[]; do iter_between_matches(s, sep) |from, to| { if to > from { - unsafe { vec::push(result, raw::slice_bytes(s, from, to)); } + unsafe { result.push(raw::slice_bytes(s, from, to)); } } } move result @@ -661,13 +551,13 @@ pure fn split_str_nonempty(s: &a/str, sep: &b/str) -> ~[~str] { /** * Splits a string into a vector of the substrings separated by LF ('\n') */ -pure fn lines(s: &str) -> ~[~str] { split_char(s, '\n') } +pub pure fn lines(s: &str) -> ~[~str] { split_char(s, '\n') } /** * Splits a string into a vector of the substrings separated by LF ('\n') * and/or CR LF ("\r\n") */ -pure fn lines_any(s: &str) -> ~[~str] { +pub pure fn lines_any(s: &str) -> ~[~str] { vec::map(lines(s), |s| { let l = len(*s); let mut cp = copy *s; @@ -679,19 +569,19 @@ pure fn lines_any(s: &str) -> ~[~str] { } /// Splits a string into a vector of the substrings separated by whitespace -pure fn words(s: &str) -> ~[~str] { +pub pure fn words(s: &str) -> ~[~str] { split_nonempty(s, |c| char::is_whitespace(c)) } /// Convert a string to lowercase. ASCII only -pure fn to_lower(s: &str) -> ~str { +pub pure fn to_lower(s: &str) -> ~str { map(s, |c| unsafe{(libc::tolower(c as libc::c_char)) as char} ) } /// Convert a string to uppercase. ASCII only -pure fn to_upper(s: &str) -> ~str { +pub pure fn to_upper(s: &str) -> ~str { map(s, |c| unsafe{(libc::toupper(c as libc::c_char)) as char} ) @@ -710,7 +600,7 @@ pure fn to_upper(s: &str) -> ~str { * * The original string with all occurances of `from` replaced with `to` */ -pure fn replace(s: &str, from: &str, to: &str) -> ~str { +pub pure fn replace(s: &str, from: &str, to: &str) -> ~str { let mut result = ~"", first = true; do iter_between_matches(s, from) |start, end| { if first { @@ -730,7 +620,7 @@ Section: Comparing strings /// Bytewise slice equality #[cfg(notest)] #[lang="str_eq"] -pure fn eq_slice(a: &str, b: &str) -> bool { +pub pure fn eq_slice(a: &str, b: &str) -> bool { do as_buf(a) |ap, alen| { do as_buf(b) |bp, blen| { if (alen != blen) { false } @@ -746,7 +636,7 @@ pure fn eq_slice(a: &str, b: &str) -> bool { } #[cfg(test)] -pure fn eq_slice(a: &str, b: &str) -> bool { +pub pure fn eq_slice(a: &str, b: &str) -> bool { do as_buf(a) |ap, alen| { do as_buf(b) |bp, blen| { if (alen != blen) { false } @@ -764,12 +654,12 @@ pure fn eq_slice(a: &str, b: &str) -> bool { /// Bytewise string equality #[cfg(notest)] #[lang="uniq_str_eq"] -pure fn eq(a: &~str, b: &~str) -> bool { +pub pure fn eq(a: &~str, b: &~str) -> bool { eq_slice(*a, *b) } #[cfg(test)] -pure fn eq(a: &~str, b: &~str) -> bool { +pub pure fn eq(a: &~str, b: &~str) -> bool { eq_slice(*a, *b) } @@ -790,7 +680,7 @@ pure fn lt(a: &str, b: &str) -> bool { } /// Bytewise less than or equal -pure fn le(a: &str, b: &str) -> bool { +pub pure fn le(a: &str, b: &str) -> bool { !lt(b, a) } @@ -872,7 +762,7 @@ Section: Iterating through strings * Return true if a predicate matches all characters or if the string * contains no characters */ -pure fn all(s: &str, it: fn(char) -> bool) -> bool { +pub pure fn all(s: &str, it: fn(char) -> bool) -> bool { all_between(s, 0u, len(s), it) } @@ -880,12 +770,12 @@ pure fn all(s: &str, it: fn(char) -> bool) -> bool { * Return true if a predicate matches any character (and false if it * matches none or there are no characters) */ -pure fn any(ss: &str, pred: fn(char) -> bool) -> bool { +pub pure fn any(ss: &str, pred: fn(char) -> bool) -> bool { !all(ss, |cc| !pred(cc)) } /// Apply a function to each character -pure fn map(ss: &str, ff: fn(char) -> char) -> ~str { +pub pure fn map(ss: &str, ff: fn(char) -> char) -> ~str { let mut result = ~""; unsafe { reserve(&mut result, len(ss)); @@ -897,7 +787,7 @@ pure fn map(ss: &str, ff: fn(char) -> char) -> ~str { } /// Iterate over the bytes in a string -pure fn bytes_each(ss: &str, it: fn(u8) -> bool) { +pub pure fn bytes_each(ss: &str, it: fn(u8) -> bool) { let mut pos = 0u; let len = len(ss); @@ -909,13 +799,13 @@ pure fn bytes_each(ss: &str, it: fn(u8) -> bool) { /// Iterate over the bytes in a string #[inline(always)] -pure fn each(s: &str, it: fn(u8) -> bool) { +pub pure fn each(s: &str, it: fn(u8) -> bool) { eachi(s, |_i, b| it(b) ) } /// Iterate over the bytes in a string, with indices #[inline(always)] -pure fn eachi(s: &str, it: fn(uint, u8) -> bool) { +pub pure fn eachi(s: &str, it: fn(uint, u8) -> bool) { let mut i = 0u, l = len(s); while (i < l) { if !it(i, s[i]) { break; } @@ -925,13 +815,13 @@ pure fn eachi(s: &str, it: fn(uint, u8) -> bool) { /// Iterates over the chars in a string #[inline(always)] -pure fn each_char(s: &str, it: fn(char) -> bool) { +pub pure fn each_char(s: &str, it: fn(char) -> bool) { each_chari(s, |_i, c| it(c)) } /// Iterates over the chars in a string, with indices #[inline(always)] -pure fn each_chari(s: &str, it: fn(uint, char) -> bool) { +pub pure fn each_chari(s: &str, it: fn(uint, char) -> bool) { let mut pos = 0u, ch_pos = 0u; let len = len(s); while pos < len { @@ -943,7 +833,7 @@ pure fn each_chari(s: &str, it: fn(uint, char) -> bool) { } /// Iterate over the characters in a string -pure fn chars_each(s: &str, it: fn(char) -> bool) { +pub pure fn chars_each(s: &str, it: fn(char) -> bool) { let mut pos = 0u; let len = len(s); while (pos < len) { @@ -954,7 +844,7 @@ pure fn chars_each(s: &str, it: fn(char) -> bool) { } /// Apply a function to each substring after splitting by character -pure fn split_char_each(ss: &str, cc: char, ff: fn(v: &str) -> bool) { +pub pure fn split_char_each(ss: &str, cc: char, ff: fn(v: &str) -> bool) { vec::each(split_char(ss, cc), |s| ff(*s)) } @@ -962,20 +852,20 @@ pure fn split_char_each(ss: &str, cc: char, ff: fn(v: &str) -> bool) { * Apply a function to each substring after splitting by character, up to * `count` times */ -pure fn splitn_char_each(ss: &str, sep: char, count: uint, +pub pure fn splitn_char_each(ss: &str, sep: char, count: uint, ff: fn(v: &str) -> bool) { vec::each(splitn_char(ss, sep, count), |s| ff(*s)) } /// Apply a function to each word -pure fn words_each(ss: &str, ff: fn(v: &str) -> bool) { +pub pure fn words_each(ss: &str, ff: fn(v: &str) -> bool) { vec::each(words(ss), |s| ff(*s)) } /** * Apply a function to each line (by '\n') */ -pure fn lines_each(ss: &str, ff: fn(v: &str) -> bool) { +pub pure fn lines_each(ss: &str, ff: fn(v: &str) -> bool) { vec::each(lines(ss), |s| ff(*s)) } @@ -996,7 +886,7 @@ Section: Searching * An `option` containing the byte index of the first matching character * or `none` if there is no match */ -pure fn find_char(s: &str, c: char) -> Option { +pub pure fn find_char(s: &str, c: char) -> Option { find_char_between(s, c, 0u, len(s)) } @@ -1020,7 +910,7 @@ pure fn find_char(s: &str, c: char) -> Option { * `start` must be less than or equal to `len(s)`. `start` must be the * index of a character boundary, as defined by `is_char_boundary`. */ -pure fn find_char_from(s: &str, c: char, start: uint) -> Option { +pub pure fn find_char_from(s: &str, c: char, start: uint) -> Option { find_char_between(s, c, start, len(s)) } @@ -1045,7 +935,7 @@ pure fn find_char_from(s: &str, c: char, start: uint) -> Option { * or equal to `len(s)`. `start` must be the index of a character boundary, * as defined by `is_char_boundary`. */ -pure fn find_char_between(s: &str, c: char, start: uint, end: uint) +pub pure fn find_char_between(s: &str, c: char, start: uint, end: uint) -> Option { if c < 128u as char { assert start <= end; @@ -1075,7 +965,7 @@ pure fn find_char_between(s: &str, c: char, start: uint, end: uint) * An `option` containing the byte index of the last matching character * or `none` if there is no match */ -pure fn rfind_char(s: &str, c: char) -> Option { +pub pure fn rfind_char(s: &str, c: char) -> Option { rfind_char_between(s, c, len(s), 0u) } @@ -1099,7 +989,7 @@ pure fn rfind_char(s: &str, c: char) -> Option { * `start` must be less than or equal to `len(s)`. `start` must be * the index of a character boundary, as defined by `is_char_boundary`. */ -pure fn rfind_char_from(s: &str, c: char, start: uint) -> Option { +pub pure fn rfind_char_from(s: &str, c: char, start: uint) -> Option { rfind_char_between(s, c, start, 0u) } @@ -1124,7 +1014,7 @@ pure fn rfind_char_from(s: &str, c: char, start: uint) -> Option { * or equal to `len(s)`. `start` must be the index of a character boundary, * as defined by `is_char_boundary`. */ -pure fn rfind_char_between(s: &str, c: char, start: uint, end: uint) +pub pure fn rfind_char_between(s: &str, c: char, start: uint, end: uint) -> Option { if c < 128u as char { assert start >= end; @@ -1155,7 +1045,7 @@ pure fn rfind_char_between(s: &str, c: char, start: uint, end: uint) * An `option` containing the byte index of the first matching character * or `none` if there is no match */ -pure fn find(s: &str, f: fn(char) -> bool) -> Option { +pub pure fn find(s: &str, f: fn(char) -> bool) -> Option { find_between(s, 0u, len(s), f) } @@ -1179,7 +1069,7 @@ pure fn find(s: &str, f: fn(char) -> bool) -> Option { * `start` must be less than or equal to `len(s)`. `start` must be the * index of a character boundary, as defined by `is_char_boundary`. */ -pure fn find_from(s: &str, start: uint, f: fn(char) +pub pure fn find_from(s: &str, start: uint, f: fn(char) -> bool) -> Option { find_between(s, start, len(s), f) } @@ -1206,7 +1096,7 @@ pure fn find_from(s: &str, start: uint, f: fn(char) * or equal to `len(s)`. `start` must be the index of a character * boundary, as defined by `is_char_boundary`. */ -pure fn find_between(s: &str, start: uint, end: uint, f: fn(char) -> bool) +pub pure fn find_between(s: &str, start: uint, end: uint, f: fn(char) -> bool) -> Option { assert start <= end; assert end <= len(s); @@ -1234,7 +1124,7 @@ pure fn find_between(s: &str, start: uint, end: uint, f: fn(char) -> bool) * An option containing the byte index of the last matching character * or `none` if there is no match */ -pure fn rfind(s: &str, f: fn(char) -> bool) -> Option { +pub pure fn rfind(s: &str, f: fn(char) -> bool) -> Option { rfind_between(s, len(s), 0u, f) } @@ -1258,7 +1148,7 @@ pure fn rfind(s: &str, f: fn(char) -> bool) -> Option { * `start` must be less than or equal to `len(s)', `start` must be the * index of a character boundary, as defined by `is_char_boundary` */ -pure fn rfind_from(s: &str, start: uint, f: fn(char) -> bool) +pub pure fn rfind_from(s: &str, start: uint, f: fn(char) -> bool) -> Option { rfind_between(s, start, 0u, f) } @@ -1285,7 +1175,8 @@ pure fn rfind_from(s: &str, start: uint, f: fn(char) -> bool) * than or equal to `len(s)`. `start` must be the index of a character * boundary, as defined by `is_char_boundary` */ -pure fn rfind_between(s: &str, start: uint, end: uint, f: fn(char) -> bool) +pub pure fn rfind_between(s: &str, start: uint, end: uint, + f: fn(char) -> bool) -> Option { assert start >= end; assert start <= len(s); @@ -1319,7 +1210,7 @@ pure fn match_at(haystack: &a/str, needle: &b/str, at: uint) -> bool { * An `option` containing the byte index of the first matching substring * or `none` if there is no match */ -pure fn find_str(haystack: &a/str, needle: &b/str) -> Option { +pub pure fn find_str(haystack: &a/str, needle: &b/str) -> Option { find_str_between(haystack, needle, 0u, len(haystack)) } @@ -1342,7 +1233,7 @@ pure fn find_str(haystack: &a/str, needle: &b/str) -> Option { * * `start` must be less than or equal to `len(s)` */ -pure fn find_str_from(haystack: &a/str, needle: &b/str, start: uint) +pub pure fn find_str_from(haystack: &a/str, needle: &b/str, start: uint) -> Option { find_str_between(haystack, needle, start, len(haystack)) } @@ -1367,7 +1258,7 @@ pure fn find_str_from(haystack: &a/str, needle: &b/str, start: uint) * `start` must be less than or equal to `end` and `end` must be less than * or equal to `len(s)`. */ -pure fn find_str_between(haystack: &a/str, needle: &b/str, start: uint, +pub pure fn find_str_between(haystack: &a/str, needle: &b/str, start: uint, end:uint) -> Option { // See Issue #1932 for why this is a naive search @@ -1393,7 +1284,7 @@ pure fn find_str_between(haystack: &a/str, needle: &b/str, start: uint, * * haystack - The string to look in * * needle - The string to look for */ -pure fn contains(haystack: &a/str, needle: &b/str) -> bool { +pub pure fn contains(haystack: &a/str, needle: &b/str) -> bool { find_str(haystack, needle).is_some() } @@ -1405,7 +1296,7 @@ pure fn contains(haystack: &a/str, needle: &b/str) -> bool { * * haystack - The string to look in * * needle - The char to look for */ -pure fn contains_char(haystack: &str, needle: char) -> bool { +pub pure fn contains_char(haystack: &str, needle: char) -> bool { find_char(haystack, needle).is_some() } @@ -1417,7 +1308,7 @@ pure fn contains_char(haystack: &str, needle: char) -> bool { * * haystack - The string to look in * * needle - The string to look for */ -pure fn starts_with(haystack: &a/str, needle: &b/str) -> bool { +pub pure fn starts_with(haystack: &a/str, needle: &b/str) -> bool { let haystack_len = len(haystack), needle_len = len(needle); if needle_len == 0u { true } else if needle_len > haystack_len { false } @@ -1432,7 +1323,7 @@ pure fn starts_with(haystack: &a/str, needle: &b/str) -> bool { * * haystack - The string to look in * * needle - The string to look for */ -pure fn ends_with(haystack: &a/str, needle: &b/str) -> bool { +pub pure fn ends_with(haystack: &a/str, needle: &b/str) -> bool { let haystack_len = len(haystack), needle_len = len(needle); if needle_len == 0u { true } else if needle_len > haystack_len { false } @@ -1444,24 +1335,24 @@ Section: String properties */ /// Determines if a string contains only ASCII characters -pure fn is_ascii(s: &str) -> bool { +pub pure fn is_ascii(s: &str) -> bool { let mut i: uint = len(s); while i > 0u { i -= 1u; if !u8::is_ascii(s[i]) { return false; } } return true; } /// Returns true if the string has length 0 -pure fn is_empty(s: &str) -> bool { len(s) == 0u } +pub pure fn is_empty(s: &str) -> bool { len(s) == 0u } /// Returns true if the string has length greater than 0 -pure fn is_not_empty(s: &str) -> bool { !is_empty(s) } +pub pure fn is_not_empty(s: &str) -> bool { !is_empty(s) } /** * Returns true if the string contains only whitespace * * Whitespace characters are determined by `char::is_whitespace` */ -pure fn is_whitespace(s: &str) -> bool { +pub pure fn is_whitespace(s: &str) -> bool { return all(s, char::is_whitespace); } @@ -1475,19 +1366,19 @@ fn is_alphanumeric(s: &str) -> bool { } /// Returns the string length/size in bytes not counting the null terminator -pure fn len(s: &str) -> uint { +pub pure fn len(s: &str) -> uint { do as_buf(s) |_p, n| { n - 1u } } /// Returns the number of characters that a string holds -pure fn char_len(s: &str) -> uint { count_chars(s, 0u, len(s)) } +pub pure fn char_len(s: &str) -> uint { count_chars(s, 0u, len(s)) } /* Section: Misc */ /// Determines if a vector of bytes contains valid UTF-8 -pure fn is_utf8(v: &[const u8]) -> bool { +pub pure fn is_utf8(v: &[const u8]) -> bool { let mut i = 0u; let total = vec::len::(v); while i < total { @@ -1505,7 +1396,7 @@ pure fn is_utf8(v: &[const u8]) -> bool { } /// Determines if a vector of `u16` contains valid UTF-16 -pure fn is_utf16(v: &[u16]) -> bool { +pub pure fn is_utf16(v: &[u16]) -> bool { let len = vec::len(v); let mut i = 0u; while (i < len) { @@ -1526,7 +1417,7 @@ pure fn is_utf16(v: &[u16]) -> bool { } /// Converts to a vector of `u16` encoded as UTF-16 -pure fn to_utf16(s: &str) -> ~[u16] { +pub pure fn to_utf16(s: &str) -> ~[u16] { let mut u = ~[]; for chars_each(s) |cch| { // Arithmetic with u32 literals is easier on the eyes than chars. @@ -1535,20 +1426,20 @@ pure fn to_utf16(s: &str) -> ~[u16] { if (ch & 0xFFFF_u32) == ch unsafe { // The BMP falls through (assuming non-surrogate, as it should) assert ch <= 0xD7FF_u32 || ch >= 0xE000_u32; - vec::push(u, ch as u16) + u.push(ch as u16) } else unsafe { // Supplementary planes break into surrogates. assert ch >= 0x1_0000_u32 && ch <= 0x10_FFFF_u32; ch -= 0x1_0000_u32; let w1 = 0xD800_u16 | ((ch >> 10) as u16); let w2 = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16); - vec::push_all(u, ~[w1, w2]) + u.push_all(~[w1, w2]) } } move u } -pure fn utf16_chars(v: &[u16], f: fn(char)) { +pub pure fn utf16_chars(v: &[u16], f: fn(char)) { let len = vec::len(v); let mut i = 0u; while (i < len && v[i] != 0u16) { @@ -1573,7 +1464,7 @@ pure fn utf16_chars(v: &[u16], f: fn(char)) { } -pure fn from_utf16(v: &[u16]) -> ~str { +pub pure fn from_utf16(v: &[u16]) -> ~str { let mut buf = ~""; unsafe { reserve(&mut buf, vec::len(v)); @@ -1596,7 +1487,7 @@ pure fn from_utf16(v: &[u16]) -> ~str { * * The number of Unicode characters in `s` between the given indices. */ -pure fn count_chars(s: &str, start: uint, end: uint) -> uint { +pub pure fn count_chars(s: &str, start: uint, end: uint) -> uint { assert is_char_boundary(s, start); assert is_char_boundary(s, end); let mut i = start, len = 0u; @@ -1609,7 +1500,7 @@ pure fn count_chars(s: &str, start: uint, end: uint) -> uint { } /// Counts the number of bytes taken by the `n` in `s` starting from `start`. -pure fn count_bytes(s: &b/str, start: uint, n: uint) -> uint { +pub pure fn count_bytes(s: &b/str, start: uint, n: uint) -> uint { assert is_char_boundary(s, start); let mut end = start, cnt = n; let l = len(s); @@ -1623,7 +1514,7 @@ pure fn count_bytes(s: &b/str, start: uint, n: uint) -> uint { } /// Given a first byte, determine how many bytes are in this UTF-8 character -pure fn utf8_char_width(b: u8) -> uint { +pub pure fn utf8_char_width(b: u8) -> uint { let byte: uint = b as uint; if byte < 128u { return 1u; } // Not a valid start byte @@ -1639,7 +1530,7 @@ pure fn utf8_char_width(b: u8) -> uint { * Returns false if the index points into the middle of a multi-byte * character sequence. */ -pure fn is_char_boundary(s: &str, index: uint) -> bool { +pub pure fn is_char_boundary(s: &str, index: uint) -> bool { if index == len(s) { return true; } let b = s[index]; return b < 128u8 || b >= 192u8; @@ -1694,7 +1585,7 @@ pure fn is_char_boundary(s: &str, index: uint) -> bool { * If `i` is greater than or equal to the length of the string. * If `i` is not the index of the beginning of a valid UTF-8 character. */ -pure fn char_range_at(s: &str, i: uint) -> {ch: char, next: uint} { +pub pure fn char_range_at(s: &str, i: uint) -> {ch: char, next: uint} { let b0 = s[i]; let w = utf8_char_width(b0); assert (w != 0u); @@ -1717,7 +1608,9 @@ pure fn char_range_at(s: &str, i: uint) -> {ch: char, next: uint} { } /// Pluck a character out of a string -pure fn char_at(s: &str, i: uint) -> char { return char_range_at(s, i).ch; } +pub pure fn char_at(s: &str, i: uint) -> char { + return char_range_at(s, i).ch; +} /** * Given a byte position and a str, return the previous char and its position @@ -1763,7 +1656,7 @@ pure fn char_range_at_reverse(ss: &str, start: uint) * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -pure fn all_between(s: &str, start: uint, end: uint, +pub pure fn all_between(s: &str, start: uint, end: uint, it: fn(char) -> bool) -> bool { assert is_char_boundary(s, start); let mut i = start; @@ -1796,7 +1689,7 @@ pure fn all_between(s: &str, start: uint, end: uint, * * `true` if `it` returns `true` for any character */ -pure fn any_between(s: &str, start: uint, end: uint, +pub pure fn any_between(s: &str, start: uint, end: uint, it: fn(char) -> bool) -> bool { !all_between(s, start, end, |c| !it(c)) } @@ -1828,10 +1721,10 @@ const tag_six_b: uint = 252u; * let i = str::as_bytes("Hello World") { |bytes| vec::len(bytes) }; * ~~~ */ -pure fn as_bytes(s: &const ~str, f: fn(~[u8]) -> T) -> T { +pub pure fn as_bytes(s: &const ~str, f: fn((&~[u8])) -> T) -> T { unsafe { let v: *~[u8] = cast::transmute(copy s); - f(*v) + f(&*v) } } @@ -1840,7 +1733,7 @@ pure fn as_bytes(s: &const ~str, f: fn(~[u8]) -> T) -> T { * * The byte slice does not include the null terminator. */ -pure fn as_bytes_slice(s: &a/str) -> &a/[u8] { +pub pure fn as_bytes_slice(s: &a/str) -> &a/[u8] { unsafe { let (ptr, len): (*u8, uint) = ::cast::reinterpret_cast(&s); let outgoing_tuple: (*u8, uint) = (ptr, len - 1); @@ -1863,7 +1756,7 @@ pure fn as_bytes_slice(s: &a/str) -> &a/[u8] { * let s = str::as_c_str("PATH", { |path| libc::getenv(path) }); * ~~~ */ -pure fn as_c_str(s: &str, f: fn(*libc::c_char) -> T) -> T { +pub pure fn as_c_str(s: &str, f: fn(*libc::c_char) -> T) -> T { do as_buf(s) |buf, len| { // NB: len includes the trailing null. assert len > 0; @@ -1885,9 +1778,9 @@ pure fn as_c_str(s: &str, f: fn(*libc::c_char) -> T) -> T { * to full strings, or suffixes of them. */ #[inline(always)] -pure fn as_buf(s: &str, f: fn(*u8, uint) -> T) -> T { +pub pure fn as_buf(s: &str, f: fn(*u8, uint) -> T) -> T { unsafe { - let v : *(*u8,uint) = ::cast::reinterpret_cast(&ptr::addr_of(s)); + let v : *(*u8,uint) = ::cast::reinterpret_cast(&ptr::addr_of(&s)); let (buf,len) = *v; f(buf, len) } @@ -1909,7 +1802,7 @@ pure fn as_buf(s: &str, f: fn(*u8, uint) -> T) -> T { * * s - A string * * n - The number of bytes to reserve space for */ -fn reserve(s: &const ~str, n: uint) { +pub fn reserve(s: &const ~str, n: uint) { unsafe { let v: *mut ~[u8] = cast::transmute(copy s); vec::reserve(&mut *v, n + 1); @@ -1936,7 +1829,7 @@ fn reserve(s: &const ~str, n: uint) { * * s - A string * * n - The number of bytes to reserve space for */ -fn reserve_at_least(s: &const ~str, n: uint) { +pub fn reserve_at_least(s: &const ~str, n: uint) { reserve(s, uint::next_power_of_two(n + 1u) - 1u) } @@ -1944,7 +1837,7 @@ fn reserve_at_least(s: &const ~str, n: uint) { * Returns the number of single-byte characters the string can hold without * reallocating */ -pure fn capacity(s: &const ~str) -> uint { +pub pure fn capacity(s: &const ~str) -> uint { do as_bytes(s) |buf| { let vcap = vec::capacity(buf); assert vcap > 0u; @@ -1953,7 +1846,7 @@ pure fn capacity(s: &const ~str) -> uint { } /// Escape each char in `s` with char::escape_default. -pure fn escape_default(s: &str) -> ~str { +pub pure fn escape_default(s: &str) -> ~str { let mut out: ~str = ~""; unsafe { reserve_at_least(&mut out, str::len(s)); @@ -1965,7 +1858,7 @@ pure fn escape_default(s: &str) -> ~str { } /// Escape each char in `s` with char::escape_unicode. -pure fn escape_unicode(s: &str) -> ~str { +pub pure fn escape_unicode(s: &str) -> ~str { let mut out: ~str = ~""; unsafe { reserve_at_least(&mut out, str::len(s)); @@ -1977,24 +1870,10 @@ pure fn escape_unicode(s: &str) -> ~str { } /// Unsafe operations -mod raw { - #[legacy_exports]; - export - from_buf, - from_buf_len, - from_c_str, - from_c_str_len, - from_bytes, - buf_as_slice, - slice_bytes, - view_bytes, - push_byte, - pop_byte, - shift_byte, - set_len; +pub mod raw { /// Create a Rust string from a null-terminated *u8 buffer - unsafe fn from_buf(buf: *u8) -> ~str { + pub unsafe fn from_buf(buf: *u8) -> ~str { let mut curr = buf, i = 0u; while *curr != 0u8 { i += 1u; @@ -2004,41 +1883,41 @@ mod raw { } /// Create a Rust string from a *u8 buffer of the given length - unsafe fn from_buf_len(buf: *const u8, len: uint) -> ~str { + pub unsafe fn from_buf_len(buf: *const u8, len: uint) -> ~str { let mut v: ~[u8] = vec::with_capacity(len + 1); vec::as_mut_buf(v, |vbuf, _len| { ptr::memcpy(vbuf, buf as *u8, len) }); - vec::raw::set_len(v, len); - vec::push(v, 0u8); + vec::raw::set_len(&mut v, len); + v.push(0u8); assert is_utf8(v); return ::cast::transmute(move v); } /// Create a Rust string from a null-terminated C string - unsafe fn from_c_str(c_str: *libc::c_char) -> ~str { + pub unsafe fn from_c_str(c_str: *libc::c_char) -> ~str { from_buf(::cast::reinterpret_cast(&c_str)) } /// Create a Rust string from a `*c_char` buffer of the given length - unsafe fn from_c_str_len(c_str: *libc::c_char, len: uint) -> ~str { + pub unsafe fn from_c_str_len(c_str: *libc::c_char, len: uint) -> ~str { from_buf_len(::cast::reinterpret_cast(&c_str), len) } /// Converts a vector of bytes to a string. - unsafe fn from_bytes(v: &[const u8]) -> ~str { + pub pub unsafe fn from_bytes(v: &[const u8]) -> ~str { do vec::as_const_buf(v) |buf, len| { from_buf_len(buf, len) } } /// Converts a byte to a string. - unsafe fn from_byte(u: u8) -> ~str { raw::from_bytes([u]) } + pub unsafe fn from_byte(u: u8) -> ~str { raw::from_bytes([u]) } /// Form a slice from a *u8 buffer of the given length without copying. - unsafe fn buf_as_slice(buf: *u8, len: uint, - f: fn(&&v: &str) -> T) -> T { + pub unsafe fn buf_as_slice(buf: *u8, len: uint, + f: fn(v: &str) -> T) -> T { let v = (buf, len + 1); assert is_utf8(::cast::reinterpret_cast(&v)); f(::cast::transmute(move v)) @@ -2054,7 +1933,7 @@ mod raw { * If begin is greater than end. * If end is greater than the length of the string. */ - unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> ~str { + pub unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> ~str { do as_buf(s) |sbuf, n| { assert (begin <= end); assert (end <= n); @@ -2066,8 +1945,8 @@ mod raw { let src = ptr::offset(sbuf, begin); ptr::memcpy(vbuf, src, end - begin); } - vec::raw::set_len(v, end - begin); - vec::push(v, 0u8); + vec::raw::set_len(&mut v, end - begin); + v.push(0u8); ::cast::transmute(move v) } } @@ -2084,7 +1963,7 @@ mod raw { * If end is greater than the length of the string. */ #[inline] - unsafe fn view_bytes(s: &str, begin: uint, end: uint) -> &str { + pub unsafe fn view_bytes(s: &str, begin: uint, end: uint) -> &str { do as_buf(s) |sbuf, n| { assert (begin <= end); assert (end <= n); @@ -2095,7 +1974,7 @@ mod raw { } /// Appends a byte to a string. (Not UTF-8 safe). - unsafe fn push_byte(s: &const ~str, b: u8) { + pub unsafe fn push_byte(s: &const ~str, b: u8) { reserve_at_least(s, s.len() + 1); do as_buf(*s) |buf, len| { let buf: *mut u8 = ::cast::reinterpret_cast(&buf); @@ -2111,7 +1990,7 @@ mod raw { } /// Removes the last byte from a string and returns it. (Not UTF-8 safe). - unsafe fn pop_byte(s: &const ~str) -> u8 { + pub unsafe fn pop_byte(s: &const ~str) -> u8 { let len = len(*s); assert (len > 0u); let b = s[len - 1u]; @@ -2120,7 +1999,7 @@ mod raw { } /// Removes the first byte from a string and returns it. (Not UTF-8 safe). - unsafe fn shift_byte(s: &mut ~str) -> u8 { + pub unsafe fn shift_byte(s: &mut ~str) -> u8 { let len = len(*s); assert (len > 0u); let b = s[0]; @@ -2129,11 +2008,11 @@ mod raw { } /// Sets the length of the string and adds the null terminator - unsafe fn set_len(v: &const ~str, new_len: uint) { + pub unsafe fn set_len(v: &const ~str, new_len: uint) { let v: **vec::raw::VecRepr = cast::transmute(copy v); let repr: *vec::raw::VecRepr = *v; (*repr).unboxed.fill = new_len + 1u; - let null = ptr::mut_offset(ptr::mut_addr_of((*repr).unboxed.data), + let null = ptr::mut_offset(ptr::mut_addr_of(&((*repr).unboxed.data)), new_len); *null = 0u8; } @@ -2150,7 +2029,7 @@ mod raw { } -trait UniqueStr { +pub trait UniqueStr { fn trim() -> self; fn trim_left() -> self; fn trim_right() -> self; @@ -2170,8 +2049,7 @@ impl ~str: UniqueStr { } #[cfg(notest)] -mod traits { - #[legacy_exports]; +pub mod traits { impl ~str : Add<&str,~str> { #[inline(always)] pure fn add(rhs: & &str) -> ~str { @@ -2181,10 +2059,9 @@ mod traits { } #[cfg(test)] -mod traits { - #[legacy_exports];} +pub mod traits {} -trait StrSlice { +pub trait StrSlice { fn all(it: fn(char) -> bool) -> bool; fn any(it: fn(char) -> bool) -> bool; fn contains(needle: &a/str) -> bool; @@ -2327,7 +2204,6 @@ impl &str: StrSlice { #[cfg(test)] mod tests { - #[legacy_exports]; use libc::c_char; diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 37403213ab26..12329616fbf9 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -7,21 +7,10 @@ use cmp::{Eq, Ord}; use libc::c_void; -export FreeGlue; -export TypeDesc; -export Closure; -export get_type_desc; -export size_of; -export min_align_of; -export pref_align_of; -export refcount; -export log_str; -export shape_eq, shape_lt, shape_le; - -type FreeGlue = fn(*TypeDesc, *c_void); +pub type FreeGlue = fn(*TypeDesc, *c_void); // Corresponds to runtime type_desc type -enum TypeDesc = { +pub enum TypeDesc = { size: uint, align: uint, take_glue: uint, @@ -31,14 +20,13 @@ enum TypeDesc = { }; /// The representation of a Rust closure -struct Closure { +pub struct Closure { code: *(), env: *(), } #[abi = "rust-intrinsic"] extern mod rusti { - #[legacy_exports]; fn get_tydesc() -> *(); fn size_of() -> uint; fn pref_align_of() -> uint; @@ -47,15 +35,15 @@ extern mod rusti { /// Compares contents of two pointers using the default method. /// Equivalent to `*x1 == *x2`. Useful for hashtables. -pure fn shape_eq(x1: &T, x2: &T) -> bool { +pub pure fn shape_eq(x1: &T, x2: &T) -> bool { *x1 == *x2 } -pure fn shape_lt(x1: &T, x2: &T) -> bool { +pub pure fn shape_lt(x1: &T, x2: &T) -> bool { *x1 < *x2 } -pure fn shape_le(x1: &T, x2: &T) -> bool { +pub pure fn shape_le(x1: &T, x2: &T) -> bool { *x1 <= *x2 } @@ -66,13 +54,13 @@ pure fn shape_le(x1: &T, x2: &T) -> bool { * performing dark magick. */ #[inline(always)] -pure fn get_type_desc() -> *TypeDesc { +pub pure fn get_type_desc() -> *TypeDesc { unsafe { rusti::get_tydesc::() as *TypeDesc } } /// Returns the size of a type #[inline(always)] -pure fn size_of() -> uint { +pub pure fn size_of() -> uint { unsafe { rusti::size_of::() } } @@ -83,26 +71,26 @@ pure fn size_of() -> uint { * than the preferred alignment. */ #[inline(always)] -pure fn min_align_of() -> uint { +pub pure fn min_align_of() -> uint { unsafe { rusti::min_align_of::() } } /// Returns the preferred alignment of a type #[inline(always)] -pure fn pref_align_of() -> uint { +pub pure fn pref_align_of() -> uint { unsafe { rusti::pref_align_of::() } } /// Returns the refcount of a shared box (as just before calling this) #[inline(always)] -pure fn refcount(+t: @T) -> uint { +pub pure fn refcount(t: @T) -> uint { unsafe { let ref_ptr: *uint = cast::reinterpret_cast(&t); *ref_ptr - 1 } } -pure fn log_str(t: &T) -> ~str { +pub pure fn log_str(t: &T) -> ~str { unsafe { do io::with_str_writer |wr| { repr::write_repr(wr, t) @@ -111,11 +99,10 @@ pure fn log_str(t: &T) -> ~str { } #[cfg(test)] -mod tests { - #[legacy_exports]; +pub mod tests { #[test] - fn size_of_basic() { + pub fn size_of_basic() { assert size_of::() == 1u; assert size_of::() == 2u; assert size_of::() == 4u; @@ -125,20 +112,20 @@ mod tests { #[test] #[cfg(target_arch = "x86")] #[cfg(target_arch = "arm")] - fn size_of_32() { + pub fn size_of_32() { assert size_of::() == 4u; assert size_of::<*uint>() == 4u; } #[test] #[cfg(target_arch = "x86_64")] - fn size_of_64() { + pub fn size_of_64() { assert size_of::() == 8u; assert size_of::<*uint>() == 8u; } #[test] - fn align_of_basic() { + pub fn align_of_basic() { assert pref_align_of::() == 1u; assert pref_align_of::() == 2u; assert pref_align_of::() == 4u; @@ -147,20 +134,20 @@ mod tests { #[test] #[cfg(target_arch = "x86")] #[cfg(target_arch = "arm")] - fn align_of_32() { + pub fn align_of_32() { assert pref_align_of::() == 4u; assert pref_align_of::<*uint>() == 4u; } #[test] #[cfg(target_arch = "x86_64")] - fn align_of_64() { + pub fn align_of_64() { assert pref_align_of::() == 8u; assert pref_align_of::<*uint>() == 8u; } #[test] - fn synthesize_closure() unsafe { + pub fn synthesize_closure() unsafe { let x = 10; let f: fn(int) -> int = |y| x + y; diff --git a/src/libcore/task.rs b/src/libcore/task.rs index 9e2949c37eff..5ca35a7f5623 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -1,5 +1,5 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; /*! @@ -32,54 +32,11 @@ use result::Result; use pipes::{stream, Chan, Port}; use local_data_priv::{local_get, local_set}; -export Task; -export TaskResult; -export Notification; -export SchedMode; -export SchedOpts; -export TaskOpts; -export TaskBuilder; - -export task; -export default_task_opts; -export get_opts; -export set_opts; -export set_sched_mode; -export add_wrapper; -export run; - -export future_result; -export run_listener; -export run_with; - -export spawn; -export spawn_unlinked; -export spawn_supervised; -export spawn_with; -export spawn_listener; -export spawn_conversation; -export spawn_sched; -export try; - -export yield; -export failing; -export get_task; -export unkillable, rekillable; -export atomically; - -export local_data; - -export SingleThreaded; -export ThreadPerCore; -export ThreadPerTask; -export ManualThreads; -export PlatformThread; - use rt::task_id; use rt::rust_task; /// A handle to a task -enum Task { +pub enum Task { TaskHandle(task_id) } @@ -99,7 +56,7 @@ impl Task : cmp::Eq { * If you wish for this result's delivery to block until all linked and/or * children tasks complete, recommend using a result future. */ -enum TaskResult { +pub enum TaskResult { Success, Failure, } @@ -115,7 +72,7 @@ impl TaskResult : Eq { } /// A message type for notifying of task lifecycle events -enum Notification { +pub enum Notification { /// Sent when a task exits with the task handle and result Exit(Task, TaskResult) } @@ -134,7 +91,7 @@ impl Notification : cmp::Eq { } /// Scheduler modes -enum SchedMode { +pub enum SchedMode { /// All tasks run in the same OS thread SingleThreaded, /// Tasks are distributed among available CPUs @@ -207,7 +164,7 @@ impl SchedMode : cmp::Eq { * default these foreign stacks have unspecified size, but with this * option their size can be precisely specified. */ -type SchedOpts = { +pub type SchedOpts = { mode: SchedMode, foreign_stack_size: Option }; @@ -239,7 +196,7 @@ type SchedOpts = { * into foreign code that blocks. Without doing so in a different * scheduler other tasks will be impeded or even blocked indefinitely. */ -type TaskOpts = { +pub type TaskOpts = { linked: bool, supervised: bool, mut notify_chan: Option>, @@ -260,7 +217,7 @@ type TaskOpts = { // the run function move them in. // FIXME (#2585): Replace the 'consumed' bit with move mode on self -enum TaskBuilder = { +pub enum TaskBuilder = { opts: TaskOpts, gen_body: fn@(+v: fn~()) -> fn~(), can_not_copy: Option, @@ -272,10 +229,10 @@ enum TaskBuilder = { * configuration methods can be chained. * For example, task().unlinked().spawn is equivalent to spawn_unlinked. */ -fn task() -> 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, }) @@ -390,7 +347,7 @@ impl TaskBuilder { * # Failure * Fails if a future_result was already set for this task. */ - fn future_result(blk: fn(+v: future::Future)) -> TaskBuilder { + fn future_result(blk: fn(v: future::Future)) -> TaskBuilder { // FIXME (#1087, #1857): Once linked failure and notification are // handled in the library, I can imagine implementing this by just // registering an arbitrary number of task::on_exit handlers and @@ -473,7 +430,7 @@ impl TaskBuilder { } /** - * Creates and exucutes a new child task + * Creates and executes a new child task * * Sets up a new task with its own call stack and schedules it to run * the provided unique closure. The task has the properties and behavior @@ -502,9 +459,9 @@ 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(+arg: A, +f: fn~(+v: A)) { + fn spawn_with(arg: A, +f: fn~(+v: A)) { let arg = ~mut Some(move arg); - do self.spawn |move arg, move f|{ + do self.spawn |move arg, move f| { f(option::swap_unwrap(arg)) } } @@ -516,7 +473,7 @@ impl TaskBuilder { * child task, passes the port to child's body, and returns a channel * linked to the port to the parent. * - * This encapsulates Some boilerplate handshaking logic that would + * This encapsulates some boilerplate handshaking logic that would * otherwise be required to establish communication from the parent * to the child. */ @@ -580,7 +537,7 @@ impl TaskBuilder { /* Task construction */ -fn default_task_opts() -> TaskOpts { +pub fn default_task_opts() -> TaskOpts { /*! * The default task options * @@ -598,7 +555,7 @@ fn default_task_opts() -> TaskOpts { /* Spawn convenience functions */ -fn spawn(+f: fn~()) { +pub fn spawn(+f: fn~()) { /*! * Creates and executes a new child task * @@ -611,7 +568,7 @@ fn spawn(+f: fn~()) { task().spawn(move f) } -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. @@ -620,7 +577,7 @@ fn spawn_unlinked(+f: fn~()) { task().unlinked().spawn(move f) } -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. @@ -629,7 +586,7 @@ fn spawn_supervised(+f: fn~()) { task().supervised().spawn(move f) } -fn spawn_with(+arg: A, +f: fn~(+v: A)) { +pub fn spawn_with(+arg: A, +f: fn~(+v: A)) { /*! * Runs a task, while transfering ownership of one argument to the * child. @@ -643,7 +600,7 @@ fn spawn_with(+arg: A, +f: fn~(+v: A)) { task().spawn_with(move arg, move f) } -fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan { +pub fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan { /*! * Runs a new task while providing a channel from the parent to the child * @@ -653,7 +610,7 @@ fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan { task().spawn_listener(move f) } -fn spawn_conversation +pub fn spawn_conversation (+f: fn~(comm::Port, comm::Chan)) -> (comm::Port, comm::Chan) { /*! @@ -665,7 +622,7 @@ fn spawn_conversation task().spawn_conversation(move f) } -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 * @@ -682,7 +639,7 @@ fn spawn_sched(mode: SchedMode, +f: fn~()) { task().sched_mode(mode).spawn(move f) } -fn try(+f: fn~() -> T) -> Result { +pub fn try(+f: fn~() -> T) -> Result { /*! * Execute a function in another task and return either the return value * of the function or result::err. @@ -696,7 +653,7 @@ fn try(+f: fn~() -> T) -> Result { /* Lifecycle functions */ -fn yield() { +pub fn yield() { //! Yield control to the task scheduler let task_ = rt::rust_get_task(); @@ -706,13 +663,13 @@ fn yield() { } } -fn failing() -> bool { +pub fn failing() -> bool { //! True if the running task has failed rt::rust_task_is_unwinding(rt::rust_get_task()) } -fn get_task() -> Task { +pub fn get_task() -> Task { //! Get a handle to the running task TaskHandle(rt::get_task_id()) @@ -733,7 +690,7 @@ fn get_task() -> Task { * } * ~~~ */ -unsafe fn unkillable(f: fn() -> U) -> U { +pub unsafe fn unkillable(f: fn() -> U) -> U { struct AllowFailure { t: *rust_task, drop { rt::rust_task_allow_kill(self.t); } @@ -752,7 +709,7 @@ unsafe fn unkillable(f: fn() -> U) -> U { } /// The inverse of unkillable. Only ever to be used nested in unkillable(). -unsafe fn rekillable(f: fn() -> U) -> U { +pub unsafe fn rekillable(f: fn() -> U) -> U { struct DisallowFailure { t: *rust_task, drop { rt::rust_task_inhibit_kill(self.t); } @@ -774,7 +731,7 @@ unsafe fn rekillable(f: fn() -> U) -> U { * A stronger version of unkillable that also inhibits scheduling operations. * For use with exclusive ARCs, which use pthread mutexes directly. */ -unsafe fn atomically(f: fn() -> U) -> U { +pub unsafe fn atomically(f: fn() -> U) -> U { struct DeferInterrupts { t: *rust_task, drop { @@ -1102,7 +1059,6 @@ fn test_spawn_sched_childs_on_same_sched() { #[nolink] #[cfg(test)] extern mod testrt { - #[legacy_exports]; fn rust_dbg_lock_create() -> *libc::c_void; fn rust_dbg_lock_destroy(lock: *libc::c_void); fn rust_dbg_lock_lock(lock: *libc::c_void); @@ -1175,10 +1131,10 @@ fn avoid_copying_the_body(spawnfn: fn(+v: fn~())) { let ch = comm::Chan(p); let x = ~1; - let x_in_parent = ptr::addr_of(*x) as uint; + let x_in_parent = ptr::p2::addr_of(&(*x)) as uint; do spawnfn { - let x_in_child = ptr::addr_of(*x) as uint; + let x_in_child = ptr::p2::addr_of(&(*x)) as uint; comm::send(ch, x_in_child); } @@ -1193,7 +1149,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) { f(); }); @@ -1211,7 +1167,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) { f(); }); diff --git a/src/libcore/task/local_data.rs b/src/libcore/task/local_data.rs index d91783284c03..2130354229a2 100644 --- a/src/libcore/task/local_data.rs +++ b/src/libcore/task/local_data.rs @@ -16,12 +16,6 @@ magic. */ -export LocalDataKey; -export local_data_pop; -export local_data_get; -export local_data_set; -export local_data_modify; - use local_data_priv::{ local_pop, local_get, @@ -43,13 +37,13 @@ use local_data_priv::{ * * These two cases aside, the interface is safe. */ -type LocalDataKey = &fn(+v: @T); +pub type LocalDataKey = &fn(v: @T); /** * Remove a task-local data value from the table, returning the * reference that was originally created to insert it. */ -unsafe fn local_data_pop( +pub unsafe fn local_data_pop( key: LocalDataKey) -> Option<@T> { local_pop(rt::rust_get_task(), key) @@ -58,7 +52,7 @@ unsafe fn local_data_pop( * Retrieve a task-local data value. It will also be kept alive in the * table until explicitly removed. */ -unsafe fn local_data_get( +pub unsafe fn local_data_get( key: LocalDataKey) -> Option<@T> { local_get(rt::rust_get_task(), key) @@ -67,8 +61,8 @@ unsafe fn local_data_get( * Store a value in task-local data. If this key already has a value, * that value is overwritten (and its destructor is run). */ -unsafe fn local_data_set( - key: LocalDataKey, +data: @T) { +pub unsafe fn local_data_set( + key: LocalDataKey, data: @T) { local_set(rt::rust_get_task(), key, data) } @@ -76,7 +70,7 @@ unsafe fn local_data_set( * Modify a task-local data value. If the function returns 'None', the * data is removed (and its reference dropped). */ -unsafe fn local_data_modify( +pub unsafe fn local_data_modify( key: LocalDataKey, modify_fn: fn(Option<@T>) -> Option<@T>) { @@ -84,8 +78,8 @@ unsafe fn local_data_modify( } #[test] -fn test_tls_multitask() unsafe { - fn my_key(+_x: @~str) { } +pub fn test_tls_multitask() unsafe { + fn my_key(_x: @~str) { } local_data_set(my_key, @~"parent data"); do task::spawn unsafe { assert local_data_get(my_key).is_none(); // TLS shouldn't carry over. @@ -100,16 +94,16 @@ fn test_tls_multitask() unsafe { } #[test] -fn test_tls_overwrite() unsafe { - fn my_key(+_x: @~str) { } +pub 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. assert *(local_data_get(my_key).get()) == ~"next data"; } #[test] -fn test_tls_pop() unsafe { - fn my_key(+_x: @~str) { } +pub fn test_tls_pop() unsafe { + fn my_key(_x: @~str) { } local_data_set(my_key, @~"weasel"); assert *(local_data_pop(my_key).get()) == ~"weasel"; // Pop must remove the data from the map. @@ -117,18 +111,18 @@ fn test_tls_pop() unsafe { } #[test] -fn test_tls_modify() unsafe { - fn my_key(+_x: @~str) { } +pub fn test_tls_modify() unsafe { + fn my_key(_x: @~str) { } local_data_modify(my_key, |data| { match data { - Some(@val) => fail ~"unwelcome value: " + val, + Some(@ref val) => fail ~"unwelcome value: " + *val, None => Some(@~"first data") } }); local_data_modify(my_key, |data| { match data { Some(@~"first data") => Some(@~"next data"), - Some(@val) => fail ~"wrong value: " + val, + Some(@ref val) => fail ~"wrong value: " + *val, None => fail ~"missing value" } }); @@ -136,23 +130,23 @@ fn test_tls_modify() unsafe { } #[test] -fn test_tls_crust_automorestack_memorial_bug() unsafe { +pub 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 // Something within a rust stack segment. Then a subsequent upcall (esp. // for logging, think vsnprintf) would run on a stack smaller than 1 MB. - fn my_key(+_x: @~str) { } + fn my_key(_x: @~str) { } do task::spawn { unsafe { local_data_set(my_key, @~"hax"); } } } #[test] -fn test_tls_multiple_types() unsafe { - fn str_key(+_x: @~str) { } - fn box_key(+_x: @@()) { } - fn int_key(+_x: @int) { } +pub fn test_tls_multiple_types() unsafe { + fn str_key(_x: @~str) { } + fn box_key(_x: @@()) { } + fn int_key(_x: @int) { } do task::spawn unsafe { local_data_set(str_key, @~"string data"); local_data_set(box_key, @@()); @@ -161,10 +155,10 @@ fn test_tls_multiple_types() unsafe { } #[test] -fn test_tls_overwrite_multiple_types() { - fn str_key(+_x: @~str) { } - fn box_key(+_x: @@()) { } - fn int_key(+_x: @int) { } +pub fn test_tls_overwrite_multiple_types() { + fn str_key(_x: @~str) { } + fn box_key(_x: @@()) { } + fn int_key(_x: @int) { } do task::spawn unsafe { local_data_set(str_key, @~"string data"); local_data_set(int_key, @42); @@ -177,10 +171,10 @@ fn test_tls_overwrite_multiple_types() { #[test] #[should_fail] #[ignore(cfg(windows))] -fn test_tls_cleanup_on_failure() unsafe { - fn str_key(+_x: @~str) { } - fn box_key(+_x: @@()) { } - fn int_key(+_x: @int) { } +pub fn test_tls_cleanup_on_failure() unsafe { + fn str_key(_x: @~str) { } + fn box_key(_x: @@()) { } + fn int_key(_x: @int) { } local_data_set(str_key, @~"parent data"); local_data_set(box_key, @@()); do task::spawn unsafe { // spawn_linked diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs index 2fbb88327ed3..9849ce7b68cd 100644 --- a/src/libcore/task/local_data_priv.rs +++ b/src/libcore/task/local_data_priv.rs @@ -3,7 +3,7 @@ use local_data::LocalDataKey; use rt::rust_task; -trait LocalData { } +pub trait LocalData { } impl @T: LocalData { } impl LocalData: Eq { @@ -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. -type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData); +pub type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData); // Has to be a pointer at outermost layer; the foreign call returns void *. -type TaskLocalMap = @dvec::DVec>; +pub type TaskLocalMap = @dvec::DVec>; -extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe { +pub 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 @@ 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. -unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { +pub 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 @@ unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap { } } -unsafe fn key_to_key_value( +pub unsafe fn key_to_key_value( key: LocalDataKey) -> *libc::c_void { // Keys are closures, which are (fnptr,envptr) pairs. Use fnptr. @@ -62,25 +62,25 @@ unsafe fn key_to_key_value( } // If returning Some(..), returns with @T with the map's reference. Careful! -unsafe fn local_data_lookup( +pub unsafe fn local_data_lookup( map: TaskLocalMap, key: LocalDataKey) -> Option<(uint, *libc::c_void)> { let key_value = key_to_key_value(key); let map_pos = (*map).position(|entry| - match entry { + match *entry { Some((k,_,_)) => k == key_value, None => false } ); do map_pos.map |index| { // .get() is guaranteed because of "None { false }" above. - let (_, data_ptr, _) = (*map)[index].get(); - (index, data_ptr) + let (_, data_ptr, _) = (*map)[*index].get(); + (*index, data_ptr) } } -unsafe fn local_get_helper( +pub unsafe fn local_get_helper( task: *rust_task, key: LocalDataKey, do_pop: bool) -> Option<@T> { @@ -91,7 +91,7 @@ unsafe fn local_get_helper( // was referenced in the local_data box, though, not here, so before // overwriting the local_data_box we need to give an extra reference. // We must also give an extra reference when not removing. - let (index, data_ptr) = result; + let (index, data_ptr) = *result; let data: @T = cast::transmute(move data_ptr); cast::bump_box_refcount(data); if do_pop { @@ -102,22 +102,22 @@ unsafe fn local_get_helper( } -unsafe fn local_pop( +pub unsafe fn local_pop( task: *rust_task, key: LocalDataKey) -> Option<@T> { local_get_helper(task, key, true) } -unsafe fn local_get( +pub unsafe fn local_get( task: *rust_task, key: LocalDataKey) -> Option<@T> { local_get_helper(task, key, false) } -unsafe fn local_set( - task: *rust_task, key: LocalDataKey, +data: @T) { +pub unsafe fn local_set( + task: *rust_task, key: LocalDataKey, data: @T) { let map = get_task_local_map(task); // Store key+data as *voids. Data is invisibly referenced once; key isn't. @@ -148,7 +148,7 @@ unsafe fn local_set( } } -unsafe fn local_modify( +pub unsafe fn local_modify( task: *rust_task, key: LocalDataKey, modify_fn: fn(Option<@T>) -> Option<@T>) { diff --git a/src/libcore/task/rt.rs b/src/libcore/task/rt.rs index b1f7b99bd071..db3d1ec9f709 100644 --- a/src/libcore/task/rt.rs +++ b/src/libcore/task/rt.rs @@ -7,16 +7,16 @@ The task interface to the runtime #[doc(hidden)]; // FIXME #3538 #[allow(non_camel_case_types)] // runtime type -type sched_id = int; +pub type sched_id = int; #[allow(non_camel_case_types)] // runtime type -type task_id = int; +pub type task_id = int; // These are both opaque runtime/compiler types that we don't know the // structure of and should only deal with via unsafe pointer #[allow(non_camel_case_types)] // runtime type -type rust_task = libc::c_void; +pub type rust_task = libc::c_void; #[allow(non_camel_case_types)] // runtime type -type rust_closure = libc::c_void; +pub type rust_closure = libc::c_void; extern { #[rust_stack] diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 21f217d57f46..0e1284da3bcb 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -66,28 +66,28 @@ use rt::rust_task; use rt::rust_closure; macro_rules! move_it ( - { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); move y } } + { $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); move y } } ) -type TaskSet = send_map::linear::LinearMap<*rust_task,()>; +pub type TaskSet = send_map::linear::LinearMap<*rust_task,()>; -fn new_taskset() -> TaskSet { +pub fn new_taskset() -> TaskSet { send_map::linear::LinearMap() } -fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) { +pub fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) { let didnt_overwrite = tasks.insert(task, ()); assert didnt_overwrite; } -fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { +pub fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { let was_present = tasks.remove(&task); assert was_present; } -fn taskset_each(tasks: &TaskSet, blk: fn(+v: *rust_task) -> bool) { +pub fn taskset_each(tasks: &TaskSet, blk: fn(v: *rust_task) -> bool) { tasks.each_key(|k| blk(*k)) } // One of these per group of linked-failure tasks. -type TaskGroupData = { +pub 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 +95,12 @@ type TaskGroupData = { // tasks in this group. mut descendants: TaskSet, }; -type TaskGroupArc = private::Exclusive>; +pub type TaskGroupArc = private::Exclusive>; -type TaskGroupInner = &mut Option; +pub type TaskGroupInner = &mut Option; // A taskgroup is 'dead' when nothing can cause it to fail; only members can. -pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool { +pub pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool { (&tg.members).is_empty() } @@ -111,7 +111,7 @@ 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. -type AncestorNode = { +pub 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 +124,16 @@ type AncestorNode = { // Recursive rest of the list. mut ancestors: AncestorList, }; -enum AncestorList = Option>; +pub enum AncestorList = Option>; // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. #[inline(always)] -fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U { +pub fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U { unsafe { x.with(blk) } } #[inline(always)] -fn access_ancestors(x: &private::Exclusive, +pub fn access_ancestors(x: &private::Exclusive, blk: fn(x: &mut AncestorNode) -> U) -> U { unsafe { x.with(blk) } } @@ -146,9 +146,9 @@ fn access_ancestors(x: &private::Exclusive, // (3) As a bonus, coalesces away all 'dead' taskgroup nodes in the list. // FIXME(#2190): Change Option to Option, to save on // allocations. Once that bug is fixed, changing the sigil should suffice. -fn each_ancestor(list: &mut AncestorList, - bail_opt: Option, - forward_blk: fn(TaskGroupInner) -> bool) +pub fn each_ancestor(list: &mut AncestorList, + bail_opt: Option, + forward_blk: fn(TaskGroupInner) -> bool) -> bool { // "Kickoff" call - there was no last generation. return !coalesce(list, bail_opt, forward_blk, uint::max_value); @@ -200,7 +200,7 @@ fn each_ancestor(list: &mut AncestorList, // the end of the list, which doesn't make sense to coalesce. return do (**ancestors).map_default((None,false)) |ancestor_arc| { // NB: Takes a lock! (this ancestor node) - do access_ancestors(&ancestor_arc) |nobe| { + do access_ancestors(ancestor_arc) |nobe| { // Check monotonicity assert last_generation > nobe.generation; /*##########################################################* @@ -240,7 +240,7 @@ fn each_ancestor(list: &mut AncestorList, if need_unwind && !nobe_is_dead { do bail_opt.iter |bail_blk| { do with_parent_tg(&mut nobe.parent_group) |tg_opt| { - bail_blk(tg_opt) + (*bail_blk)(tg_opt) } } } @@ -271,7 +271,7 @@ fn each_ancestor(list: &mut AncestorList, } // One of these per task. -struct TCB { +pub 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,8 +303,8 @@ struct TCB { } } -fn TCB(me: *rust_task, +tasks: TaskGroupArc, +ancestors: AncestorList, - is_main: bool, +notifier: Option) -> TCB { +pub fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList, + is_main: bool, notifier: Option) -> TCB { let notifier = move notifier; notifier.iter(|x| { x.failed = false; }); @@ -318,7 +318,7 @@ fn TCB(me: *rust_task, +tasks: TaskGroupArc, +ancestors: AncestorList, } } -struct AutoNotify { +pub struct AutoNotify { notify_chan: Chan, mut failed: bool, drop { @@ -327,15 +327,15 @@ struct AutoNotify { } } -fn AutoNotify(+chan: Chan) -> AutoNotify { +pub fn AutoNotify(chan: Chan) -> AutoNotify { AutoNotify { notify_chan: chan, failed: true // Un-set above when taskgroup successfully made. } } -fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task, - is_member: bool) -> bool { +pub 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. if newstate.is_some() { @@ -350,7 +350,8 @@ fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task, } // NB: Runs in destructor/post-exit context. Can't 'fail'. -fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, is_member: bool) { +pub 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. if newstate.is_some() { @@ -362,7 +363,7 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task, is_member: bool) { } // NB: Runs in destructor/post-exit context. Can't 'fail'. -fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) { +pub 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 @@ -377,13 +378,13 @@ fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) { // see 'None' if Somebody already failed and we got a kill signal.) if newstate.is_some() { let group = option::unwrap(move newstate); - for taskset_each(&group.members) |+sibling| { + for taskset_each(&group.members) |sibling| { // Skip self - killing ourself won't do much good. if sibling != me { rt::rust_task_kill_other(sibling); } } - for taskset_each(&group.descendants) |+child| { + for taskset_each(&group.descendants) |child| { assert child != me; rt::rust_task_kill_other(child); } @@ -404,8 +405,8 @@ macro_rules! taskgroup_key ( () => (cast::transmute((-2 as uint, 0u))) ) -fn gen_child_taskgroup(linked: bool, supervised: bool) - -> (TaskGroupArc, AncestorList, bool) { +pub fn gen_child_taskgroup(linked: bool, supervised: bool) + -> (TaskGroupArc, AncestorList, bool) { let spawner = rt::rust_get_task(); /*######################################################################* * Step 1. Get spawner's taskgroup info. @@ -451,7 +452,9 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) // it should be enabled only in debug builds. let new_generation = match *old_ancestors { - Some(arc) => access_ancestors(&arc, |a| a.generation+1), + Some(ref arc) => { + access_ancestors(arc, |a| a.generation+1) + } None => 0 // the actual value doesn't really matter. }; assert new_generation < uint::max_value; @@ -484,7 +487,7 @@ fn gen_child_taskgroup(linked: bool, supervised: bool) } } -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); @@ -509,8 +512,8 @@ fn spawn_raw(+opts: TaskOpts, +f: fn~()) { let child_wrapper = make_child_wrapper(new_task, move child_tg, move ancestors, is_main, move notify_chan, move f); - let fptr = ptr::addr_of(child_wrapper); - let closure: *rust_closure = cast::reinterpret_cast(&fptr); + + let closure = cast::transmute(&child_wrapper); // Getting killed between these two calls would free the child's // closure. (Reordering them wouldn't help - then getting killed @@ -526,9 +529,9 @@ fn spawn_raw(+opts: TaskOpts, +f: fn~()) { // (3a) If any of those fails, it leaves all groups, and does nothing. // (3b) Otherwise it builds a task control structure and puts it in TLS, // (4) ...and runs the provided body function. - fn make_child_wrapper(child: *rust_task, +child_arc: TaskGroupArc, - +ancestors: AncestorList, is_main: bool, - +notify_chan: Option>, + fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc, + ancestors: AncestorList, is_main: bool, + notify_chan: Option>, +f: fn~()) -> fn~() { let child_data = ~mut Some((move child_arc, move ancestors)); return fn~(move notify_chan, move child_data, move f) { @@ -541,8 +544,8 @@ fn spawn_raw(+opts: TaskOpts, +f: fn~()) { //let mut notifier = None;//notify_chan.map(|c| AutoNotify(c)); let notifier = match notify_chan { - Some(notify_chan_value) => { - let moved_ncv = move_it!(notify_chan_value); + Some(ref notify_chan_value) => { + let moved_ncv = move_it!(*notify_chan_value); Some(AutoNotify(move moved_ncv)) } _ => None diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index db5907743707..ef15aa00f113 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -10,7 +10,7 @@ The `ToBytes` and `IterBytes` traits use io::Writer; -type Cb = fn(buf: &[const u8]) -> bool; +pub type Cb = fn(buf: &[const u8]) -> bool; /** * A trait to implement in order to make a type hashable; @@ -19,7 +19,7 @@ type Cb = fn(buf: &[const u8]) -> bool; * modified when default methods and trait inheritence are * completed. */ -trait IterBytes { +pub trait IterBytes { /** * Call the provided callback `f` one or more times with * byte-slices that should be used when computing a hash @@ -211,7 +211,7 @@ impl @[A]: IterBytes { } } -pure fn iter_bytes_2(a: &A, b: &B, +pub pure fn iter_bytes_2(a: &A, b: &B, lsb0: bool, z: Cb) { let mut flag = true; a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); @@ -219,7 +219,7 @@ pure fn iter_bytes_2(a: &A, b: &B, b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag}); } -pure fn iter_bytes_3(a: &A, b: &B, c: &C, lsb0: bool, z: Cb) { @@ -231,7 +231,7 @@ pure fn iter_bytes_3(a: &A, b: &B, c: &C, @@ -247,7 +247,7 @@ pure fn iter_bytes_4 Option: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { match self { - Some(a) => iter_bytes_2(&0u8, &a, lsb0, f), + Some(ref a) => iter_bytes_2(&0u8, a, lsb0, f), None => 1u8.iter_bytes(lsb0, f) } } diff --git a/src/libcore/to_str.rs b/src/libcore/to_str.rs index f279945a1610..a3659937ad45 100644 --- a/src/libcore/to_str.rs +++ b/src/libcore/to_str.rs @@ -8,7 +8,7 @@ The `ToStr` trait for converting to strings #[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; -trait ToStr { fn to_str() -> ~str; } +pub trait ToStr { fn to_str() -> ~str; } impl int: ToStr { fn to_str() -> ~str { int::str(self) } @@ -101,7 +101,6 @@ impl ~A: ToStr { #[cfg(test)] #[allow(non_implicitly_copyable_typarams)] mod tests { - #[legacy_exports]; #[test] fn test_simple_types() { assert 1.to_str() == ~"1"; diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs index 8ec6ed3f0c24..246ce16c8131 100644 --- a/src/libcore/tuple.rs +++ b/src/libcore/tuple.rs @@ -6,7 +6,7 @@ use cmp::{Eq, Ord}; -trait TupleOps { +pub trait TupleOps { pure fn first() -> T; pure fn second() -> U; pure fn swap() -> (U, T); @@ -34,49 +34,54 @@ impl (T, U): TupleOps { } -trait ExtendedTupleOps { - fn zip() -> ~[(A, B)]; - fn map(f: fn(A, B) -> C) -> ~[C]; +pub trait ExtendedTupleOps { + fn zip(&self) -> ~[(A, B)]; + fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C]; } impl (&[A], &[B]): ExtendedTupleOps { - - fn zip() -> ~[(A, B)] { - let (a, b) = self; - vec::zip_slice(a, b) + fn zip(&self) -> ~[(A, B)] { + match *self { + (ref a, ref b) => { + vec::zip_slice(*a, *b) + } + } } - fn map(f: fn(A, B) -> C) -> ~[C] { - let (a, b) = self; - vec::map2(a, b, f) + fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] { + match *self { + (ref a, ref b) => { + vec::map2(*a, *b, f) + } + } } } impl (~[A], ~[B]): ExtendedTupleOps { - fn zip() -> ~[(A, B)] { - // FIXME #2543: Bad copy - let (a, b) = copy self; - vec::zip(move a, move b) + fn zip(&self) -> ~[(A, B)] { + match *self { + (ref a, ref b) => { + vec::zip_slice(*a, *b) + } + } } - fn map(f: fn(A, B) -> C) -> ~[C] { - // FIXME #2543: Bad copy - let (a, b) = copy self; - vec::map2(a, b, f) + fn map(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C] { + match *self { + (ref a, ref b) => { + vec::map2(*a, *b, f) + } + } } } impl (A, B) : Eq { pure fn eq(other: &(A, B)) -> bool { - // XXX: This would be a lot less wordy with ref bindings, but I don't - // trust that they work yet. match self { - (self_a, self_b) => { - match (*other) { - (ref other_a, ref other_b) => { - self_a.eq(other_a) && self_b.eq(other_b) - } + (ref self_a, ref self_b) => match other { + &(ref other_a, ref other_b) => { + (*self_a).eq(other_a) && (*self_b).eq(other_b) } } } @@ -106,16 +111,11 @@ impl (A, B) : Ord { impl (A, B, C) : Eq { pure fn eq(other: &(A, B, C)) -> bool { - // XXX: This would be a lot less wordy with ref bindings, but I don't - // trust that they work yet. match self { - (self_a, self_b, self_c) => { - match (*other) { - (ref other_a, ref other_b, ref other_c) => { - self_a.eq(other_a) && - self_b.eq(other_b) && - self_c.eq(other_c) - } + (ref self_a, ref self_b, ref self_c) => match other { + &(ref other_a, ref other_b, ref other_c) => { + (*self_a).eq(other_a) && (*self_b).eq(other_b) + && (*self_c).eq(other_c) } } } diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs index dba28ec06e61..7d0421c07301 100644 --- a/src/libcore/uint-template.rs +++ b/src/libcore/uint-template.rs @@ -6,49 +6,36 @@ use T = inst::T; use cmp::{Eq, Ord}; use from_str::FromStr; -export min_value, max_value; -export min, max; -export add, sub, mul, div, rem; -export lt, le, eq, ne, ge, gt; -export is_positive, is_negative; -export is_nonpositive, is_nonnegative; -export range; -export compl; -export to_str, to_str_bytes; -export from_str, from_str_radix, str, parse_bytes; -export num, ord, eq, times, timesi; -export bits, bytes; +pub const bits : uint = inst::bits; +pub const bytes : uint = (inst::bits / 8); -const bits : uint = inst::bits; -const bytes : uint = (inst::bits / 8); +pub const min_value: T = 0 as T; +pub const max_value: T = 0 as T - 1 as T; -const min_value: T = 0 as T; -const max_value: T = 0 as T - 1 as T; +pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } } +pub pure fn max(x: T, y: T) -> T { if x > y { x } else { y } } -pure fn min(x: T, y: T) -> T { if x < y { x } else { y } } -pure fn max(x: T, y: T) -> T { if x > y { x } else { y } } +pub pure fn add(x: T, y: T) -> T { x + y } +pub pure fn sub(x: T, y: T) -> T { x - y } +pub pure fn mul(x: T, y: T) -> T { x * y } +pub pure fn div(x: T, y: T) -> T { x / y } +pub pure fn rem(x: T, y: T) -> T { x % y } -pure fn add(x: T, y: T) -> T { x + y } -pure fn sub(x: T, y: T) -> T { x - y } -pure fn mul(x: T, y: T) -> T { x * y } -pure fn div(x: T, y: T) -> T { x / y } -pure fn rem(x: T, y: T) -> T { x % y } +pub pure fn lt(x: T, y: T) -> bool { x < y } +pub pure fn le(x: T, y: T) -> bool { x <= y } +pub pure fn eq(x: T, y: T) -> bool { x == y } +pub pure fn ne(x: T, y: T) -> bool { x != y } +pub pure fn ge(x: T, y: T) -> bool { x >= y } +pub pure fn gt(x: T, y: T) -> bool { x > y } -pure fn lt(x: T, y: T) -> bool { x < y } -pure fn le(x: T, y: T) -> bool { x <= y } -pure fn eq(x: T, y: T) -> bool { x == y } -pure fn ne(x: T, y: T) -> bool { x != y } -pure fn ge(x: T, y: T) -> bool { x >= y } -pure fn gt(x: T, y: T) -> bool { x > y } - -pure fn is_positive(x: T) -> bool { x > 0 as T } -pure fn is_negative(x: T) -> bool { x < 0 as T } -pure fn is_nonpositive(x: T) -> bool { x <= 0 as T } -pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } +pub pure fn is_positive(x: T) -> bool { x > 0 as T } +pub pure fn is_negative(x: T) -> bool { x < 0 as T } +pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T } +pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T } #[inline(always)] /// Iterate over the range [`lo`..`hi`) -pure fn range(lo: T, hi: T, it: fn(T) -> bool) { +pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) { let mut i = lo; while i < hi { if !it(i) { break } @@ -57,7 +44,7 @@ pure fn range(lo: T, hi: T, it: fn(T) -> bool) { } /// Computes the bitwise complement -pure fn compl(i: T) -> T { +pub pure fn compl(i: T) -> T { max_value ^ i } @@ -74,11 +61,11 @@ impl T : Eq { } impl T: num::Num { - pure fn add(&&other: T) -> T { return self + other; } - pure fn sub(&&other: T) -> T { return self - other; } - pure fn mul(&&other: T) -> T { return self * other; } - pure fn div(&&other: T) -> T { return self / other; } - pure fn modulo(&&other: T) -> T { return self % other; } + pure fn add(other: &T) -> T { return self + *other; } + pure fn sub(other: &T) -> T { return self - *other; } + pure fn mul(other: &T) -> T { return self * *other; } + pure fn div(other: &T) -> T { return self / *other; } + pure fn modulo(other: &T) -> T { return self % *other; } pure fn neg() -> T { return -self; } pure fn to_int() -> int { return self as int; } @@ -126,7 +113,7 @@ impl T: iter::TimesIx { * * `buf` must not be empty */ -fn parse_bytes(buf: &[const u8], radix: uint) -> Option { +pub fn parse_bytes(buf: &[const u8], radix: uint) -> Option { if vec::len(buf) == 0u { return None; } let mut i = vec::len(buf) - 1u; let mut power = 1u as T; @@ -143,14 +130,14 @@ fn parse_bytes(buf: &[const u8], radix: uint) -> Option { } /// Parse a string to an int -fn from_str(s: &str) -> Option { parse_bytes(str::to_bytes(s), 10u) } +pub fn from_str(s: &str) -> Option { parse_bytes(str::to_bytes(s), 10u) } impl T : FromStr { static fn from_str(s: &str) -> Option { from_str(s) } } /// Parse a string as an unsigned integer. -fn from_str_radix(buf: &str, radix: u64) -> Option { +pub fn from_str_radix(buf: &str, radix: u64) -> Option { if str::len(buf) == 0u { return None; } let mut i = str::len(buf) - 1u; let mut power = 1u64, n = 0u64; @@ -172,7 +159,7 @@ fn from_str_radix(buf: &str, radix: u64) -> Option { * * Fails if `radix` < 2 or `radix` > 16 */ -pure fn to_str(num: T, radix: uint) -> ~str { +pub pure fn to_str(num: T, radix: uint) -> ~str { do to_str_bytes(false, num, radix) |slice| { do vec::as_imm_buf(slice) |p, len| { unsafe { str::raw::from_buf_len(p, len) } @@ -181,7 +168,7 @@ pure fn to_str(num: T, radix: uint) -> ~str { } /// Low-level helper routine for string conversion. -pure fn to_str_bytes(neg: bool, num: T, radix: uint, +pub pure fn to_str_bytes(neg: bool, num: T, radix: uint, f: fn(v: &[u8]) -> U) -> U { #[inline(always)] @@ -239,17 +226,16 @@ pure fn to_str_bytes(neg: bool, num: T, radix: uint, *ptr::mut_offset(mp, i) = '-' as u8; } - vec::raw::form_slice(ptr::offset(p, i), - len - i, f) + vec::raw::buf_as_slice(ptr::offset(p, i), len - i, f) } } } /// Convert to a string -fn str(i: T) -> ~str { return to_str(i, 10u); } +pub fn str(i: T) -> ~str { return to_str(i, 10u); } #[test] -fn test_to_str() { +pub fn test_to_str() { assert to_str(0 as T, 10u) == ~"0"; assert to_str(1 as T, 10u) == ~"1"; assert to_str(2 as T, 10u) == ~"2"; @@ -261,7 +247,7 @@ fn test_to_str() { #[test] #[ignore] -fn test_from_str() { +pub fn test_from_str() { assert from_str(~"0") == Some(0u as T); assert from_str(~"3") == Some(3u as T); assert from_str(~"10") == Some(10u as T); @@ -275,7 +261,7 @@ fn test_from_str() { #[test] #[ignore] -fn test_parse_bytes() { +pub fn test_parse_bytes() { use str::to_bytes; assert parse_bytes(to_bytes(~"123"), 10u) == Some(123u as T); assert parse_bytes(to_bytes(~"1001"), 2u) == Some(9u as T); @@ -291,19 +277,19 @@ fn test_parse_bytes() { #[test] #[should_fail] #[ignore(cfg(windows))] -fn to_str_radix1() { +pub fn to_str_radix1() { uint::to_str(100u, 1u); } #[test] #[should_fail] #[ignore(cfg(windows))] -fn to_str_radix17() { +pub fn to_str_radix17() { uint::to_str(100u, 17u); } #[test] -fn test_times() { +pub fn test_times() { use iter::Times; let ten = 10 as T; let mut accum = 0; diff --git a/src/libcore/uint-template/u16.rs b/src/libcore/uint-template/u16.rs index b84b975c6859..d8e078eb65c2 100644 --- a/src/libcore/uint-template/u16.rs +++ b/src/libcore/uint-template/u16.rs @@ -1,2 +1,2 @@ -type T = u16; -const bits: uint = 16; +pub type T = u16; +pub const bits: uint = 16; diff --git a/src/libcore/uint-template/u32.rs b/src/libcore/uint-template/u32.rs index d5324e03a16d..0e2eb2f09e1d 100644 --- a/src/libcore/uint-template/u32.rs +++ b/src/libcore/uint-template/u32.rs @@ -1,2 +1,2 @@ -type T = u32; -const bits: uint = 32; \ No newline at end of file +pub type T = u32; +pub const bits: uint = 32; \ No newline at end of file diff --git a/src/libcore/uint-template/u64.rs b/src/libcore/uint-template/u64.rs index ee7f35bf6e31..030c6379628c 100644 --- a/src/libcore/uint-template/u64.rs +++ b/src/libcore/uint-template/u64.rs @@ -1,2 +1,2 @@ -type T = u64; -const bits: uint = 64; \ No newline at end of file +pub type T = u64; +pub const bits: uint = 64; \ No newline at end of file diff --git a/src/libcore/uint-template/u8.rs b/src/libcore/uint-template/u8.rs index b7df2605db41..539567a2cfd4 100644 --- a/src/libcore/uint-template/u8.rs +++ b/src/libcore/uint-template/u8.rs @@ -1,7 +1,7 @@ -type T = u8; -const bits: uint = 8; +pub type T = u8; +pub const bits: uint = 8; // Type-specific functions here. These must be reexported by the // parent module so that they appear in core::u8 and not core::u8::u8; -pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; } +pub pure fn is_ascii(x: T) -> bool { return 0 as T == x & 128 as T; } diff --git a/src/libcore/uint-template/uint.rs b/src/libcore/uint-template/uint.rs index a02ce84052e2..24beaad4d5e8 100644 --- a/src/libcore/uint-template/uint.rs +++ b/src/libcore/uint-template/uint.rs @@ -1,11 +1,11 @@ -type T = uint; +pub type T = uint; #[cfg(target_arch = "x86")] #[cfg(target_arch = "arm")] -const bits: uint = 32; +pub const bits: uint = 32; #[cfg(target_arch = "x86_64")] -const bits: uint = 64; +pub const bits: uint = 64; /** * Divide two numbers, return the result, rounded up. @@ -19,7 +19,7 @@ const bits: uint = 64; * * The smallest integer `q` such that `x/y <= q`. */ -pure fn div_ceil(x: uint, y: uint) -> uint { +pub pure fn div_ceil(x: uint, y: uint) -> uint { let div = x / y; if x % y == 0u { div } else { div + 1u } @@ -37,7 +37,7 @@ pure fn div_ceil(x: uint, y: uint) -> uint { * * The integer `q` closest to `x/y`. */ -pure fn div_round(x: uint, y: uint) -> uint { +pub pure fn div_round(x: uint, y: uint) -> uint { let div = x / y; if x % y * 2u < y { div } else { div + 1u } @@ -58,7 +58,7 @@ pure fn div_round(x: uint, y: uint) -> uint { * The smallest integer `q` such that `x/y <= q`. This * is either `x/y` or `x/y + 1`. */ -pure fn div_floor(x: uint, y: uint) -> uint { return x / y; } +pub pure fn div_floor(x: uint, y: uint) -> uint { return x / y; } /** * Iterate over the range [`lo`..`hi`), or stop when requested @@ -75,7 +75,7 @@ pure fn div_floor(x: uint, y: uint) -> uint { return x / y; } * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool { +pub pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool { let mut i = lo; while i < hi { if (!it(i)) { return false; } @@ -86,7 +86,7 @@ pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool { /// Returns the smallest power of 2 greater than or equal to `n` #[inline(always)] -fn next_power_of_two(n: uint) -> uint { +pub fn next_power_of_two(n: uint) -> uint { let halfbits: uint = sys::size_of::() * 4u; let mut tmp: uint = n - 1u; let mut shift: uint = 1u; diff --git a/src/libcore/unicode.rs b/src/libcore/unicode.rs index ef26ae5d223c..9341ef7cef43 100644 --- a/src/libcore/unicode.rs +++ b/src/libcore/unicode.rs @@ -3,9 +3,8 @@ #[forbid(deprecated_mode)]; #[forbid(deprecated_pattern)]; -mod general_category { - #[legacy_exports]; - pure fn Cc(c: char) -> bool { +pub mod general_category { + pub pure fn Cc(c: char) -> bool { return match c { '\x00' .. '\x1f' | '\x7f' .. '\x9f' => true, @@ -13,7 +12,7 @@ mod general_category { }; } - pure fn Cf(c: char) -> bool { + pub pure fn Cf(c: char) -> bool { return match c { '\xad' | '\u0600' .. '\u0603' @@ -32,21 +31,21 @@ mod general_category { }; } - pure fn Co(c: char) -> bool { + pub pure fn Co(c: char) -> bool { return match c { '\ue000' .. '\uf8ff' => true, _ => false }; } - pure fn Cs(c: char) -> bool { + pub pure fn Cs(c: char) -> bool { return match c { '\ud800' .. '\udfff' => true, _ => false }; } - pure fn Ll(c: char) -> bool { + pub pure fn Ll(c: char) -> bool { return match c { '\x61' .. '\x7a' | '\xaa' @@ -651,7 +650,7 @@ mod general_category { }; } - pure fn Lm(c: char) -> bool { + pub pure fn Lm(c: char) -> bool { return match c { '\u02b0' .. '\u02c1' | '\u02c6' .. '\u02d1' @@ -707,7 +706,7 @@ mod general_category { }; } - pure fn Lo(c: char) -> bool { + pub pure fn Lo(c: char) -> bool { return match c { '\u01bb' | '\u01c0' .. '\u01c3' @@ -893,7 +892,7 @@ mod general_category { }; } - pure fn Lt(c: char) -> bool { + pub pure fn Lt(c: char) -> bool { return match c { '\u01c5' | '\u01c8' @@ -910,7 +909,7 @@ mod general_category { }; } - pure fn Lu(c: char) -> bool { + pub pure fn Lu(c: char) -> bool { return match c { '\x41' .. '\x5a' | '\xc0' .. '\xd6' @@ -1502,7 +1501,7 @@ mod general_category { }; } - pure fn Mc(c: char) -> bool { + pub pure fn Mc(c: char) -> bool { return match c { '\u0903' | '\u093b' @@ -1613,7 +1612,7 @@ mod general_category { }; } - pure fn Me(c: char) -> bool { + pub pure fn Me(c: char) -> bool { return match c { '\u0488' .. '\u0489' | '\u20dd' .. '\u20e0' @@ -1624,7 +1623,7 @@ mod general_category { }; } - pure fn Mn(c: char) -> bool { + pub pure fn Mn(c: char) -> bool { return match c { '\u0300' .. '\u036f' | '\u0483' .. '\u0487' @@ -1817,7 +1816,7 @@ mod general_category { }; } - pure fn Nd(c: char) -> bool { + pub pure fn Nd(c: char) -> bool { return match c { '\x30' .. '\x39' | '\u0660' .. '\u0669' @@ -1861,7 +1860,7 @@ mod general_category { }; } - pure fn Nl(c: char) -> bool { + pub pure fn Nl(c: char) -> bool { return match c { '\u16ee' .. '\u16f0' | '\u2160' .. '\u2182' @@ -1880,7 +1879,7 @@ mod general_category { }; } - pure fn No(c: char) -> bool { + pub pure fn No(c: char) -> bool { return match c { '\xb2' .. '\xb3' | '\xb9' @@ -1928,7 +1927,7 @@ mod general_category { }; } - pure fn Pc(c: char) -> bool { + pub pure fn Pc(c: char) -> bool { return match c { '\x5f' | '\u203f' .. '\u2040' @@ -1941,7 +1940,7 @@ mod general_category { }; } - pure fn Pd(c: char) -> bool { + pub pure fn Pd(c: char) -> bool { return match c { '\x2d' | '\u058a' @@ -1963,7 +1962,7 @@ mod general_category { }; } - pure fn Pe(c: char) -> bool { + pub pure fn Pe(c: char) -> bool { return match c { '\x29' | '\x5d' @@ -2040,7 +2039,7 @@ mod general_category { }; } - pure fn Pf(c: char) -> bool { + pub pure fn Pf(c: char) -> bool { return match c { '\xbb' | '\u2019' @@ -2057,7 +2056,7 @@ mod general_category { }; } - pure fn Pi(c: char) -> bool { + pub pure fn Pi(c: char) -> bool { return match c { '\xab' | '\u2018' @@ -2075,7 +2074,7 @@ mod general_category { }; } - pure fn Po(c: char) -> bool { + pub pure fn Po(c: char) -> bool { return match c { '\x21' .. '\x23' | '\x25' .. '\x27' @@ -2208,7 +2207,7 @@ mod general_category { }; } - pure fn Ps(c: char) -> bool { + pub pure fn Ps(c: char) -> bool { return match c { '\x28' | '\x5b' @@ -2287,7 +2286,7 @@ mod general_category { }; } - pure fn Sc(c: char) -> bool { + pub pure fn Sc(c: char) -> bool { return match c { '\x24' | '\xa2' .. '\xa5' @@ -2310,7 +2309,7 @@ mod general_category { }; } - pure fn Sk(c: char) -> bool { + pub pure fn Sk(c: char) -> bool { return match c { '\x5e' | '\x60' @@ -2344,7 +2343,7 @@ mod general_category { }; } - pure fn Sm(c: char) -> bool { + pub pure fn Sm(c: char) -> bool { return match c { '\x2b' | '\x3c' .. '\x3e' @@ -2415,7 +2414,7 @@ mod general_category { }; } - pure fn So(c: char) -> bool { + pub pure fn So(c: char) -> bool { return match c { '\xa6' .. '\xa7' | '\xa9' @@ -2534,21 +2533,21 @@ mod general_category { }; } - pure fn Zl(c: char) -> bool { + pub pure fn Zl(c: char) -> bool { return match c { '\u2028' => true, _ => false }; } - pure fn Zp(c: char) -> bool { + pub pure fn Zp(c: char) -> bool { return match c { '\u2029' => true, _ => false }; } - pure fn Zs(c: char) -> bool { + pub pure fn Zs(c: char) -> bool { return match c { '\x20' | '\xa0' @@ -2567,7 +2566,7 @@ mod general_category { mod derived_property { #[legacy_exports]; /// Check if a character has the alphabetic unicode property - pure fn Alphabetic(c: char) -> bool { + pub pure fn Alphabetic(c: char) -> bool { return match c { '\x41' .. '\x5a' | '\x61' .. '\x7a' @@ -3305,7 +3304,7 @@ mod derived_property { }; } - pure fn XID_Continue(c: char) -> bool { + pub pure fn XID_Continue(c: char) -> bool { return match c { '\x30' .. '\x39' | '\x41' .. '\x5a' @@ -4176,7 +4175,7 @@ mod derived_property { }; } - pure fn XID_Start(c: char) -> bool { + pub pure fn XID_Start(c: char) -> bool { return match c { '\x41' .. '\x5a' | '\x61' .. '\x7a' diff --git a/src/libcore/util.rs b/src/libcore/util.rs index 8c38949f5dfa..aa1fe14ba882 100644 --- a/src/libcore/util.rs +++ b/src/libcore/util.rs @@ -5,25 +5,25 @@ Miscellaneous helpers for common patterns. */ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; +// tjc: re-forbid deprecated modes after snapshot #[forbid(deprecated_pattern)]; use cmp::Eq; /// The identity function. #[inline(always)] -pure fn id(+x: T) -> T { move x } +pub pure fn id(x: T) -> T { move x } /// Ignores a value. #[inline(always)] -pure fn ignore(+_x: T) { } +pub pure fn ignore(_x: T) { } /// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the /// original value of `*ptr`. #[inline(always)] -fn with( +pub fn with( ptr: &mut T, - +new_value: T, + new_value: T, op: &fn() -> R) -> R { // NDM: if swap operator were defined somewhat differently, @@ -41,7 +41,7 @@ fn with( * deinitialising or copying either one. */ #[inline(always)] -fn swap(x: &mut T, y: &mut T) { +pub fn swap(x: &mut T, y: &mut T) { *x <-> *y; } @@ -50,19 +50,19 @@ fn swap(x: &mut T, y: &mut T) { * value, without deinitialising or copying either one. */ #[inline(always)] -fn replace(dest: &mut T, +src: T) -> T { +pub fn replace(dest: &mut T, src: T) -> T { let mut tmp <- src; swap(dest, &mut tmp); move tmp } /// A non-copyable dummy type. -struct NonCopyable { +pub struct NonCopyable { i: (), drop { } } -fn NonCopyable() -> NonCopyable { NonCopyable { i: () } } +pub fn NonCopyable() -> NonCopyable { NonCopyable { i: () } } /** A utility function for indicating unreachable code. It will fail if @@ -88,7 +88,7 @@ fn choose_weighted_item(v: &[Item]) -> Item { ~~~ */ -fn unreachable() -> ! { +pub fn unreachable() -> ! { fail ~"internal error: entered unreachable code"; } diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index e3df52b3cd6e..0c822bd0a031 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -1,104 +1,16 @@ //! Vectors +#[warn(deprecated_mode)]; +#[warn(deprecated_pattern)]; +#[warn(non_camel_case_types)]; + use cmp::{Eq, Ord}; use option::{Some, None}; use ptr::addr_of; use libc::size_t; -export append; -export append_one; -export consume, consume_mut; -export init_op; -export is_empty; -export is_not_empty; -export same_length; -export reserve; -export reserve_at_least; -export capacity; -export len; -export from_fn; -export from_elem; -export from_slice; -export with_capacity; -export build, build_sized, build_sized_opt; -export to_mut; -export from_mut; -export head; -export tail; -export tailn; -export init; -export last; -export last_opt; -export slice; -export view, mut_view, const_view; -export split; -export splitn; -export rsplit; -export rsplitn; -export shift; -export unshift; -export pop; -export swap_remove; -export push, push_all, push_all_move; -export grow; -export grow_fn; -export grow_set; -export truncate; -export dedup; -export map; -export mapi; -export map2; -export map_consume; -export flat_map; -export filter_map; -export filter; -export concat; -export connect; -export foldl; -export foldr; -export any; -export any2; -export all; -export alli; -export all2; -export contains; -export count; -export find; -export find_between; -export rfind; -export rfind_between; -export position_elem; -export position; -export position_between; -export rposition; -export rposition_between; -export unzip; -export zip, zip_slice; -export swap; -export reverse; -export reversed; -export each, each_mut, each_const, eachi, rev_each, rev_eachi; -export iter2; -export permute; -export windowed; -export as_imm_buf; -export as_mut_buf; -export as_const_buf; -export raw; -export bytes; -export extensions; -export ConstVector; -export CopyableVector; -export ImmutableVector; -export ImmutableEqVector; -export ImmutableCopyableVector; -export IterTraitExtensions; -export vec_concat; -export traits; - #[abi = "cdecl"] extern mod rustrt { - #[legacy_exports]; fn vec_reserve_shared(++t: *sys::TypeDesc, ++v: **raw::VecRepr, ++n: libc::size_t); @@ -106,22 +18,21 @@ extern mod rustrt { #[abi = "rust-intrinsic"] extern mod rusti { - #[legacy_exports]; fn move_val_init(&dst: T, -src: T); } /// Returns true if a vector contains no elements -pure fn is_empty(v: &[const T]) -> bool { +pub pure fn is_empty(v: &[const T]) -> bool { as_const_buf(v, |_p, len| len == 0u) } /// Returns true if a vector contains some elements -pure fn is_not_empty(v: &[const T]) -> bool { +pub pure fn is_not_empty(v: &[const T]) -> bool { as_const_buf(v, |_p, len| len > 0u) } /// Returns true if two vectors have the same length -pure fn same_length(xs: &[const T], ys: &[const U]) -> bool { +pub pure fn same_length(xs: &[const T], ys: &[const U]) -> bool { len(xs) == len(ys) } @@ -136,9 +47,9 @@ pure fn same_length(xs: &[const T], ys: &[const U]) -> bool { * * v - A vector * * n - The number of elements to reserve space for */ -fn reserve(+v: &mut ~[T], +n: uint) { +pub fn reserve(v: &mut ~[T], n: uint) { // Only make the (slow) call into the runtime if we have to - if capacity(*v) < n { + if capacity(v) < n { unsafe { let ptr: **raw::VecRepr = cast::transmute(v); rustrt::vec_reserve_shared(sys::get_type_desc::(), @@ -162,22 +73,22 @@ fn reserve(+v: &mut ~[T], +n: uint) { * * v - A vector * * n - The number of elements to reserve space for */ -fn reserve_at_least(v: &mut ~[T], n: uint) { +pub fn reserve_at_least(v: &mut ~[T], n: uint) { reserve(v, uint::next_power_of_two(n)); } /// Returns the number of elements the vector can hold without reallocating #[inline(always)] -pure fn capacity(&&v: ~[const T]) -> uint { +pub pure fn capacity(v: &const ~[T]) -> uint { unsafe { - let repr: **raw::VecRepr = ::cast::reinterpret_cast(&addr_of(v)); + let repr: **raw::VecRepr = ::cast::transmute(v); (**repr).unboxed.alloc / sys::size_of::() } } /// Returns the length of a vector #[inline(always)] -pure fn len(&&v: &[const T]) -> uint { +pub pure fn len(v: &[const T]) -> uint { as_const_buf(v, |_p, len| len) } @@ -187,12 +98,19 @@ pure fn len(&&v: &[const T]) -> uint { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value returned by the function `op`. */ -pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] { - let mut v = with_capacity(n_elts); - let mut i: uint = 0u; - while i < n_elts unsafe { raw::set(v, i, op(i)); i += 1u; } - unsafe { raw::set_len(v, n_elts); } - move v +pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] { + unsafe { + let mut v = with_capacity(n_elts); + 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)); + i += 1u; + } + } + raw::set_len(&mut v, n_elts); + return move v; + } } /** @@ -201,22 +119,16 @@ pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] { * Creates an immutable vector of size `n_elts` and initializes the elements * to the value `t`. */ -pure fn from_elem(n_elts: uint, t: T) -> ~[T] { - let mut v = with_capacity(n_elts); - let mut i: uint = 0u; - unsafe { // because unsafe::set is unsafe - while i < n_elts { raw::set(v, i, t); i += 1u; } - unsafe { raw::set_len(v, n_elts); } - } - move v +pub pure fn from_elem(n_elts: uint, t: T) -> ~[T] { + from_fn(n_elts, |_i| copy t) } /// Creates a new unique vector with the same contents as the slice -pure fn from_slice(t: &[T]) -> ~[T] { +pub pure fn from_slice(t: &[T]) -> ~[T] { from_fn(t.len(), |i| t[i]) } -pure fn with_capacity(capacity: uint) -> ~[T] { +pub pure fn with_capacity(capacity: uint) -> ~[T] { let mut vec = ~[]; unsafe { reserve(&mut vec, capacity); } return move vec; @@ -235,10 +147,10 @@ pure fn with_capacity(capacity: uint) -> ~[T] { * onto the vector being constructed. */ #[inline(always)] -pure fn build_sized(size: uint, - builder: fn(push: pure fn(+v: A))) -> ~[A] { +pub pure fn build_sized(size: uint, + builder: fn(push: pure fn(v: A))) -> ~[A] { let mut vec = with_capacity(size); - builder(|+x| unsafe { push(vec, move x) }); + builder(|x| unsafe { vec.push(move x) }); move vec } @@ -253,7 +165,7 @@ pure fn build_sized(size: uint, * onto the vector being constructed. */ #[inline(always)] -pure fn build(builder: fn(push: pure fn(+v: A))) -> ~[A] { +pub pure fn build(builder: fn(push: pure fn(v: A))) -> ~[A] { build_sized(4, builder) } @@ -270,28 +182,28 @@ pure fn build(builder: fn(push: pure fn(+v: A))) -> ~[A] { * onto the vector being constructed. */ #[inline(always)] -pure fn build_sized_opt(size: Option, - builder: fn(push: pure fn(+v: A))) -> ~[A] { +pub pure fn build_sized_opt(size: Option, + builder: fn(push: pure fn(v: A))) -> ~[A] { build_sized(size.get_default(4), builder) } /// Produces a mut vector from an immutable vector. -pure fn to_mut(+v: ~[T]) -> ~[mut T] { +pub pure fn to_mut(v: ~[T]) -> ~[mut T] { unsafe { ::cast::transmute(move v) } } /// Produces an immutable vector from a mut vector. -pure fn from_mut(+v: ~[mut T]) -> ~[T] { +pub pure fn from_mut(v: ~[mut T]) -> ~[T] { unsafe { ::cast::transmute(move v) } } // Accessors /// Returns the first element of a vector -pure fn head(v: &[const T]) -> T { v[0] } +pub pure fn head(v: &[const T]) -> T { v[0] } /// Returns a vector containing all but the first element of a slice -pure fn tail(v: &[const T]) -> ~[T] { +pub pure fn tail(v: &[const T]) -> ~[T] { return slice(v, 1u, len(v)); } @@ -299,18 +211,18 @@ pure fn tail(v: &[const T]) -> ~[T] { * Returns a vector containing all but the first `n` \ * elements of a slice */ -pure fn tailn(v: &[const T], n: uint) -> ~[T] { +pub pure fn tailn(v: &[const T], n: uint) -> ~[T] { slice(v, n, len(v)) } /// Returns a vector containing all but the last element of a slice -pure fn init(v: &[const T]) -> ~[T] { +pub pure fn init(v: &[const T]) -> ~[T] { assert len(v) != 0u; slice(v, 0u, len(v) - 1u) } /// Returns the last element of the slice `v`, failing if the slice is empty. -pure fn last(v: &[const T]) -> T { +pub pure fn last(v: &[const T]) -> T { if len(v) == 0u { fail ~"last_unsafe: empty vector" } v[len(v) - 1u] } @@ -319,24 +231,24 @@ pure fn last(v: &[const T]) -> T { * Returns `Some(x)` where `x` is the last element of the slice `v`, * or `none` if the vector is empty. */ -pure fn last_opt(v: &[const T]) -> Option { +pub pure fn last_opt(v: &[const T]) -> Option { if len(v) == 0u { return None; } Some(v[len(v) - 1u]) } /// Returns a copy of the elements from [`start`..`end`) from `v`. -pure fn slice(v: &[const T], start: uint, end: uint) -> ~[T] { +pub pure fn slice(v: &[const T], start: uint, end: uint) -> ~[T] { assert (start <= end); assert (end <= len(v)); let mut result = ~[]; unsafe { - for uint::range(start, end) |i| { vec::push(result, v[i]) } + for uint::range(start, end) |i| { result.push(v[i]) } } move result } /// Return a slice that points into another slice. -pure fn view(v: &[T], start: uint, end: uint) -> &[T] { +pub pure fn view(v: &r/[T], start: uint, end: uint) -> &r/[T] { assert (start <= end); assert (end <= len(v)); do as_imm_buf(v) |p, _len| { @@ -349,7 +261,7 @@ pure fn view(v: &[T], start: uint, end: uint) -> &[T] { } /// Return a slice that points into another slice. -pure fn mut_view(v: &[mut T], start: uint, end: uint) -> &[mut T] { +pub pure fn mut_view(v: &r/[mut T], start: uint, end: uint) -> &r/[mut T] { assert (start <= end); assert (end <= len(v)); do as_mut_buf(v) |p, _len| { @@ -362,7 +274,8 @@ pure fn mut_view(v: &[mut T], start: uint, end: uint) -> &[mut T] { } /// Return a slice that points into another slice. -pure fn const_view(v: &[const T], start: uint, end: uint) -> &[const T] { +pub pure fn const_view(v: &r/[const T], start: uint, + end: uint) -> &r/[const T] { assert (start <= end); assert (end <= len(v)); do as_const_buf(v) |p, _len| { @@ -375,7 +288,7 @@ pure fn const_view(v: &[const T], start: uint, end: uint) -> &[const T] { } /// Split the vector `v` by applying each element against the predicate `f`. -fn split(v: &[T], f: fn(T) -> bool) -> ~[~[T]] { +pub fn split(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -383,14 +296,14 @@ fn split(v: &[T], f: fn(T) -> bool) -> ~[~[T]] { let mut result = ~[]; while start < ln { match position_between(v, start, ln, f) { - None => break, - Some(i) => { - push(result, slice(v, start, i)); - start = i + 1u; - } + None => break, + Some(i) => { + result.push(slice(v, start, i)); + start = i + 1u; + } } } - push(result, slice(v, start, ln)); + result.push(slice(v, start, ln)); move result } @@ -398,7 +311,7 @@ fn split(v: &[T], f: fn(T) -> bool) -> ~[~[T]] { * Split the vector `v` by applying each element against the predicate `f` up * to `n` times. */ -fn splitn(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] { +pub fn splitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -407,16 +320,16 @@ fn splitn(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] { let mut result = ~[]; while start < ln && count > 0u { match position_between(v, start, ln, f) { - None => break, - Some(i) => { - push(result, slice(v, start, i)); - // Make sure to skip the separator. - start = i + 1u; - count -= 1u; - } + None => break, + Some(i) => { + result.push(slice(v, start, i)); + // Make sure to skip the separator. + start = i + 1u; + count -= 1u; + } } } - push(result, slice(v, start, ln)); + result.push(slice(v, start, ln)); move result } @@ -424,7 +337,7 @@ fn splitn(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] { * Reverse split the vector `v` by applying each element against the predicate * `f`. */ -fn rsplit(v: &[T], f: fn(T) -> bool) -> ~[~[T]] { +pub fn rsplit(v: &[T], f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -432,14 +345,14 @@ fn rsplit(v: &[T], f: fn(T) -> bool) -> ~[~[T]] { let mut result = ~[]; while end > 0u { match rposition_between(v, 0u, end, f) { - None => break, - Some(i) => { - push(result, slice(v, i + 1u, end)); - end = i; - } + None => break, + Some(i) => { + result.push(slice(v, i + 1u, end)); + end = i; + } } } - push(result, slice(v, 0u, end)); + result.push(slice(v, 0u, end)); reverse(result); return move result; } @@ -448,7 +361,7 @@ fn rsplit(v: &[T], f: fn(T) -> bool) -> ~[~[T]] { * Reverse split the vector `v` by applying each element against the predicate * `f` up to `n times. */ -fn rsplitn(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] { +pub fn rsplitn(v: &[T], n: uint, f: fn(t: &T) -> bool) -> ~[~[T]] { let ln = len(v); if (ln == 0u) { return ~[] } @@ -457,16 +370,16 @@ fn rsplitn(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] { let mut result = ~[]; while end > 0u && count > 0u { match rposition_between(v, 0u, end, f) { - None => break, - Some(i) => { - push(result, slice(v, i + 1u, end)); - // Make sure to skip the separator. - end = i; - count -= 1u; - } + None => break, + Some(i) => { + result.push(slice(v, i + 1u, end)); + // Make sure to skip the separator. + end = i; + count -= 1u; + } } } - push(result, slice(v, 0u, end)); + result.push(slice(v, 0u, end)); reverse(result); move result } @@ -474,12 +387,12 @@ fn rsplitn(v: &[T], n: uint, f: fn(T) -> bool) -> ~[~[T]] { // Mutators /// Removes the first element from a vector and return it -fn shift(&v: ~[T]) -> T { - let ln = len::(v); +pub fn shift(v: &mut ~[T]) -> T { + let ln = v.len(); assert (ln > 0); let mut vv = ~[]; - v <-> vv; + *v <-> vv; unsafe { let mut rr; @@ -489,25 +402,25 @@ fn shift(&v: ~[T]) -> T { for uint::range(1, ln) |i| { let r <- *ptr::offset(vv, i); - push(v, move r); + v.push(move r); } } - raw::set_len(vv, 0); + raw::set_len(&mut vv, 0); move rr } } /// Prepend an element to the vector -fn unshift(&v: ~[T], +x: T) { +pub fn unshift(v: &mut ~[T], x: T) { let mut vv = ~[move x]; - v <-> vv; - while len(vv) > 0 { - push(v, shift(vv)); - } + *v <-> vv; + v.push_all_move(vv); } -fn consume(+v: ~[T], f: fn(uint, +v: T)) unsafe { +pub fn consume(v: ~[T], f: fn(uint, v: T)) unsafe { + let mut v = move v; // FIXME(#3488) + do as_imm_buf(v) |p, ln| { for uint::range(0, ln) |i| { let x <- *ptr::offset(p, i); @@ -515,29 +428,22 @@ fn consume(+v: ~[T], f: fn(uint, +v: T)) unsafe { } } - raw::set_len(v, 0); + raw::set_len(&mut v, 0); } -fn consume_mut(+v: ~[mut T], f: fn(uint, +v: T)) unsafe { - do as_imm_buf(v) |p, ln| { - for uint::range(0, ln) |i| { - let x <- *ptr::offset(p, i); - f(i, move x); - } - } - - raw::set_len(v, 0); +pub fn consume_mut(v: ~[mut T], f: fn(uint, v: T)) { + consume(vec::from_mut(v), f) } /// Remove the last element from a vector and return it -fn pop(&v: ~[const T]) -> T { - let ln = len(v); +pub fn pop(v: &mut ~[T]) -> T { + let ln = v.len(); if ln == 0 { fail ~"sorry, cannot vec::pop an empty vector" } - let valptr = ptr::mut_addr_of(v[ln - 1u]); + let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]); unsafe { - let val <- *valptr; + let val = move *valptr; raw::set_len(v, ln - 1u); move val } @@ -549,28 +455,22 @@ fn pop(&v: ~[const T]) -> T { * * Fails if index >= length. */ -fn swap_remove(&v: ~[const T], index: uint) -> T { - let ln = len(v); +pub fn swap_remove(v: &mut ~[T], index: uint) -> T { + let ln = v.len(); if index >= ln { fail fmt!("vec::swap_remove - index %u >= length %u", index, ln); } - let lastptr = ptr::mut_addr_of(v[ln - 1]); - unsafe { - let mut val <- *lastptr; - if index < ln - 1 { - let valptr = ptr::mut_addr_of(v[index]); - *valptr <-> val; - } - raw::set_len(v, ln - 1); - move val + if index < ln - 1 { + v[index] <-> v[ln - 1]; } + vec::pop(v) } /// Append an element to a vector #[inline(always)] -fn push(&v: ~[T], +initval: T) { +pub fn push(v: &mut ~[T], initval: T) { unsafe { - let repr: **raw::VecRepr = ::cast::reinterpret_cast(&addr_of(v)); + let repr: **raw::VecRepr = ::cast::transmute(copy v); let fill = (**repr).unboxed.fill; if (**repr).unboxed.alloc > fill { push_fast(v, move initval); @@ -583,24 +483,24 @@ fn push(&v: ~[T], +initval: T) { // This doesn't bother to make sure we have space. #[inline(always)] // really pretty please -unsafe fn push_fast(&v: ~[T], +initval: T) { - let repr: **raw::VecRepr = ::cast::reinterpret_cast(&addr_of(v)); +unsafe fn push_fast(v: &mut ~[T], initval: T) { + let repr: **raw::VecRepr = ::cast::transmute(v); let fill = (**repr).unboxed.fill; (**repr).unboxed.fill += sys::size_of::(); - let p = ptr::addr_of((**repr).unboxed.data); + let p = addr_of(&((**repr).unboxed.data)); let p = ptr::offset(p, fill) as *mut T; rusti::move_val_init(*p, move initval); } #[inline(never)] -fn push_slow(&v: ~[T], +initval: T) { - reserve_at_least(&mut v, v.len() + 1u); +fn push_slow(v: &mut ~[T], initval: T) { + reserve_at_least(v, v.len() + 1u); unsafe { push_fast(v, move initval) } } #[inline(always)] -fn push_all(&v: ~[T], rhs: &[const T]) { - reserve(&mut v, v.len() + rhs.len()); +pub fn push_all(v: &mut ~[T], rhs: &[const T]) { + reserve(v, v.len() + rhs.len()); for uint::range(0u, rhs.len()) |i| { push(v, unsafe { raw::get(rhs, i) }) @@ -608,8 +508,9 @@ fn push_all(&v: ~[T], rhs: &[const T]) { } #[inline(always)] -fn push_all_move(&v: ~[T], -rhs: ~[const T]) { - reserve(&mut v, v.len() + rhs.len()); +pub fn push_all_move(v: &mut ~[T], rhs: ~[T]) { + let mut rhs = move rhs; // FIXME(#3488) + reserve(v, v.len() + rhs.len()); unsafe { do as_imm_buf(rhs) |p, len| { for uint::range(0, len) |i| { @@ -617,13 +518,13 @@ fn push_all_move(&v: ~[T], -rhs: ~[const T]) { push(v, move x); } } - raw::set_len(rhs, 0); + raw::set_len(&mut rhs, 0); } } /// Shorten a vector, dropping excess elements. -fn truncate(&v: ~[const T], newlen: uint) { - do as_imm_buf(v) |p, oldlen| { +pub fn truncate(v: &mut ~[T], newlen: uint) { + do as_imm_buf(*v) |p, oldlen| { assert(newlen <= oldlen); unsafe { // This loop is optimized out for non-drop types. @@ -639,10 +540,10 @@ fn truncate(&v: ~[const T], newlen: uint) { * Remove consecutive repeated elements from a vector; if the vector is * sorted, this removes all duplicates. */ -fn dedup(&v: ~[const T]) unsafe { +pub fn dedup(v: &mut ~[T]) unsafe { if v.len() < 1 { return; } let mut last_written = 0, next_to_read = 1; - do as_const_buf(v) |p, ln| { + do as_const_buf(*v) |p, ln| { // We have a mutable reference to v, so we can make arbitrary changes. // (cf. push and pop) let p = p as *mut T; @@ -672,23 +573,23 @@ fn dedup(&v: ~[const T]) unsafe { // Appending #[inline(always)] -pure fn append(+lhs: ~[T], rhs: &[const T]) -> ~[T] { +pub pure fn append(lhs: ~[T], rhs: &[const T]) -> ~[T] { let mut v <- lhs; unsafe { - push_all(v, rhs); + v.push_all(rhs); } move v } #[inline(always)] -pure fn append_one(+lhs: ~[T], +x: T) -> ~[T] { +pub pure fn append_one(lhs: ~[T], x: T) -> ~[T] { let mut v <- lhs; - unsafe { push(v, move x); } + unsafe { v.push(move x); } move v } #[inline(always)] -pure fn append_mut(+lhs: ~[mut T], rhs: &[const T]) -> ~[mut T] { +pure fn append_mut(lhs: ~[mut T], rhs: &[const T]) -> ~[mut T] { to_mut(append(from_mut(lhs), rhs)) } @@ -701,11 +602,14 @@ pure fn append_mut(+lhs: ~[mut T], rhs: &[const T]) -> ~[mut T] { * * n - The number of elements to add * * initval - The value for the new elements */ -fn grow(&v: ~[T], n: uint, initval: T) { - reserve_at_least(&mut v, len(v) + n); +pub fn grow(v: &mut ~[T], n: uint, initval: &T) { + reserve_at_least(v, v.len() + n); let mut i: uint = 0u; - while i < n { push(v, initval); i += 1u; } + while i < n { + v.push(*initval); + i += 1u; + } } /** @@ -721,10 +625,13 @@ fn grow(&v: ~[T], n: uint, initval: T) { * * init_op - A function to call to retreive each appended element's * value */ -fn grow_fn(&v: ~[T], n: uint, op: iter::InitOp) { - reserve_at_least(&mut v, len(v) + n); +pub fn grow_fn(v: &mut ~[T], n: uint, op: iter::InitOp) { + reserve_at_least(v, v.len() + n); let mut i: uint = 0u; - while i < n { push(v, op(i)); i += 1u; } + while i < n { + v.push(op(i)); + i += 1u; + } } /** @@ -735,30 +642,35 @@ fn grow_fn(&v: ~[T], n: uint, op: iter::InitOp) { * of the vector, expands the vector by replicating `initval` to fill the * intervening space. */ -fn grow_set(&v: ~[T], index: uint, initval: T, val: T) { - if index >= len(v) { grow(v, index - len(v) + 1u, initval); } - v[index] = val; +pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { + let l = v.len(); + if index >= l { grow(v, index - l + 1u, initval); } + v[index] = move val; } // Functional utilities /// Apply a function to each element of a vector and return the results -pure fn map(v: &[T], f: fn(v: &T) -> U) -> ~[U] { +pub pure fn map(v: &[T], f: fn(t: &T) -> U) -> ~[U] { let mut result = with_capacity(len(v)); - for each(v) |elem| { unsafe { push(result, f(elem)); } } + for each(v) |elem| { + unsafe { + result.push(f(elem)); + } + } move result } -fn map_consume(+v: ~[T], f: fn(+v: T) -> U) -> ~[U] { +pub fn map_consume(v: ~[T], f: fn(v: T) -> U) -> ~[U] { let mut result = ~[]; do consume(move v) |_i, x| { - vec::push(result, f(move x)); + result.push(f(move x)); } move result } /// Apply a function to each element of a vector and return the results -pure fn mapi(v: &[T], f: fn(uint, v: &T) -> U) -> ~[U] { +pub pure fn mapi(v: &[T], f: fn(uint, t: &T) -> U) -> ~[U] { let mut i = 0; do map(v) |e| { i += 1; @@ -770,21 +682,21 @@ pure fn mapi(v: &[T], f: fn(uint, v: &T) -> U) -> ~[U] { * Apply a function to each element of a vector and return a concatenation * of each result vector */ -pure fn flat_map(v: &[T], f: fn(T) -> ~[U]) -> ~[U] { +pub pure fn flat_map(v: &[T], f: fn(t: &T) -> ~[U]) -> ~[U] { let mut result = ~[]; - for each(v) |elem| { unsafe{ push_all_move(result, f(*elem)); } } + for each(v) |elem| { unsafe{ result.push_all_move(f(elem)); } } move result } /// Apply a function to each pair of elements and return the results -pure fn map2(v0: &[T], v1: &[U], - f: fn(T, U) -> V) -> ~[V] { +pub pure fn map2(v0: &[T], v1: &[U], + f: fn(t: &T, v: &U) -> V) -> ~[V] { let v0_len = len(v0); if v0_len != len(v1) { fail; } let mut u: ~[V] = ~[]; let mut i = 0u; while i < v0_len { - unsafe { push(u, f(copy v0[i], copy v1[i])) }; + unsafe { u.push(f(&v0[i], &v1[i])) }; i += 1u; } move u @@ -796,13 +708,13 @@ pure fn map2(v0: &[T], v1: &[U], * If function `f` returns `none` then that element is excluded from * the resulting vector. */ -pure fn filter_map(v: &[T], f: fn(T) -> Option) +pub pure fn filter_map(v: &[T], f: fn(t: &T) -> Option) -> ~[U] { let mut result = ~[]; for each(v) |elem| { - match f(*elem) { + match f(elem) { None => {/* no-op */ } - Some(result_elem) => unsafe { push(result, result_elem); } + Some(move result_elem) => unsafe { result.push(result_elem); } } } move result @@ -815,10 +727,10 @@ pure fn filter_map(v: &[T], f: fn(T) -> Option) * Apply function `f` to each element of `v` and return a vector containing * only those elements for which `f` returned true. */ -pure fn filter(v: &[T], f: fn(T) -> bool) -> ~[T] { +pub pure fn filter(v: &[T], f: fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; for each(v) |elem| { - if f(*elem) { unsafe { push(result, *elem); } } + if f(elem) { unsafe { result.push(*elem); } } } move result } @@ -828,37 +740,39 @@ pure fn filter(v: &[T], f: fn(T) -> bool) -> ~[T] { * * Flattens a vector of vectors of T into a single vector of T. */ -pure fn concat(v: &[~[T]]) -> ~[T] { +pub pure fn concat(v: &[~[T]]) -> ~[T] { let mut r = ~[]; - for each(v) |inner| { unsafe { push_all(r, *inner); } } + for each(v) |inner| { unsafe { r.push_all(*inner); } } move r } /// Concatenate a vector of vectors, placing a given separator between each -pure fn connect(v: &[~[T]], sep: T) -> ~[T] { +pub pure fn connect(v: &[~[T]], sep: &T) -> ~[T] { let mut r: ~[T] = ~[]; let mut first = true; for each(v) |inner| { - if first { first = false; } else { unsafe { push(r, sep); } } - unsafe { push_all(r, *inner) }; + if first { first = false; } else { unsafe { r.push(*sep); } } + unsafe { r.push_all(*inner) }; } move r } /// Reduce a vector from left to right -pure fn foldl(z: T, v: &[U], p: fn(T, U) -> T) -> T { +pub pure fn foldl(z: T, v: &[U], p: fn(t: T, u: &U) -> T) -> T { let mut accum = z; for each(v) |elt| { - accum = p(accum, *elt); + // it should be possible to move accum in, but the liveness analysis + // is not smart enough. + accum = p(accum, elt); } return accum; } /// Reduce a vector from right to left -pure fn foldr(v: &[T], z: U, p: fn(T, U) -> U) -> U { +pub pure fn foldr(v: &[T], z: U, p: fn(t: &T, u: U) -> U) -> U { let mut accum = z; for rev_each(v) |elt| { - accum = p(*elt, accum); + accum = p(elt, accum); } return accum; } @@ -868,8 +782,8 @@ pure fn foldr(v: &[T], z: U, p: fn(T, U) -> U) -> U { * * If the vector contains no elements then false is returned. */ -pure fn any(v: &[T], f: fn(T) -> bool) -> bool { - for each(v) |elem| { if f(*elem) { return true; } } +pub pure fn any(v: &[T], f: fn(t: &T) -> bool) -> bool { + for each(v) |elem| { if f(elem) { return true; } } return false; } @@ -878,13 +792,13 @@ pure fn any(v: &[T], f: fn(T) -> bool) -> bool { * * If the vectors contains no elements then false is returned. */ -pure fn any2(v0: &[T], v1: &[U], - f: fn(T, U) -> bool) -> bool { +pub pure fn any2(v0: &[T], v1: &[U], + f: fn(a: &T, b: &U) -> bool) -> bool { let v0_len = len(v0); let v1_len = len(v1); let mut i = 0u; while i < v0_len && i < v1_len { - if f(v0[i], v1[i]) { return true; }; + if f(&v0[i], &v1[i]) { return true; }; i += 1u; } return false; @@ -895,8 +809,8 @@ pure fn any2(v0: &[T], v1: &[U], * * If the vector contains no elements then true is returned. */ -pure fn all(v: &[T], f: fn(T) -> bool) -> bool { - for each(v) |elem| { if !f(*elem) { return false; } } +pub pure fn all(v: &[T], f: fn(t: &T) -> bool) -> bool { + for each(v) |elem| { if !f(elem) { return false; } } return true; } @@ -905,8 +819,8 @@ pure fn all(v: &[T], f: fn(T) -> bool) -> bool { * * If the vector contains no elements then true is returned. */ -pure fn alli(v: &[T], f: fn(uint, T) -> bool) -> bool { - for eachi(v) |i, elem| { if !f(i, *elem) { return false; } } +pub pure fn alli(v: &[T], f: fn(uint, t: &T) -> bool) -> bool { + for eachi(v) |i, elem| { if !f(i, elem) { return false; } } return true; } @@ -915,25 +829,25 @@ pure fn alli(v: &[T], f: fn(uint, T) -> bool) -> bool { * * If the vectors are not the same size then false is returned. */ -pure fn all2(v0: &[T], v1: &[U], - f: fn(T, U) -> bool) -> bool { +pub pure fn all2(v0: &[T], v1: &[U], + f: fn(t: &T, u: &U) -> bool) -> bool { let v0_len = len(v0); if v0_len != len(v1) { return false; } let mut i = 0u; - while i < v0_len { if !f(v0[i], v1[i]) { return false; }; i += 1u; } + while i < v0_len { if !f(&v0[i], &v1[i]) { return false; }; i += 1u; } return true; } /// Return true if a vector contains an element with the given value -pure fn contains(v: &[T], x: T) -> bool { - for each(v) |elt| { if x == *elt { return true; } } +pub pure fn contains(v: &[T], x: &T) -> bool { + for each(v) |elt| { if *x == *elt { return true; } } return false; } /// Returns the number of elements that are equal to a given value -pure fn count(v: &[T], x: T) -> uint { +pub pure fn count(v: &[T], x: &T) -> uint { let mut cnt = 0u; - for each(v) |elt| { if x == *elt { cnt += 1u; } } + for each(v) |elt| { if *x == *elt { cnt += 1u; } } return cnt; } @@ -944,7 +858,7 @@ pure fn count(v: &[T], x: T) -> uint { * When function `f` returns true then an option containing the element * is returned. If `f` matches no elements then none is returned. */ -pure fn find(v: &[T], f: fn(T) -> bool) -> Option { +pub pure fn find(v: &[T], f: fn(t: &T) -> bool) -> Option { find_between(v, 0u, len(v), f) } @@ -955,9 +869,9 @@ pure fn find(v: &[T], f: fn(T) -> bool) -> Option { * [`start`, `end`). When function `f` returns true then an option containing * the element is returned. If `f` matches no elements then none is returned. */ -pure fn find_between(v: &[T], start: uint, end: uint, - f: fn(T) -> bool) -> Option { - position_between(v, start, end, f).map(|i| v[i]) +pub pure fn find_between(v: &[T], start: uint, end: uint, + f: fn(t: &T) -> bool) -> Option { + position_between(v, start, end, f).map(|i| v[*i]) } /** @@ -967,7 +881,7 @@ pure fn find_between(v: &[T], start: uint, end: uint, * `f` returns true then an option containing the element is returned. If `f` * matches no elements then none is returned. */ -pure fn rfind(v: &[T], f: fn(T) -> bool) -> Option { +pub pure fn rfind(v: &[T], f: fn(t: &T) -> bool) -> Option { rfind_between(v, 0u, len(v), f) } @@ -976,16 +890,16 @@ pure fn rfind(v: &[T], f: fn(T) -> bool) -> Option { * * Apply function `f` to each element of `v` in reverse order within the range * [`start`, `end`). When function `f` returns true then an option containing - * the element is returned. If `f` matches no elements then none is returned. + * the element is returned. If `f` matches no elements then none is return. */ -pure fn rfind_between(v: &[T], start: uint, end: uint, - f: fn(T) -> bool) -> Option { - rposition_between(v, start, end, f).map(|i| v[i]) +pub pure fn rfind_between(v: &[T], start: uint, end: uint, + f: fn(t: &T) -> bool) -> Option { + rposition_between(v, start, end, f).map(|i| v[*i]) } /// Find the first index containing a matching value -pure fn position_elem(v: &[T], x: T) -> Option { - position(v, |y| x == y) +pub pure fn position_elem(v: &[T], x: &T) -> Option { + position(v, |y| *x == *y) } /** @@ -995,7 +909,7 @@ pure fn position_elem(v: &[T], x: T) -> Option { * then an option containing the index is returned. If `f` matches no elements * then none is returned. */ -pure fn position(v: &[T], f: fn(T) -> bool) -> Option { +pub pure fn position(v: &[T], f: fn(t: &T) -> bool) -> Option { position_between(v, 0u, len(v), f) } @@ -1006,18 +920,18 @@ pure fn position(v: &[T], f: fn(T) -> bool) -> Option { * [`start`, `end`). When function `f` returns true then an option containing * the index is returned. If `f` matches no elements then none is returned. */ -pure fn position_between(v: &[T], start: uint, end: uint, - f: fn(T) -> bool) -> Option { +pub pure fn position_between(v: &[T], start: uint, end: uint, + f: fn(t: &T) -> bool) -> Option { assert start <= end; assert end <= len(v); let mut i = start; - while i < end { if f(v[i]) { return Some::(i); } i += 1u; } + while i < end { if f(&v[i]) { return Some::(i); } i += 1u; } return None; } /// Find the last index containing a matching value -pure fn rposition_elem(v: &[T], x: T) -> Option { - rposition(v, |y| x == y) +pure fn rposition_elem(v: &[T], x: &T) -> Option { + rposition(v, |y| *x == *y) } /** @@ -1027,7 +941,7 @@ pure fn rposition_elem(v: &[T], x: T) -> Option { * `f` returns true then an option containing the index is returned. If `f` * matches no elements then none is returned. */ -pure fn rposition(v: &[T], f: fn(T) -> bool) -> Option { +pub pure fn rposition(v: &[T], f: fn(t: &T) -> bool) -> Option { rposition_between(v, 0u, len(v), f) } @@ -1039,13 +953,13 @@ pure fn rposition(v: &[T], f: fn(T) -> bool) -> Option { * containing the index is returned. If `f` matches no elements then none is * returned. */ -pure fn rposition_between(v: &[T], start: uint, end: uint, - f: fn(T) -> bool) -> Option { +pub pure fn rposition_between(v: &[T], start: uint, end: uint, + f: fn(t: &T) -> bool) -> Option { assert start <= end; assert end <= len(v); let mut i = end; while i > start { - if f(v[i - 1u]) { return Some::(i - 1u); } + if f(&v[i - 1u]) { return Some::(i - 1u); } i -= 1u; } return None; @@ -1059,15 +973,15 @@ pure fn rposition_between(v: &[T], start: uint, end: uint, * Convert a vector of pairs into a pair of vectors, by reference. As unzip(). */ pure fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { - let mut as_ = ~[], bs = ~[]; + let mut ts = ~[], us = ~[]; for each(v) |p| { - let (a, b) = *p; + let (t, u) = *p; unsafe { - vec::push(as_, a); - vec::push(bs, b); + ts.push(t); + us.push(u); } } - return (move as_, move bs); + return (move ts, move us); } /** @@ -1078,13 +992,13 @@ pure fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { * and the i-th element of the second vector contains the second element * of the i-th tuple of the input vector. */ -pure fn unzip(+v: ~[(T, U)]) -> (~[T], ~[U]) { +pub pure fn unzip(v: ~[(T, U)]) -> (~[T], ~[U]) { let mut ts = ~[], us = ~[]; unsafe { do consume(move v) |_i, p| { - let (a,b) = move p; - push(ts, move a); - push(us, move b); + let (t, u) = move p; + ts.push(move t); + us.push(move u); } } (move ts, move us) @@ -1093,13 +1007,13 @@ pure fn unzip(+v: ~[(T, U)]) -> (~[T], ~[U]) { /** * Convert two vectors to a vector of pairs, by reference. As zip(). */ -pure fn zip_slice(v: &[const T], u: &[const U]) +pub pure fn zip_slice(v: &[const T], u: &[const U]) -> ~[(T, U)] { let mut zipped = ~[]; let sz = len(v); let mut i = 0u; assert sz == len(u); - while i < sz unsafe { vec::push(zipped, (v[i], u[i])); i += 1u; } + while i < sz unsafe { zipped.push((v[i], u[i])); i += 1u; } move zipped } @@ -1109,12 +1023,13 @@ pure fn zip_slice(v: &[const T], u: &[const U]) * Returns a vector of tuples, where the i-th tuple contains contains the * i-th elements from each of the input vectors. */ -pure fn zip(+v: ~[const T], +u: ~[const U]) -> ~[(T, U)] { - let mut v = move v, u = move u, i = len(v); +pub pure fn zip(v: ~[T], u: ~[U]) -> ~[(T, U)] { + let mut v = move v, u = move u; // FIXME(#3488) + let mut i = len(v); assert i == len(u); let mut w = with_capacity(i); while i > 0 { - unsafe { push(w, (pop(v),pop(u))); } + unsafe { w.push((v.pop(),u.pop())); } i -= 1; } unsafe { reverse(w); } @@ -1130,25 +1045,25 @@ pure fn zip(+v: ~[const T], +u: ~[const U]) -> ~[(T, U)] { * * a - The index of the first element * * b - The index of the second element */ -fn swap(v: &[mut T], a: uint, b: uint) { +pub fn swap(v: &[mut T], a: uint, b: uint) { v[a] <-> v[b]; } /// Reverse the order of elements in a vector, in place -fn reverse(v: &[mut T]) { +pub fn reverse(v: &[mut T]) { let mut i: uint = 0u; let ln = len::(v); while i < ln / 2u { v[i] <-> v[ln - i - 1u]; i += 1u; } } /// Returns a vector with the order of elements reversed -pure fn reversed(v: &[const T]) -> ~[T] { +pub pure fn reversed(v: &[const T]) -> ~[T] { let mut rs: ~[T] = ~[]; let mut i = len::(v); if i == 0 { return (move rs); } else { i -= 1; } unsafe { - while i != 0 { vec::push(rs, v[i]); i -= 1; } - vec::push(rs, v[0]); + while i != 0 { rs.push(v[i]); i -= 1; } + rs.push(v[0]); } move rs } @@ -1159,7 +1074,7 @@ pure fn reversed(v: &[const T]) -> ~[T] { * Return true to continue, false to break. */ #[inline(always)] -pure fn each(v: &r/[T], f: fn((&r/T)) -> bool) { +pub pure fn each(v: &r/[T], f: fn((&r/T)) -> bool) { // ^^^^ // NB---this CANNOT be &[const T]! The reason // is that you are passing it to `f()` using @@ -1183,7 +1098,7 @@ pure fn each(v: &r/[T], f: fn((&r/T)) -> bool) { /// a vector with mutable contents and you would like /// to mutate the contents as you iterate. #[inline(always)] -fn each_mut(v: &[mut T], f: fn(elem: &mut T) -> bool) { +pub fn each_mut(v: &[mut T], f: fn(elem: &mut T) -> bool) { let mut i = 0; let n = v.len(); while i < n { @@ -1197,7 +1112,7 @@ fn each_mut(v: &[mut T], f: fn(elem: &mut T) -> bool) { /// Like `each()`, but for the case where you have a vector that *may or may /// not* have mutable contents. #[inline(always)] -pure fn each_const(v: &[const T], f: fn(elem: &const T) -> bool) { +pub pure fn each_const(v: &[const T], f: fn(elem: &const T) -> bool) { let mut i = 0; let n = v.len(); while i < n { @@ -1214,7 +1129,7 @@ pure fn each_const(v: &[const T], f: fn(elem: &const T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pure fn eachi(v: &r/[T], f: fn(uint, v: &r/T) -> bool) { +pub pure fn eachi(v: &r/[T], f: fn(uint, v: &r/T) -> bool) { let mut i = 0; for each(v) |p| { if !f(i, p) { return; } @@ -1228,7 +1143,7 @@ pure fn eachi(v: &r/[T], f: fn(uint, v: &r/T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pure fn rev_each(v: &r/[T], blk: fn(v: &r/T) -> bool) { +pub pure fn rev_each(v: &r/[T], blk: fn(v: &r/T) -> bool) { rev_eachi(v, |_i, v| blk(v)) } @@ -1238,7 +1153,7 @@ pure fn rev_each(v: &r/[T], blk: fn(v: &r/T) -> bool) { * Return true to continue, false to break. */ #[inline(always)] -pure fn rev_eachi(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) { +pub pure fn rev_eachi(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) { let mut i = v.len(); while i > 0 { i -= 1; @@ -1256,10 +1171,12 @@ pure fn rev_eachi(v: &r/[T], blk: fn(i: uint, v: &r/T) -> bool) { * Both vectors must have the same length */ #[inline] -fn iter2(v1: &[U], v2: &[T], f: fn(U, T)) { +pub fn each2(v1: &[U], v2: &[T], f: fn(u: &U, t: &T) -> bool) { assert len(v1) == len(v2); for uint::range(0u, len(v1)) |i| { - f(v1[i], v2[i]) + if !f(&v1[i], &v2[i]) { + return; + } } } @@ -1273,33 +1190,37 @@ fn iter2(v1: &[U], v2: &[T], f: fn(U, T)) { * The total number of permutations produced is `len(v)!`. If `v` contains * repeated elements, then some permutations are repeated. */ -pure fn permute(v: &[const T], put: fn(~[T])) { +pure fn each_permutation(v: &[T], put: fn(ts: &[T]) -> bool) { let ln = len(v); - if ln == 0u { - put(~[]); + if ln <= 1 { + put(v); } else { + // This does not seem like the most efficient implementation. You + // could make far fewer copies if you put your mind to it. let mut i = 0u; while i < ln { let elt = v[i]; let mut rest = slice(v, 0u, i); unsafe { - push_all(rest, const_view(v, i+1u, ln)); - permute(rest, |permutation| { - put(append(~[elt], permutation)) - }) + rest.push_all(const_view(v, i+1u, ln)); + for each_permutation(rest) |permutation| { + if !put(append(~[elt], permutation)) { + return; + } + } } i += 1u; } } } -pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { +pub pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { let mut ww = ~[]; assert 1u <= nn; for vec::eachi (xx) |ii, _x| { let len = vec::len(xx); if ii+nn <= len unsafe { - vec::push(ww, vec::slice(xx, ii, ii+nn)); + ww.push(vec::slice(xx, ii, ii+nn)); } } move ww @@ -1312,8 +1233,9 @@ pure fn windowed(nn: uint, xx: &[TT]) -> ~[~[TT]] { * foreign interop. */ #[inline(always)] -pure fn as_imm_buf(s: &[T], /* NB---this CANNOT be const, see below */ - f: fn(*T, uint) -> U) -> U { +pub pure fn as_imm_buf(s: &[T], + /* NB---this CANNOT be const, see below */ + f: fn(*T, uint) -> U) -> U { // NB---Do not change the type of s to `&[const T]`. This is // unsound. The reason is that we are going to create immutable pointers @@ -1323,7 +1245,7 @@ pure fn as_imm_buf(s: &[T], /* NB---this CANNOT be const, see below */ unsafe { let v : *(*T,uint) = - ::cast::reinterpret_cast(&ptr::addr_of(s)); + ::cast::reinterpret_cast(&addr_of(&s)); let (buf,len) = *v; f(buf, len / sys::size_of::()) } @@ -1331,12 +1253,12 @@ pure fn as_imm_buf(s: &[T], /* NB---this CANNOT be const, see below */ /// Similar to `as_imm_buf` but passing a `*const T` #[inline(always)] -pure fn as_const_buf(s: &[const T], +pub pure fn as_const_buf(s: &[const T], f: fn(*const T, uint) -> U) -> U { unsafe { let v : *(*const T,uint) = - ::cast::reinterpret_cast(&ptr::addr_of(s)); + ::cast::reinterpret_cast(&addr_of(&s)); let (buf,len) = *v; f(buf, len / sys::size_of::()) } @@ -1344,12 +1266,12 @@ pure fn as_const_buf(s: &[const T], /// Similar to `as_imm_buf` but passing a `*mut T` #[inline(always)] -pure fn as_mut_buf(s: &[mut T], +pub pure fn as_mut_buf(s: &[mut T], f: fn(*mut T, uint) -> U) -> U { unsafe { let v : *(*mut T,uint) = - ::cast::reinterpret_cast(&ptr::addr_of(s)); + ::cast::reinterpret_cast(&addr_of(&s)); let (buf,len) = *v; f(buf, len / sys::size_of::()) } @@ -1446,8 +1368,7 @@ impl @[T] : Ord { } #[cfg(notest)] -mod traits { - #[legacy_exports]; +pub mod traits { impl ~[T] : Add<&[const T],~[T]> { #[inline(always)] pure fn add(rhs: & &[const T]) -> ~[T] { @@ -1464,10 +1385,9 @@ mod traits { } #[cfg(test)] -mod traits { - #[legacy_exports];} +pub mod traits {} -trait ConstVector { +pub trait ConstVector { pure fn is_empty() -> bool; pure fn is_not_empty() -> bool; pure fn len() -> uint; @@ -1486,7 +1406,7 @@ impl &[const T]: ConstVector { pure fn len() -> uint { len(self) } } -trait CopyableVector { +pub trait CopyableVector { pure fn head() -> T; pure fn init() -> ~[T]; pure fn last() -> T; @@ -1513,36 +1433,43 @@ impl &[const T]: CopyableVector { pure fn tail() -> ~[T] { tail(self) } } -trait ImmutableVector { - pure fn foldr(z: U, p: fn(T, U) -> U) -> U; - pure fn map(f: fn(v: &T) -> U) -> ~[U]; - pure fn mapi(f: fn(uint, v: &T) -> U) -> ~[U]; +pub trait ImmutableVector { + pure fn view(start: uint, end: uint) -> &self/[T]; + pure fn foldr(z: U, p: fn(t: &T, u: U) -> U) -> U; + pure fn map(f: fn(t: &T) -> U) -> ~[U]; + pure fn mapi(f: fn(uint, t: &T) -> U) -> ~[U]; fn map_r(f: fn(x: &T) -> U) -> ~[U]; - pure fn alli(f: fn(uint, T) -> bool) -> bool; - pure fn flat_map(f: fn(T) -> ~[U]) -> ~[U]; - pure fn filter_map(f: fn(T) -> Option) -> ~[U]; + pure fn alli(f: fn(uint, t: &T) -> bool) -> bool; + pure fn flat_map(f: fn(t: &T) -> ~[U]) -> ~[U]; + pure fn filter_map(f: fn(t: &T) -> Option) -> ~[U]; } -trait ImmutableEqVector { - pure fn position(f: fn(T) -> bool) -> Option; - pure fn position_elem(x: T) -> Option; - pure fn rposition(f: fn(T) -> bool) -> Option; - pure fn rposition_elem(x: T) -> Option; +pub trait ImmutableEqVector { + pure fn position(f: fn(t: &T) -> bool) -> Option; + pure fn position_elem(t: &T) -> Option; + pure fn rposition(f: fn(t: &T) -> bool) -> Option; + pure fn rposition_elem(t: &T) -> Option; } /// Extension methods for vectors impl &[T]: ImmutableVector { + /// Return a slice that points into another slice. + pure fn view(start: uint, end: uint) -> &self/[T] { + view(self, start, end) + } /// Reduce a vector from right to left #[inline] - pure fn foldr(z: U, p: fn(T, U) -> U) -> U { foldr(self, z, p) } + pure fn foldr(z: U, p: fn(t: &T, u: U) -> U) -> U { + foldr(self, z, p) + } /// Apply a function to each element of a vector and return the results #[inline] - pure fn map(f: fn(v: &T) -> U) -> ~[U] { map(self, f) } + pure fn map(f: fn(t: &T) -> U) -> ~[U] { map(self, f) } /** * Apply a function to the index and value of each element in the vector * and return the results */ - pure fn mapi(f: fn(uint, v: &T) -> U) -> ~[U] { + pure fn mapi(f: fn(uint, t: &T) -> U) -> ~[U] { mapi(self, f) } @@ -1551,7 +1478,7 @@ impl &[T]: ImmutableVector { let mut r = ~[]; let mut i = 0; while i < self.len() { - push(r, f(&self[i])); + r.push(f(&self[i])); i += 1; } move r @@ -1562,7 +1489,7 @@ impl &[T]: ImmutableVector { * * If the vector is empty, true is returned. */ - pure fn alli(f: fn(uint, T) -> bool) -> bool { + pure fn alli(f: fn(uint, t: &T) -> bool) -> bool { alli(self, f) } /** @@ -1570,7 +1497,9 @@ impl &[T]: ImmutableVector { * of each result vector */ #[inline] - pure fn flat_map(f: fn(T) -> ~[U]) -> ~[U] { flat_map(self, f) } + pure fn flat_map(f: fn(t: &T) -> ~[U]) -> ~[U] { + flat_map(self, f) + } /** * Apply a function to each element of a vector and return the results * @@ -1578,7 +1507,7 @@ impl &[T]: ImmutableVector { * the resulting vector. */ #[inline] - pure fn filter_map(f: fn(T) -> Option) -> ~[U] { + pure fn filter_map(f: fn(t: &T) -> Option) -> ~[U] { filter_map(self, f) } } @@ -1592,10 +1521,16 @@ impl &[T]: ImmutableEqVector { * elements then none is returned. */ #[inline] - pure fn position(f: fn(T) -> bool) -> Option { position(self, f) } + pure fn position(f: fn(t: &T) -> bool) -> Option { + position(self, f) + } + /// Find the first index containing a matching value #[inline] - pure fn position_elem(x: T) -> Option { position_elem(self, x) } + pure fn position_elem(x: &T) -> Option { + position_elem(self, x) + } + /** * Find the last index matching some predicate * @@ -1604,15 +1539,21 @@ impl &[T]: ImmutableEqVector { * returned. If `f` matches no elements then none is returned. */ #[inline] - pure fn rposition(f: fn(T) -> bool) -> Option { rposition(self, f) } + pure fn rposition(f: fn(t: &T) -> bool) -> Option { + rposition(self, f) + } + /// Find the last index containing a matching value #[inline] - pure fn rposition_elem(x: T) -> Option { rposition_elem(self, x) } + pure fn rposition_elem(t: &T) -> Option { + rposition_elem(self, t) + } } -trait ImmutableCopyableVector { - pure fn filter(f: fn(T) -> bool) -> ~[T]; - pure fn rfind(f: fn(T) -> bool) -> Option; +pub trait ImmutableCopyableVector { + pure fn filter(f: fn(t: &T) -> bool) -> ~[T]; + + pure fn rfind(f: fn(t: &T) -> bool) -> Option; } /// Extension methods for vectors @@ -1625,7 +1566,10 @@ impl &[T]: ImmutableCopyableVector { * containing only those elements for which `f` returned true. */ #[inline] - pure fn filter(f: fn(T) -> bool) -> ~[T] { filter(self, f) } + pure fn filter(f: fn(t: &T) -> bool) -> ~[T] { + filter(self, f) + } + /** * Search for the last element that matches a given predicate * @@ -1634,28 +1578,102 @@ impl &[T]: ImmutableCopyableVector { * returned. If `f` matches no elements then none is returned. */ #[inline] - pure fn rfind(f: fn(T) -> bool) -> Option { rfind(self, f) } + pure fn rfind(f: fn(t: &T) -> bool) -> Option { rfind(self, f) } +} + +pub trait MutableVector { + fn push(&mut self, t: T); + fn push_all_move(&mut self, rhs: ~[T]); + fn pop(&mut self) -> T; + fn shift(&mut self) -> T; + fn unshift(&mut self, x: T); + fn swap_remove(&mut self, index: uint) -> T; + fn truncate(&mut self, newlen: uint); +} + +pub trait MutableCopyableVector { + fn push_all(&mut self, rhs: &[const T]); + fn grow(&mut self, n: uint, initval: &T); + fn grow_fn(&mut self, n: uint, op: iter::InitOp); + fn grow_set(&mut self, index: uint, initval: &T, val: T); +} + +trait MutableEqVector { + fn dedup(&mut self); +} + +impl ~[T]: MutableVector { + fn push(&mut self, t: T) { + push(self, move t); + } + + fn push_all_move(&mut self, rhs: ~[T]) { + push_all_move(self, move rhs); + } + + fn pop(&mut self) -> T { + pop(self) + } + + fn shift(&mut self) -> T { + shift(self) + } + + fn unshift(&mut self, x: T) { + unshift(self, x) + } + + fn swap_remove(&mut self, index: uint) -> T { + swap_remove(self, index) + } + + fn truncate(&mut self, newlen: uint) { + truncate(self, newlen); + } +} + +impl ~[T]: MutableCopyableVector { + fn push_all(&mut self, rhs: &[const T]) { + push_all(self, rhs); + } + + fn grow(&mut self, n: uint, initval: &T) { + grow(self, n, initval); + } + + fn grow_fn(&mut self, n: uint, op: iter::InitOp) { + grow_fn(self, n, op); + } + + fn grow_set(&mut self, index: uint, initval: &T, val: T) { + grow_set(self, index, initval, val); + } +} + +impl ~[T]: MutableEqVector { + fn dedup(&mut self) { + dedup(self) + } } /// Unsafe operations -mod raw { - #[legacy_exports]; +pub mod raw { // FIXME: This should have crate visibility (#1893 blocks that) /// The internal representation of a (boxed) vector - struct VecRepr { + pub struct VecRepr { box_header: box::raw::BoxHeaderRepr, unboxed: UnboxedVecRepr } /// The internal 'unboxed' representation of a vector - struct UnboxedVecRepr { + pub struct UnboxedVecRepr { mut fill: uint, mut alloc: uint, data: u8 } - type SliceRepr = { + pub type SliceRepr = { mut data: *u8, mut len: uint }; @@ -1669,9 +1687,9 @@ mod raw { * * elts - The number of elements in the buffer */ #[inline(always)] - unsafe fn from_buf(ptr: *T, elts: uint) -> ~[T] { + pub unsafe fn from_buf(ptr: *T, elts: uint) -> ~[T] { let mut dst = with_capacity(elts); - set_len(dst, elts); + set_len(&mut dst, elts); as_mut_buf(dst, |p_dst, _len_dst| ptr::memcpy(p_dst, ptr, elts)); move dst } @@ -1684,8 +1702,8 @@ mod raw { * the vector is actually the specified size. */ #[inline(always)] - unsafe fn set_len(&&v: ~[const T], new_len: uint) { - let repr: **VecRepr = ::cast::reinterpret_cast(&addr_of(v)); + pub unsafe fn set_len(v: &mut ~[T], new_len: uint) { + let repr: **VecRepr = ::cast::transmute(v); (**repr).unboxed.fill = new_len * sys::size_of::(); } @@ -1699,23 +1717,23 @@ mod raw { * would also make any pointers to it invalid. */ #[inline(always)] - unsafe fn to_ptr(v: &[T]) -> *T { - let repr: **SliceRepr = ::cast::reinterpret_cast(&addr_of(v)); - return ::cast::reinterpret_cast(&addr_of((**repr).data)); + pub unsafe fn to_ptr(v: &[T]) -> *T { + let repr: **SliceRepr = ::cast::transmute(&v); + return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); } /** see `to_ptr()` */ #[inline(always)] - unsafe fn to_const_ptr(v: &[const T]) -> *const T { - let repr: **SliceRepr = ::cast::reinterpret_cast(&addr_of(v)); - return ::cast::reinterpret_cast(&addr_of((**repr).data)); + pub unsafe fn to_const_ptr(v: &[const T]) -> *const T { + let repr: **SliceRepr = ::cast::transmute(&v); + return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); } /** see `to_ptr()` */ #[inline(always)] - unsafe fn to_mut_ptr(v: &[mut T]) -> *mut T { - let repr: **SliceRepr = ::cast::reinterpret_cast(&addr_of(v)); - return ::cast::reinterpret_cast(&addr_of((**repr).data)); + pub unsafe fn to_mut_ptr(v: &[mut T]) -> *mut T { + let repr: **SliceRepr = ::cast::transmute(&v); + return ::cast::reinterpret_cast(&addr_of(&((**repr).data))); } /** @@ -1723,10 +1741,12 @@ mod raw { * not bytes). */ #[inline(always)] - unsafe fn form_slice(p: *T, len: uint, f: fn(v: &[T]) -> U) -> U { + pub unsafe fn buf_as_slice(p: *T, + len: uint, + f: fn(v: &[T]) -> U) -> U { let pair = (p, len * sys::size_of::()); let v : *(&blk/[T]) = - ::cast::reinterpret_cast(&ptr::addr_of(pair)); + ::cast::reinterpret_cast(&addr_of(&pair)); f(*v) } @@ -1734,15 +1754,17 @@ mod raw { * Unchecked vector indexing. */ #[inline(always)] - unsafe fn get(v: &[const T], i: uint) -> T { + pub unsafe fn get(v: &[const T], i: uint) -> T { as_const_buf(v, |p, _len| *ptr::const_offset(p, i)) } /** - * Unchecked vector index assignment. + * Unchecked vector index assignment. Does not drop the + * old value and hence is only suitable when the vector + * is newly allocated. */ #[inline(always)] - unsafe fn set(v: &[mut T], i: uint, +val: T) { + pub unsafe fn init_elem(v: &[mut T], i: uint, val: T) { let mut box = Some(move val); do as_mut_buf(v) |p, _len| { let mut box2 = None; @@ -1758,7 +1780,7 @@ mod raw { * Copies `count` bytes from `src` to `dst`. The source and destination * may overlap. */ - unsafe fn memcpy(dst: &[mut T], src: &[const T], count: uint) { + pub unsafe fn memcpy(dst: &[mut T], src: &[const T], count: uint) { do as_mut_buf(dst) |p_dst, _len_dst| { do as_const_buf(src) |p_src, _len_src| { ptr::memcpy(p_dst, p_src, count) @@ -1772,7 +1794,7 @@ mod raw { * Copies `count` bytes from `src` to `dst`. The source and destination * may overlap. */ - unsafe fn memmove(dst: &[mut T], src: &[const T], count: uint) { + pub unsafe fn memmove(dst: &[mut T], src: &[const T], count: uint) { do as_mut_buf(dst) |p_dst, _len_dst| { do as_const_buf(src) |p_src, _len_src| { ptr::memmove(p_dst, p_src, count) @@ -1782,14 +1804,10 @@ mod raw { } /// Operations on `[u8]` -mod bytes { - #[legacy_exports]; - export cmp; - export lt, le, eq, ne, ge, gt; - export memcpy, memmove; +pub mod bytes { /// Bytewise string comparison - pure fn cmp(a: &~[u8], b: &~[u8]) -> int { + pub pure fn cmp(a: &~[u8], b: &~[u8]) -> int { let a_len = len(*a); let b_len = len(*b); let n = uint::min(a_len, b_len) as libc::size_t; @@ -1810,22 +1828,22 @@ mod bytes { } /// Bytewise less than or equal - pure fn lt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) < 0 } + pub pure fn lt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) < 0 } /// Bytewise less than or equal - pure fn le(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) <= 0 } + pub pure fn le(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) <= 0 } /// Bytewise equality - pure fn eq(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) == 0 } + pub pure fn eq(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) == 0 } /// Bytewise inequality - pure fn ne(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) != 0 } + pub pure fn ne(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) != 0 } /// Bytewise greater than or equal - pure fn ge(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) >= 0 } + pub pure fn ge(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) >= 0 } /// Bytewise greater than - pure fn gt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) > 0 } + pub pure fn gt(a: &~[u8], b: &~[u8]) -> bool { cmp(a, b) > 0 } /** * Copies data from one vector to another. @@ -1833,7 +1851,7 @@ mod bytes { * Copies `count` bytes from `src` to `dst`. The source and destination * may not overlap. */ - fn memcpy(dst: &[mut u8], src: &[const u8], count: uint) { + pub fn memcpy(dst: &[mut u8], src: &[const u8], count: uint) { assert dst.len() >= count; assert src.len() >= count; @@ -1846,7 +1864,7 @@ mod bytes { * Copies `count` bytes from `src` to `dst`. The source and destination * may overlap. */ - fn memmove(dst: &[mut u8], src: &[const u8], count: uint) { + pub fn memmove(dst: &[mut u8], src: &[const u8], count: uint) { assert dst.len() >= count; assert src.len() >= count; @@ -1861,7 +1879,7 @@ mod bytes { // required in the slice. impl &[A]: iter::BaseIter { - pure fn each(blk: fn(v: &A) -> bool) { + pub pure fn each(blk: fn(v: &A) -> bool) { // FIXME(#2263)---should be able to call each(self, blk) for each(self) |e| { if (!blk(e)) { @@ -1873,64 +1891,67 @@ impl &[A]: iter::BaseIter { } impl &[A]: iter::ExtendedIter { - pure fn eachi(blk: fn(uint, v: &A) -> bool) { iter::eachi(self, blk) } - pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) } - pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) } - pure fn foldl(+b0: B, blk: fn(B, A) -> B) -> B { - iter::foldl(self, move b0, blk) + pub pure fn eachi(blk: fn(uint, v: &A) -> bool) { + iter::eachi(&self, blk) } - pure fn position(f: fn(A) -> bool) -> Option { - iter::position(self, f) + pub pure fn all(blk: fn(&A) -> bool) -> bool { iter::all(&self, blk) } + pub pure fn any(blk: fn(&A) -> bool) -> bool { iter::any(&self, blk) } + pub pure fn foldl(b0: B, blk: fn(&B, &A) -> B) -> B { + iter::foldl(&self, move b0, blk) + } + pub pure fn position(f: fn(&A) -> bool) -> Option { + iter::position(&self, f) } } impl &[A]: iter::EqIter { - pure fn contains(x: A) -> bool { iter::contains(self, x) } - pure fn count(x: A) -> uint { iter::count(self, x) } + pub pure fn contains(x: &A) -> bool { iter::contains(&self, x) } + pub pure fn count(x: &A) -> uint { iter::count(&self, x) } } impl &[A]: iter::CopyableIter { - pure fn filter_to_vec(pred: fn(A) -> bool) -> ~[A] { - iter::filter_to_vec(self, pred) + pure fn filter_to_vec(pred: fn(a: A) -> bool) -> ~[A] { + iter::filter_to_vec(&self, pred) } - pure fn map_to_vec(op: fn(v: &A) -> B) -> ~[B] { - iter::map_to_vec(self, op) + pure fn map_to_vec(op: fn(v: A) -> B) -> ~[B] { + iter::map_to_vec(&self, op) } - pure fn to_vec() -> ~[A] { iter::to_vec(self) } + pure fn to_vec() -> ~[A] { iter::to_vec(&self) } // FIXME--bug in resolve prevents this from working (#2611) // fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] { // iter::flat_map_to_vec(self, op) // } - pure fn find(p: fn(A) -> bool) -> Option { iter::find(self, p) } + pub pure fn find(p: fn(a: A) -> bool) -> Option { + iter::find(&self, p) + } } impl &[A]: iter::CopyableOrderedIter { - pure fn min() -> A { iter::min(self) } - pure fn max() -> A { iter::max(self) } + pure fn min() -> A { iter::min(&self) } + pure fn max() -> A { iter::max(&self) } } // ___________________________________________________________________________ #[cfg(test)] mod tests { - #[legacy_exports]; fn square(n: uint) -> uint { return n * n; } fn square_ref(n: &uint) -> uint { return square(*n); } - pure fn is_three(&&n: uint) -> bool { return n == 3u; } + pure fn is_three(n: &uint) -> bool { return *n == 3u; } - pure fn is_odd(&&n: uint) -> bool { return n % 2u == 1u; } + pure fn is_odd(n: &uint) -> bool { return *n % 2u == 1u; } - pure fn is_equal(&&x: uint, &&y:uint) -> bool { return x == y; } + pure fn is_equal(x: &uint, y:&uint) -> bool { return *x == *y; } - fn square_if_odd(&&n: uint) -> Option { - return if n % 2u == 1u { Some(n * n) } else { None }; + fn square_if_odd(n: &uint) -> Option { + return if *n % 2u == 1u { Some(*n * *n) } else { None }; } - fn add(&&x: uint, &&y: uint) -> uint { return x + y; } + fn add(x: uint, y: &uint) -> uint { return x + *y; } #[test] fn test_unsafe_ptrs() { @@ -2060,7 +2081,7 @@ mod tests { fn test_pop() { // Test on-stack pop. let mut v = ~[1, 2, 3]; - let mut e = pop(v); + let mut e = v.pop(); assert (len(v) == 2u); assert (v[0] == 1); assert (v[1] == 2); @@ -2068,7 +2089,7 @@ mod tests { // Test on-heap pop. v = ~[1, 2, 3, 4, 5]; - e = pop(v); + e = v.pop(); assert (len(v) == 4u); assert (v[0] == 1); assert (v[1] == 2); @@ -2080,11 +2101,11 @@ mod tests { #[test] fn test_swap_remove() { let mut v = ~[1, 2, 3, 4, 5]; - let mut e = swap_remove(v, 0); + let mut e = v.swap_remove(0); assert (len(v) == 4); assert e == 1; assert (v[0] == 5); - e = swap_remove(v, 3); + e = v.swap_remove(3); assert (len(v) == 3); assert e == 4; assert (v[0] == 5); @@ -2097,11 +2118,11 @@ mod tests { // Tests that we don't accidentally run destructors twice. let mut v = ~[::private::exclusive(()), ::private::exclusive(()), ::private::exclusive(())]; - let mut _e = swap_remove(v, 0); + let mut _e = v.swap_remove(0); assert (len(v) == 2); - _e = swap_remove(v, 1); + _e = v.swap_remove(1); assert (len(v) == 1); - _e = swap_remove(v, 0); + _e = v.swap_remove(0); assert (len(v) == 0); } @@ -2109,12 +2130,12 @@ mod tests { fn test_push() { // Test on-stack push(). let mut v = ~[]; - push(v, 1); + v.push(1); assert (len(v) == 1u); assert (v[0] == 1); // Test on-heap push(). - push(v, 2); + v.push(2); assert (len(v) == 2u); assert (v[0] == 1); assert (v[1] == 2); @@ -2124,13 +2145,13 @@ mod tests { fn test_grow() { // Test on-stack grow(). let mut v = ~[]; - grow(v, 2u, 1); + v.grow(2u, &1); assert (len(v) == 2u); assert (v[0] == 1); assert (v[1] == 1); // Test on-heap grow(). - grow(v, 3u, 2); + v.grow(3u, &2); assert (len(v) == 5u); assert (v[0] == 1); assert (v[1] == 1); @@ -2142,7 +2163,7 @@ mod tests { #[test] fn test_grow_fn() { let mut v = ~[]; - grow_fn(v, 3u, square); + v.grow_fn(3u, square); assert (len(v) == 3u); assert (v[0] == 0u); assert (v[1] == 1u); @@ -2152,7 +2173,7 @@ mod tests { #[test] fn test_grow_set() { let mut v = ~[1, 2, 3]; - grow_set(v, 4u, 4, 5); + v.grow_set(4u, &4, 5); assert (len(v) == 5u); assert (v[0] == 1); assert (v[1] == 2); @@ -2164,7 +2185,7 @@ mod tests { #[test] fn test_truncate() { let mut v = ~[@6,@5,@4]; - truncate(v, 1); + v.truncate(1); assert(v.len() == 1); assert(*(v[0]) == 6); // If the unsafe block didn't drop things properly, we blow up here. @@ -2172,9 +2193,9 @@ mod tests { #[test] fn test_dedup() { - fn case(-a: ~[uint], -b: ~[uint]) { + fn case(a: ~[uint], b: ~[uint]) { let mut v = a; - dedup(v); + v.dedup(); assert(v == b); } case(~[], ~[]); @@ -2190,11 +2211,11 @@ mod tests { #[test] fn test_dedup_unique() { let mut v0 = ~[~1, ~1, ~2, ~3]; - dedup(v0); + v0.dedup(); let mut v1 = ~[~1, ~2, ~2, ~3]; - dedup(v1); + v1.dedup(); let mut v2 = ~[~1, ~2, ~3, ~3]; - dedup(v2); + v2.dedup(); /* * If the ~pointers were leaked or otherwise misused, valgrind and/or * rustrt should raise errors. @@ -2204,11 +2225,11 @@ mod tests { #[test] fn test_dedup_shared() { let mut v0 = ~[@1, @1, @2, @3]; - dedup(v0); + v0.dedup(); let mut v1 = ~[@1, @2, @2, @3]; - dedup(v1); + v1.dedup(); let mut v2 = ~[@1, @2, @3, @3]; - dedup(v2); + v2.dedup(); /* * If the @pointers were leaked or otherwise misused, valgrind and/or * rustrt should raise errors. @@ -2238,7 +2259,7 @@ mod tests { #[test] fn test_map2() { - fn times(&&x: int, &&y: int) -> int { return x * y; } + fn times(x: &int, y: &int) -> int { return *x * *y; } let f = times; let v0 = ~[1, 2, 3, 4, 5]; let v1 = ~[5, 4, 3, 2, 1]; @@ -2264,9 +2285,9 @@ mod tests { assert (w[1] == 9u); assert (w[2] == 25u); - fn halve(&&i: int) -> Option { - if i % 2 == 0 { - return option::Some::(i / 2); + fn halve(i: &int) -> Option { + if *i % 2 == 0 { + return option::Some::(*i / 2); } else { return option::None::; } } fn halve_for_sure(i: &int) -> int { return *i / 2; } @@ -2302,8 +2323,8 @@ mod tests { #[test] fn test_foldl2() { - fn sub(&&a: int, &&b: int) -> int { - a - b + fn sub(a: int, b: &int) -> int { + a - *b } let mut v = ~[1, 2, 3, 4]; let sum = foldl(0, v, sub); @@ -2312,8 +2333,8 @@ mod tests { #[test] fn test_foldr() { - fn sub(&&a: int, &&b: int) -> int { - a - b + fn sub(a: &int, b: int) -> int { + *a - b } let mut v = ~[1, 2, 3, 4]; let sum = foldr(v, 0, sub); @@ -2376,23 +2397,23 @@ mod tests { } #[test] - fn test_permute() { + fn test_each_permutation() { let mut results: ~[~[int]]; results = ~[]; - permute(~[], |v| vec::push(results, copy v)); + for each_permutation(~[]) |v| { results.push(from_slice(v)); } assert results == ~[~[]]; results = ~[]; - permute(~[7], |v| push(results, copy v)); + for each_permutation(~[7]) |v| { results.push(from_slice(v)); } assert results == ~[~[7]]; results = ~[]; - permute(~[1,1], |v| push(results, copy v)); + for each_permutation(~[1,1]) |v| { results.push(from_slice(v)); } assert results == ~[~[1,1],~[1,1]]; results = ~[]; - permute(~[5,2,0], |v| push(results, copy v)); + for each_permutation(~[5,2,0]) |v| { results.push(from_slice(v)); } assert results == ~[~[5,2,0],~[5,0,2],~[2,5,0],~[2,0,5],~[0,5,2],~[0,2,5]]; } @@ -2444,19 +2465,19 @@ mod tests { #[test] fn test_position_elem() { - assert position_elem(~[], 1).is_none(); + assert position_elem(~[], &1).is_none(); let v1 = ~[1, 2, 3, 3, 2, 5]; - assert position_elem(v1, 1) == Some(0u); - assert position_elem(v1, 2) == Some(1u); - assert position_elem(v1, 5) == Some(5u); - assert position_elem(v1, 4).is_none(); + assert position_elem(v1, &1) == Some(0u); + assert position_elem(v1, &2) == Some(1u); + assert position_elem(v1, &5) == Some(5u); + assert position_elem(v1, &4).is_none(); } #[test] fn test_position() { - fn less_than_three(&&i: int) -> bool { return i < 3; } - fn is_eighteen(&&i: int) -> bool { return i == 18; } + fn less_than_three(i: &int) -> bool { return *i < 3; } + fn is_eighteen(i: &int) -> bool { return *i == 18; } assert position(~[], less_than_three).is_none(); @@ -2469,7 +2490,7 @@ mod tests { fn test_position_between() { assert position_between(~[], 0u, 0u, f).is_none(); - fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' } + fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; assert position_between(v, 0u, 0u, f).is_none(); @@ -2497,8 +2518,8 @@ mod tests { fn test_find() { assert find(~[], f).is_none(); - fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' } - fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' } + fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } + fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' } let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; assert find(v, f) == Some((1, 'b')); @@ -2509,7 +2530,7 @@ mod tests { fn test_find_between() { assert find_between(~[], 0u, 0u, f).is_none(); - fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' } + fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; assert find_between(v, 0u, 0u, f).is_none(); @@ -2537,8 +2558,8 @@ mod tests { fn test_rposition() { assert find(~[], f).is_none(); - fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' } - fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' } + fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } + fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' } let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; assert position(v, f) == Some(1u); @@ -2549,7 +2570,7 @@ mod tests { fn test_rposition_between() { assert rposition_between(~[], 0u, 0u, f).is_none(); - fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' } + fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; assert rposition_between(v, 0u, 0u, f).is_none(); @@ -2577,8 +2598,8 @@ mod tests { fn test_rfind() { assert rfind(~[], f).is_none(); - fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' } - fn g(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'd' } + fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } + fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' } let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; assert rfind(v, f) == Some((3, 'b')); @@ -2589,7 +2610,7 @@ mod tests { fn test_rfind_between() { assert rfind_between(~[], 0u, 0u, f).is_none(); - fn f(xy: (int, char)) -> bool { let (_x, y) = xy; y == 'b' } + fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' } let mut v = ~[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')]; assert rfind_between(v, 0u, 0u, f).is_none(); @@ -2649,7 +2670,7 @@ mod tests { #[test] fn test_split() { - fn f(&&x: int) -> bool { x == 3 } + fn f(x: &int) -> bool { *x == 3 } assert split(~[], f) == ~[]; assert split(~[1, 2], f) == ~[~[1, 2]]; @@ -2660,7 +2681,7 @@ mod tests { #[test] fn test_splitn() { - fn f(&&x: int) -> bool { x == 3 } + fn f(x: &int) -> bool { *x == 3 } assert splitn(~[], 1u, f) == ~[]; assert splitn(~[1, 2], 1u, f) == ~[~[1, 2]]; @@ -2672,7 +2693,7 @@ mod tests { #[test] fn test_rsplit() { - fn f(&&x: int) -> bool { x == 3 } + fn f(x: &int) -> bool { *x == 3 } assert rsplit(~[], f) == ~[]; assert rsplit(~[1, 2], f) == ~[~[1, 2]]; @@ -2682,7 +2703,7 @@ mod tests { #[test] fn test_rsplitn() { - fn f(&&x: int) -> bool { x == 3 } + fn f(x: &int) -> bool { *x == 3 } assert rsplitn(~[], 1u, f) == ~[]; assert rsplitn(~[1, 2], 1u, f) == ~[~[1, 2]]; @@ -2705,9 +2726,9 @@ mod tests { #[test] fn test_connect() { - assert connect(~[], 0) == ~[]; - assert connect(~[~[1], ~[2, 3]], 0) == ~[1, 0, 2, 3]; - assert connect(~[~[1], ~[2], ~[3]], 0) == ~[1, 0, 2, 0, 3]; + assert connect(~[], &0) == ~[]; + assert connect(~[~[1], ~[2, 3]], &0) == ~[1, 0, 2, 3]; + assert connect(~[~[1], ~[2], ~[3]], &0) == ~[1, 0, 2, 0, 3]; } #[test] @@ -2753,7 +2774,7 @@ mod tests { #[test] fn test_unshift() { let mut x = ~[1, 2, 3]; - unshift(x, 0); + x.unshift(0); assert x == ~[0, 1, 2, 3]; } @@ -2761,23 +2782,558 @@ mod tests { fn test_capacity() { let mut v = ~[0u64]; reserve(&mut v, 10u); - assert capacity(v) == 10u; + assert capacity(&v) == 10u; let mut v = ~[0u32]; reserve(&mut v, 10u); - assert capacity(v) == 10u; + assert capacity(&v) == 10u; } -/* #[test] - #[ignore] // region inference doesn't work well enough for this yet. fn test_view() { let v = ~[1, 2, 3, 4, 5]; - let v = view(v, 1u, 3u); + let v = v.view(1u, 3u); assert(len(v) == 2u); assert(v[0] == 2); assert(v[1] == 3); } -*/ + + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_from_fn_fail() { + do from_fn(100) |v| { + if v == 50 { fail } + (~0, @0) + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_build_fail() { + do build |push| { + push((~0, @0)); + push((~0, @0)); + push((~0, @0)); + push((~0, @0)); + fail; + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_split_fail_ret_true() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do split(v) |_elt| { + if i == 2 { + fail + } + i += 1; + + true + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_split_fail_ret_false() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do split(v) |_elt| { + if i == 2 { + fail + } + i += 1; + + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_splitn_fail_ret_true() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do splitn(v, 100) |_elt| { + if i == 2 { + fail + } + i += 1; + + true + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_splitn_fail_ret_false() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do split(v) |_elt| { + if i == 2 { + fail + } + i += 1; + + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_rsplit_fail_ret_true() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do rsplit(v) |_elt| { + if i == 2 { + fail + } + i += 1; + + true + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_rsplit_fail_ret_false() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do rsplit(v) |_elt| { + if i == 2 { + fail + } + i += 1; + + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_rsplitn_fail_ret_true() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do rsplitn(v, 100) |_elt| { + if i == 2 { + fail + } + i += 1; + + true + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_rsplitn_fail_ret_false() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do rsplitn(v, 100) |_elt| { + if i == 2 { + fail + } + i += 1; + + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_consume_fail() { + let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do consume(v) |_i, _elt| { + if i == 2 { + fail + } + i += 1; + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_consume_mut_fail() { + let v = ~[mut (~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do consume_mut(v) |_i, _elt| { + if i == 2 { + fail + } + i += 1; + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_grow_fn_fail() { + let mut v = ~[]; + do v.grow_fn(100) |i| { + if i == 50 { + fail + } + (~0, @0) + } + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_map_fail() { + let v = [mut (~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do map(v) |_elt| { + if i == 2 { + fail + } + i += 0; + ~[(~0, @0)] + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_map_consume_fail() { + let v = ~[(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do map_consume(v) |_elt| { + if i == 2 { + fail + } + i += 0; + ~[(~0, @0)] + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_mapi_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do mapi(v) |_i, _elt| { + if i == 2 { + fail + } + i += 0; + ~[(~0, @0)] + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_flat_map_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do map(v) |_elt| { + if i == 2 { + fail + } + i += 0; + ~[(~0, @0)] + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_map2_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do map2(v, v) |_elt1, _elt2| { + if i == 2 { + fail + } + i += 0; + ~[(~0, @0)] + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_filter_map_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do filter_map(v) |_elt| { + if i == 2 { + fail + } + i += 0; + Some((~0, @0)) + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_filter_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do filter(v) |_elt| { + if i == 2 { + fail + } + i += 0; + true + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_foldl_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do foldl((~0, @0), v) |_a, _b| { + if i == 2 { + fail + } + i += 0; + (~0, @0) + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_foldr_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do foldr(v, (~0, @0)) |_a, _b| { + if i == 2 { + fail + } + i += 0; + (~0, @0) + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_any_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do any(v) |_elt| { + if i == 2 { + fail + } + i += 0; + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_any2_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do any(v) |_elt| { + if i == 2 { + fail + } + i += 0; + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_all_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do all(v) |_elt| { + if i == 2 { + fail + } + i += 0; + true + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_alli_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do alli(v) |_i, _elt| { + if i == 2 { + fail + } + i += 0; + true + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_all2_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do all2(v, v) |_elt1, _elt2| { + if i == 2 { + fail + } + i += 0; + true + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_find_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do find(v) |_elt| { + if i == 2 { + fail + } + i += 0; + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_position_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do position(v) |_elt| { + if i == 2 { + fail + } + i += 0; + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_rposition_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do rposition(v) |_elt| { + if i == 2 { + fail + } + i += 0; + false + }; + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_each_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do each(v) |_elt| { + if i == 2 { + fail + } + i += 0; + false + } + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_eachi_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + do eachi(v) |_i, _elt| { + if i == 2 { + fail + } + i += 0; + false + } + } + + #[test] + #[ignore(windows)] + #[should_fail] + #[allow(non_implicitly_copyable_typarams)] + fn test_permute_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + let mut i = 0; + for each_permutation(v) |_elt| { + if i == 2 { + fail + } + i += 0; + } + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_as_imm_buf_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + do as_imm_buf(v) |_buf, _i| { + fail + } + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_as_const_buf_fail() { + let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + do as_const_buf(v) |_buf, _i| { + fail + } + } + + #[test] + #[ignore(windows)] + #[should_fail] + fn test_as_mut_buf_fail() { + let v = [mut (~0, @0), (~0, @0), (~0, @0), (~0, @0)]; + do as_mut_buf(v) |_buf, _i| { + fail + } + } } // Local Variables: diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 4ffe72451138..60db62ce01ae 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -1,6 +1,5 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap /** * Concurrency-enabled mechanisms for sharing mutable and/or immutable state * between tasks. @@ -12,14 +11,9 @@ use private::{SharedMutableState, shared_mutable_state, use sync::{Mutex, mutex_with_condvars, RWlock, rwlock_with_condvars}; -export ARC, clone, get; -export Condvar; -export MutexARC, mutex_arc_with_condvars, unwrap_mutex_arc; -export RWARC, rw_arc_with_condvars, RWWriteMode, RWReadMode; -export unwrap_rw_arc; /// As sync::condvar, a mechanism for unlock-and-descheduling and signalling. -struct Condvar { is_mutex: bool, failed: &mut bool, cond: &sync::Condvar } +pub struct Condvar { is_mutex: bool, failed: &mut bool, cond: &sync::Condvar } impl &Condvar { /// Atomically exit the associated ARC and block until a signal is sent. @@ -72,7 +66,7 @@ impl &Condvar { struct ARC { x: SharedMutableState } /// Create an atomically reference counted wrapper. -fn ARC(+data: T) -> ARC { +pub fn ARC(data: T) -> ARC { ARC { x: unsafe { shared_mutable_state(move data) } } } @@ -80,7 +74,7 @@ fn ARC(+data: T) -> ARC { * Access the underlying data in an atomically reference counted * wrapper. */ -fn get(rc: &a/ARC) -> &a/T { +pub fn get(rc: &a/ARC) -> &a/T { unsafe { get_shared_immutable_state(&rc.x) } } @@ -91,7 +85,7 @@ fn get(rc: &a/ARC) -> &a/T { * object. However, one of the `arc` objects can be sent to another task, * allowing them to share the underlying data. */ -fn clone(rc: &ARC) -> ARC { +pub fn clone(rc: &ARC) -> ARC { ARC { x: unsafe { clone_shared_mutable_state(&rc.x) } } } @@ -104,7 +98,7 @@ fn clone(rc: &ARC) -> ARC { * unwrap from a task that holds another reference to the same ARC; it is * guaranteed to deadlock. */ -fn unwrap(+rc: ARC) -> T { +fn unwrap(rc: ARC) -> T { let ARC { x: x } <- rc; unsafe { unwrap_shared_mutable_state(move x) } } @@ -119,14 +113,14 @@ struct MutexARCInner { lock: Mutex, failed: bool, data: T } struct MutexARC { x: SharedMutableState> } /// Create a mutex-protected ARC with the supplied data. -fn MutexARC(+user_data: T) -> MutexARC { +pub fn MutexARC(user_data: T) -> MutexARC { mutex_arc_with_condvars(move user_data, 1) } /** * Create a mutex-protected ARC with the supplied data and a specified number * of condvars (as sync::mutex_with_condvars). */ -fn mutex_arc_with_condvars(+user_data: T, +pub fn mutex_arc_with_condvars(user_data: T, num_condvars: uint) -> MutexARC { let data = MutexARCInner { lock: mutex_with_condvars(num_condvars), @@ -197,7 +191,7 @@ impl &MutexARC { * Will additionally fail if another task has failed while accessing the arc. */ // FIXME(#2585) make this a by-move method on the arc -fn unwrap_mutex_arc(+arc: MutexARC) -> T { +pub fn unwrap_mutex_arc(arc: MutexARC) -> T { let MutexARC { x: x } <- arc; let inner = unsafe { unwrap_shared_mutable_state(move x) }; let MutexARCInner { failed: failed, data: data, _ } <- inner; @@ -253,14 +247,14 @@ struct RWARC { } /// Create a reader/writer ARC with the supplied data. -fn RWARC(+user_data: T) -> RWARC { +pub fn RWARC(user_data: T) -> RWARC { rw_arc_with_condvars(move user_data, 1) } /** * Create a reader/writer ARC with the supplied data and a specified number * of condvars (as sync::rwlock_with_condvars). */ -fn rw_arc_with_condvars(+user_data: T, +pub fn rw_arc_with_condvars(user_data: T, num_condvars: uint) -> RWARC { let data = RWARCInner { lock: rwlock_with_condvars(num_condvars), @@ -340,7 +334,7 @@ impl &RWARC { * } * ~~~ */ - fn write_downgrade(blk: fn(+v: RWWriteMode) -> U) -> U { + fn write_downgrade(blk: fn(v: RWWriteMode) -> U) -> U { let state = unsafe { get_shared_mutable_state(&self.x) }; do borrow_rwlock(state).write_downgrade |write_mode| { check_poison(false, state.failed); @@ -350,7 +344,7 @@ impl &RWARC { } /// To be called inside of the write_downgrade block. - fn downgrade(+token: RWWriteMode/&a) -> RWReadMode/&a { + fn downgrade(token: RWWriteMode/&a) -> RWReadMode/&a { // The rwlock should assert that the token belongs to us for us. let state = unsafe { get_shared_immutable_state(&self.x) }; let RWWriteMode((data, t, _poison)) <- token; @@ -375,7 +369,7 @@ impl &RWARC { * in write mode. */ // FIXME(#2585) make this a by-move method on the arc -fn unwrap_rw_arc(+arc: RWARC) -> T { +pub fn unwrap_rw_arc(arc: RWARC) -> T { let RWARC { x: x, _ } <- arc; let inner = unsafe { unwrap_shared_mutable_state(move x) }; let RWARCInner { failed: failed, data: data, _ } <- inner; @@ -396,10 +390,10 @@ fn borrow_rwlock(state: &r/mut RWARCInner) -> &r/RWlock { // FIXME (#3154) ice with struct/& prevents these from being structs. /// The "write permission" token used for RWARC.write_downgrade(). -enum RWWriteMode = +pub enum RWWriteMode = (&mut T, sync::RWlockWriteMode, PoisonOnFail); /// The "read permission" token used for RWARC.write_downgrade(). -enum RWReadMode = (&T, sync::RWlockReadMode); +pub enum RWReadMode = (&T, sync::RWlockReadMode); impl &RWWriteMode { /// Access the pre-downgrade RWARC in write mode. @@ -648,7 +642,7 @@ mod tests { let mut children = ~[]; for 5.times { let arc3 = ~arc.clone(); - do task::task().future_result(|+r| vec::push(children, r)).spawn { + do task::task().future_result(|+r| children.push(r)).spawn { do arc3.read |num| { assert *num >= 0; } @@ -676,7 +670,7 @@ mod tests { let mut reader_convos = ~[]; for 10.times { let ((rc1,rp1),(rc2,rp2)) = (pipes::stream(),pipes::stream()); - vec::push(reader_convos, (rc1,rp2)); + reader_convos.push((rc1,rp2)); let arcn = ~arc.clone(); do task::spawn { rp1.recv(); // wait for downgrader to give go-ahead @@ -719,7 +713,7 @@ mod tests { // send to other readers for vec::each(reader_convos) |x| { match *x { - (rc, _) => rc.send(()), + (ref rc, _) => rc.send(()), } } } @@ -728,7 +722,7 @@ mod tests { // complete handshake with other readers for vec::each(reader_convos) |x| { match *x { - (_, rp) => rp.recv(), + (_, ref rp) => rp.recv(), } } wc1.send(()); // tell writer to try again diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 4af647aabf70..4d2b910fa851 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -23,9 +23,6 @@ // to waste time running the destructors of POD. #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - -export Arena, arena_with_size; use list::{List, Cons, Nil}; use cast::reinterpret_cast; @@ -34,12 +31,10 @@ use libc::size_t; #[abi = "rust-intrinsic"] extern mod rusti { - #[legacy_exports]; fn move_val_init(&dst: T, -src: T); fn needs_drop() -> bool; } extern mod rustrt { - #[legacy_exports]; #[rust_stack] fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t); } @@ -52,7 +47,7 @@ const tydesc_drop_glue_index: size_t = 3 as size_t; // will always stay at 0. type Chunk = {data: @[u8], mut fill: uint, is_pod: bool}; -struct Arena { +pub struct Arena { // The head is seperated out from the list as a unbenchmarked // microoptimization, to avoid needing to case on the list to // access the head. @@ -63,25 +58,25 @@ struct Arena { unsafe { destroy_chunk(&self.head); for list::each(self.chunks) |chunk| { - if !chunk.is_pod { destroy_chunk(&chunk); } + if !chunk.is_pod { destroy_chunk(chunk); } } } } } fn chunk(size: uint, is_pod: bool) -> Chunk { - let mut v = @[]; - unsafe { at_vec::raw::reserve(v, size); } - { data: v, mut fill: 0u, is_pod: is_pod } + let mut v: @[const u8] = @[]; + unsafe { at_vec::raw::reserve(&mut v, size); } + { data: unsafe { cast::transmute(v) }, mut fill: 0u, is_pod: is_pod } } -fn arena_with_size(initial_size: uint) -> Arena { +pub fn arena_with_size(initial_size: uint) -> Arena { return Arena {mut head: chunk(initial_size, false), mut pod_head: chunk(initial_size, true), mut chunks: @Nil}; } -fn Arena() -> Arena { +pub fn Arena() -> Arena { arena_with_size(32u) } diff --git a/src/libstd/base64.rs b/src/libstd/base64.rs index 0da23db7291f..9bad4d397500 100644 --- a/src/libstd/base64.rs +++ b/src/libstd/base64.rs @@ -1,8 +1,7 @@ #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use io::Reader; -trait ToBase64 { +pub trait ToBase64 { fn to_base64() -> ~str; } @@ -63,7 +62,7 @@ impl &str: ToBase64 { } } -trait FromBase64 { +pub trait FromBase64 { fn from_base64() -> ~[u8]; } @@ -102,12 +101,12 @@ impl ~[u8]: FromBase64 { } else if ch == '=' { match len - i { 1u => { - vec::push(r, ((n >> 16u) & 0xFFu) as u8); - vec::push(r, ((n >> 8u ) & 0xFFu) as u8); + r.push(((n >> 16u) & 0xFFu) as u8); + r.push(((n >> 8u ) & 0xFFu) as u8); return copy r; } 2u => { - vec::push(r, ((n >> 10u) & 0xFFu) as u8); + r.push(((n >> 10u) & 0xFFu) as u8); return copy r; } _ => fail ~"invalid base64 padding" @@ -119,9 +118,9 @@ impl ~[u8]: FromBase64 { i += 1u; }; - vec::push(r, ((n >> 16u) & 0xFFu) as u8); - vec::push(r, ((n >> 8u ) & 0xFFu) as u8); - vec::push(r, ((n ) & 0xFFu) as u8); + r.push(((n >> 16u) & 0xFFu) as u8); + r.push(((n >> 8u ) & 0xFFu) as u8); + r.push(((n ) & 0xFFu) as u8); } r diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 2c0a3716411d..77f0d39c338e 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -1,10 +1,7 @@ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap use vec::{to_mut, from_elem}; -export Bitv, from_bytes, from_bools, from_fn; - struct SmallBitv { /// only the lowest nbits of this value are used. the rest is undefined. mut bits: u32 @@ -98,7 +95,7 @@ struct BigBitv { mut storage: ~[mut uint] } -fn BigBitv(+storage: ~[mut uint]) -> BigBitv { +fn BigBitv(storage: ~[mut uint]) -> BigBitv { BigBitv {storage: storage} } @@ -140,17 +137,17 @@ impl BigBitv { } #[inline(always)] - fn each_storage(op: fn(&v: uint) -> bool) { + fn each_storage(op: fn(v: &mut uint) -> bool) { for uint::range(0, self.storage.len()) |i| { let mut w = self.storage[i]; - let b = !op(w); + let b = !op(&mut w); self.storage[i] = w; if !b { break; } } } #[inline(always)] - fn invert() { for self.each_storage() |w| { w = !w } } + fn invert() { for self.each_storage() |w| { *w = !*w } } #[inline(always)] fn union(b: &BigBitv, nbits: uint) -> bool { @@ -210,12 +207,12 @@ enum BitvVariant { Big(~BigBitv), Small(~SmallBitv) } enum Op {Union, Intersect, Assign, Difference} // The bitvector type -struct Bitv { +pub struct Bitv { rep: BitvVariant, nbits: uint } -fn Bitv (nbits: uint, init: bool) -> Bitv { +pub fn Bitv (nbits: uint, init: bool) -> Bitv { let rep = if nbits <= 32 { Small(~SmallBitv(if init {!0} else {0})) } @@ -241,22 +238,22 @@ priv impl Bitv { self.die(); } match self.rep { - Small(s) => match other.rep { - Small(s1) => match op { - Union => s.union(s1, self.nbits), - Intersect => s.intersect(s1, self.nbits), - Assign => s.become(s1, self.nbits), - Difference => s.difference(s1, self.nbits) + Small(ref s) => match other.rep { + Small(ref s1) => match op { + Union => s.union(*s1, self.nbits), + Intersect => s.intersect(*s1, self.nbits), + Assign => s.become(*s1, self.nbits), + Difference => s.difference(*s1, self.nbits) }, Big(_) => self.die() }, - Big(s) => match other.rep { + Big(ref s) => match other.rep { Small(_) => self.die(), - Big(s1) => match op { - Union => s.union(s1, self.nbits), - Intersect => s.intersect(s1, self.nbits), - Assign => s.become(s1, self.nbits), - Difference => s.difference(s1, self.nbits) + Big(ref s1) => match op { + Union => s.union(*s1, self.nbits), + Intersect => s.intersect(*s1, self.nbits), + Assign => s.become(*s1, self.nbits), + Difference => s.difference(*s1, self.nbits) } } } @@ -297,10 +294,10 @@ impl Bitv { #[inline(always)] fn clone() -> ~Bitv { ~match self.rep { - Small(b) => { + Small(ref b) => { Bitv{nbits: self.nbits, rep: Small(~SmallBitv{bits: b.bits})} } - Big(b) => { + Big(ref b) => { let st = to_mut(from_elem(self.nbits / uint_bits + 1, 0)); let len = st.len(); for uint::range(0, len) |i| { st[i] = b.storage[i]; }; @@ -314,8 +311,8 @@ impl Bitv { pure fn get(i: uint) -> bool { assert (i < self.nbits); match self.rep { - Big(b) => b.get(i), - Small(s) => s.get(i) + Big(ref b) => b.get(i), + Small(ref s) => s.get(i) } } @@ -328,8 +325,8 @@ impl Bitv { fn set(i: uint, x: bool) { assert (i < self.nbits); match self.rep { - Big(b) => b.set(i, x), - Small(s) => s.set(i, x) + Big(ref b) => b.set(i, x), + Small(ref s) => s.set(i, x) } } @@ -340,15 +337,15 @@ impl Bitv { * bitvectors contain identical elements. */ #[inline(always)] - fn equal(v1: Bitv) -> bool { + fn equal(v1: &Bitv) -> bool { if self.nbits != v1.nbits { return false; } match self.rep { - Small(b) => match v1.rep { - Small(b1) => b.equals(b1, self.nbits), + Small(ref b) => match v1.rep { + Small(ref b1) => b.equals(*b1, self.nbits), _ => false }, - Big(s) => match v1.rep { - Big(s1) => s.equals(s1, self.nbits), + Big(ref s) => match v1.rep { + Big(ref s1) => s.equals(*s1, self.nbits), Small(_) => return false } } @@ -358,8 +355,8 @@ impl Bitv { #[inline(always)] fn clear() { match self.rep { - Small(b) => b.clear(), - Big(s) => for s.each_storage() |w| { w = 0u } + Small(ref b) => b.clear(), + Big(ref s) => for s.each_storage() |w| { *w = 0u } } } @@ -367,16 +364,16 @@ impl Bitv { #[inline(always)] fn set_all() { match self.rep { - Small(b) => b.set_all(), - Big(s) => for s.each_storage() |w| { w = !0u } } + Small(ref b) => b.set_all(), + Big(ref s) => for s.each_storage() |w| { *w = !0u } } } /// Invert all bits #[inline(always)] fn invert() { match self.rep { - Small(b) => b.invert(), - Big(s) => for s.each_storage() |w| { w = !w } } + Small(ref b) => b.invert(), + Big(ref s) => for s.each_storage() |w| { *w = !*w } } } /** @@ -389,13 +386,13 @@ impl Bitv { * Returns `true` if `v0` was changed. */ #[inline(always)] - fn difference(v: ~Bitv) -> bool { self.do_op(Difference, v) } + fn difference(v: &Bitv) -> bool { self.do_op(Difference, v) } /// Returns true if all bits are 1 #[inline(always)] fn is_true() -> bool { match self.rep { - Small(b) => b.is_true(self.nbits), + Small(ref b) => b.is_true(self.nbits), _ => { for self.each() |i| { if !i { return false; } } true @@ -415,7 +412,7 @@ impl Bitv { /// Returns true if all bits are 0 fn is_false() -> bool { match self.rep { - Small(b) => b.is_false(self.nbits), + Small(ref b) => b.is_false(self.nbits), Big(_) => { for self.each() |i| { if i { return false; } } true @@ -520,7 +517,7 @@ impl Bitv { * with the most significant bits of each byte coming first. Each * bit becomes true if equal to 1 or false if equal to 0. */ -fn from_bytes(bytes: &[u8]) -> Bitv { +pub fn from_bytes(bytes: &[u8]) -> Bitv { from_fn(bytes.len() * 8, |i| { let b = bytes[i / 8] as uint; let offset = i % 8; @@ -531,7 +528,7 @@ fn from_bytes(bytes: &[u8]) -> Bitv { /** * Transform a [bool] into a bitv by converting each bool into a bit. */ -fn from_bools(bools: &[bool]) -> Bitv { +pub fn from_bools(bools: &[bool]) -> Bitv { from_fn(bools.len(), |i| bools[i]) } @@ -539,7 +536,7 @@ fn from_bools(bools: &[bool]) -> Bitv { * Create a bitv of the specified length where the value at each * index is f(index). */ -fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv { +pub fn from_fn(len: uint, f: fn(index: uint) -> bool) -> Bitv { let bitv = Bitv(len, false); for uint::range(0, len) |i| { bitv.set(i, f(i)); @@ -556,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 { - pure fn index(&&i: uint) -> bool { + pure fn index(+i: uint) -> bool { self.get(i) } } @@ -866,14 +863,14 @@ mod tests { fn test_equal_differing_sizes() { let v0 = Bitv(10u, false); let v1 = Bitv(11u, false); - assert !v0.equal(v1); + assert !v0.equal(&v1); } #[test] fn test_equal_greatly_differing_sizes() { let v0 = Bitv(10u, false); let v1 = Bitv(110u, false); - assert !v0.equal(v1); + assert !v0.equal(&v1); } #[test] @@ -884,7 +881,7 @@ mod tests { let b = bitv::Bitv(1, true); b.set(0, true); - assert a.equal(b); + assert a.equal(&b); } #[test] @@ -899,7 +896,7 @@ mod tests { b.set(i, true); } - assert a.equal(b); + assert a.equal(&b); } #[test] diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index fde9df858d79..1ff5b63ee12f 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -26,19 +26,13 @@ * still held if needed. */ -export CVec; -export CVec, c_vec_with_dtor; -export get, set; -export len; -export ptr; - /** * The type representing a foreign chunk of memory * * Wrapped in a enum for opacity; FIXME #818 when it is possible to have * truly opaque types, this should be revisited. */ -enum CVec { +pub enum CVec { CVecCtor({ base: *mut T, len: uint, rsrc: @DtorRes}) } @@ -70,7 +64,7 @@ fn DtorRes(dtor: Option) -> DtorRes { * * base - A foreign pointer to a buffer * * len - The number of elements in the buffer */ -unsafe fn CVec(base: *mut T, len: uint) -> CVec { +pub unsafe fn CVec(base: *mut T, len: uint) -> CVec { return CVecCtor({ base: base, len: len, @@ -89,7 +83,7 @@ unsafe fn CVec(base: *mut T, len: uint) -> CVec { * * dtor - A function to run when the value is destructed, useful * for freeing the buffer, etc. */ -unsafe fn c_vec_with_dtor(base: *mut T, len: uint, dtor: fn@()) +pub unsafe fn c_vec_with_dtor(base: *mut T, len: uint, dtor: fn@()) -> CVec { return CVecCtor({ base: base, @@ -107,7 +101,7 @@ unsafe fn c_vec_with_dtor(base: *mut T, len: uint, dtor: fn@()) * * Fails if `ofs` is greater or equal to the length of the vector */ -fn get(t: CVec, ofs: uint) -> T { +pub fn get(t: CVec, ofs: uint) -> T { assert ofs < len(t); return unsafe { *ptr::mut_offset((*t).base, ofs) }; } @@ -117,7 +111,7 @@ fn get(t: CVec, ofs: uint) -> T { * * Fails if `ofs` is greater or equal to the length of the vector */ -fn set(t: CVec, ofs: uint, v: T) { +pub fn set(t: CVec, ofs: uint, +v: T) { assert ofs < len(t); unsafe { *ptr::mut_offset((*t).base, ofs) = v }; } @@ -127,18 +121,17 @@ fn set(t: CVec, ofs: uint, v: T) { */ /// Returns the length of the vector -fn len(t: CVec) -> uint { +pub fn len(t: CVec) -> uint { return (*t).len; } /// Returns a pointer to the first element of the vector -unsafe fn ptr(t: CVec) -> *mut T { +pub unsafe fn ptr(t: CVec) -> *mut T { return (*t).base; } #[cfg(test)] mod tests { - #[legacy_exports]; use libc::*; fn malloc(n: size_t) -> CVec { diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs index bc16aa2e03e8..866dbce1c085 100644 --- a/src/libstd/cell.rs +++ b/src/libstd/cell.rs @@ -1,19 +1,18 @@ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap /// A dynamic, mutable location. /// /// Similar to a mutable option type, but friendlier. -struct Cell { +pub struct Cell { mut value: Option } /// Creates a new full cell with the given value. -fn Cell(+value: T) -> Cell { +pub fn Cell(value: T) -> Cell { Cell { value: Some(move value) } } -fn empty_cell() -> Cell { +pub fn empty_cell() -> Cell { Cell { value: None } } @@ -30,7 +29,7 @@ impl Cell { } /// Returns the value, failing if the cell is full. - fn put_back(+value: T) { + fn put_back(value: T) { if !self.is_empty() { fail ~"attempt to put a value back into a full cell"; } diff --git a/src/libstd/cmp.rs b/src/libstd/cmp.rs index 9b094f9215c6..2ec0bf41675c 100644 --- a/src/libstd/cmp.rs +++ b/src/libstd/cmp.rs @@ -1,10 +1,9 @@ #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; /// Additional general-purpose comparison functionality. const fuzzy_epsilon: float = 1.0e-6; -trait FuzzyEq { +pub trait FuzzyEq { pure fn fuzzy_eq(other: &self) -> bool; } diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index e2d4646d6706..4d87ebeac99d 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -6,14 +6,11 @@ Higher level communication abstractions. // NB: transitionary, de-mode-ing. #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use pipes::{Channel, Recv, Chan, Port, Selectable}; -export DuplexStream; - /// An extension of `pipes::stream` that allows both sending and receiving. -struct DuplexStream { +pub struct DuplexStream { priv chan: Chan, priv port: Port , } @@ -49,7 +46,7 @@ impl DuplexStream : Selectable { } /// Creates a bidirectional stream. -fn DuplexStream() +pub fn DuplexStream() -> (DuplexStream, DuplexStream) { let (c2, p1) = pipes::stream(); diff --git a/src/libstd/dbg.rs b/src/libstd/dbg.rs index 2b9df33b2d41..f85d4655ad14 100644 --- a/src/libstd/dbg.rs +++ b/src/libstd/dbg.rs @@ -1,16 +1,8 @@ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap //! Unsafe debugging functions for inspecting values. use cast::reinterpret_cast; -export debug_tydesc; -export debug_opaque; -export debug_box; -export debug_tag; -export debug_fn; -export ptr_cast; -export breakpoint; #[abi = "cdecl"] extern mod rustrt { @@ -24,34 +16,34 @@ extern mod rustrt { fn rust_dbg_breakpoint(); } -fn debug_tydesc() { +pub fn debug_tydesc() { rustrt::debug_tydesc(sys::get_type_desc::()); } -fn debug_opaque(+x: T) { - rustrt::debug_opaque(sys::get_type_desc::(), ptr::addr_of(x) as *()); +pub fn debug_opaque(x: T) { + rustrt::debug_opaque(sys::get_type_desc::(), ptr::addr_of(&x) as *()); } -fn debug_box(x: @T) { - rustrt::debug_box(sys::get_type_desc::(), ptr::addr_of(x) as *()); +pub fn debug_box(x: @T) { + rustrt::debug_box(sys::get_type_desc::(), ptr::addr_of(&x) as *()); } -fn debug_tag(+x: T) { - rustrt::debug_tag(sys::get_type_desc::(), ptr::addr_of(x) as *()); +pub fn debug_tag(x: T) { + rustrt::debug_tag(sys::get_type_desc::(), ptr::addr_of(&x) as *()); } -fn debug_fn(+x: T) { - rustrt::debug_fn(sys::get_type_desc::(), ptr::addr_of(x) as *()); +pub fn debug_fn(x: T) { + rustrt::debug_fn(sys::get_type_desc::(), ptr::addr_of(&x) as *()); } -unsafe fn ptr_cast(x: @T) -> @U { +pub unsafe fn ptr_cast(x: @T) -> @U { reinterpret_cast( &rustrt::debug_ptrcast(sys::get_type_desc::(), reinterpret_cast(&x))) } /// Triggers a debugger breakpoint -fn breakpoint() { +pub fn breakpoint() { rustrt::rust_dbg_breakpoint(); } diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 17d4b39b01e6..f4fbc11c4f71 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -1,16 +1,15 @@ //! A deque. Untested as of yet. Likely buggy -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap #[forbid(non_camel_case_types)]; use option::{Some, None}; use dvec::DVec; use core::cmp::{Eq}; -trait Deque { +pub trait Deque { fn size() -> uint; - fn add_front(T); - fn add_back(T); + fn add_front(v: T); + fn add_back(v: T); fn pop_front() -> T; fn pop_back() -> T; fn peek_front() -> T; @@ -20,7 +19,7 @@ trait Deque { // FIXME (#2343) eventually, a proper datatype plus an exported impl would // be preferrable. -fn create() -> Deque { +pub fn create() -> Deque { type Cell = Option; let initial_capacity: uint = 32u; // 2^5 @@ -28,7 +27,7 @@ fn create() -> Deque { * Grow is only called on full elts, so nelts is also len(elts), unlike * elsewhere. */ - fn grow(nelts: uint, lo: uint, +elts: ~[Cell]) + fn grow(nelts: uint, lo: uint, elts: ~[Cell]) -> ~[Cell] { let mut elts = move elts; assert (nelts == vec::len(elts)); @@ -38,15 +37,15 @@ fn create() -> Deque { let nalloc = uint::next_power_of_two(nelts + 1u); while i < nalloc { if i < nelts { - vec::push(rv, elts[(lo + i) % nelts]); - } else { vec::push(rv, None); } + rv.push(elts[(lo + i) % nelts]); + } else { rv.push(None); } i += 1u; } move rv } fn get(elts: &DVec>, i: uint) -> T { - match (*elts).get_elt(i) { Some(t) => t, _ => fail } + match (*elts).get_elt(i) { Some(move t) => t, _ => fail } } type Repr = {mut nelts: uint, @@ -120,7 +119,6 @@ fn create() -> Deque { #[cfg(test)] mod tests { - #[legacy_exports]; #[test] fn test_simple() { let d: deque::Deque = deque::create::(); @@ -202,7 +200,7 @@ mod tests { assert (deq.get(3) == d); } - fn test_parameterized(+a: T, +b: T, +c: T, +d: T) { + fn test_parameterized(a: T, +b: T, +c: T, +d: T) { let deq: deque::Deque = deque::create::(); assert (deq.size() == 0u); deq.add_front(a); diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index db41c428cbe6..238e9d77a771 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -4,31 +4,6 @@ use core::Option; use option::{Some, None}; -export Doc; -export doc_at; -export maybe_get_doc; -export get_doc; -export docs; -export tagged_docs; -export doc_data; -export doc_as_str; -export doc_as_u8; -export doc_as_u16; -export doc_as_u32; -export doc_as_u64; -export doc_as_i8; -export doc_as_i16; -export doc_as_i32; -export doc_as_i64; -export Writer; -export serializer; -export ebml_deserializer; -export EbmlDeserializer; -export deserializer; -export with_doc_data; -export get_doc; -export extensions; - type EbmlTag = {id: uint, size: uint}; type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: uint}; @@ -37,12 +12,12 @@ type EbmlState = {ebml_tag: EbmlTag, tag_pos: uint, data_pos: uint}; // separate modules within this file. // ebml reading -type Doc = {data: @~[u8], start: uint, end: uint}; +pub type Doc = {data: @~[u8], start: uint, end: uint}; type TaggedDoc = {tag: uint, doc: Doc}; impl Doc: ops::Index { - pure fn index(&&tag: uint) -> Doc { + pure fn index(+tag: uint) -> Doc { unsafe { get_doc(self, tag) } @@ -72,11 +47,11 @@ fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} { } else { error!("vint too big"); fail; } } -fn Doc(data: @~[u8]) -> Doc { +pub fn Doc(data: @~[u8]) -> Doc { return {data: data, start: 0u, end: vec::len::(*data)}; } -fn doc_at(data: @~[u8], start: uint) -> TaggedDoc { +pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc { let elt_tag = vuint_at(*data, start); let elt_size = vuint_at(*data, elt_tag.next); let end = elt_size.next + elt_size.val; @@ -84,7 +59,7 @@ fn doc_at(data: @~[u8], start: uint) -> TaggedDoc { doc: {data: data, start: elt_size.next, end: end}}; } -fn maybe_get_doc(d: Doc, tg: uint) -> Option { +pub fn maybe_get_doc(d: Doc, tg: uint) -> Option { let mut pos = d.start; while pos < d.end { let elt_tag = vuint_at(*d.data, pos); @@ -101,7 +76,7 @@ fn maybe_get_doc(d: Doc, tg: uint) -> Option { return None::; } -fn get_doc(d: Doc, tg: uint) -> Doc { +pub fn get_doc(d: Doc, tg: uint) -> Doc { match maybe_get_doc(d, tg) { Some(d) => return d, None => { @@ -111,7 +86,7 @@ fn get_doc(d: Doc, tg: uint) -> Doc { } } -fn docs(d: Doc, it: fn(uint, Doc) -> bool) { +pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) { let mut pos = d.start; while pos < d.end { let elt_tag = vuint_at(*d.data, pos); @@ -123,7 +98,7 @@ fn docs(d: Doc, it: fn(uint, Doc) -> bool) { } } -fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { +pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { let mut pos = d.start; while pos < d.end { let elt_tag = vuint_at(*d.data, pos); @@ -137,43 +112,43 @@ fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { } } -fn doc_data(d: Doc) -> ~[u8] { vec::slice::(*d.data, d.start, d.end) } +pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::(*d.data, d.start, d.end) } -fn with_doc_data(d: Doc, f: fn(x: &[u8]) -> T) -> T { +pub fn with_doc_data(d: Doc, f: fn(x: &[u8]) -> T) -> T { return f(vec::view(*d.data, d.start, d.end)); } -fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); } +pub fn doc_as_str(d: Doc) -> ~str { return str::from_bytes(doc_data(d)); } -fn doc_as_u8(d: Doc) -> u8 { +pub fn doc_as_u8(d: Doc) -> u8 { assert d.end == d.start + 1u; return (*d.data)[d.start]; } -fn doc_as_u16(d: Doc) -> u16 { +pub fn doc_as_u16(d: Doc) -> u16 { assert d.end == d.start + 2u; return io::u64_from_be_bytes(*d.data, d.start, 2u) as u16; } -fn doc_as_u32(d: Doc) -> u32 { +pub fn doc_as_u32(d: Doc) -> u32 { assert d.end == d.start + 4u; return io::u64_from_be_bytes(*d.data, d.start, 4u) as u32; } -fn doc_as_u64(d: Doc) -> u64 { +pub fn doc_as_u64(d: Doc) -> u64 { assert d.end == d.start + 8u; return io::u64_from_be_bytes(*d.data, d.start, 8u); } -fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } -fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } -fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } -fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } +pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } +pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } +pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } +pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } // ebml writing type Writer_ = {writer: io::Writer, mut size_positions: ~[uint]}; -enum Writer { +pub enum Writer { Writer_(Writer_) } @@ -197,7 +172,7 @@ fn write_vuint(w: io::Writer, n: uint) { fail fmt!("vint to write too big: %?", n); } -fn Writer(w: io::Writer) -> Writer { +pub fn Writer(w: io::Writer) -> Writer { let size_positions: ~[uint] = ~[]; return Writer_({writer: w, mut size_positions: size_positions}); } @@ -211,13 +186,13 @@ impl Writer { write_vuint(self.writer, tag_id); // Write a placeholder four-byte size. - vec::push(self.size_positions, self.writer.tell()); + self.size_positions.push(self.writer.tell()); let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8]; self.writer.write(zeroes); } fn end_tag() { - let last_size_pos = vec::pop::(self.size_positions); + let last_size_pos = self.size_positions.pop(); let cur_pos = self.writer.tell(); self.writer.seek(last_size_pos as int, io::SeekSet); let size = (cur_pos - last_size_pos - 4u); @@ -292,7 +267,7 @@ impl Writer { self.writer.write(b); } - fn wr_str(s: ~str) { + fn wr_str(s: &str) { debug!("Write str: %?", s); self.writer.write(str::to_bytes(s)); } @@ -409,16 +384,16 @@ impl ebml::Writer: serialization::Serializer { type EbmlDeserializer_ = {mut parent: ebml::Doc, mut pos: uint}; -enum EbmlDeserializer { +pub enum EbmlDeserializer { EbmlDeserializer_(EbmlDeserializer_) } -fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer { +pub fn ebml_deserializer(d: ebml::Doc) -> EbmlDeserializer { EbmlDeserializer_({mut parent: d, mut pos: d.start}) } priv impl EbmlDeserializer { - fn _check_label(lbl: ~str) { + fn _check_label(lbl: &str) { if self.pos < self.parent.end { let {tag: r_tag, doc: r_doc} = ebml::doc_at(self.parent.data, self.pos); @@ -516,7 +491,7 @@ impl EbmlDeserializer: serialization::Deserializer { fn read_str() -> ~str { ebml::doc_as_str(self.next_doc(EsStr)) } // Compound types: - fn read_enum(name: ~str, f: fn() -> T) -> T { + fn read_enum(name: &str, f: fn() -> T) -> T { debug!("read_enum(%s)", name); self._check_label(name); self.push_doc(self.next_doc(EsEnum), f) @@ -565,7 +540,7 @@ impl EbmlDeserializer: serialization::Deserializer { f() } - fn read_rec_field(f_name: ~str, f_idx: uint, f: fn() -> T) -> T { + fn read_rec_field(f_name: &str, f_idx: uint, f: fn() -> T) -> T { debug!("read_rec_field(%s, idx=%u)", f_name, f_idx); self._check_label(f_name); f() @@ -588,11 +563,11 @@ impl EbmlDeserializer: serialization::Deserializer { #[test] fn test_option_int() { - fn serialize_1(s: S, v: int) { + fn serialize_1(&&s: S, v: int) { s.emit_i64(v as i64); } - fn serialize_0(s: S, v: Option) { + fn serialize_0(&&s: S, v: Option) { do s.emit_enum(~"core::option::t") { match v { None => s.emit_enum_variant( @@ -606,11 +581,11 @@ fn test_option_int() { } } - fn deserialize_1(s: S) -> int { + fn deserialize_1(&&s: S) -> int { s.read_i64() as int } - fn deserialize_0(s: S) -> Option { + fn deserialize_0(&&s: S) -> Option { do s.read_enum(~"core::option::t") { do s.read_enum_variant |i| { match i { diff --git a/src/libstd/ebml2.rs b/src/libstd/ebml2.rs new file mode 100644 index 000000000000..30d68da06f56 --- /dev/null +++ b/src/libstd/ebml2.rs @@ -0,0 +1,643 @@ +use serialization2; + +// 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 + +struct EbmlTag { + id: uint, + size: uint, +} + +struct EbmlState { + ebml_tag: EbmlTag, + tag_pos: uint, + data_pos: uint, +} + +// FIXME (#2739): When we have module renaming, make "reader" and "writer" +// separate modules within this file. + +// ebml reading +struct Doc { + data: @~[u8], + start: uint, + end: uint, +} + +struct TaggedDoc { + tag: uint, + doc: Doc, +} + +impl Doc: ops::Index { + pure fn index(+tag: uint) -> Doc { + unsafe { + get_doc(self, tag) + } + } +} + +fn vuint_at(data: &[u8], start: uint) -> {val: uint, next: uint} { + let a = data[start]; + if a & 0x80u8 != 0u8 { + return {val: (a & 0x7fu8) as uint, next: start + 1u}; + } + if a & 0x40u8 != 0u8 { + return {val: ((a & 0x3fu8) as uint) << 8u | + (data[start + 1u] as uint), + next: start + 2u}; + } else if a & 0x20u8 != 0u8 { + return {val: ((a & 0x1fu8) as uint) << 16u | + (data[start + 1u] as uint) << 8u | + (data[start + 2u] as uint), + next: start + 3u}; + } else if a & 0x10u8 != 0u8 { + return {val: ((a & 0x0fu8) as uint) << 24u | + (data[start + 1u] as uint) << 16u | + (data[start + 2u] as uint) << 8u | + (data[start + 3u] as uint), + next: start + 4u}; + } else { error!("vint too big"); fail; } +} + +pub fn Doc(data: @~[u8]) -> Doc { + Doc { data: data, start: 0u, end: vec::len::(*data) } +} + +pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc { + let elt_tag = vuint_at(*data, start); + let elt_size = vuint_at(*data, elt_tag.next); + let end = elt_size.next + elt_size.val; + TaggedDoc { + tag: elt_tag.val, + doc: Doc { data: data, start: elt_size.next, end: end } + } +} + +pub fn maybe_get_doc(d: Doc, tg: uint) -> Option { + let mut pos = d.start; + while pos < d.end { + let elt_tag = vuint_at(*d.data, pos); + let elt_size = vuint_at(*d.data, elt_tag.next); + pos = elt_size.next + elt_size.val; + if elt_tag.val == tg { + return Some(Doc { data: d.data, start: elt_size.next, end: pos }); + } + } + None +} + +pub fn get_doc(d: Doc, tg: uint) -> Doc { + match maybe_get_doc(d, tg) { + Some(d) => d, + None => { + error!("failed to find block with tag %u", tg); + fail; + } + } +} + +pub fn docs(d: Doc, it: fn(uint, Doc) -> bool) { + let mut pos = d.start; + while pos < d.end { + let elt_tag = vuint_at(*d.data, pos); + let elt_size = vuint_at(*d.data, elt_tag.next); + pos = elt_size.next + elt_size.val; + let doc = Doc { data: d.data, start: elt_size.next, end: pos }; + if !it(elt_tag.val, doc) { + break; + } + } +} + +pub fn tagged_docs(d: Doc, tg: uint, it: fn(Doc) -> bool) { + let mut pos = d.start; + while pos < d.end { + let elt_tag = vuint_at(*d.data, pos); + let elt_size = vuint_at(*d.data, elt_tag.next); + pos = elt_size.next + elt_size.val; + if elt_tag.val == tg { + let doc = Doc { data: d.data, start: elt_size.next, end: pos }; + if !it(doc) { + break; + } + } + } +} + +pub fn doc_data(d: Doc) -> ~[u8] { vec::slice::(*d.data, d.start, d.end) } + +pub fn with_doc_data(d: Doc, f: fn(x: &[u8]) -> T) -> T { + f(vec::view(*d.data, d.start, d.end)) +} + +pub fn doc_as_str(d: Doc) -> ~str { str::from_bytes(doc_data(d)) } + +pub fn doc_as_u8(d: Doc) -> u8 { + assert d.end == d.start + 1u; + (*d.data)[d.start] +} + +pub fn doc_as_u16(d: Doc) -> u16 { + assert d.end == d.start + 2u; + io::u64_from_be_bytes(*d.data, d.start, 2u) as u16 +} + +pub fn doc_as_u32(d: Doc) -> u32 { + assert d.end == d.start + 4u; + io::u64_from_be_bytes(*d.data, d.start, 4u) as u32 +} + +pub fn doc_as_u64(d: Doc) -> u64 { + assert d.end == d.start + 8u; + io::u64_from_be_bytes(*d.data, d.start, 8u) +} + +pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 } +pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 } +pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 } +pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 } + +// ebml writing +struct Serializer { + writer: io::Writer, + priv mut size_positions: ~[uint], +} + +fn write_sized_vuint(w: io::Writer, n: uint, size: uint) { + match size { + 1u => w.write(&[0x80u8 | (n as u8)]), + 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]), + 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8, + n as u8]), + 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8, + (n >> 8_u) as u8, n as u8]), + _ => fail fmt!("vint to write too big: %?", n) + }; +} + +fn write_vuint(w: io::Writer, n: uint) { + if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; } + if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; } + if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; } + if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; } + fail fmt!("vint to write too big: %?", n); +} + +pub fn Serializer(w: io::Writer) -> Serializer { + let size_positions: ~[uint] = ~[]; + Serializer { writer: w, mut size_positions: size_positions } +} + +// FIXME (#2741): Provide a function to write the standard ebml header. +impl Serializer { + fn start_tag(tag_id: uint) { + debug!("Start tag %u", tag_id); + + // Write the enum ID: + write_vuint(self.writer, tag_id); + + // Write a placeholder four-byte size. + self.size_positions.push(self.writer.tell()); + let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8]; + self.writer.write(zeroes); + } + + fn end_tag() { + let last_size_pos = self.size_positions.pop(); + let cur_pos = self.writer.tell(); + self.writer.seek(last_size_pos as int, io::SeekSet); + let size = (cur_pos - last_size_pos - 4u); + write_sized_vuint(self.writer, size, 4u); + self.writer.seek(cur_pos as int, io::SeekSet); + + debug!("End tag (size = %u)", size); + } + + fn wr_tag(tag_id: uint, blk: fn()) { + self.start_tag(tag_id); + blk(); + self.end_tag(); + } + + fn wr_tagged_bytes(tag_id: uint, b: &[u8]) { + write_vuint(self.writer, tag_id); + write_vuint(self.writer, vec::len(b)); + self.writer.write(b); + } + + fn wr_tagged_u64(tag_id: uint, v: u64) { + do io::u64_to_be_bytes(v, 8u) |v| { + self.wr_tagged_bytes(tag_id, v); + } + } + + fn wr_tagged_u32(tag_id: uint, v: u32) { + do io::u64_to_be_bytes(v as u64, 4u) |v| { + self.wr_tagged_bytes(tag_id, v); + } + } + + fn wr_tagged_u16(tag_id: uint, v: u16) { + do io::u64_to_be_bytes(v as u64, 2u) |v| { + self.wr_tagged_bytes(tag_id, v); + } + } + + fn wr_tagged_u8(tag_id: uint, v: u8) { + self.wr_tagged_bytes(tag_id, &[v]); + } + + fn wr_tagged_i64(tag_id: uint, v: i64) { + do io::u64_to_be_bytes(v as u64, 8u) |v| { + self.wr_tagged_bytes(tag_id, v); + } + } + + fn wr_tagged_i32(tag_id: uint, v: i32) { + do io::u64_to_be_bytes(v as u64, 4u) |v| { + self.wr_tagged_bytes(tag_id, v); + } + } + + fn wr_tagged_i16(tag_id: uint, v: i16) { + do io::u64_to_be_bytes(v as u64, 2u) |v| { + self.wr_tagged_bytes(tag_id, v); + } + } + + fn wr_tagged_i8(tag_id: uint, v: i8) { + self.wr_tagged_bytes(tag_id, &[v as u8]); + } + + fn wr_tagged_str(tag_id: uint, v: &str) { + str::byte_slice(v, |b| self.wr_tagged_bytes(tag_id, b)); + } + + fn wr_bytes(b: &[u8]) { + debug!("Write %u bytes", vec::len(b)); + self.writer.write(b); + } + + fn wr_str(s: &str) { + debug!("Write str: %?", s); + self.writer.write(str::to_bytes(s)); + } +} + +// FIXME (#2743): optionally perform "relaxations" on end_tag to more +// efficiently encode sizes; this is a fixed point iteration + +// Set to true to generate more debugging in EBML serialization. +// Totally lame approach. +const debug: bool = false; + +enum EbmlSerializerTag { + EsUint, EsU64, EsU32, EsU16, EsU8, + EsInt, EsI64, EsI32, EsI16, EsI8, + EsBool, + EsStr, + EsF64, EsF32, EsFloat, + EsEnum, EsEnumVid, EsEnumBody, + EsVec, EsVecLen, EsVecElt, + + EsOpaque, + + EsLabel // Used only when debugging +} + +priv impl Serializer { + // used internally to emit things like the vector length and so on + fn _emit_tagged_uint(t: EbmlSerializerTag, v: uint) { + assert v <= 0xFFFF_FFFF_u; + self.wr_tagged_u32(t as uint, v as u32); + } + + fn _emit_label(label: &str) { + // There are various strings that we have access to, such as + // the name of a record field, which do not actually appear in + // the serialized EBML (normally). This is just for + // efficiency. When debugging, though, we can emit such + // labels and then they will be checked by deserializer to + // try and check failures more quickly. + if debug { self.wr_tagged_str(EsLabel as uint, label) } + } +} + +impl Serializer { + fn emit_opaque(&self, f: fn()) { + do self.wr_tag(EsOpaque as uint) { + f() + } + } +} + +impl Serializer: serialization2::Serializer { + fn emit_nil(&self) {} + + fn emit_uint(&self, v: uint) { + self.wr_tagged_u64(EsUint as uint, v as u64); + } + fn emit_u64(&self, v: u64) { self.wr_tagged_u64(EsU64 as uint, v); } + fn emit_u32(&self, v: u32) { self.wr_tagged_u32(EsU32 as uint, v); } + fn emit_u16(&self, v: u16) { self.wr_tagged_u16(EsU16 as uint, v); } + fn emit_u8(&self, v: u8) { self.wr_tagged_u8 (EsU8 as uint, v); } + + fn emit_int(&self, v: int) { + self.wr_tagged_i64(EsInt as uint, v as i64); + } + fn emit_i64(&self, v: i64) { self.wr_tagged_i64(EsI64 as uint, v); } + fn emit_i32(&self, v: i32) { self.wr_tagged_i32(EsI32 as uint, v); } + fn emit_i16(&self, v: i16) { self.wr_tagged_i16(EsI16 as uint, v); } + fn emit_i8(&self, v: i8) { self.wr_tagged_i8 (EsI8 as uint, v); } + + fn emit_bool(&self, v: bool) { + self.wr_tagged_u8(EsBool as uint, v as u8) + } + + // FIXME (#2742): implement these + fn emit_f64(&self, _v: f64) { fail ~"Unimplemented: serializing an f64"; } + fn emit_f32(&self, _v: f32) { fail ~"Unimplemented: serializing an f32"; } + fn emit_float(&self, _v: float) { + fail ~"Unimplemented: serializing a float"; + } + + fn emit_char(&self, _v: char) { + fail ~"Unimplemented: serializing a char"; + } + + fn emit_borrowed_str(&self, v: &str) { + self.wr_tagged_str(EsStr as uint, v) + } + + fn emit_owned_str(&self, v: &str) { + self.emit_borrowed_str(v) + } + + fn emit_managed_str(&self, v: &str) { + self.emit_borrowed_str(v) + } + + fn emit_borrowed(&self, f: fn()) { f() } + fn emit_owned(&self, f: fn()) { f() } + fn emit_managed(&self, f: fn()) { f() } + + fn emit_enum(&self, name: &str, f: fn()) { + self._emit_label(name); + self.wr_tag(EsEnum as uint, f) + } + fn emit_enum_variant(&self, _v_name: &str, v_id: uint, _cnt: uint, + f: fn()) { + self._emit_tagged_uint(EsEnumVid, v_id); + self.wr_tag(EsEnumBody as uint, f) + } + fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { f() } + + fn emit_borrowed_vec(&self, len: uint, f: fn()) { + do self.wr_tag(EsVec as uint) { + self._emit_tagged_uint(EsVecLen, len); + f() + } + } + + fn emit_owned_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + + fn emit_managed_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + + fn emit_vec_elt(&self, _idx: uint, f: fn()) { + self.wr_tag(EsVecElt as uint, f) + } + + fn emit_rec(&self, f: fn()) { f() } + fn emit_struct(&self, _name: &str, f: fn()) { f() } + fn emit_field(&self, name: &str, _idx: uint, f: fn()) { + self._emit_label(name); + f() + } + + fn emit_tup(&self, _len: uint, f: fn()) { f() } + fn emit_tup_elt(&self, _idx: uint, f: fn()) { f() } +} + +struct Deserializer { + priv mut parent: Doc, + priv mut pos: uint, +} + +pub fn Deserializer(d: Doc) -> Deserializer { + Deserializer { mut parent: d, mut pos: d.start } +} + +priv impl Deserializer { + fn _check_label(lbl: &str) { + if self.pos < self.parent.end { + let TaggedDoc { tag: r_tag, doc: r_doc } = + doc_at(self.parent.data, self.pos); + + if r_tag == (EsLabel as uint) { + self.pos = r_doc.end; + let str = doc_as_str(r_doc); + if lbl != str { + fail fmt!("Expected label %s but found %s", lbl, str); + } + } + } + } + + fn next_doc(exp_tag: EbmlSerializerTag) -> Doc { + debug!(". next_doc(exp_tag=%?)", exp_tag); + if self.pos >= self.parent.end { + fail ~"no more documents in current node!"; + } + let TaggedDoc { tag: r_tag, doc: r_doc } = + doc_at(self.parent.data, self.pos); + debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?", + copy self.parent.start, copy self.parent.end, + copy self.pos, r_tag, r_doc.start, r_doc.end); + if r_tag != (exp_tag as uint) { + fail fmt!("expected EMBL doc with tag %? but found tag %?", + exp_tag, r_tag); + } + if r_doc.end > self.parent.end { + fail fmt!("invalid EBML, child extends to 0x%x, parent to 0x%x", + r_doc.end, self.parent.end); + } + self.pos = r_doc.end; + r_doc + } + + fn push_doc(d: Doc, f: fn() -> T) -> T{ + let old_parent = self.parent; + let old_pos = self.pos; + self.parent = d; + self.pos = d.start; + let r = f(); + self.parent = old_parent; + self.pos = old_pos; + move r + } + + fn _next_uint(exp_tag: EbmlSerializerTag) -> uint { + let r = doc_as_u32(self.next_doc(exp_tag)); + debug!("_next_uint exp_tag=%? result=%?", exp_tag, r); + r as uint + } +} + +impl Deserializer { + fn read_opaque(&self, op: fn(Doc) -> R) -> R { + do self.push_doc(self.next_doc(EsOpaque)) { + op(copy self.parent) + } + } +} + +impl Deserializer: serialization2::Deserializer { + fn read_nil(&self) -> () { () } + + fn read_u64(&self) -> u64 { doc_as_u64(self.next_doc(EsU64)) } + fn read_u32(&self) -> u32 { doc_as_u32(self.next_doc(EsU32)) } + fn read_u16(&self) -> u16 { doc_as_u16(self.next_doc(EsU16)) } + fn read_u8 (&self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) } + fn read_uint(&self) -> uint { + let v = doc_as_u64(self.next_doc(EsUint)); + if v > (core::uint::max_value as u64) { + fail fmt!("uint %? too large for this architecture", v); + } + v as uint + } + + fn read_i64(&self) -> i64 { doc_as_u64(self.next_doc(EsI64)) as i64 } + fn read_i32(&self) -> i32 { doc_as_u32(self.next_doc(EsI32)) as i32 } + fn read_i16(&self) -> i16 { doc_as_u16(self.next_doc(EsI16)) as i16 } + fn read_i8 (&self) -> i8 { doc_as_u8 (self.next_doc(EsI8 )) as i8 } + fn read_int(&self) -> int { + let v = doc_as_u64(self.next_doc(EsInt)) as i64; + if v > (int::max_value as i64) || v < (int::min_value as i64) { + fail fmt!("int %? out of range for this architecture", v); + } + v as int + } + + fn read_bool(&self) -> bool { doc_as_u8(self.next_doc(EsBool)) as bool } + + fn read_f64(&self) -> f64 { fail ~"read_f64()"; } + fn read_f32(&self) -> f32 { fail ~"read_f32()"; } + fn read_float(&self) -> float { fail ~"read_float()"; } + + fn read_char(&self) -> char { fail ~"read_char()"; } + + fn read_owned_str(&self) -> ~str { doc_as_str(self.next_doc(EsStr)) } + fn read_managed_str(&self) -> @str { fail ~"read_managed_str()"; } + + // Compound types: + fn read_owned(&self, f: fn() -> T) -> T { + debug!("read_owned()"); + f() + } + + fn read_managed(&self, f: fn() -> T) -> T { + debug!("read_managed()"); + f() + } + + fn read_enum(&self, name: &str, f: fn() -> T) -> T { + debug!("read_enum(%s)", name); + self._check_label(name); + self.push_doc(self.next_doc(EsEnum), f) + } + + fn read_enum_variant(&self, f: fn(uint) -> T) -> T { + debug!("read_enum_variant()"); + let idx = self._next_uint(EsEnumVid); + debug!(" idx=%u", idx); + do self.push_doc(self.next_doc(EsEnumBody)) { + f(idx) + } + } + + fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T { + debug!("read_enum_variant_arg(idx=%u)", idx); + f() + } + + fn read_owned_vec(&self, f: fn(uint) -> T) -> T { + debug!("read_owned_vec()"); + do self.push_doc(self.next_doc(EsVec)) { + let len = self._next_uint(EsVecLen); + debug!(" len=%u", len); + f(len) + } + } + + fn read_managed_vec(&self, f: fn(uint) -> T) -> T { + debug!("read_managed_vec()"); + do self.push_doc(self.next_doc(EsVec)) { + let len = self._next_uint(EsVecLen); + debug!(" len=%u", len); + f(len) + } + } + + fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { + debug!("read_vec_elt(idx=%u)", idx); + self.push_doc(self.next_doc(EsVecElt), f) + } + + fn read_rec(&self, f: fn() -> T) -> T { + debug!("read_rec()"); + f() + } + + fn read_struct(&self, name: &str, f: fn() -> T) -> T { + debug!("read_struct(name=%s)", name); + f() + } + + fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { + debug!("read_field(name=%s, idx=%u)", name, idx); + self._check_label(name); + f() + } + + fn read_tup(&self, len: uint, f: fn() -> T) -> T { + debug!("read_tup(len=%u)", len); + f() + } + + fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { + debug!("read_tup_elt(idx=%u)", idx); + f() + } +} + +// ___________________________________________________________________________ +// Testing + +#[cfg(test)] +mod tests { + #[test] + fn test_option_int() { + fn test_v(v: Option) { + debug!("v == %?", v); + let bytes = do io::with_bytes_writer |wr| { + let ebml_w = Serializer(wr); + v.serialize(&ebml_w) + }; + let ebml_doc = Doc(@bytes); + let deser = Deserializer(ebml_doc); + let v1 = serialization2::deserialize(&deser); + debug!("v1 == %?", v1); + assert v == v1; + } + + test_v(Some(22)); + test_v(None); + test_v(Some(3)); + } +} diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs index d3cc11d2a311..2973c8cc9f78 100644 --- a/src/libstd/fun_treemap.rs +++ b/src/libstd/fun_treemap.rs @@ -1,5 +1,4 @@ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +#[warn(deprecated_mode)]; /*! * A functional key,value store that works on anything. @@ -16,13 +15,7 @@ use core::cmp::{Eq, Ord}; use option::{Some, None}; use option = option; -export Treemap; -export init; -export insert; -export find; -export traverse; - -type Treemap = @TreeNode; +pub type Treemap = @TreeNode; enum TreeNode { Empty, @@ -30,14 +23,14 @@ enum TreeNode { } /// Create a treemap -fn init() -> Treemap { @Empty } +pub fn init() -> Treemap { @Empty } /// Insert a value into the map -fn insert(m: Treemap, +k: K, +v: V) +pub fn insert(m: Treemap, +k: K, +v: V) -> Treemap { @match m { @Empty => Node(@k, @v, @Empty, @Empty), - @Node(@kk, vv, left, right) => { + @Node(@copy kk, vv, left, right) => { if k < kk { Node(@kk, vv, insert(left, k, v), right) } else if k == kk { @@ -48,19 +41,19 @@ fn insert(m: Treemap, +k: K, +v: V) } /// Find a value based on the key -fn find(m: Treemap, +k: K) -> Option { +pub fn find(m: Treemap, +k: K) -> Option { match *m { Empty => None, - Node(@kk, @v, left, right) => { - if k == kk { + Node(@ref kk, @copy v, left, right) => { + if k == *kk { Some(v) - } else if k < kk { find(left, move k) } else { find(right, move k) } + } else if k < *kk { find(left, move k) } else { find(right, move k) } } } } /// Visit all pairs in the map in order. -fn traverse(m: Treemap, f: fn(K, V)) { +pub fn traverse(m: Treemap, f: fn((&K), (&V))) { match *m { Empty => (), /* @@ -68,11 +61,9 @@ fn traverse(m: Treemap, f: fn(K, V)) { matches to me, so I changed it. but that may be a de-optimization -- tjc */ - Node(@k, @v, left, right) => { - // copy v to make aliases work out - let v1 = v; + Node(@ref k, @ref v, left, right) => { traverse(left, f); - f(k, v1); + f(k, v); traverse(right, f); } } diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index f8b86d800613..771eaaeca7fa 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -62,31 +62,12 @@ * } */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap use core::cmp::Eq; use core::result::{Err, Ok}; use core::option; use core::option::{Some, None}; -export Opt; -export reqopt; -export optopt; -export optflag; -export optflagopt; -export optmulti; -export getopts; -export Matches; -export Fail_; -export fail_str; -export opt_present; -export opts_present; -export opt_str; -export opts_str; -export opt_strs; -export opt_maybe_str; -export opt_default; -export Result; //NDM enum Name { Long(~str), @@ -98,7 +79,7 @@ enum HasArg { Yes, No, Maybe, } enum Occur { Req, Optional, Multi, } /// A description of a possible option -type Opt = {name: Name, hasarg: HasArg, occur: Occur}; +pub type Opt = {name: Name, hasarg: HasArg, occur: Occur}; fn mkname(nm: &str) -> Name { let unm = str::from_slice(nm); @@ -110,9 +91,9 @@ fn mkname(nm: &str) -> Name { impl Name : Eq { pure fn eq(other: &Name) -> bool { match self { - Long(e0a) => { + Long(ref e0a) => { match (*other) { - Long(e0b) => e0a == e0b, + Long(ref e0b) => e0a == e0b, _ => false } } @@ -135,22 +116,22 @@ impl Occur : Eq { } /// Create an option that is required and takes an argument -fn reqopt(name: &str) -> Opt { +pub fn reqopt(name: &str) -> Opt { return {name: mkname(name), hasarg: Yes, occur: Req}; } /// Create an option that is optional and takes an argument -fn optopt(name: &str) -> Opt { +pub fn optopt(name: &str) -> Opt { return {name: mkname(name), hasarg: Yes, occur: Optional}; } /// Create an option that is optional and does not take an argument -fn optflag(name: &str) -> Opt { +pub fn optflag(name: &str) -> Opt { return {name: mkname(name), hasarg: No, occur: Optional}; } /// Create an option that is optional and takes an optional argument -fn optflagopt(name: &str) -> Opt { +pub fn optflagopt(name: &str) -> Opt { return {name: mkname(name), hasarg: Maybe, occur: Optional}; } @@ -158,7 +139,7 @@ fn optflagopt(name: &str) -> Opt { * Create an option that is optional, takes an argument, and may occur * multiple times */ -fn optmulti(name: &str) -> Opt { +pub fn optmulti(name: &str) -> Opt { return {name: mkname(name), hasarg: Yes, occur: Multi}; } @@ -168,7 +149,7 @@ enum Optval { Val(~str), Given, } * The result of checking command line arguments. Contains a vector * of matches and a vector of free strings. */ -type Matches = {opts: ~[Opt], vals: ~[~[Optval]], free: ~[~str]}; +pub type Matches = {opts: ~[Opt], vals: ~[~[Optval]], free: ~[~str]}; fn is_arg(arg: &str) -> bool { return str::len(arg) > 1u && arg[0] == '-' as u8; @@ -177,7 +158,7 @@ fn is_arg(arg: &str) -> bool { fn name_str(nm: &Name) -> ~str { return match *nm { Short(ch) => str::from_char(ch), - Long(s) => s + Long(copy s) => s }; } @@ -189,7 +170,7 @@ fn find_opt(opts: &[Opt], +nm: Name) -> Option { * The type returned when the command line does not conform to the * expected format. Pass this value to to get an error message. */ -enum Fail_ { +pub enum Fail_ { ArgumentMissing(~str), UnrecognizedOption(~str), OptionMissing(~str), @@ -198,15 +179,23 @@ enum Fail_ { } /// Convert a `fail_` enum into an error string -fn fail_str(+f: Fail_) -> ~str { +pub fn fail_str(f: Fail_) -> ~str { return match f { - ArgumentMissing(nm) => ~"Argument to option '" + nm + ~"' missing.", - UnrecognizedOption(nm) => ~"Unrecognized option: '" + nm + ~"'.", - OptionMissing(nm) => ~"Required option '" + nm + ~"' missing.", - OptionDuplicated(nm) => ~"Option '" + nm + ~"' given more than once.", - UnexpectedArgument(nm) => { - ~"Option " + nm + ~" does not take an argument." - } + ArgumentMissing(ref nm) => { + ~"Argument to option '" + *nm + ~"' missing." + } + UnrecognizedOption(ref nm) => { + ~"Unrecognized option: '" + *nm + ~"'." + } + OptionMissing(ref nm) => { + ~"Required option '" + *nm + ~"' missing." + } + OptionDuplicated(ref nm) => { + ~"Option '" + *nm + ~"' given more than once." + } + UnexpectedArgument(ref nm) => { + ~"Option " + *nm + ~" does not take an argument." + } }; } @@ -214,7 +203,7 @@ fn fail_str(+f: Fail_) -> ~str { * The result of parsing a command line with a set of options * (result::t) */ -type Result = result::Result; +pub type Result = result::Result; /** * Parse command line arguments according to the provided options @@ -223,9 +212,9 @@ type Result = result::Result; * `opt_str`, etc. to interrogate results. Returns `err(Fail_)` on failure. * Use to get an error message. */ -fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe { +pub fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe { let n_opts = vec::len::(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); @@ -234,10 +223,10 @@ fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe { let cur = args[i]; let curlen = str::len(cur); if !is_arg(cur) { - vec::push(free, cur); + free.push(cur); } else if cur == ~"--" { let mut j = i + 1u; - while j < l { vec::push(free, args[j]); j += 1u; } + while j < l { free.push(args[j]); j += 1u; } break; } else { let mut names; @@ -287,7 +276,7 @@ fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe { } } } - vec::push(names, opt); + names.push(opt); j = range.next; } } @@ -303,23 +292,22 @@ fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe { if !i_arg.is_none() { return Err(UnexpectedArgument(name_str(nm))); } - vec::push(vals[optid], Given); + vals[optid].push(Given); } Maybe => { if !i_arg.is_none() { - vec::push(vals[optid], Val(i_arg.get())); + vals[optid].push(Val(i_arg.get())); } else if name_pos < vec::len::(names) || i + 1u == l || is_arg(args[i + 1u]) { - vec::push(vals[optid], Given); - } else { i += 1u; vec::push(vals[optid], Val(args[i])); } + vals[optid].push(Given); + } else { i += 1u; vals[optid].push(Val(args[i])); } } Yes => { if !i_arg.is_none() { - vec::push(vals[optid], - Val(i_arg.get())); + vals[optid].push(Val(i_arg.get())); } else if i + 1u == l { return Err(ArgumentMissing(name_str(nm))); - } else { i += 1u; vec::push(vals[optid], Val(args[i])); } + } else { i += 1u; vals[optid].push(Val(args[i])); } } } } @@ -347,7 +335,7 @@ fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe { free: free}); } -fn opt_vals(+mm: Matches, nm: &str) -> ~[Optval] { +fn opt_vals(mm: Matches, nm: &str) -> ~[Optval] { return match find_opt(mm.opts, mkname(nm)) { Some(id) => mm.vals[id], None => { @@ -357,15 +345,15 @@ fn opt_vals(+mm: Matches, nm: &str) -> ~[Optval] { }; } -fn opt_val(+mm: Matches, nm: &str) -> Optval { return opt_vals(mm, nm)[0]; } +fn opt_val(mm: Matches, nm: &str) -> Optval { return opt_vals(mm, nm)[0]; } /// Returns true if an option was matched -fn opt_present(+mm: Matches, nm: &str) -> bool { +pub fn opt_present(mm: Matches, nm: &str) -> bool { return vec::len::(opt_vals(mm, nm)) > 0u; } /// Returns true if any of several options were matched -fn opts_present(+mm: Matches, names: &[~str]) -> bool { +pub fn opts_present(mm: Matches, names: &[~str]) -> bool { for vec::each(names) |nm| { match find_opt(mm.opts, mkname(*nm)) { Some(_) => return true, @@ -382,8 +370,8 @@ fn opts_present(+mm: Matches, names: &[~str]) -> bool { * Fails if the option was not matched or if the match did not take an * argument */ -fn opt_str(+mm: Matches, nm: &str) -> ~str { - return match opt_val(mm, nm) { Val(s) => s, _ => fail }; +pub fn opt_str(mm: Matches, nm: &str) -> ~str { + return match opt_val(mm, nm) { Val(copy s) => s, _ => fail }; } /** @@ -392,10 +380,10 @@ fn opt_str(+mm: Matches, nm: &str) -> ~str { * Fails if the no option was provided from the given list, or if the no such * option took an argument */ -fn opts_str(+mm: Matches, names: &[~str]) -> ~str { +pub fn opts_str(mm: Matches, names: &[~str]) -> ~str { for vec::each(names) |nm| { match opt_val(mm, *nm) { - Val(s) => return s, + Val(copy s) => return s, _ => () } } @@ -409,19 +397,22 @@ fn opts_str(+mm: Matches, names: &[~str]) -> ~str { * * Used when an option accepts multiple values. */ -fn opt_strs(+mm: Matches, nm: &str) -> ~[~str] { +pub fn opt_strs(mm: Matches, nm: &str) -> ~[~str] { let mut acc: ~[~str] = ~[]; for vec::each(opt_vals(mm, nm)) |v| { - match *v { Val(s) => vec::push(acc, s), _ => () } + match *v { Val(copy s) => acc.push(s), _ => () } } return acc; } /// Returns the string argument supplied to a matching option or none -fn opt_maybe_str(+mm: Matches, nm: &str) -> Option<~str> { +pub fn opt_maybe_str(mm: Matches, nm: &str) -> Option<~str> { let vals = opt_vals(mm, nm); if vec::len::(vals) == 0u { return None::<~str>; } - return match vals[0] { Val(s) => Some::<~str>(s), _ => None::<~str> }; + return match vals[0] { + Val(copy s) => Some(s), + _ => None + }; } @@ -432,10 +423,10 @@ fn opt_maybe_str(+mm: Matches, nm: &str) -> Option<~str> { * present but no argument was provided, and the argument if the option was * present and an argument was provided. */ -fn opt_default(+mm: Matches, nm: &str, def: &str) -> Option<~str> { +pub fn opt_default(mm: Matches, nm: &str, def: &str) -> Option<~str> { let vals = opt_vals(mm, nm); if vec::len::(vals) == 0u { return None::<~str>; } - return match vals[0] { Val(s) => Some::<~str>(s), + return match vals[0] { Val(copy s) => Some::<~str>(s), _ => Some::<~str>(str::from_slice(def)) } } @@ -460,7 +451,7 @@ mod tests { use opt = getopts; use result::{Err, Ok}; - fn check_fail_type(+f: Fail_, ft: FailType) { + fn check_fail_type(f: Fail_, ft: FailType) { match f { ArgumentMissing(_) => assert ft == ArgumentMissing_, UnrecognizedOption(_) => assert ft == UnrecognizedOption_, @@ -478,7 +469,7 @@ mod tests { let opts = ~[reqopt(~"test")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (opt_present(m, ~"test")); assert (opt_str(m, ~"test") == ~"20"); } @@ -492,7 +483,7 @@ mod tests { let opts = ~[reqopt(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, OptionMissing_), + Err(copy f) => check_fail_type(f, OptionMissing_), _ => fail } } @@ -503,7 +494,7 @@ mod tests { let opts = ~[reqopt(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, ArgumentMissing_), + Err(copy f) => check_fail_type(f, ArgumentMissing_), _ => fail } } @@ -514,7 +505,7 @@ mod tests { let opts = ~[reqopt(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, OptionDuplicated_), + Err(copy f) => check_fail_type(f, OptionDuplicated_), _ => fail } } @@ -525,7 +516,7 @@ mod tests { let opts = ~[reqopt(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (opt_present(m, ~"t")); assert (opt_str(m, ~"t") == ~"20"); } @@ -539,7 +530,7 @@ mod tests { let opts = ~[reqopt(~"t")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, OptionMissing_), + Err(copy f) => check_fail_type(f, OptionMissing_), _ => fail } } @@ -550,7 +541,7 @@ mod tests { let opts = ~[reqopt(~"t")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, ArgumentMissing_), + Err(copy f) => check_fail_type(f, ArgumentMissing_), _ => fail } } @@ -561,7 +552,7 @@ mod tests { let opts = ~[reqopt(~"t")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, OptionDuplicated_), + Err(copy f) => check_fail_type(f, OptionDuplicated_), _ => fail } } @@ -574,7 +565,7 @@ mod tests { let opts = ~[optopt(~"test")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (opt_present(m, ~"test")); assert (opt_str(m, ~"test") == ~"20"); } @@ -588,7 +579,7 @@ mod tests { let opts = ~[optopt(~"test")]; let rs = getopts(args, opts); match rs { - Ok(m) => assert (!opt_present(m, ~"test")), + Ok(copy m) => assert (!opt_present(m, ~"test")), _ => fail } } @@ -599,7 +590,7 @@ mod tests { let opts = ~[optopt(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, ArgumentMissing_), + Err(copy f) => check_fail_type(f, ArgumentMissing_), _ => fail } } @@ -610,7 +601,7 @@ mod tests { let opts = ~[optopt(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, OptionDuplicated_), + Err(copy f) => check_fail_type(f, OptionDuplicated_), _ => fail } } @@ -621,7 +612,7 @@ mod tests { let opts = ~[optopt(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (opt_present(m, ~"t")); assert (opt_str(m, ~"t") == ~"20"); } @@ -635,7 +626,7 @@ mod tests { let opts = ~[optopt(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => assert (!opt_present(m, ~"t")), + Ok(copy m) => assert (!opt_present(m, ~"t")), _ => fail } } @@ -646,7 +637,7 @@ mod tests { let opts = ~[optopt(~"t")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, ArgumentMissing_), + Err(copy f) => check_fail_type(f, ArgumentMissing_), _ => fail } } @@ -657,7 +648,7 @@ mod tests { let opts = ~[optopt(~"t")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, OptionDuplicated_), + Err(copy f) => check_fail_type(f, OptionDuplicated_), _ => fail } } @@ -670,7 +661,7 @@ mod tests { let opts = ~[optflag(~"test")]; let rs = getopts(args, opts); match rs { - Ok(m) => assert (opt_present(m, ~"test")), + Ok(copy m) => assert (opt_present(m, ~"test")), _ => fail } } @@ -681,7 +672,7 @@ mod tests { let opts = ~[optflag(~"test")]; let rs = getopts(args, opts); match rs { - Ok(m) => assert (!opt_present(m, ~"test")), + Ok(copy m) => assert (!opt_present(m, ~"test")), _ => fail } } @@ -692,7 +683,7 @@ mod tests { let opts = ~[optflag(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => { + Err(copy f) => { log(error, fail_str(f)); check_fail_type(f, UnexpectedArgument_); } @@ -706,7 +697,7 @@ mod tests { let opts = ~[optflag(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, OptionDuplicated_), + Err(copy f) => check_fail_type(f, OptionDuplicated_), _ => fail } } @@ -717,7 +708,7 @@ mod tests { let opts = ~[optflag(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => assert (opt_present(m, ~"t")), + Ok(copy m) => assert (opt_present(m, ~"t")), _ => fail } } @@ -728,7 +719,7 @@ mod tests { let opts = ~[optflag(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => assert (!opt_present(m, ~"t")), + Ok(copy m) => assert (!opt_present(m, ~"t")), _ => fail } } @@ -739,7 +730,7 @@ mod tests { let opts = ~[optflag(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(ref m) => { // The next variable after the flag is just a free argument assert (m.free[0] == ~"20"); @@ -754,7 +745,7 @@ mod tests { let opts = ~[optflag(~"t")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, OptionDuplicated_), + Err(copy f) => check_fail_type(f, OptionDuplicated_), _ => fail } } @@ -767,7 +758,7 @@ mod tests { let opts = ~[optmulti(~"test")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (opt_present(m, ~"test")); assert (opt_str(m, ~"test") == ~"20"); } @@ -781,7 +772,7 @@ mod tests { let opts = ~[optmulti(~"test")]; let rs = getopts(args, opts); match rs { - Ok(m) => assert (!opt_present(m, ~"test")), + Ok(copy m) => assert (!opt_present(m, ~"test")), _ => fail } } @@ -792,7 +783,7 @@ mod tests { let opts = ~[optmulti(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, ArgumentMissing_), + Err(copy f) => check_fail_type(f, ArgumentMissing_), _ => fail } } @@ -803,7 +794,7 @@ mod tests { let opts = ~[optmulti(~"test")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (opt_present(m, ~"test")); assert (opt_str(m, ~"test") == ~"20"); let pair = opt_strs(m, ~"test"); @@ -820,7 +811,7 @@ mod tests { let opts = ~[optmulti(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (opt_present(m, ~"t")); assert (opt_str(m, ~"t") == ~"20"); } @@ -834,7 +825,7 @@ mod tests { let opts = ~[optmulti(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => assert (!opt_present(m, ~"t")), + Ok(copy m) => assert (!opt_present(m, ~"t")), _ => fail } } @@ -845,7 +836,7 @@ mod tests { let opts = ~[optmulti(~"t")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, ArgumentMissing_), + Err(copy f) => check_fail_type(f, ArgumentMissing_), _ => fail } } @@ -856,7 +847,7 @@ mod tests { let opts = ~[optmulti(~"t")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (opt_present(m, ~"t")); assert (opt_str(m, ~"t") == ~"20"); let pair = opt_strs(m, ~"t"); @@ -873,7 +864,7 @@ mod tests { let opts = ~[optmulti(~"t")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, UnrecognizedOption_), + Err(copy f) => check_fail_type(f, UnrecognizedOption_), _ => fail } } @@ -884,7 +875,7 @@ mod tests { let opts = ~[optmulti(~"test")]; let rs = getopts(args, opts); match rs { - Err(f) => check_fail_type(f, UnrecognizedOption_), + Err(copy f) => check_fail_type(f, UnrecognizedOption_), _ => fail } } @@ -901,7 +892,7 @@ mod tests { optopt(~"notpresent")]; let rs = getopts(args, opts); match rs { - Ok(m) => { + Ok(copy m) => { assert (m.free[0] == ~"prog"); assert (m.free[1] == ~"free1"); assert (opt_str(m, ~"s") == ~"20"); @@ -926,8 +917,8 @@ mod tests { let args = ~[~"-e", ~"foo", ~"--encrypt", ~"foo"]; let opts = ~[optopt(~"e"), optopt(~"encrypt")]; let matches = match getopts(args, opts) { - result::Ok(m) => m, - result::Err(_f) => fail + result::Ok(move m) => m, + result::Err(_) => fail }; assert opts_present(matches, ~[~"e"]); assert opts_present(matches, ~[~"encrypt"]); @@ -947,8 +938,8 @@ mod tests { let args = ~[~"-Lfoo"]; let opts = ~[optmulti(~"L")]; let matches = match getopts(args, opts) { - result::Ok(m) => m, - result::Err(_f) => fail + result::Ok(move m) => m, + result::Err(_) => fail }; assert opts_present(matches, ~[~"L"]); assert opts_str(matches, ~[~"L"]) == ~"foo"; diff --git a/src/libstd/json.rs b/src/libstd/json.rs index 0094b5a92773..2d78ef066cc8 100644 --- a/src/libstd/json.rs +++ b/src/libstd/json.rs @@ -1,47 +1,29 @@ // Rust JSON serialization library // Copyright (c) 2011 Google Inc. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap #[forbid(non_camel_case_types)]; //! json serialization use core::cmp::{Eq, Ord}; -use result::{Result, Ok, Err}; -use io::WriterUtil; -use map::HashMap; -use map::Map; +use io::{WriterUtil, ReaderUtil}; +use send_map::linear; use sort::Sort; -export Json; -export Error; -export to_writer; -export to_writer_pretty; -export to_str; -export to_str_pretty; -export from_reader; -export from_str; -export eq; -export ToJson; - -export Num; -export String; -export Boolean; -export List; -export Dict; -export Null; - /// Represents a json value -enum Json { - Num(float), - String(@~str), +pub enum Json { + Number(float), + String(~str), Boolean(bool), - List(@~[Json]), - Dict(map::HashMap<~str, Json>), + List(List), + Object(~Object), Null, } -type Error = { +pub type List = ~[Json]; +pub type Object = linear::LinearMap<~str, Json>; + +pub struct Error { line: uint, col: uint, msg: @~str, @@ -197,28 +179,309 @@ fn escape_str(s: &str) -> ~str { escaped } +fn spaces(n: uint) -> ~str { + let mut ss = ~""; + for n.times { str::push_str(&ss, " "); } + return ss; +} + +pub struct Serializer { + priv wr: io::Writer, +} + +pub fn Serializer(wr: io::Writer) -> Serializer { + Serializer { wr: wr } +} + +pub impl Serializer: serialization2::Serializer { + fn emit_nil(&self) { self.wr.write_str("null") } + + fn emit_uint(&self, v: uint) { self.emit_float(v as float); } + fn emit_u64(&self, v: u64) { self.emit_float(v as float); } + fn emit_u32(&self, v: u32) { self.emit_float(v as float); } + fn emit_u16(&self, v: u16) { self.emit_float(v as float); } + fn emit_u8(&self, v: u8) { self.emit_float(v as float); } + + fn emit_int(&self, v: int) { self.emit_float(v as float); } + fn emit_i64(&self, v: i64) { self.emit_float(v as float); } + fn emit_i32(&self, v: i32) { self.emit_float(v as float); } + fn emit_i16(&self, v: i16) { self.emit_float(v as float); } + fn emit_i8(&self, v: i8) { self.emit_float(v as float); } + + fn emit_bool(&self, v: bool) { + if v { + self.wr.write_str("true"); + } else { + self.wr.write_str("false"); + } + } + + fn emit_f64(&self, v: f64) { self.emit_float(v as float); } + fn emit_f32(&self, v: f32) { self.emit_float(v as float); } + fn emit_float(&self, v: float) { + self.wr.write_str(float::to_str(v, 6u)); + } + + fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) } + + fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)) } + fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) } + fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) } + + fn emit_borrowed(&self, f: fn()) { f() } + fn emit_owned(&self, f: fn()) { f() } + fn emit_managed(&self, f: fn()) { f() } + + fn emit_enum(&self, name: &str, f: fn()) { + if name != "option" { fail ~"only supports option enum" } + f() + } + fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) { + if id == 0 { + self.emit_nil(); + } else { + f() + } + } + fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { + f() + } + + fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + self.wr.write_char('['); + f(); + self.wr.write_char(']'); + } + fn emit_owned_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + fn emit_managed_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + fn emit_vec_elt(&self, idx: uint, f: fn()) { + if idx != 0 { self.wr.write_char(','); } + f() + } + + fn emit_rec(&self, f: fn()) { + self.wr.write_char('{'); + f(); + self.wr.write_char('}'); + } + fn emit_struct(&self, _name: &str, f: fn()) { + self.wr.write_char('{'); + f(); + self.wr.write_char('}'); + } + fn emit_field(&self, name: &str, idx: uint, f: fn()) { + if idx != 0 { self.wr.write_char(','); } + self.wr.write_str(escape_str(name)); + self.wr.write_char(':'); + f(); + } + + fn emit_tup(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f); + } + fn emit_tup_elt(&self, idx: uint, f: fn()) { + self.emit_vec_elt(idx, f) + } +} + +pub struct PrettySerializer { + priv wr: io::Writer, + priv mut indent: uint, +} + +pub fn PrettySerializer(wr: io::Writer) -> PrettySerializer { + PrettySerializer { wr: wr, indent: 0 } +} + +pub impl PrettySerializer: serialization2::Serializer { + fn emit_nil(&self) { self.wr.write_str("null") } + + fn emit_uint(&self, v: uint) { self.emit_float(v as float); } + fn emit_u64(&self, v: u64) { self.emit_float(v as float); } + fn emit_u32(&self, v: u32) { self.emit_float(v as float); } + fn emit_u16(&self, v: u16) { self.emit_float(v as float); } + fn emit_u8(&self, v: u8) { self.emit_float(v as float); } + + fn emit_int(&self, v: int) { self.emit_float(v as float); } + fn emit_i64(&self, v: i64) { self.emit_float(v as float); } + fn emit_i32(&self, v: i32) { self.emit_float(v as float); } + fn emit_i16(&self, v: i16) { self.emit_float(v as float); } + fn emit_i8(&self, v: i8) { self.emit_float(v as float); } + + fn emit_bool(&self, v: bool) { + if v { + self.wr.write_str("true"); + } else { + self.wr.write_str("false"); + } + } + + fn emit_f64(&self, v: f64) { self.emit_float(v as float); } + fn emit_f32(&self, v: f32) { self.emit_float(v as float); } + fn emit_float(&self, v: float) { + self.wr.write_str(float::to_str(v, 6u)); + } + + fn emit_char(&self, v: char) { self.emit_borrowed_str(str::from_char(v)) } + + fn emit_borrowed_str(&self, v: &str) { self.wr.write_str(escape_str(v)); } + fn emit_owned_str(&self, v: &str) { self.emit_borrowed_str(v) } + fn emit_managed_str(&self, v: &str) { self.emit_borrowed_str(v) } + + fn emit_borrowed(&self, f: fn()) { f() } + fn emit_owned(&self, f: fn()) { f() } + fn emit_managed(&self, f: fn()) { f() } + + fn emit_enum(&self, name: &str, f: fn()) { + if name != "option" { fail ~"only supports option enum" } + f() + } + fn emit_enum_variant(&self, _name: &str, id: uint, _cnt: uint, f: fn()) { + if id == 0 { + self.emit_nil(); + } else { + f() + } + } + fn emit_enum_variant_arg(&self, _idx: uint, f: fn()) { + f() + } + + fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + self.wr.write_char('['); + self.indent += 2; + f(); + self.indent -= 2; + self.wr.write_char(']'); + } + fn emit_owned_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + fn emit_managed_vec(&self, len: uint, f: fn()) { + self.emit_borrowed_vec(len, f) + } + fn emit_vec_elt(&self, idx: uint, f: fn()) { + if idx == 0 { + self.wr.write_char('\n'); + } else { + self.wr.write_str(",\n"); + } + self.wr.write_str(spaces(self.indent)); + f() + } + + fn emit_rec(&self, f: fn()) { + self.wr.write_char('{'); + self.indent += 2; + f(); + self.indent -= 2; + self.wr.write_char('}'); + } + fn emit_struct(&self, _name: &str, f: fn()) { + self.emit_rec(f) + } + fn emit_field(&self, name: &str, idx: uint, f: fn()) { + if idx == 0 { + self.wr.write_char('\n'); + } else { + self.wr.write_str(",\n"); + } + self.wr.write_str(spaces(self.indent)); + self.wr.write_str(escape_str(name)); + self.wr.write_str(": "); + f(); + } + fn emit_tup(&self, sz: uint, f: fn()) { + self.emit_borrowed_vec(sz, f); + } + fn emit_tup_elt(&self, idx: uint, f: fn()) { + self.emit_vec_elt(idx, f) + } +} + +pub impl Json: serialization2::Serializable { + fn serialize(&self, s: &S) { + match *self { + Number(v) => v.serialize(s), + String(ref v) => v.serialize(s), + Boolean(v) => v.serialize(s), + List(v) => v.serialize(s), + Object(ref v) => { + do s.emit_rec || { + let mut idx = 0; + for v.each |key, value| { + do s.emit_field(*key, idx) { + value.serialize(s); + } + idx += 1; + } + } + }, + Null => s.emit_nil(), + } + } +} + +/// Serializes a json value into a io::writer +pub fn to_writer(wr: io::Writer, json: &Json) { + json.serialize(&Serializer(wr)) +} + /// Serializes a json value into a string -fn to_str(j: Json) -> ~str { - io::with_str_writer(|wr| to_writer(wr, j)) +pub fn to_str(json: &Json) -> ~str { + io::with_str_writer(|wr| to_writer(wr, json)) } -/// Serializes a json value into a string, with whitespace and sorting -fn to_str_pretty(j: Json) -> ~str { - io::with_str_writer(|wr| to_writer_pretty(wr, j, 0)) +/// Serializes a json value into a io::writer +pub fn to_pretty_writer(wr: io::Writer, json: &Json) { + json.serialize(&PrettySerializer(wr)) } -type Parser_ = { - rdr: io::Reader, - mut ch: char, - mut line: uint, - mut col: uint, -}; - -enum Parser { - Parser_(Parser_) +/// Serializes a json value into a string +pub fn to_pretty_str(json: &Json) -> ~str { + io::with_str_writer(|wr| to_pretty_writer(wr, json)) } -impl Parser { +pub struct Parser { + priv rdr: io::Reader, + priv mut ch: char, + priv mut line: uint, + priv mut col: uint, +} + +/// Deserializes a json value from an io::reader +pub fn Parser(rdr: io::Reader) -> Parser { + Parser { + rdr: rdr, + ch: rdr.read_char(), + line: 1u, + col: 1u, + } +} + +pub impl Parser { + fn parse() -> Result { + match move self.parse_value() { + Ok(move value) => { + // Skip trailing whitespaces. + self.parse_whitespace(); + // Make sure there is no trailing characters. + if self.eof() { + Ok(value) + } else { + self.error(~"trailing characters") + } + } + Err(move e) => Err(e) + } + } +} + +priv impl Parser { fn eof() -> bool { self.ch == -1 as char } fn bump() { @@ -237,24 +500,8 @@ impl Parser { self.ch } - fn error(+msg: ~str) -> Result { - Err({ line: self.line, col: self.col, msg: @msg }) - } - - fn parse() -> Result { - match self.parse_value() { - Ok(value) => { - // Skip trailing whitespaces. - self.parse_whitespace(); - // Make sure there is no trailing characters. - if self.eof() { - Ok(value) - } else { - self.error(~"trailing characters") - } - } - e => e - } + fn error(msg: ~str) -> Result { + Err(Error { line: self.line, col: self.col, msg: @msg }) } fn parse_value() -> Result { @@ -267,10 +514,11 @@ impl Parser { 't' => self.parse_ident(~"rue", Boolean(true)), 'f' => self.parse_ident(~"alse", Boolean(false)), '0' .. '9' | '-' => self.parse_number(), - '"' => match self.parse_str() { - Ok(s) => Ok(String(s)), - Err(e) => Err(e) - }, + '"' => + match move self.parse_str() { + Ok(move s) => Ok(String(s)), + Err(move e) => Err(e), + }, '[' => self.parse_list(), '{' => self.parse_object(), _ => self.error(~"invalid syntax") @@ -281,10 +529,10 @@ impl Parser { while char::is_whitespace(self.ch) { self.bump(); } } - fn parse_ident(ident: ~str, value: Json) -> Result { + fn parse_ident(ident: &str, +value: Json) -> Result { if str::all(ident, |c| c == self.next_char()) { self.bump(); - Ok(value) + Ok(move value) } else { self.error(~"invalid syntax") } @@ -317,7 +565,7 @@ impl Parser { } } - Ok(Num(neg * res)) + Ok(Number(neg * res)) } fn parse_integer() -> Result { @@ -419,7 +667,7 @@ impl Parser { Ok(res) } - fn parse_str() -> Result<@~str, Error> { + fn parse_str() -> Result<~str, Error> { let mut escape = false; let mut res = ~""; @@ -428,14 +676,14 @@ impl Parser { if (escape) { match self.ch { - '"' => str::push_char(&mut res, '"'), - '\\' => str::push_char(&mut res, '\\'), - '/' => str::push_char(&mut res, '/'), - 'b' => str::push_char(&mut res, '\x08'), - 'f' => str::push_char(&mut res, '\x0c'), - 'n' => str::push_char(&mut res, '\n'), - 'r' => str::push_char(&mut res, '\r'), - 't' => str::push_char(&mut res, '\t'), + '"' => str::push_char(&res, '"'), + '\\' => str::push_char(&res, '\\'), + '/' => str::push_char(&res, '/'), + 'b' => str::push_char(&res, '\x08'), + 'f' => str::push_char(&res, '\x0c'), + 'n' => str::push_char(&res, '\n'), + 'r' => str::push_char(&res, '\r'), + 't' => str::push_char(&res, '\t'), 'u' => { // Parse \u1234. let mut i = 0u; @@ -464,7 +712,7 @@ impl Parser { ~"invalid \\u escape (not four digits)"); } - str::push_char(&mut res, n as char); + str::push_char(&res, n as char); } _ => return self.error(~"invalid escape") } @@ -474,9 +722,9 @@ impl Parser { } else { if self.ch == '"' { self.bump(); - return Ok(@res); + return Ok(res); } - str::push_char(&mut res, self.ch); + str::push_char(&res, self.ch); } } @@ -491,13 +739,13 @@ impl Parser { if self.ch == ']' { self.bump(); - return Ok(List(@values)); + return Ok(List(values)); } loop { - match self.parse_value() { - Ok(v) => vec::push(values, v), - e => return e + match move self.parse_value() { + Ok(move v) => values.push(v), + Err(move e) => return Err(e) } self.parse_whitespace(); @@ -507,7 +755,7 @@ impl Parser { match self.ch { ',' => self.bump(), - ']' => { self.bump(); return Ok(List(@values)); } + ']' => { self.bump(); return Ok(List(values)); } _ => return self.error(~"expected `,` or `]`") } }; @@ -517,11 +765,11 @@ impl Parser { self.bump(); self.parse_whitespace(); - let values = map::HashMap(); + let mut values = ~linear::LinearMap(); if self.ch == '}' { self.bump(); - return Ok(Dict(values)); + return Ok(Object(values)); } while !self.eof() { @@ -531,9 +779,9 @@ impl Parser { return self.error(~"key must be a string"); } - let key = match self.parse_str() { - Ok(key) => key, - Err(e) => return Err(e) + let key = match move self.parse_str() { + Ok(move key) => key, + Err(move e) => return Err(e) }; self.parse_whitespace(); @@ -544,15 +792,15 @@ impl Parser { } self.bump(); - match self.parse_value() { - Ok(value) => { values.insert(copy *key, value); } - e => return e + match move self.parse_value() { + Ok(move value) => { values.insert(key, value); } + Err(move e) => return Err(e) } self.parse_whitespace(); match self.ch { ',' => self.bump(), - '}' => { self.bump(); return Ok(Dict(values)); } + '}' => { self.bump(); return Ok(Object(values)); } _ => { if self.eof() { break; } return self.error(~"expected `,` or `}`"); @@ -565,198 +813,415 @@ impl Parser { } /// Deserializes a json value from an io::reader -fn from_reader(rdr: io::Reader) -> Result { - let parser = Parser_({ - rdr: rdr, - mut ch: rdr.read_char(), - mut line: 1u, - mut col: 1u, - }); - - parser.parse() +pub fn from_reader(rdr: io::Reader) -> Result { + Parser(rdr).parse() } /// Deserializes a json value from a string -fn from_str(s: &str) -> Result { - io::with_str_reader(s, from_reader) +pub fn from_str(s: &str) -> Result { + do io::with_str_reader(s) |rdr| { + from_reader(rdr) + } } -/// Test if two json values are equal -pure fn eq(value0: Json, value1: Json) -> bool { - match (value0, value1) { - (Num(f0), Num(f1)) => f0 == f1, - (String(s0), String(s1)) => s0 == s1, - (Boolean(b0), Boolean(b1)) => b0 == b1, - (List(l0), List(l1)) => vec::all2(*l0, *l1, eq), - (Dict(d0), Dict(d1)) => { - if d0.size() == d1.size() { - let mut equal = true; - for d0.each |k, v0| { - match d1.find(k) { - Some(v1) => if !eq(v0, v1) { equal = false }, - None => equal = false - } - }; - equal - } else { - false - } - } - (Null, Null) => true, - _ => false +pub struct Deserializer { + priv json: Json, + priv mut stack: ~[&Json], +} + +pub fn Deserializer(rdr: io::Reader) -> Result { + match move from_reader(rdr) { + Ok(move json) => { + let des = Deserializer { json: json, stack: ~[] }; + Ok(move des) + } + Err(move e) => Err(e) } } +priv impl Deserializer { + fn peek(&self) -> &self/Json { + if self.stack.len() == 0 { self.stack.push(&self.json); } + vec::last(self.stack) + } + + fn pop(&self) -> &self/Json { + if self.stack.len() == 0 { self.stack.push(&self.json); } + self.stack.pop() + } +} + +pub impl Deserializer: serialization2::Deserializer { + fn read_nil(&self) -> () { + debug!("read_nil"); + match *self.pop() { + Null => (), + _ => fail ~"not a null" + } + } + + fn read_u64(&self) -> u64 { self.read_float() as u64 } + fn read_u32(&self) -> u32 { self.read_float() as u32 } + fn read_u16(&self) -> u16 { self.read_float() as u16 } + fn read_u8 (&self) -> u8 { self.read_float() as u8 } + fn read_uint(&self) -> uint { self.read_float() as uint } + + fn read_i64(&self) -> i64 { self.read_float() as i64 } + fn read_i32(&self) -> i32 { self.read_float() as i32 } + fn read_i16(&self) -> i16 { self.read_float() as i16 } + fn read_i8 (&self) -> i8 { self.read_float() as i8 } + fn read_int(&self) -> int { self.read_float() as int } + + fn read_bool(&self) -> bool { + debug!("read_bool"); + match *self.pop() { + Boolean(b) => b, + _ => fail ~"not a boolean" + } + } + + fn read_f64(&self) -> f64 { self.read_float() as f64 } + fn read_f32(&self) -> f32 { self.read_float() as f32 } + fn read_float(&self) -> float { + debug!("read_float"); + match *self.pop() { + Number(f) => f, + _ => fail ~"not a number" + } + } + + fn read_char(&self) -> char { + let v = str::chars(self.read_owned_str()); + if v.len() != 1 { fail ~"string must have one character" } + v[0] + } + + fn read_owned_str(&self) -> ~str { + debug!("read_owned_str"); + match *self.pop() { + String(ref s) => copy *s, + _ => fail ~"not a string" + } + } + + fn read_managed_str(&self) -> @str { + // FIXME(#3604): There's no way to convert from a ~str to a @str. + fail ~"read_managed_str()"; + } + + fn read_owned(&self, f: fn() -> T) -> T { + debug!("read_owned()"); + f() + } + + fn read_managed(&self, f: fn() -> T) -> T { + debug!("read_managed()"); + f() + } + + fn read_enum(&self, name: &str, f: fn() -> T) -> T { + debug!("read_enum(%s)", name); + if name != ~"option" { fail ~"only supports the option enum" } + f() + } + + fn read_enum_variant(&self, f: fn(uint) -> T) -> T { + debug!("read_enum_variant()"); + let idx = match *self.peek() { + Null => 0, + _ => 1, + }; + f(idx) + } + + fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T { + debug!("read_enum_variant_arg(idx=%u)", idx); + if idx != 0 { fail ~"unknown index" } + f() + } + + fn read_owned_vec(&self, f: fn(uint) -> T) -> T { + debug!("read_owned_vec()"); + let len = match *self.peek() { + List(list) => list.len(), + _ => fail ~"not a list", + }; + let res = f(len); + self.pop(); + res + } + + fn read_managed_vec(&self, f: fn(uint) -> T) -> T { + debug!("read_owned_vec()"); + let len = match *self.peek() { + List(ref list) => list.len(), + _ => fail ~"not a list", + }; + let res = f(len); + self.pop(); + res + } + + fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T { + debug!("read_vec_elt(idx=%u)", idx); + match *self.peek() { + List(ref list) => { + // FIXME(#3148)---should be inferred + let list: &self/~[Json] = list; + + self.stack.push(&list[idx]); + f() + } + _ => fail ~"not a list", + } + } + + fn read_rec(&self, f: fn() -> T) -> T { + debug!("read_rec()"); + let value = f(); + self.pop(); + value + } + + fn read_struct(&self, _name: &str, f: fn() -> T) -> T { + debug!("read_struct()"); + let value = f(); + self.pop(); + value + } + + fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T { + debug!("read_rec_field(%s, idx=%u)", name, idx); + let top = self.peek(); + match *top { + Object(ref obj) => { + // FIXME(#3148) This hint should not be necessary. + let obj: &self/~Object = obj; + + match obj.find_ref(&name.to_unique()) { + None => fail fmt!("no such field: %s", name), + Some(json) => { + self.stack.push(json); + f() + } + } + } + Number(_) => fail ~"num", + String(_) => fail ~"str", + Boolean(_) => fail ~"bool", + List(_) => fail fmt!("list: %?", top), + Null => fail ~"null", + + //_ => fail fmt!("not an object: %?", *top) + } + } + + fn read_tup(&self, len: uint, f: fn() -> T) -> T { + debug!("read_tup(len=%u)", len); + let value = f(); + self.pop(); + value + } + + fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T { + debug!("read_tup_elt(idx=%u)", idx); + match *self.peek() { + List(ref list) => { + // FIXME(#3148)---should be inferred + let list: &self/~[Json] = list; + self.stack.push(&list[idx]); + f() + } + _ => fail ~"not a list" + } + } +} + +impl Json : Eq { + pure fn eq(other: &Json) -> bool { + // XXX: This is ugly because matching on references is broken, and + // we can't match on dereferenced tuples without a copy. + match self { + Number(f0) => + match *other { Number(f1) => f0 == f1, _ => false }, + String(ref s0) => + match *other { String(ref s1) => s0 == s1, _ => false }, + Boolean(b0) => + match *other { Boolean(b1) => b0 == b1, _ => false }, + Null => + match *other { Null => true, _ => false }, + List(v0) => + match *other { List(v1) => v0 == v1, _ => false }, + Object(ref d0) => { + match *other { + Object(ref d1) => { + if d0.len() == d1.len() { + let mut equal = true; + for d0.each |k, v0| { + match d1.find_ref(k) { + Some(v1) if v0 == v1 => { }, + _ => { equal = false; break } + } + }; + equal + } else { + false + } + } + _ => false + } + } + } + } + pure fn ne(other: &Json) -> bool { !self.eq(other) } +} + /// Test if two json values are less than one another -pure fn lt(value0: Json, value1: Json) -> bool { - match value0 { - Num(f0) => { - match value1 { - Num(f1) => f0 < f1, - String(_) | Boolean(_) | List(_) | Dict(_) | Null => true +impl Json : Ord { + pure fn lt(other: &Json) -> bool { + match self { + Number(f0) => { + match *other { + Number(f1) => f0 < f1, + String(_) | Boolean(_) | List(_) | Object(_) | + Null => true + } } - } - String(s0) => { - match value1 { - Num(_) => false, - String(s1) => s0 < s1, - Boolean(_) | List(_) | Dict(_) | Null => true + String(ref s0) => { + match *other { + Number(_) => false, + String(ref s1) => s0 < s1, + Boolean(_) | List(_) | Object(_) | Null => true + } } - } - Boolean(b0) => { - match value1 { - Num(_) | String(_) => false, - Boolean(b1) => b0 < b1, - List(_) | Dict(_) | Null => true + Boolean(b0) => { + match *other { + Number(_) | String(_) => false, + Boolean(b1) => b0 < b1, + List(_) | Object(_) | Null => true + } } - } - List(l0) => { - match value1 { - Num(_) | String(_) | Boolean(_) => false, - List(l1) => l0 < l1, - Dict(_) | Null => true + List(l0) => { + match *other { + Number(_) | String(_) | Boolean(_) => false, + List(l1) => l0 < l1, + Object(_) | Null => true + } } - } - Dict(d0) => { - match value1 { - Num(_) | String(_) | Boolean(_) | List(_) => false, - Dict(d1) => { - unsafe { - let (d0_flat, d1_flat) = { - let d0_flat = dvec::DVec(); - for d0.each |k, v| { d0_flat.push((k, v)); } - let mut d0_flat = dvec::unwrap(move d0_flat); + Object(ref d0) => { + match *other { + Number(_) | String(_) | Boolean(_) | List(_) => false, + Object(ref d1) => { + unsafe { + let mut d0_flat = ~[]; + let mut d1_flat = ~[]; + + // XXX: this is horribly inefficient... + for d0.each |k, v| { + d0_flat.push((@copy *k, @copy *v)); + } d0_flat.qsort(); - let mut d1_flat = dvec::DVec(); - for d1.each |k, v| { d1_flat.push((k, v)); } - let mut d1_flat = dvec::unwrap(move d1_flat); + for d1.each |k, v| { + d1_flat.push((@copy *k, @copy *v)); + } d1_flat.qsort(); - (move d0_flat, move d1_flat) - }; - - d0_flat < d1_flat + d0_flat < d1_flat + } } + Null => true } - Null => true } - } - Null => { - match value1 { - Num(_) | String(_) | Boolean(_) | List(_) | Dict(_) => false, - Null => true + Null => { + match *other { + Number(_) | String(_) | Boolean(_) | List(_) | + Object(_) => + false, + Null => true + } } } } + pure fn le(other: &Json) -> bool { !(*other).lt(&self) } + pure fn ge(other: &Json) -> bool { !self.lt(other) } + pure fn gt(other: &Json) -> bool { (*other).lt(&self) } } impl Error : Eq { pure fn eq(other: &Error) -> bool { - self.line == (*other).line && - self.col == (*other).col && - self.msg == (*other).msg + self.line == other.line && + self.col == other.col && + self.msg == other.msg } pure fn ne(other: &Error) -> bool { !self.eq(other) } } -impl Json : Eq { - pure fn eq(other: &Json) -> bool { eq(self, (*other)) } - pure fn ne(other: &Json) -> bool { !self.eq(other) } -} - -impl Json : Ord { - pure fn lt(other: &Json) -> bool { lt(self, (*other)) } - pure fn le(other: &Json) -> bool { !(*other).lt(&self) } - pure fn ge(other: &Json) -> bool { !self.lt(other) } - pure fn gt(other: &Json) -> bool { (*other).lt(&self) } -} - trait ToJson { fn to_json() -> Json; } impl Json: ToJson { - fn to_json() -> Json { self } + fn to_json() -> Json { copy self } } impl @Json: ToJson { - fn to_json() -> Json { *self } + fn to_json() -> Json { (*self).to_json() } } impl int: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl i8: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl i16: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl i32: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl i64: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl uint: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl u8: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl u16: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl u32: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl u64: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl float: ToJson { - fn to_json() -> Json { Num(self) } + fn to_json() -> Json { Number(self) } } impl f32: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl f64: ToJson { - fn to_json() -> Json { Num(self as float) } + fn to_json() -> Json { Number(self as float) } } impl (): ToJson { @@ -768,59 +1233,70 @@ impl bool: ToJson { } impl ~str: ToJson { - fn to_json() -> Json { String(@copy self) } + fn to_json() -> Json { String(copy self) } } impl @~str: ToJson { - fn to_json() -> Json { String(self) } + fn to_json() -> Json { String(copy *self) } } impl (A, B): ToJson { fn to_json() -> Json { match self { - (a, b) => { - List(@~[a.to_json(), b.to_json()]) + (ref a, ref b) => { + List(~[a.to_json(), b.to_json()]) } } } } impl (A, B, C): ToJson { - fn to_json() -> Json { match self { - (a, b, c) => { - List(@~[a.to_json(), b.to_json(), c.to_json()]) + (ref a, ref b, ref c) => { + List(~[a.to_json(), b.to_json(), c.to_json()]) } } } } impl ~[A]: ToJson { - fn to_json() -> Json { List(@self.map(|elt| elt.to_json())) } + fn to_json() -> Json { List(self.map(|elt| elt.to_json())) } } -impl HashMap<~str, A>: ToJson { +impl linear::LinearMap<~str, A>: ToJson { fn to_json() -> Json { - let d = map::HashMap(); + let mut d = linear::LinearMap(); for self.each() |key, value| { - d.insert(copy key, value.to_json()); + d.insert(copy *key, value.to_json()); } - Dict(d) + Object(~d) } } +/* +impl @std::map::HashMap<~str, A>: ToJson { + fn to_json() -> Json { + let mut d = linear::LinearMap(); + for self.each_ref |key, value| { + d.insert(copy *key, value.to_json()); + } + Object(~d) + } +} +*/ + impl Option: ToJson { fn to_json() -> Json { match self { None => Null, - Some(value) => value.to_json() + Some(ref value) => value.to_json() } } } impl Json: to_str::ToStr { - fn to_str() -> ~str { to_str(self) } + fn to_str() -> ~str { to_str(&self) } } impl Error: to_str::ToStr { @@ -831,105 +1307,104 @@ impl Error: to_str::ToStr { #[cfg(test)] mod tests { - #[legacy_exports]; - fn mk_dict(items: &[(~str, Json)]) -> Json { - let d = map::HashMap(); + fn mk_object(items: &[(~str, Json)]) -> Json { + let mut d = ~linear::LinearMap(); - for vec::each(items) |item| { - let (key, value) = copy *item; - d.insert(key, value); + for items.each |item| { + match *item { + (copy key, copy value) => { d.insert(key, value); }, + } }; - Dict(d) + Object(d) } #[test] fn test_write_null() { - assert to_str(Null) == ~"null"; + assert to_str(&Null) == ~"null"; } #[test] - fn test_write_num() { - assert to_str(Num(3f)) == ~"3"; - assert to_str(Num(3.1f)) == ~"3.1"; - assert to_str(Num(-1.5f)) == ~"-1.5"; - assert to_str(Num(0.5f)) == ~"0.5"; + fn test_write_number() { + assert to_str(&Number(3f)) == ~"3"; + assert to_str(&Number(3.1f)) == ~"3.1"; + assert to_str(&Number(-1.5f)) == ~"-1.5"; + assert to_str(&Number(0.5f)) == ~"0.5"; } #[test] fn test_write_str() { - assert to_str(String(@~"")) == ~"\"\""; - assert to_str(String(@~"foo")) == ~"\"foo\""; + assert to_str(&String(~"")) == ~"\"\""; + assert to_str(&String(~"foo")) == ~"\"foo\""; } #[test] fn test_write_bool() { - assert to_str(Boolean(true)) == ~"true"; - assert to_str(Boolean(false)) == ~"false"; + assert to_str(&Boolean(true)) == ~"true"; + assert to_str(&Boolean(false)) == ~"false"; } #[test] fn test_write_list() { - assert to_str(List(@~[])) == ~"[]"; - assert to_str(List(@~[Boolean(true)])) == ~"[true]"; - assert to_str(List(@~[ + assert to_str(&List(~[])) == ~"[]"; + assert to_str(&List(~[Boolean(true)])) == ~"[true]"; + assert to_str(&List(~[ Boolean(false), Null, - List(@~[String(@~"foo\nbar"), Num(3.5f)]) - ])) == ~"[false, null, [\"foo\\nbar\", 3.5]]"; + List(~[String(~"foo\nbar"), Number(3.5f)]) + ])) == ~"[false,null,[\"foo\\nbar\",3.5]]"; } #[test] - fn test_write_dict() { - assert to_str(mk_dict(~[])) == ~"{}"; - assert to_str(mk_dict(~[(~"a", Boolean(true))])) - == ~"{ \"a\": true }"; - let a = mk_dict(~[ + fn test_write_object() { + assert to_str(&mk_object(~[])) == ~"{}"; + assert to_str(&mk_object(~[(~"a", Boolean(true))])) + == ~"{\"a\":true}"; + let a = mk_object(~[ (~"a", Boolean(true)), - (~"b", List(@~[ - mk_dict(~[(~"c", String(@~"\x0c\r"))]), - mk_dict(~[(~"d", String(@~""))]) + (~"b", List(~[ + mk_object(~[(~"c", String(~"\x0c\r"))]), + mk_object(~[(~"d", String(~""))]) ])) ]); - let astr = to_str(a); - let b = result::get(from_str(astr)); - let bstr = to_str(b); - assert astr == bstr; + // We can't compare the strings directly because the object fields be + // printed in a different order. + let b = result::unwrap(from_str(to_str(&a))); assert a == b; } #[test] fn test_trailing_characters() { assert from_str(~"nulla") == - Err({line: 1u, col: 5u, msg: @~"trailing characters"}); + Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}); assert from_str(~"truea") == - Err({line: 1u, col: 5u, msg: @~"trailing characters"}); + Err(Error {line: 1u, col: 5u, msg: @~"trailing characters"}); assert from_str(~"falsea") == - Err({line: 1u, col: 6u, msg: @~"trailing characters"}); + Err(Error {line: 1u, col: 6u, msg: @~"trailing characters"}); assert from_str(~"1a") == - Err({line: 1u, col: 2u, msg: @~"trailing characters"}); + Err(Error {line: 1u, col: 2u, msg: @~"trailing characters"}); assert from_str(~"[]a") == - Err({line: 1u, col: 3u, msg: @~"trailing characters"}); + Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}); assert from_str(~"{}a") == - Err({line: 1u, col: 3u, msg: @~"trailing characters"}); + Err(Error {line: 1u, col: 3u, msg: @~"trailing characters"}); } #[test] fn test_read_identifiers() { assert from_str(~"n") == - Err({line: 1u, col: 2u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}); assert from_str(~"nul") == - Err({line: 1u, col: 4u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}); assert from_str(~"t") == - Err({line: 1u, col: 2u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}); assert from_str(~"truz") == - Err({line: 1u, col: 4u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}); assert from_str(~"f") == - Err({line: 1u, col: 2u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 2u, msg: @~"invalid syntax"}); assert from_str(~"faz") == - Err({line: 1u, col: 3u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 3u, msg: @~"invalid syntax"}); assert from_str(~"null") == Ok(Null); assert from_str(~"true") == Ok(Boolean(true)); @@ -940,124 +1415,125 @@ mod tests { } #[test] - fn test_read_num() { + fn test_read_number() { assert from_str(~"+") == - Err({line: 1u, col: 1u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}); assert from_str(~".") == - Err({line: 1u, col: 1u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 1u, msg: @~"invalid syntax"}); assert from_str(~"-") == - Err({line: 1u, col: 2u, msg: @~"invalid number"}); + Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}); assert from_str(~"00") == - Err({line: 1u, col: 2u, msg: @~"invalid number"}); + Err(Error {line: 1u, col: 2u, msg: @~"invalid number"}); assert from_str(~"1.") == - Err({line: 1u, col: 3u, msg: @~"invalid number"}); + Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}); assert from_str(~"1e") == - Err({line: 1u, col: 3u, msg: @~"invalid number"}); + Err(Error {line: 1u, col: 3u, msg: @~"invalid number"}); assert from_str(~"1e+") == - Err({line: 1u, col: 4u, msg: @~"invalid number"}); + Err(Error {line: 1u, col: 4u, msg: @~"invalid number"}); - assert from_str(~"3") == Ok(Num(3f)); - assert from_str(~"3.1") == Ok(Num(3.1f)); - assert from_str(~"-1.2") == Ok(Num(-1.2f)); - assert from_str(~"0.4") == Ok(Num(0.4f)); - assert from_str(~"0.4e5") == Ok(Num(0.4e5f)); - assert from_str(~"0.4e+15") == Ok(Num(0.4e15f)); - assert from_str(~"0.4e-01") == Ok(Num(0.4e-01f)); - assert from_str(~" 3 ") == Ok(Num(3f)); + assert from_str(~"3") == Ok(Number(3f)); + assert from_str(~"3.1") == Ok(Number(3.1f)); + assert from_str(~"-1.2") == Ok(Number(-1.2f)); + assert from_str(~"0.4") == Ok(Number(0.4f)); + assert from_str(~"0.4e5") == Ok(Number(0.4e5f)); + assert from_str(~"0.4e+15") == Ok(Number(0.4e15f)); + assert from_str(~"0.4e-01") == Ok(Number(0.4e-01f)); + assert from_str(~" 3 ") == Ok(Number(3f)); } #[test] fn test_read_str() { assert from_str(~"\"") == - Err({line: 1u, col: 2u, msg: @~"EOF while parsing string"}); + Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"}); assert from_str(~"\"lol") == - Err({line: 1u, col: 5u, msg: @~"EOF while parsing string"}); + Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing string"}); - assert from_str(~"\"\"") == Ok(String(@~"")); - assert from_str(~"\"foo\"") == Ok(String(@~"foo")); - assert from_str(~"\"\\\"\"") == Ok(String(@~"\"")); - assert from_str(~"\"\\b\"") == Ok(String(@~"\x08")); - assert from_str(~"\"\\n\"") == Ok(String(@~"\n")); - assert from_str(~"\"\\r\"") == Ok(String(@~"\r")); - assert from_str(~"\"\\t\"") == Ok(String(@~"\t")); - assert from_str(~" \"foo\" ") == Ok(String(@~"foo")); + assert from_str(~"\"\"") == Ok(String(~"")); + assert from_str(~"\"foo\"") == Ok(String(~"foo")); + assert from_str(~"\"\\\"\"") == Ok(String(~"\"")); + assert from_str(~"\"\\b\"") == Ok(String(~"\x08")); + assert from_str(~"\"\\n\"") == Ok(String(~"\n")); + assert from_str(~"\"\\r\"") == Ok(String(~"\r")); + assert from_str(~"\"\\t\"") == Ok(String(~"\t")); + assert from_str(~" \"foo\" ") == Ok(String(~"foo")); } #[test] fn test_unicode_hex_escapes_in_str() { - assert from_str(~"\"\\u12ab\"") == Ok(String(@~"\u12ab")); - assert from_str(~"\"\\uAB12\"") == Ok(String(@~"\uAB12")); + assert from_str(~"\"\\u12ab\"") == Ok(String(~"\u12ab")); + assert from_str(~"\"\\uAB12\"") == Ok(String(~"\uAB12")); } #[test] fn test_read_list() { assert from_str(~"[") == - Err({line: 1u, col: 2u, msg: @~"EOF while parsing value"}); + Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing value"}); assert from_str(~"[1") == - Err({line: 1u, col: 3u, msg: @~"EOF while parsing list"}); + Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing list"}); assert from_str(~"[1,") == - Err({line: 1u, col: 4u, msg: @~"EOF while parsing value"}); + Err(Error {line: 1u, col: 4u, msg: @~"EOF while parsing value"}); assert from_str(~"[1,]") == - Err({line: 1u, col: 4u, msg: @~"invalid syntax"}); + Err(Error {line: 1u, col: 4u, msg: @~"invalid syntax"}); assert from_str(~"[6 7]") == - Err({line: 1u, col: 4u, msg: @~"expected `,` or `]`"}); + Err(Error {line: 1u, col: 4u, msg: @~"expected `,` or `]`"}); - assert from_str(~"[]") == Ok(List(@~[])); - assert from_str(~"[ ]") == Ok(List(@~[])); - assert from_str(~"[true]") == Ok(List(@~[Boolean(true)])); - assert from_str(~"[ false ]") == Ok(List(@~[Boolean(false)])); - assert from_str(~"[null]") == Ok(List(@~[Null])); - assert from_str(~"[3, 1]") == Ok(List(@~[Num(3f), Num(1f)])); - assert from_str(~"\n[3, 2]\n") == Ok(List(@~[Num(3f), Num(2f)])); + assert from_str(~"[]") == Ok(List(~[])); + assert from_str(~"[ ]") == Ok(List(~[])); + assert from_str(~"[true]") == Ok(List(~[Boolean(true)])); + assert from_str(~"[ false ]") == Ok(List(~[Boolean(false)])); + assert from_str(~"[null]") == Ok(List(~[Null])); + assert from_str(~"[3, 1]") == Ok(List(~[Number(3f), Number(1f)])); + assert from_str(~"\n[3, 2]\n") == Ok(List(~[Number(3f), Number(2f)])); assert from_str(~"[2, [4, 1]]") == - Ok(List(@~[Num(2f), List(@~[Num(4f), Num(1f)])])); + Ok(List(~[Number(2f), List(~[Number(4f), Number(1f)])])); } #[test] - fn test_read_dict() { + fn test_read_object() { assert from_str(~"{") == - Err({line: 1u, col: 2u, msg: @~"EOF while parsing object"}); + Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing object"}); assert from_str(~"{ ") == - Err({line: 1u, col: 3u, msg: @~"EOF while parsing object"}); + Err(Error {line: 1u, col: 3u, msg: @~"EOF while parsing object"}); assert from_str(~"{1") == - Err({line: 1u, col: 2u, msg: @~"key must be a string"}); + Err(Error {line: 1u, col: 2u, msg: @~"key must be a string"}); assert from_str(~"{ \"a\"") == - Err({line: 1u, col: 6u, msg: @~"EOF while parsing object"}); + Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"}); assert from_str(~"{\"a\"") == - Err({line: 1u, col: 5u, msg: @~"EOF while parsing object"}); + Err(Error {line: 1u, col: 5u, msg: @~"EOF while parsing object"}); assert from_str(~"{\"a\" ") == - Err({line: 1u, col: 6u, msg: @~"EOF while parsing object"}); + Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing object"}); assert from_str(~"{\"a\" 1") == - Err({line: 1u, col: 6u, msg: @~"expected `:`"}); + Err(Error {line: 1u, col: 6u, msg: @~"expected `:`"}); assert from_str(~"{\"a\":") == - Err({line: 1u, col: 6u, msg: @~"EOF while parsing value"}); + Err(Error {line: 1u, col: 6u, msg: @~"EOF while parsing value"}); assert from_str(~"{\"a\":1") == - Err({line: 1u, col: 7u, msg: @~"EOF while parsing object"}); + Err(Error {line: 1u, col: 7u, msg: @~"EOF while parsing object"}); assert from_str(~"{\"a\":1 1") == - Err({line: 1u, col: 8u, msg: @~"expected `,` or `}`"}); + Err(Error {line: 1u, col: 8u, msg: @~"expected `,` or `}`"}); assert from_str(~"{\"a\":1,") == - Err({line: 1u, col: 8u, msg: @~"EOF while parsing object"}); + Err(Error {line: 1u, col: 8u, msg: @~"EOF while parsing object"}); - assert eq(result::get(from_str(~"{}")), mk_dict(~[])); - assert eq(result::get(from_str(~"{\"a\": 3}")), - mk_dict(~[(~"a", Num(3.0f))])); + assert result::unwrap(from_str(~"{}")) == mk_object(~[]); + assert result::unwrap(from_str(~"{\"a\": 3}")) == + mk_object(~[(~"a", Number(3.0f))]); - assert eq(result::get(from_str(~"{ \"a\": null, \"b\" : true }")), - mk_dict(~[ + assert result::unwrap(from_str(~"{ \"a\": null, \"b\" : true }")) == + mk_object(~[ (~"a", Null), - (~"b", Boolean(true))])); - assert eq(result::get(from_str(~"\n{ \"a\": null, \"b\" : true }\n")), - mk_dict(~[ + (~"b", Boolean(true))]); + assert result::unwrap( + from_str(~"\n{ \"a\": null, \"b\" : true }\n")) == + mk_object(~[ (~"a", Null), - (~"b", Boolean(true))])); - assert eq(result::get(from_str(~"{\"a\" : 1.0 ,\"b\": [ true ]}")), - mk_dict(~[ - (~"a", Num(1.0)), - (~"b", List(@~[Boolean(true)])) - ])); - assert eq(result::get(from_str( + (~"b", Boolean(true))]); + assert result::unwrap(from_str(~"{\"a\" : 1.0 ,\"b\": [ true ]}")) == + mk_object(~[ + (~"a", Number(1.0)), + (~"b", List(~[Boolean(true)])) + ]); + assert result::unwrap(from_str( ~"{" + ~"\"a\": 1.0, " + ~"\"b\": [" + @@ -1065,22 +1541,22 @@ mod tests { ~"\"foo\\nbar\", " + ~"{ \"c\": {\"d\": null} } " + ~"]" + - ~"}")), - mk_dict(~[ - (~"a", Num(1.0f)), - (~"b", List(@~[ + ~"}")) == + mk_object(~[ + (~"a", Number(1.0f)), + (~"b", List(~[ Boolean(true), - String(@~"foo\nbar"), - mk_dict(~[ - (~"c", mk_dict(~[(~"d", Null)])) + String(~"foo\nbar"), + mk_object(~[ + (~"c", mk_object(~[(~"d", Null)])) ]) ])) - ])); + ]); } #[test] fn test_multiline_errors() { assert from_str(~"{\n \"foo\":\n \"bar\"") == - Err({line: 3u, col: 8u, msg: @~"EOF while parsing object"}); + Err(Error {line: 3u, col: 8u, msg: @~"EOF while parsing object"}); } } diff --git a/src/libstd/list.rs b/src/libstd/list.rs index 45eafb3d018a..4ff493f5ab91 100644 --- a/src/libstd/list.rs +++ b/src/libstd/list.rs @@ -1,20 +1,19 @@ //! A standard linked list -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +#[warn(deprecated_mode)]; use core::cmp::Eq; use core::option; use option::*; use option::{Some, None}; -enum List { +pub enum List { Cons(T, @List), Nil, } /// Cregate a list from a vector -fn from_vec(v: &[T]) -> @List { - vec::foldr(v, @Nil::, |h, t| @Cons(h, t)) +pub fn from_vec(v: &[T]) -> @List { + vec::foldr(v, @Nil::, |h, t| @Cons(*h, t)) } /** @@ -30,9 +29,9 @@ fn from_vec(v: &[T]) -> @List { * * z - The initial value * * f - The function to apply */ -fn foldl(+z: T, ls: @List, f: fn((&T), (&U)) -> T) -> T { +pub fn foldl(z: T, ls: @List, f: fn((&T), (&U)) -> T) -> T { let mut accum: T = z; - do iter(ls) |elt| { accum = f(&accum, &elt);} + do iter(ls) |elt| { accum = f(&accum, elt);} accum } @@ -43,12 +42,12 @@ fn foldl(+z: T, ls: @List, f: fn((&T), (&U)) -> T) -> T { * When function `f` returns true then an option containing the element * is returned. If `f` matches no elements then none is returned. */ -fn find(ls: @List, f: fn((&T)) -> bool) -> Option { +pub fn find(ls: @List, f: fn((&T)) -> bool) -> Option { let mut ls = ls; loop { ls = match *ls { - Cons(hd, tl) => { - if f(&hd) { return Some(hd); } + Cons(ref hd, tl) => { + if f(hd) { return Some(*hd); } tl } Nil => return None @@ -57,15 +56,15 @@ fn find(ls: @List, f: fn((&T)) -> bool) -> Option { } /// Returns true if a list contains an element with the given value -fn has(ls: @List, +elt: T) -> bool { +pub fn has(ls: @List, +elt: T) -> bool { for each(ls) |e| { - if e == elt { return true; } + if *e == elt { return true; } } return false; } /// Returns true if the list is empty -pure fn is_empty(ls: @List) -> bool { +pub pure fn is_empty(ls: @List) -> bool { match *ls { Nil => true, _ => false @@ -73,19 +72,19 @@ pure fn is_empty(ls: @List) -> bool { } /// Returns true if the list is not empty -pure fn is_not_empty(ls: @List) -> bool { +pub pure fn is_not_empty(ls: @List) -> bool { return !is_empty(ls); } /// Returns the length of a list -fn len(ls: @List) -> uint { +pub fn len(ls: @List) -> uint { let mut count = 0u; iter(ls, |_e| count += 1u); count } /// Returns all but the first element of a list -pure fn tail(ls: @List) -> @List { +pub pure fn tail(ls: @List) -> @List { match *ls { Cons(_, tl) => return tl, Nil => fail ~"list empty" @@ -93,19 +92,19 @@ pure fn tail(ls: @List) -> @List { } /// Returns the first element of a list -pure fn head(ls: @List) -> T { +pub pure fn head(ls: @List) -> T { match *ls { - Cons(hd, _) => hd, + Cons(copy hd, _) => hd, // makes me sad _ => fail ~"head invoked on empty list" } } /// Appends one list to another -pure fn append(l: @List, m: @List) -> @List { +pub pure fn append(l: @List, m: @List) -> @List { match *l { Nil => return m, - Cons(x, xs) => { + Cons(copy x, xs) => { let rest = append(xs, m); return @Cons(x, rest); } @@ -121,11 +120,11 @@ pure fn push(ll: &mut @list, +vv: T) { */ /// Iterate over a list -fn iter(l: @List, f: fn(T)) { +pub fn iter(l: @List, f: fn((&T))) { let mut cur = l; loop { cur = match *cur { - Cons(hd, tl) => { + Cons(ref hd, tl) => { f(hd); tl } @@ -135,11 +134,11 @@ fn iter(l: @List, f: fn(T)) { } /// Iterate over a list -fn each(l: @List, f: fn(T) -> bool) { +pub fn each(l: @List, f: fn((&T)) -> bool) { let mut cur = l; loop { cur = match *cur { - Cons(hd, tl) => { + Cons(ref hd, tl) => { if !f(hd) { return; } tl } @@ -151,9 +150,9 @@ fn each(l: @List, f: fn(T) -> bool) { impl List : Eq { pure fn eq(other: &List) -> bool { match self { - Cons(e0a, e1a) => { + Cons(ref e0a, e1a) => { match (*other) { - Cons(e0b, e1b) => e0a == e0b && e1a == e1b, + Cons(ref e0b, e1b) => e0a == e0b && e1a == e1b, _ => false } } diff --git a/src/libstd/map.rs b/src/libstd/map.rs index 9bdf6e15ee57..cc42c5623762 100644 --- a/src/libstd/map.rs +++ b/src/libstd/map.rs @@ -1,7 +1,6 @@ //! A map type -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap use io::WriterUtil; use to_str::ToStr; @@ -12,16 +11,12 @@ use core::cmp::Eq; use hash::Hash; use to_bytes::IterBytes; -export HashMap, hashfn, eqfn, Set, Map, chained, set_add; -export hash_from_vec; -export vec_from_set; - /// A convenience type to treat a hashmap as a set -type Set = HashMap; +pub type Set = HashMap; -type HashMap = chained::T; +pub type HashMap = chained::T; -trait Map { +pub trait Map { /// Return the number of elements in the map pure fn size() -> uint; @@ -33,10 +28,10 @@ trait Map { * * 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; + fn contains_key(key: K) -> bool; /// Returns true if the map contains a value for the specified /// key, taking the key by reference. @@ -46,31 +41,31 @@ trait Map { * Get the value for the specified key. Fails if the key does not exist in * the map. */ - fn get(+key: K) -> V; + fn get(key: K) -> V; /** * Get the value for the specified key. If the key does not exist in * the map then returns none. */ - pure fn find(+key: K) -> Option; + pure fn find(key: K) -> Option; /** * Remove and return a value from the map. Returns true if the * key was present in the map, otherwise false. */ - fn remove(+key: K) -> bool; + fn remove(key: K) -> bool; /// Clear the map, removing all key/value pairs. 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); + pure fn each_key(fn(key: K) -> bool); /// Iterate over all the values in the map by value - pure fn each_value(fn(+value: V) -> bool); + pure fn each_value(fn(value: V) -> bool); /// Iterate over all the key/value pairs in the map by reference pure fn each_ref(fn(key: &K, value: &V) -> bool); @@ -83,10 +78,9 @@ trait Map { } mod util { - #[legacy_exports]; - type Rational = {num: int, den: int}; // : int::positive(*.den); + pub type Rational = {num: int, den: int}; // : int::positive(*.den); - pure fn rational_leq(x: Rational, y: Rational) -> bool { + pub pure fn rational_leq(x: Rational, y: Rational) -> bool { // NB: Uses the fact that rationals have positive denominators WLOG: x.num * y.den <= y.num * x.den @@ -96,9 +90,7 @@ mod util { // FIXME (#2344): package this up and export it as a datatype usable for // external code that doesn't want to pay the cost of a box. -mod chained { - #[legacy_exports]; - export T, mk, HashMap; +pub mod chained { const initial_capacity: uint = 32u; // 2^5 @@ -114,7 +106,7 @@ mod chained { mut chains: ~[mut Option<@Entry>] } - type T = @HashMap_; + pub type T = @HashMap_; enum SearchResult { NotFound, @@ -209,7 +201,7 @@ mod chained { impl T: Map { pure fn size() -> uint { self.count } - fn contains_key(+k: K) -> bool { + fn contains_key(k: K) -> bool { self.contains_key_ref(&k) } @@ -221,7 +213,7 @@ 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 => { @@ -263,7 +255,7 @@ mod chained { } } - pure fn find(+k: K) -> Option { + pure fn find(k: K) -> Option { unsafe { match self.search_tbl(&k, k.hash_keyed(0,0) as uint) { NotFound => None, @@ -273,7 +265,7 @@ mod chained { } } - fn get(+k: K) -> V { + fn get(k: K) -> V { let opt_v = self.find(k); if opt_v.is_none() { fail fmt!("Key not found in table: %?", k); @@ -281,7 +273,7 @@ mod chained { option::unwrap(move opt_v) } - fn remove(+k: K) -> bool { + fn remove(k: K) -> bool { match self.search_tbl(&k, k.hash_keyed(0,0) as uint) { NotFound => false, FoundFirst(idx, entry) => { @@ -302,15 +294,15 @@ 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)) } - pure fn each_key(blk: fn(+key: K) -> bool) { + pure fn each_key(blk: fn(key: K) -> bool) { self.each_key_ref(|p| blk(*p)) } - pure fn each_value(blk: fn(+value: V) -> bool) { + pure fn each_value(blk: fn(value: V) -> bool) { self.each_value_ref(|p| blk(*p)) } @@ -356,7 +348,7 @@ mod chained { } impl T: ops::Index { - pure fn index(&&k: K) -> V { + pure fn index(+k: K) -> V { unsafe { self.get(k) } @@ -367,7 +359,7 @@ mod chained { vec::to_mut(vec::from_elem(nchains, None)) } - fn mk() -> T { + pub fn mk() -> T { let slf: T = @HashMap_ {count: 0u, chains: chains(initial_capacity)}; slf @@ -379,18 +371,18 @@ Function: hashmap Construct a hashmap. */ -fn HashMap() +pub fn HashMap() -> HashMap { chained::mk() } /// Convenience function for adding keys to a hashmap with nil type keys -fn set_add(set: Set, +key: K) -> bool { +pub fn set_add(set: Set, key: K) -> bool { set.insert(key, ()) } /// Convert a set into a vector. -fn vec_from_set(s: Set) -> ~[T] { +pub fn vec_from_set(s: Set) -> ~[T] { do vec::build_sized(s.size()) |push| { for s.each_key() |k| { push(k); @@ -399,12 +391,12 @@ fn vec_from_set(s: Set) -> ~[T] { } /// Construct a hashmap from a vector -fn hash_from_vec( +pub fn hash_from_vec( items: &[(K, V)]) -> HashMap { let map = HashMap(); for vec::each(items) |item| { match *item { - (key, value) => { + (copy key, copy value) => { map.insert(key, value); } } @@ -423,13 +415,13 @@ impl @Mut>: } } - fn insert(+key: K, +value: V) -> bool { + fn insert(key: K, value: V) -> bool { do self.borrow_mut |p| { p.insert(key, value) } } - fn contains_key(+key: K) -> bool { + fn contains_key(key: K) -> bool { do self.borrow_const |p| { p.contains_key(&key) } @@ -441,13 +433,13 @@ impl @Mut>: } } - fn get(+key: K) -> V { + fn get(key: K) -> V { do self.borrow_const |p| { p.get(&key) } } - pure fn find(+key: K) -> Option { + pure fn find(key: K) -> Option { unsafe { do self.borrow_const |p| { p.find(&key) @@ -455,7 +447,7 @@ impl @Mut>: } } - fn remove(+key: K) -> bool { + fn remove(key: K) -> bool { do self.borrow_mut |p| { p.remove(&key) } @@ -467,7 +459,7 @@ impl @Mut>: } } - 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)) @@ -475,7 +467,7 @@ impl @Mut>: } } - pure fn each_key(op: fn(+key: K) -> bool) { + pure fn each_key(op: fn(key: K) -> bool) { unsafe { do self.borrow_imm |p| { p.each_key(|k| op(*k)) @@ -483,7 +475,7 @@ impl @Mut>: } } - pure fn each_value(op: fn(+value: V) -> bool) { + pure fn each_value(op: fn(value: V) -> bool) { unsafe { do self.borrow_imm |p| { p.each_value(|v| op(*v)) @@ -518,7 +510,6 @@ impl @Mut>: #[cfg(test)] mod tests { - #[legacy_exports]; #[test] fn test_simple() { diff --git a/src/libstd/md4.rs b/src/libstd/md4.rs index a42723246702..581beb78bdc5 100644 --- a/src/libstd/md4.rs +++ b/src/libstd/md4.rs @@ -1,7 +1,6 @@ #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; -fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} { +pub fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} { // subtle: if orig_len is merely uint, then the code below // which performs shifts by 32 bits or more has undefined // results. @@ -11,14 +10,14 @@ fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} { let mut msg = vec::append(vec::from_slice(msg), ~[0x80u8]); let mut bitlen = orig_len + 8u64; while (bitlen + 64u64) % 512u64 > 0u64 { - vec::push(msg, 0u8); + msg.push(0u8); bitlen += 8u64; } // append length let mut i = 0u64; while i < 8u64 { - vec::push(msg, (orig_len >> (i * 8u64)) as u8); + msg.push((orig_len >> (i * 8u64)) as u8); i += 1u64; } @@ -85,7 +84,7 @@ fn md4(msg: &[u8]) -> {a: u32, b: u32, c: u32, d: u32} { return {a: a, b: b, c: c, d: d}; } -fn md4_str(msg: &[u8]) -> ~str { +pub fn md4_str(msg: &[u8]) -> ~str { let {a, b, c, d} = md4(msg); fn app(a: u32, b: u32, c: u32, d: u32, f: fn(u32)) { f(a); f(b); f(c); f(d); @@ -103,7 +102,7 @@ fn md4_str(msg: &[u8]) -> ~str { result } -fn md4_text(msg: &str) -> ~str { md4_str(str::to_bytes(msg)) } +pub fn md4_text(msg: &str) -> ~str { md4_str(str::to_bytes(msg)) } #[test] fn test_md4() { diff --git a/src/libstd/net.rs b/src/libstd/net.rs index 8665ea2e9cf5..76a5955c3e19 100644 --- a/src/libstd/net.rs +++ b/src/libstd/net.rs @@ -1,10 +1,5 @@ //! Top-level module for network-related functionality -use tcp = net_tcp; -export tcp; - -use ip = net_ip; -export ip; - -use url = net_url; -export url; \ No newline at end of file +pub use tcp = net_tcp; +pub use ip = net_ip; +pub use url = net_url; diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index 3e104e259b8e..2d9dd5bdf4e8 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -1,6 +1,5 @@ //! Types/fns concerning Internet Protocol (IP), versions 4 & 6 #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use iotask = uv::iotask::IoTask; use interact = uv::iotask::interact; @@ -21,14 +20,8 @@ use get_data_for_req = uv::ll::get_data_for_req; use ll = uv::ll; use comm = core::comm; -export IpAddr, parse_addr_err; -export format_addr; -export v4, v6; -export get_addr; -export Ipv4, Ipv6; - /// An IP address -enum IpAddr { +pub enum IpAddr { /// An IPv4 address Ipv4(sockaddr_in), Ipv6(sockaddr_in6) @@ -46,17 +39,17 @@ type ParseAddrErr = { * * * ip - a `std::net::ip::ip_addr` */ -fn format_addr(ip: &IpAddr) -> ~str { +pub fn format_addr(ip: &IpAddr) -> ~str { match *ip { - Ipv4(addr) => unsafe { - let result = uv_ip4_name(&addr); + Ipv4(ref addr) => unsafe { + let result = uv_ip4_name(addr); if result == ~"" { fail ~"failed to convert inner sockaddr_in address to str" } result }, - Ipv6(addr) => unsafe { - let result = uv_ip6_name(&addr); + Ipv6(ref addr) => unsafe { + let result = uv_ip6_name(addr); if result == ~"" { fail ~"failed to convert inner sockaddr_in address to str" } @@ -84,17 +77,17 @@ enum IpGetAddrErr { * a vector of `ip_addr` results, in the case of success, or an error * object in the case of failure */ -fn get_addr(node: &str, iotask: iotask) +pub fn get_addr(node: &str, iotask: iotask) -> result::Result<~[IpAddr], IpGetAddrErr> { do core::comm::listen |output_ch| { do str::as_buf(node) |node_ptr, len| unsafe { log(debug, fmt!("slice len %?", len)); let handle = create_uv_getaddrinfo_t(); - let handle_ptr = ptr::addr_of(handle); + let handle_ptr = ptr::addr_of(&handle); let handle_data: GetAddrData = { output_ch: output_ch }; - let handle_data_ptr = ptr::addr_of(handle_data); + let handle_data_ptr = ptr::addr_of(&handle_data); do interact(iotask) |loop_ptr| unsafe { let result = uv_getaddrinfo( loop_ptr, @@ -117,8 +110,7 @@ fn get_addr(node: &str, iotask: iotask) } } -mod v4 { - #[legacy_exports]; +pub mod v4 { /** * Convert a str to `ip_addr` * @@ -134,37 +126,37 @@ mod v4 { * * * an `ip_addr` of the `ipv4` variant */ - fn parse_addr(ip: &str) -> IpAddr { + pub fn parse_addr(ip: &str) -> IpAddr { match try_parse_addr(ip) { - result::Ok(addr) => copy(addr), - result::Err(err_data) => fail err_data.err_msg + result::Ok(copy addr) => addr, + result::Err(ref err_data) => fail err_data.err_msg } } // the simple, old style numberic representation of // ipv4 - type Ipv4Rep = { a: u8, b: u8, c: u8, d:u8 }; + pub type Ipv4Rep = { a: u8, b: u8, c: u8, d:u8 }; - trait AsUnsafeU32 { + pub trait AsUnsafeU32 { unsafe fn as_u32() -> u32; } impl Ipv4Rep: AsUnsafeU32 { // this is pretty dastardly, i know unsafe fn as_u32() -> u32 { - *((ptr::addr_of(self)) as *u32) + *((ptr::addr_of(&self)) as *u32) } } - fn parse_to_ipv4_rep(ip: &str) -> result::Result { + pub fn parse_to_ipv4_rep(ip: &str) -> result::Result { let parts = vec::map(str::split_char(ip, '.'), |s| { match uint::from_str(*s) { - Some(n) if n <= 255u => n, - _ => 256u + Some(n) if n <= 255 => n, + _ => 256 } }); - if vec::len(parts) != 4u { + if parts.len() != 4 { result::Err(fmt!("'%s' doesn't have 4 parts", ip)) } - else if vec::contains(parts, 256u) { + else if parts.contains(&256) { result::Err(fmt!("invalid octal in addr '%s'", ip)) } else { @@ -172,28 +164,28 @@ mod v4 { c: parts[2] as u8, d: parts[3] as u8}) } } - fn try_parse_addr(ip: &str) -> result::Result { + pub fn try_parse_addr(ip: &str) -> result::Result { unsafe { let INADDR_NONE = ll::get_INADDR_NONE(); let ip_rep_result = parse_to_ipv4_rep(ip); - if result::is_err(ip_rep_result) { - let err_str = result::get_err(ip_rep_result); + if result::is_err(&ip_rep_result) { + let err_str = result::get_err(&ip_rep_result); return result::Err({err_msg: err_str}) } // ipv4_rep.as_u32 is unsafe :/ let input_is_inaddr_none = - result::get(ip_rep_result).as_u32() == INADDR_NONE; + result::get(&ip_rep_result).as_u32() == INADDR_NONE; let new_addr = uv_ip4_addr(str::from_slice(ip), 22); let reformatted_name = uv_ip4_name(&new_addr); log(debug, fmt!("try_parse_addr: input ip: %s reparsed ip: %s", ip, reformatted_name)); let ref_ip_rep_result = parse_to_ipv4_rep(reformatted_name); - if result::is_err(ref_ip_rep_result) { - let err_str = result::get_err(ref_ip_rep_result); + if result::is_err(&ref_ip_rep_result) { + let err_str = result::get_err(&ref_ip_rep_result); return result::Err({err_msg: err_str}) } - if result::get(ref_ip_rep_result).as_u32() == INADDR_NONE && + if result::get(&ref_ip_rep_result).as_u32() == INADDR_NONE && !input_is_inaddr_none { return result::Err( {err_msg: ~"uv_ip4_name produced invalid result."}) @@ -204,8 +196,7 @@ mod v4 { } } } -mod v6 { - #[legacy_exports]; +pub mod v6 { /** * Convert a str to `ip_addr` * @@ -221,13 +212,13 @@ mod v6 { * * * an `ip_addr` of the `ipv6` variant */ - fn parse_addr(ip: &str) -> IpAddr { + pub fn parse_addr(ip: &str) -> IpAddr { match try_parse_addr(ip) { - result::Ok(addr) => copy(addr), - result::Err(err_data) => fail err_data.err_msg + result::Ok(copy addr) => addr, + result::Err(copy err_data) => fail err_data.err_msg } } - fn try_parse_addr(ip: &str) -> result::Result { + pub fn try_parse_addr(ip: &str) -> result::Result { unsafe { // need to figure out how to establish a parse failure.. let new_addr = uv_ip6_addr(str::from_slice(ip), 22); @@ -252,7 +243,7 @@ type GetAddrData = { }; extern fn get_addr_cb(handle: *uv_getaddrinfo_t, status: libc::c_int, - res: *addrinfo) unsafe { + res: *addrinfo) unsafe { log(debug, ~"in get_addr_cb"); let handle_data = get_data_for_req(handle) as *GetAddrData; @@ -277,7 +268,7 @@ extern fn get_addr_cb(handle: *uv_getaddrinfo_t, status: libc::c_int, result::Err(GetAddrUnknownError)); break; }; - vec::push(out_vec, move new_ip_addr); + out_vec.push(move new_ip_addr); let next_addr = ll::get_next_addrinfo(curr_addr); if next_addr == ptr::null::() as *addrinfo { @@ -312,7 +303,6 @@ extern fn get_addr_cb(handle: *uv_getaddrinfo_t, status: libc::c_int, #[cfg(test)] mod test { - #[legacy_exports]; #[test] fn test_ip_ipv4_parse_and_format_ip() { let localhost_str = ~"127.0.0.1"; @@ -330,11 +320,11 @@ mod test { #[test] fn test_ip_ipv4_bad_parse() { match v4::try_parse_addr(~"b4df00d") { - result::Err(err_info) => { + result::Err(ref err_info) => { log(debug, fmt!("got error as expected %?", err_info)); assert true; } - result::Ok(addr) => { + result::Ok(ref addr) => { fail fmt!("Expected failure, but got addr %?", addr); } } @@ -343,11 +333,11 @@ mod test { #[ignore(target_os="win32")] fn test_ip_ipv6_bad_parse() { match v6::try_parse_addr(~"::,~2234k;") { - result::Err(err_info) => { + result::Err(ref err_info) => { log(debug, fmt!("got error as expected %?", err_info)); assert true; } - result::Ok(addr) => { + result::Ok(ref addr) => { fail fmt!("Expected failure, but got addr %?", addr); } } @@ -358,7 +348,7 @@ mod test { let localhost_name = ~"localhost"; let iotask = uv::global_loop::get(); let ga_result = get_addr(localhost_name, iotask); - if result::is_err(ga_result) { + if result::is_err(&ga_result) { fail ~"got err result from net::ip::get_addr();" } // note really sure how to realiably test/assert @@ -384,6 +374,6 @@ mod test { let localhost_name = ~"sjkl234m,./sdf"; let iotask = uv::global_loop::get(); let ga_result = get_addr(localhost_name, iotask); - assert result::is_err(ga_result); + assert result::is_err(&ga_result); } } diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index a0a209eae52c..546231da6333 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -11,22 +11,8 @@ use libc::size_t; use io::{Reader, ReaderUtil, Writer}; use comm = core::comm; -// tcp interfaces -export TcpSocket; -// buffered socket -export TcpSocketBuf, socket_buf; -// errors -export TcpErrData, TcpConnectErrData; -// operations on a tcp_socket -export write, write_future, read_start, read_stop; -// tcp server stuff -export listen, accept; -// tcp client stuff -export connect; - #[nolink] extern mod rustrt { - #[legacy_exports]; fn rust_uv_current_kernel_malloc(size: libc::c_uint) -> *libc::c_void; fn rust_uv_current_kernel_free(mem: *libc::c_void); fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint; @@ -48,7 +34,7 @@ struct TcpSocket { } } -fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket { +pub fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket { TcpSocket { socket_data: socket_data } @@ -64,14 +50,14 @@ struct TcpSocketBuf { data: @TcpBufferedSocketData, } -fn TcpSocketBuf(data: @TcpBufferedSocketData) -> TcpSocketBuf { +pub fn TcpSocketBuf(data: @TcpBufferedSocketData) -> TcpSocketBuf { TcpSocketBuf { data: data } } /// Contains raw, string-based, error information returned from libuv -type TcpErrData = { +pub type TcpErrData = { err_name: ~str, err_msg: ~str }; @@ -103,7 +89,7 @@ enum TcpListenErrData { AccessDenied } /// Details returned as part of a `result::err` result from `tcp::connect` -enum TcpConnectErrData { +pub enum TcpConnectErrData { /** * Some unplanned-for error. The first and second fields correspond * to libuv's `err_name` and `err_msg` fields, respectively. @@ -129,7 +115,7 @@ enum TcpConnectErrData { * the remote host. In the event of failure, a * `net::tcp::tcp_connect_err_data` instance will be returned */ -fn connect(+input_ip: ip::IpAddr, port: uint, +pub fn connect(input_ip: ip::IpAddr, port: uint, iotask: IoTask) -> result::Result unsafe { let result_po = core::comm::Port::(); @@ -138,7 +124,7 @@ fn connect(+input_ip: ip::IpAddr, port: uint, 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 conn_data_ptr = ptr::addr_of(&conn_data); let reader_po = core::comm::Port::>(); let stream_handle_ptr = malloc_uv_tcp_t(); *(stream_handle_ptr as *mut uv::ll::uv_tcp_t) = uv::ll::tcp_t(); @@ -150,7 +136,7 @@ fn connect(+input_ip: ip::IpAddr, port: uint, write_req: uv::ll::write_t(), iotask: iotask }; - let socket_data_ptr = ptr::addr_of(*socket_data); + let socket_data_ptr = ptr::addr_of(&(*socket_data)); log(debug, fmt!("tcp_connect result_ch %?", conn_data.result_ch)); // get an unsafe representation of our stream_handle_ptr that // we can send into the interact cb to be handled in libuv.. @@ -165,10 +151,10 @@ fn connect(+input_ip: ip::IpAddr, port: uint, log(debug, ~"tcp_init successful"); log(debug, ~"dealing w/ ipv4 connection.."); let connect_req_ptr = - ptr::addr_of((*socket_data_ptr).connect_req); + ptr::addr_of(&((*socket_data_ptr).connect_req)); let addr_str = ip::format_addr(&input_ip); let connect_result = match input_ip { - ip::Ipv4(addr) => { + ip::Ipv4(ref addr) => { // have to "recreate" the sockaddr_in/6 // since the ip_addr discards the port // info.. should probably add an additional @@ -179,16 +165,16 @@ fn connect(+input_ip: ip::IpAddr, port: uint, uv::ll::tcp_connect( connect_req_ptr, stream_handle_ptr, - ptr::addr_of(in_addr), + ptr::addr_of(&in_addr), tcp_connect_on_connect_cb) } - ip::Ipv6(addr) => { + ip::Ipv6(ref addr) => { log(debug, fmt!("addr: %?", addr)); let in_addr = uv::ll::ip6_addr(addr_str, port as int); uv::ll::tcp_connect6( connect_req_ptr, stream_handle_ptr, - ptr::addr_of(in_addr), + ptr::addr_of(&in_addr), tcp_connect_on_connect_cb) } }; @@ -233,7 +219,7 @@ fn connect(+input_ip: ip::IpAddr, port: uint, log(debug, ~"tcp::connect - received success on result_po"); result::Ok(TcpSocket(socket_data)) } - ConnFailure(err_data) => { + ConnFailure(ref err_data) => { core::comm::recv(closed_signal_po); log(debug, ~"tcp::connect - received failure on result_po"); // still have to free the malloc'd stream handle.. @@ -262,9 +248,9 @@ fn connect(+input_ip: ip::IpAddr, port: uint, * A `result` object with a `nil` value as the `ok` variant, or a * `tcp_err_data` value as the `err` variant */ -fn write(sock: &TcpSocket, raw_write_data: ~[u8]) +pub fn write(sock: &TcpSocket, raw_write_data: ~[u8]) -> result::Result<(), TcpErrData> unsafe { - let socket_data_ptr = ptr::addr_of(*(sock.socket_data)); + let socket_data_ptr = ptr::addr_of(&(*(sock.socket_data))); write_common_impl(socket_data_ptr, raw_write_data) } @@ -299,9 +285,9 @@ fn write(sock: &TcpSocket, raw_write_data: ~[u8]) * `result` object with a `nil` value as the `ok` variant, or a `tcp_err_data` * value as the `err` variant */ -fn write_future(sock: &TcpSocket, raw_write_data: ~[u8]) +pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8]) -> future::Future> unsafe { - let socket_data_ptr = ptr::addr_of(*(sock.socket_data)); + let socket_data_ptr = ptr::addr_of(&(*(sock.socket_data))); do future_spawn { let data_copy = copy(raw_write_data); write_common_impl(socket_data_ptr, data_copy) @@ -323,10 +309,10 @@ fn write_future(sock: &TcpSocket, raw_write_data: ~[u8]) * optionally, loop on) from until `read_stop` is called, or a * `tcp_err_data` record */ -fn read_start(sock: &TcpSocket) +pub fn read_start(sock: &TcpSocket) -> result::Result>, TcpErrData> unsafe { - let socket_data = ptr::addr_of(*(sock.socket_data)); + let socket_data = ptr::addr_of(&(*(sock.socket_data))); read_start_common_impl(socket_data) } @@ -337,11 +323,11 @@ fn read_start(sock: &TcpSocket) * * * `sock` - a `net::tcp::tcp_socket` that you wish to stop reading on */ -fn read_stop(sock: &TcpSocket, +pub fn read_stop(sock: &TcpSocket, +read_port: comm::Port>) -> 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); + let socket_data = ptr::addr_of(&(*sock.socket_data)); read_stop_common_impl(socket_data) } @@ -362,7 +348,7 @@ fn read_stop(sock: &TcpSocket, */ fn read(sock: &TcpSocket, timeout_msecs: uint) -> result::Result<~[u8],TcpErrData> { - let socket_data = ptr::addr_of(*(sock.socket_data)); + let socket_data = ptr::addr_of(&(*(sock.socket_data))); read_common_impl(socket_data, timeout_msecs) } @@ -397,7 +383,7 @@ fn read(sock: &TcpSocket, timeout_msecs: uint) */ fn read_future(sock: &TcpSocket, timeout_msecs: uint) -> future::Future> { - let socket_data = ptr::addr_of(*(sock.socket_data)); + let socket_data = ptr::addr_of(&(*(sock.socket_data))); do future_spawn { read_common_impl(socket_data, timeout_msecs) } @@ -472,7 +458,7 @@ fn read_future(sock: &TcpSocket, timeout_msecs: uint) * this function will return a `net::tcp::tcp_err_data` record * as the `err` variant of a `result`. */ -fn accept(new_conn: TcpNewConnection) +pub fn accept(new_conn: TcpNewConnection) -> result::Result unsafe { match new_conn{ @@ -491,7 +477,7 @@ fn accept(new_conn: TcpNewConnection) write_req : uv::ll::write_t(), iotask : iotask }; - let client_socket_data_ptr = ptr::addr_of(*client_socket_data); + let client_socket_data_ptr = ptr::addr_of(&(*client_socket_data)); let client_stream_handle_ptr = (*client_socket_data_ptr).stream_handle_ptr; @@ -535,7 +521,7 @@ fn accept(new_conn: TcpNewConnection) } // UNSAFE LIBUV INTERACTION END match core::comm::recv(result_po) { - Some(err_data) => result::Err(err_data), + Some(copy err_data) => result::Err(err_data), None => result::Ok(TcpSocket(client_socket_data)) } } @@ -570,7 +556,7 @@ fn accept(new_conn: TcpNewConnection) * successful/normal shutdown, and a `tcp_listen_err_data` enum in the event * of listen exiting because of an error */ -fn listen(+host_ip: ip::IpAddr, port: uint, backlog: uint, +pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint, iotask: IoTask, +on_establish_cb: fn~(comm::Chan>), +new_connect_cb: fn~(TcpNewConnection, @@ -587,7 +573,7 @@ fn listen(+host_ip: ip::IpAddr, port: uint, backlog: uint, } } -fn listen_common(+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>), +on_connect_cb: fn~(*uv::ll::uv_tcp_t)) @@ -596,7 +582,7 @@ fn listen_common(+host_ip: ip::IpAddr, port: uint, backlog: uint, let kill_po = core::comm::Port::>(); 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_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), @@ -605,7 +591,7 @@ fn listen_common(+host_ip: ip::IpAddr, port: uint, backlog: uint, iotask: iotask, mut active: true }; - let server_data_ptr = ptr::addr_of(server_data); + let server_data_ptr = ptr::addr_of(&server_data); let setup_result = do core::comm::listen |setup_ch| { // this is to address a compiler warning about @@ -623,17 +609,17 @@ fn listen_common(+host_ip: ip::IpAddr, port: uint, backlog: uint, server_data_ptr); let addr_str = ip::format_addr(&loc_ip); let bind_result = match loc_ip { - ip::Ipv4(addr) => { + ip::Ipv4(ref addr) => { log(debug, fmt!("addr: %?", addr)); let in_addr = uv::ll::ip4_addr(addr_str, port as int); uv::ll::tcp_bind(server_stream_ptr, - ptr::addr_of(in_addr)) + ptr::addr_of(&in_addr)) } - ip::Ipv6(addr) => { + ip::Ipv6(ref addr) => { log(debug, fmt!("addr: %?", addr)); let in_addr = uv::ll::ip6_addr(addr_str, port as int); uv::ll::tcp_bind6(server_stream_ptr, - ptr::addr_of(in_addr)) + ptr::addr_of(&in_addr)) } }; match bind_result { @@ -666,7 +652,7 @@ fn listen_common(+host_ip: ip::IpAddr, port: uint, backlog: uint, setup_ch.recv() }; match setup_result { - Some(err_data) => { + Some(ref err_data) => { do iotask::interact(iotask) |loop_ptr| unsafe { log(debug, fmt!("tcp::listen post-kill recv hl interact %?", loop_ptr)); @@ -703,8 +689,9 @@ fn listen_common(+host_ip: ip::IpAddr, port: uint, backlog: uint, stream_closed_po.recv(); match kill_result { // some failure post bind/listen - Some(err_data) => result::Err(GenericListenErr(err_data.err_name, - err_data.err_msg)), + Some(ref err_data) => result::Err(GenericListenErr( + err_data.err_name, + err_data.err_msg)), // clean exit None => result::Ok(()) } @@ -727,17 +714,17 @@ fn listen_common(+host_ip: ip::IpAddr, port: uint, backlog: uint, * * A buffered wrapper that you can cast as an `io::reader` or `io::writer` */ -fn socket_buf(+sock: TcpSocket) -> TcpSocketBuf { +pub fn socket_buf(sock: TcpSocket) -> TcpSocketBuf { TcpSocketBuf(@{ sock: move sock, mut buf: ~[] }) } /// Convenience methods extending `net::tcp::tcp_socket` impl TcpSocket { - fn read_start() -> result::Result result::Result>, TcpErrData> { read_start(&self) } - fn read_stop(-read_port: + pub fn read_stop(read_port: comm::Port>) -> result::Result<(), TcpErrData> { read_stop(&self, move read_port) @@ -750,11 +737,11 @@ impl TcpSocket { future::Future> { read_future(&self, timeout_msecs) } - fn write(raw_write_data: ~[u8]) + pub fn write(raw_write_data: ~[u8]) -> result::Result<(), TcpErrData> { write(&self, raw_write_data) } - fn write_future(raw_write_data: ~[u8]) + pub fn write_future(raw_write_data: ~[u8]) -> future::Future> { write_future(&self, raw_write_data) } @@ -762,7 +749,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); @@ -779,7 +766,7 @@ impl TcpSocketBuf: io::Reader { } } else { - vec::push_all(self.data.buf, result::unwrap(read_result)); + self.data.buf.push_all(result::unwrap(read_result)); } } @@ -790,7 +777,7 @@ impl TcpSocketBuf: io::Reader { vec::bytes::memcpy(buf, vec::view(data, 0, data.len()), count); - vec::push_all(self.data.buf, vec::view(data, count, data.len())); + self.data.buf.push_all(vec::view(data, count, data.len())); count } @@ -798,13 +785,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) { - vec::unshift((*(self.data)).buf, amt as u8); + 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 } @@ -815,9 +802,9 @@ impl TcpSocketBuf: io::Reader { /// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket` impl TcpSocketBuf: io::Writer { - fn write(data: &[const u8]) unsafe { + pub fn write(data: &[const u8]) unsafe { let socket_data_ptr = - ptr::addr_of(*((*(self.data)).sock).socket_data); + ptr::addr_of(&(*((*(self.data)).sock).socket_data)); let w_result = write_common_impl(socket_data_ptr, vec::slice(data, 0, vec::len(data))); if w_result.is_err() { @@ -826,7 +813,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 } @@ -849,7 +836,7 @@ fn tear_down_socket_data(socket_data: @TcpSocketData) unsafe { let close_data = { closed_ch: closed_ch }; - let close_data_ptr = ptr::addr_of(close_data); + let close_data_ptr = ptr::addr_of(&close_data); let stream_handle_ptr = (*socket_data).stream_handle_ptr; do iotask::interact((*socket_data).iotask) |loop_ptr| unsafe { log(debug, fmt!("interact dtor for tcp_socket stream %? loop %?", @@ -871,20 +858,20 @@ fn read_common_impl(socket_data: *TcpSocketData, timeout_msecs: uint) log(debug, ~"starting tcp::read"); let iotask = (*socket_data).iotask; let rs_result = read_start_common_impl(socket_data); - if result::is_err(rs_result) { - let err_data = result::get_err(rs_result); + if result::is_err(&rs_result) { + let err_data = result::get_err(&rs_result); result::Err(err_data) } else { log(debug, ~"tcp::read before recv_timeout"); let read_result = if timeout_msecs > 0u { timer::recv_timeout( - iotask, timeout_msecs, result::get(rs_result)) + iotask, timeout_msecs, result::get(&rs_result)) } else { - Some(core::comm::recv(result::get(rs_result))) + Some(core::comm::recv(result::get(&rs_result))) }; log(debug, ~"tcp::read after recv_timeout"); - match read_result { + match move read_result { None => { log(debug, ~"tcp::read: timed out.."); let err_data = { @@ -894,7 +881,7 @@ fn read_common_impl(socket_data: *TcpSocketData, timeout_msecs: uint) read_stop_common_impl(socket_data); result::Err(err_data) } - Some(data_result) => { + Some(move data_result) => { log(debug, ~"tcp::read got data"); read_stop_common_impl(socket_data); data_result @@ -924,7 +911,7 @@ fn read_stop_common_impl(socket_data: *TcpSocketData) -> } }; match core::comm::recv(stop_po) { - Some(err_data) => result::Err(err_data.to_tcp_err()), + Some(ref err_data) => result::Err(err_data.to_tcp_err()), None => result::Ok(()) } } @@ -954,7 +941,7 @@ fn read_start_common_impl(socket_data: *TcpSocketData) } }; match core::comm::recv(start_po) { - Some(err_data) => result::Err(err_data.to_tcp_err()), + Some(ref err_data) => result::Err(err_data.to_tcp_err()), None => result::Ok((*socket_data).reader_po) } } @@ -965,18 +952,18 @@ fn read_start_common_impl(socket_data: *TcpSocketData) fn write_common_impl(socket_data_ptr: *TcpSocketData, raw_write_data: ~[u8]) -> result::Result<(), TcpErrData> unsafe { - let write_req_ptr = ptr::addr_of((*socket_data_ptr).write_req); + let write_req_ptr = ptr::addr_of(&((*socket_data_ptr).write_req)); let stream_handle_ptr = (*socket_data_ptr).stream_handle_ptr; let write_buf_vec = ~[ uv::ll::buf_init( vec::raw::to_ptr(raw_write_data), vec::len(raw_write_data)) ]; - let write_buf_vec_ptr = ptr::addr_of(write_buf_vec); + let write_buf_vec_ptr = ptr::addr_of(&write_buf_vec); let result_po = core::comm::Port::(); let write_data = { result_ch: core::comm::Chan(result_po) }; - let write_data_ptr = ptr::addr_of(write_data); + let write_data_ptr = ptr::addr_of(&write_data); do iotask::interact((*socket_data_ptr).iotask) |loop_ptr| unsafe { log(debug, fmt!("in interact cb for tcp::write %?", loop_ptr)); match uv::ll::write(write_req_ptr, @@ -1001,7 +988,7 @@ fn write_common_impl(socket_data_ptr: *TcpSocketData, // aftermath, so we don't have to sit here blocking. match core::comm::recv(result_po) { TcpWriteSuccess => result::Ok(()), - TcpWriteError(err_data) => result::Err(err_data.to_tcp_err()) + TcpWriteError(ref err_data) => result::Err(err_data.to_tcp_err()) } } @@ -1223,16 +1210,13 @@ type TcpBufferedSocketData = { //#[cfg(test)] mod test { - #[legacy_exports]; // FIXME don't run on fbsd or linux 32 bit (#2064) #[cfg(target_os="win32")] #[cfg(target_os="darwin")] #[cfg(target_os="linux")] mod tcp_ipv4_server_and_client_test { - #[legacy_exports]; #[cfg(target_arch="x86_64")] mod impl64 { - #[legacy_exports]; #[test] fn test_gl_tcp_server_and_client_ipv4() unsafe { impl_gl_tcp_ipv4_server_and_client(); @@ -1257,7 +1241,6 @@ mod test { } #[cfg(target_arch="x86")] mod impl32 { - #[legacy_exports]; #[test] #[ignore(cfg(target_os = "linux"))] fn test_gl_tcp_server_and_client_ipv4() unsafe { @@ -1475,7 +1458,7 @@ mod test { */ } - fn buf_write(+w: &W, val: &str) { + fn buf_write(w: &W, val: &str) { log(debug, fmt!("BUF_WRITE: val len %?", str::len(val))); do str::byte_slice(val) |b_slice| { log(debug, fmt!("BUF_WRITE: b_slice len %?", @@ -1484,7 +1467,7 @@ mod test { } } - fn buf_read(+r: &R, len: uint) -> ~str { + fn buf_read(r: &R, len: uint) -> ~str { let new_bytes = (*r).read_bytes(len); log(debug, fmt!("in buf_read.. new_bytes len: %?", vec::len(new_bytes))); @@ -1514,9 +1497,9 @@ mod test { let accept_result = accept(new_conn); log(debug, ~"SERVER: after accept()"); - if result::is_err(accept_result) { + if result::is_err(&accept_result) { log(debug, ~"SERVER: error accept connection"); - let err_data = result::get_err(accept_result); + let err_data = result::get_err(&accept_result); core::comm::send(kill_ch, Some(err_data)); log(debug, ~"SERVER/WORKER: send on err cont ch"); @@ -1530,8 +1513,8 @@ mod test { log(debug, ~"SERVER: successfully accepted"+ ~"connection!"); let received_req_bytes = read(&sock, 0u); - match received_req_bytes { - result::Ok(data) => { + match move received_req_bytes { + result::Ok(move data) => { log(debug, ~"SERVER: got REQ str::from_bytes.."); log(debug, fmt!("SERVER: REQ data len: %?", vec::len(data))); @@ -1542,7 +1525,7 @@ mod test { log(debug, ~"SERVER: after write.. die"); core::comm::send(kill_ch, None); } - result::Err(err_data) => { + result::Err(move err_data) => { log(debug, fmt!("SERVER: error recvd: %s %s", err_data.err_name, err_data.err_msg)); core::comm::send(kill_ch, Some(err_data)); @@ -1558,11 +1541,11 @@ mod test { log(debug, ~"SERVER: recv'd on cont_ch..leaving listen cb"); }); // err check on listen_result - if result::is_err(listen_result) { - match result::get_err(listen_result) { - GenericListenErr(name, msg) => { + if result::is_err(&listen_result) { + match result::get_err(&listen_result) { + GenericListenErr(ref name, ref msg) => { fail fmt!("SERVER: exited abnormally name %s msg %s", - name, msg); + *name, *msg); } AccessDenied => { fail ~"SERVER: exited abnormally, got access denied.."; @@ -1592,8 +1575,8 @@ mod test { new_conn, kill_ch); }); // err check on listen_result - if result::is_err(listen_result) { - result::get_err(listen_result) + if result::is_err(&listen_result) { + result::get_err(&listen_result) } else { fail ~"SERVER: did not fail as expected" @@ -1609,9 +1592,9 @@ mod test { log(debug, ~"CLIENT: starting.."); let connect_result = connect(move server_ip_addr, server_port, iotask); - if result::is_err(connect_result) { + if result::is_err(&connect_result) { log(debug, ~"CLIENT: failed to connect"); - let err_data = result::get_err(connect_result); + let err_data = result::get_err(&connect_result); Err(err_data) } else { @@ -1636,9 +1619,9 @@ mod test { fn tcp_write_single(sock: &TcpSocket, val: ~[u8]) { let write_result_future = sock.write_future(val); let write_result = write_result_future.get(); - if result::is_err(write_result) { + if result::is_err(&write_result) { log(debug, ~"tcp_write_single: write failed!"); - let err_data = result::get_err(write_result); + let err_data = result::get_err(&write_result); log(debug, fmt!("tcp_write_single err name: %s msg: %s", err_data.err_name, err_data.err_msg)); // meh. torn on what to do here. diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index 74c603e29e91..40c9f96f5e84 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -1,6 +1,5 @@ //! Types/fns concerning URLs (see RFC 3986) -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after a snapshot use core::cmp::Eq; use map::HashMap; @@ -11,15 +10,6 @@ use result::{Err, Ok}; use to_str::ToStr; use to_bytes::IterBytes; -export Url, Query; -export from_str, to_str; -export get_scheme; -export query_to_str; - -export encode, decode; -export encode_component, decode_component; -export encode_form_urlencoded, decode_form_urlencoded; - struct Url { scheme: ~str, user: Option, @@ -35,9 +25,9 @@ type UserInfo = { pass: Option<~str> }; -type Query = ~[(~str, ~str)]; +pub type Query = ~[(~str, ~str)]; -fn Url(+scheme: ~str, +user: Option, +host: ~str, +pub fn Url(scheme: ~str, +user: Option, +host: ~str, +port: Option<~str>, +path: ~str, +query: Query, +fragment: Option<~str>) -> Url { Url { scheme: move scheme, user: move user, host: move host, @@ -45,7 +35,7 @@ fn Url(+scheme: ~str, +user: Option, +host: ~str, 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} } @@ -94,7 +84,7 @@ fn encode_inner(s: &str, full_url: bool) -> ~str { * * This function is compliant with RFC 3986. */ -fn encode(s: &str) -> ~str { +pub fn encode(s: &str) -> ~str { encode_inner(s, true) } @@ -104,7 +94,7 @@ fn encode(s: &str) -> ~str { * * This function is compliant with RFC 3986. */ -fn encode_component(s: &str) -> ~str { +pub fn encode_component(s: &str) -> ~str { encode_inner(s, false) } @@ -151,14 +141,14 @@ fn decode_inner(s: &str, full_url: bool) -> ~str { * * This will only decode escape sequences generated by encode_uri. */ -fn decode(s: &str) -> ~str { +pub fn decode(s: &str) -> ~str { decode_inner(s, true) } /** * Decode a string encoded with percent encoding. */ -fn decode_component(s: &str) -> ~str { +pub fn decode_component(s: &str) -> ~str { decode_inner(s, false) } @@ -184,7 +174,7 @@ fn encode_plus(s: &str) -> ~str { /** * Encode a hashmap to the 'application/x-www-form-urlencoded' media type. */ -fn encode_form_urlencoded(m: HashMap<~str, @DVec<@~str>>) -> ~str { +pub fn encode_form_urlencoded(m: HashMap<~str, @DVec<@~str>>) -> ~str { let mut out = ~""; let mut first = true; @@ -210,7 +200,7 @@ fn encode_form_urlencoded(m: HashMap<~str, @DVec<@~str>>) -> ~str { * Decode a string encoded with the 'application/x-www-form-urlencoded' media * type into a hashmap. */ -fn decode_form_urlencoded(s: ~[u8]) -> +pub fn decode_form_urlencoded(s: ~[u8]) -> map::HashMap<~str, @dvec::DVec<@~str>> { do io::with_bytes_reader(s) |rdr| { let m = HashMap(); @@ -307,7 +297,7 @@ fn userinfo_from_str(uinfo: &str) -> UserInfo { return UserInfo(user, pass); } -fn userinfo_to_str(+userinfo: UserInfo) -> ~str { +fn userinfo_to_str(userinfo: UserInfo) -> ~str { if option::is_some(&userinfo.pass) { return str::concat(~[copy userinfo.user, ~":", option::unwrap(copy userinfo.pass), @@ -329,13 +319,13 @@ fn query_from_str(rawquery: &str) -> Query { if str::len(rawquery) != 0 { for str::split_char(rawquery, '&').each |p| { let (k, v) = split_char_first(*p, '='); - vec::push(query, (decode_component(k), decode_component(v))); + query.push((decode_component(k), decode_component(v))); }; } return query; } -fn query_to_str(+query: Query) -> ~str { +pub fn query_to_str(query: Query) -> ~str { let mut strvec = ~[]; for query.each |kv| { let (k, v) = copy *kv; @@ -345,7 +335,7 @@ fn query_to_str(+query: Query) -> ~str { } // returns the scheme and the rest of the url, or a parsing error -fn get_scheme(rawurl: &str) -> result::Result<(~str, ~str), @~str> { +pub fn get_scheme(rawurl: &str) -> result::Result<(~str, ~str), @~str> { for str::each_chari(rawurl) |i,c| { match c { 'A' .. 'Z' | 'a' .. 'z' => loop, @@ -524,7 +514,7 @@ fn get_authority(rawurl: &str) -> let host_is_end_plus_one: &fn() -> bool = || { end+1 == len - && !['?', '#', '/'].contains(rawurl[end] as char) + && !['?', '#', '/'].contains(&(rawurl[end] as char)) }; // finish up @@ -624,33 +614,33 @@ fn get_query_fragment(rawurl: &str) -> * */ -fn from_str(rawurl: &str) -> result::Result { +pub fn from_str(rawurl: &str) -> result::Result { // scheme let mut schm = get_scheme(rawurl); - if result::is_err(schm) { - return result::Err(copy *result::get_err(schm)); + if result::is_err(&schm) { + return result::Err(copy *result::get_err(&schm)); } let (scheme, rest) = result::unwrap(schm); // authority let mut auth = get_authority(rest); - if result::is_err(auth) { - return result::Err(copy *result::get_err(auth)); + if result::is_err(&auth) { + return result::Err(copy *result::get_err(&auth)); } let (userinfo, host, port, rest) = result::unwrap(auth); // path let has_authority = if host == ~"" { false } else { true }; let mut pth = get_path(rest, has_authority); - if result::is_err(pth) { - return result::Err(copy *result::get_err(pth)); + if result::is_err(&pth) { + return result::Err(copy *result::get_err(&pth)); } let (path, rest) = result::unwrap(pth); // query and fragment let mut qry = get_query_fragment(rest); - if result::is_err(qry) { - return result::Err(copy *result::get_err(qry)); + if result::is_err(&qry) { + return result::Err(copy *result::get_err(&qry)); } let (query, fragment) = result::unwrap(qry); @@ -661,7 +651,7 @@ fn from_str(rawurl: &str) -> result::Result { impl Url : FromStr { static fn from_str(s: &str) -> Option { match from_str(s) { - Ok(url) => Some(url), + Ok(move url) => Some(url), Err(_) => None } } @@ -682,7 +672,7 @@ impl Url : FromStr { * result in just "http://somehost.com". * */ -fn to_str(+url: Url) -> ~str { +pub fn to_str(url: Url) -> ~str { let user = if url.user.is_some() { userinfo_to_str(option::unwrap(copy url.user)) } else { @@ -714,7 +704,7 @@ fn to_str(+url: Url) -> ~str { } impl Url: to_str::ToStr { - fn to_str() -> ~str { + pub fn to_str() -> ~str { to_str(self) } } @@ -736,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) } } @@ -796,13 +786,13 @@ mod tests { assert p == option::Some(~"8000"); // invalid authorities; - assert result::is_err(get_authority( + assert result::is_err(&get_authority( ~"//user:pass@rust-lang:something")); - assert result::is_err(get_authority( + assert result::is_err(&get_authority( ~"//user@rust-lang:something:/path")); - assert result::is_err(get_authority( + assert result::is_err(&get_authority( ~"//2001:0db8:85a3:0042:0000:8a2e:0370:7334:800a")); - assert result::is_err(get_authority( + assert result::is_err(&get_authority( ~"//2001:0db8:85a3:0042:0000:8a2e:0370:7334:8000:00")); // these parse as empty, because they don't start with '//' @@ -830,7 +820,7 @@ mod tests { assert r == ~"?q=v"; //failure cases - assert result::is_err(get_path(~"something?q", true)); + assert result::is_err(&get_path(~"something?q", true)); } @@ -877,13 +867,13 @@ mod tests { #[test] fn test_no_scheme() { - assert result::is_err(get_scheme(~"noschemehere.html")); + assert result::is_err(&get_scheme(~"noschemehere.html")); } #[test] fn test_invalid_scheme_errors() { - assert result::is_err(from_str(~"99://something")); - assert result::is_err(from_str(~"://something")); + assert result::is_err(&from_str(~"99://something")); + assert result::is_err(&from_str(~"://something")); } #[test] diff --git a/src/libstd/par.rs b/src/libstd/par.rs index 38a814b22e04..65e41dba5d83 100644 --- a/src/libstd/par.rs +++ b/src/libstd/par.rs @@ -1,6 +1,5 @@ use future_spawn = future::spawn; -export map, mapi, alli, any, mapi_factory; /** * The maximum number of tasks this module will spawn for a single @@ -55,7 +54,7 @@ fn map_slices( f(base, slice) } }; - vec::push(futures, move f); + futures.push(move f); }; base += items_per_task; } @@ -73,21 +72,21 @@ fn map_slices( } /// A parallel version of map. -fn map(xs: ~[A], f: fn~(A) -> B) -> ~[B] { +pub fn map(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)) + vec::map(slice, |x| f(x)) } })) } /// A parallel version of mapi. -fn mapi(xs: ~[A], - f: fn~(uint, A) -> B) -> ~[B] { +pub fn mapi(xs: &[A], + +f: fn~(uint, (&A)) -> B) -> ~[B] { let slices = map_slices(xs, || { fn~(base: uint, slice : &[A], copy f) -> ~[B] { vec::mapi(slice, |i, x| { - f(i + base, *x) + f(i + base, x) }) } }); @@ -103,7 +102,7 @@ fn mapi(xs: ~[A], * In this case, f is a function that creates functions to run over the * inner elements. This is to skirt the need for copy constructors. */ -fn mapi_factory( +pub fn mapi_factory( xs: &[A], f: fn() -> fn~(uint, A) -> B) -> ~[B] { let slices = map_slices(xs, || { let f = f(); @@ -120,21 +119,21 @@ fn mapi_factory( } /// Returns true if the function holds for all elements in the vector. -fn alli(xs: ~[A], f: fn~(uint, A) -> bool) -> bool { +pub fn alli(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| { f(i + base, x) }) } - })) |x| { x } + })) |x| { *x } } /// Returns true if the function holds for any elements in the vector. -fn any(xs: ~[A], f: fn~(A) -> bool) -> bool { +pub fn any(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)) } - })) |x| { x } + })) |x| { *x } } diff --git a/src/libstd/prettyprint.rs b/src/libstd/prettyprint.rs index fa4c41dfa136..bc528800666d 100644 --- a/src/libstd/prettyprint.rs +++ b/src/libstd/prettyprint.rs @@ -1,5 +1,4 @@ #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use io::Writer; use io::WriterUtil; diff --git a/src/libstd/prettyprint2.rs b/src/libstd/prettyprint2.rs new file mode 100644 index 000000000000..87af519eb123 --- /dev/null +++ b/src/libstd/prettyprint2.rs @@ -0,0 +1,176 @@ +#[forbid(deprecated_mode)]; + +use io::Writer; +use io::WriterUtil; +use serialization2; + +pub struct Serializer { + wr: io::Writer, +} + +pub fn Serializer(wr: io::Writer) -> Serializer { + Serializer { wr: wr } +} + +pub impl Serializer: serialization2::Serializer { + fn emit_nil(&self) { + self.wr.write_str(~"()") + } + + fn emit_uint(&self, v: uint) { + self.wr.write_str(fmt!("%?u", v)); + } + + fn emit_u64(&self, v: u64) { + self.wr.write_str(fmt!("%?_u64", v)); + } + + fn emit_u32(&self, v: u32) { + self.wr.write_str(fmt!("%?_u32", v)); + } + + fn emit_u16(&self, v: u16) { + self.wr.write_str(fmt!("%?_u16", v)); + } + + fn emit_u8(&self, v: u8) { + self.wr.write_str(fmt!("%?_u8", v)); + } + + fn emit_int(&self, v: int) { + self.wr.write_str(fmt!("%?", v)); + } + + fn emit_i64(&self, v: i64) { + self.wr.write_str(fmt!("%?_i64", v)); + } + + fn emit_i32(&self, v: i32) { + self.wr.write_str(fmt!("%?_i32", v)); + } + + fn emit_i16(&self, v: i16) { + self.wr.write_str(fmt!("%?_i16", v)); + } + + fn emit_i8(&self, v: i8) { + self.wr.write_str(fmt!("%?_i8", v)); + } + + fn emit_bool(&self, v: bool) { + self.wr.write_str(fmt!("%b", v)); + } + + fn emit_float(&self, v: float) { + self.wr.write_str(fmt!("%?_f", v)); + } + + fn emit_f64(&self, v: f64) { + self.wr.write_str(fmt!("%?_f64", v)); + } + + fn emit_f32(&self, v: f32) { + self.wr.write_str(fmt!("%?_f32", v)); + } + + fn emit_char(&self, v: char) { + self.wr.write_str(fmt!("%?", v)); + } + + fn emit_borrowed_str(&self, v: &str) { + self.wr.write_str(fmt!("&%?", v)); + } + + fn emit_owned_str(&self, v: &str) { + self.wr.write_str(fmt!("~%?", v)); + } + + fn emit_managed_str(&self, v: &str) { + self.wr.write_str(fmt!("@%?", v)); + } + + fn emit_borrowed(&self, f: fn()) { + self.wr.write_str(~"&"); + f(); + } + + fn emit_owned(&self, f: fn()) { + self.wr.write_str(~"~"); + f(); + } + + fn emit_managed(&self, f: fn()) { + self.wr.write_str(~"@"); + f(); + } + + fn emit_enum(&self, _name: &str, f: fn()) { + f(); + } + + fn emit_enum_variant(&self, v_name: &str, _v_id: uint, sz: uint, + f: fn()) { + self.wr.write_str(v_name); + if sz > 0u { self.wr.write_str(~"("); } + f(); + if sz > 0u { self.wr.write_str(~")"); } + } + + fn emit_enum_variant_arg(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } + f(); + } + + fn emit_borrowed_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"&["); + f(); + self.wr.write_str(~"]"); + } + + fn emit_owned_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"~["); + f(); + self.wr.write_str(~"]"); + } + + fn emit_managed_vec(&self, _len: uint, f: fn()) { + self.wr.write_str(~"@["); + f(); + self.wr.write_str(~"]"); + } + + fn emit_vec_elt(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } + f(); + } + + fn emit_rec(&self, f: fn()) { + self.wr.write_str(~"{"); + f(); + self.wr.write_str(~"}"); + } + + fn emit_struct(&self, name: &str, f: fn()) { + self.wr.write_str(fmt!("%s {", name)); + f(); + self.wr.write_str(~"}"); + } + + fn emit_field(&self, name: &str, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } + self.wr.write_str(name); + self.wr.write_str(~": "); + f(); + } + + fn emit_tup(&self, _len: uint, f: fn()) { + self.wr.write_str(~"("); + f(); + self.wr.write_str(~")"); + } + + fn emit_tup_elt(&self, idx: uint, f: fn()) { + if idx > 0u { self.wr.write_str(~", "); } + f(); + } +} diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index 2d49ede3507f..5df4fc10a036 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -24,17 +24,16 @@ */ #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; /// The type of ropes. -type Rope = node::Root; +pub type Rope = node::Root; /* Section: Creating a rope */ /// Create an empty rope -fn empty() -> Rope { +pub fn empty() -> Rope { return node::Empty; } @@ -55,7 +54,7 @@ fn empty() -> Rope { * * this operation does not copy the string; * * the function runs in linear time. */ -fn of_str(str: @~str) -> Rope { +pub fn of_str(str: @~str) -> Rope { return of_substr(str, 0u, str::len(*str)); } @@ -81,7 +80,7 @@ fn of_str(str: @~str) -> Rope { * * this function does _not_ check the validity of the substring; * * this function fails if `byte_offset` or `byte_len` do not match `str`. */ -fn of_substr(str: @~str, byte_offset: uint, byte_len: uint) -> Rope { +pub fn of_substr(str: @~str, byte_offset: uint, byte_len: uint) -> Rope { if byte_len == 0u { return node::Empty; } if byte_offset + byte_len > str::len(*str) { fail; } return node::Content(node::of_substr(str, byte_offset, byte_len)); @@ -98,7 +97,7 @@ Section: Adding things to a rope * * * this function executes in near-constant time */ -fn append_char(rope: Rope, char: char) -> Rope { +pub fn append_char(rope: Rope, char: char) -> Rope { return append_str(rope, @str::from_chars(~[char])); } @@ -109,7 +108,7 @@ fn append_char(rope: Rope, char: char) -> Rope { * * * this function executes in near-linear time */ -fn append_str(rope: Rope, str: @~str) -> Rope { +pub fn append_str(rope: Rope, str: @~str) -> Rope { return append_rope(rope, of_str(str)) } @@ -119,7 +118,7 @@ fn append_str(rope: Rope, str: @~str) -> Rope { * # Performance note * * this function executes in near-constant time */ -fn prepend_char(rope: Rope, char: char) -> Rope { +pub fn prepend_char(rope: Rope, char: char) -> Rope { return prepend_str(rope, @str::from_chars(~[char])); } @@ -129,12 +128,12 @@ fn prepend_char(rope: Rope, char: char) -> Rope { * # Performance note * * this function executes in near-linear time */ -fn prepend_str(rope: Rope, str: @~str) -> Rope { +pub fn prepend_str(rope: Rope, str: @~str) -> Rope { return append_rope(of_str(str), rope) } /// Concatenate two ropes -fn append_rope(left: Rope, right: Rope) -> Rope { +pub fn append_rope(left: Rope, right: Rope) -> Rope { match (left) { node::Empty => return right, node::Content(left_content) => { @@ -155,7 +154,7 @@ fn append_rope(left: Rope, right: Rope) -> Rope { * rope remains balanced. However, this function does not take any further * measure to ensure that the result is balanced. */ -fn concat(v: ~[Rope]) -> Rope { +pub fn concat(v: ~[Rope]) -> Rope { //Copy `v` into a mut vector let mut len = vec::len(v); if len == 0u { return node::Empty; } @@ -198,7 +197,7 @@ Section: Keeping ropes healthy * If you perform numerous rope concatenations, it is generally a good idea * to rebalance your rope at some point, before using it for other purposes. */ -fn bal(rope:Rope) -> Rope { +pub fn bal(rope:Rope) -> Rope { match (rope) { node::Empty => return rope, node::Content(x) => match (node::bal(x)) { @@ -226,7 +225,7 @@ Section: Transforming ropes * * this function fails if char_offset/char_len do not represent * valid positions in rope */ -fn sub_chars(rope: Rope, char_offset: uint, char_len: uint) -> Rope { +pub fn sub_chars(rope: Rope, char_offset: uint, char_len: uint) -> Rope { if char_len == 0u { return node::Empty; } match (rope) { node::Empty => fail, @@ -251,7 +250,7 @@ fn sub_chars(rope: Rope, char_offset: uint, char_len: uint) -> Rope { * * this function fails if byte_offset/byte_len do not represent * valid positions in rope */ -fn sub_bytes(rope: Rope, byte_offset: uint, byte_len: uint) -> Rope { +pub fn sub_bytes(rope: Rope, byte_offset: uint, byte_len: uint) -> Rope { if byte_len == 0u { return node::Empty; } match (rope) { node::Empty => fail, @@ -277,7 +276,7 @@ Section: Comparing ropes * A negative value if `left < right`, 0 if eq(left, right) or a positive * value if `left > right` */ -fn cmp(left: Rope, right: Rope) -> int { +pub fn cmp(left: Rope, right: Rope) -> int { match ((left, right)) { (node::Empty, node::Empty) => return 0, (node::Empty, _) => return -1, @@ -292,7 +291,7 @@ fn cmp(left: Rope, right: Rope) -> int { * Returns `true` if both ropes have the same content (regardless of * their structure), `false` otherwise */ -fn eq(left: Rope, right: Rope) -> bool { +pub fn eq(left: Rope, right: Rope) -> bool { return cmp(left, right) == 0; } @@ -307,7 +306,7 @@ fn eq(left: Rope, right: Rope) -> bool { * `true` if `left <= right` in lexicographical order (regardless of their * structure), `false` otherwise */ -fn le(left: Rope, right: Rope) -> bool { +pub fn le(left: Rope, right: Rope) -> bool { return cmp(left, right) <= 0; } @@ -322,7 +321,7 @@ fn le(left: Rope, right: Rope) -> bool { * `true` if `left < right` in lexicographical order (regardless of their * structure), `false` otherwise */ -fn lt(left: Rope, right: Rope) -> bool { +pub fn lt(left: Rope, right: Rope) -> bool { return cmp(left, right) < 0; } @@ -337,7 +336,7 @@ fn lt(left: Rope, right: Rope) -> bool { * `true` if `left >= right` in lexicographical order (regardless of their * structure), `false` otherwise */ -fn ge(left: Rope, right: Rope) -> bool { +pub fn ge(left: Rope, right: Rope) -> bool { return cmp(left, right) >= 0; } @@ -352,7 +351,7 @@ fn ge(left: Rope, right: Rope) -> bool { * `true` if `left > right` in lexicographical order (regardless of their * structure), `false` otherwise */ -fn gt(left: Rope, right: Rope) -> bool { +pub fn gt(left: Rope, right: Rope) -> bool { return cmp(left, right) > 0; } @@ -380,7 +379,7 @@ Section: Iterating * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -fn loop_chars(rope: Rope, it: fn(char) -> bool) -> bool { +pub fn loop_chars(rope: Rope, it: fn(c: char) -> bool) -> bool { match (rope) { node::Empty => return true, node::Content(x) => return node::loop_chars(x, it) @@ -394,7 +393,7 @@ fn loop_chars(rope: Rope, it: fn(char) -> bool) -> bool { * * rope - A rope to traverse. It may be empty * * it - A block to execute with each consecutive character of the rope. */ -fn iter_chars(rope: Rope, it: fn(char)) { +pub fn iter_chars(rope: Rope, it: fn(char)) { do loop_chars(rope) |x| { it(x); true @@ -423,36 +422,33 @@ fn iter_chars(rope: Rope, it: fn(char)) { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ -fn loop_leaves(rope: Rope, it: fn(node::Leaf) -> bool) -> bool{ +pub fn loop_leaves(rope: Rope, it: fn(node::Leaf) -> bool) -> bool{ match (rope) { node::Empty => return true, node::Content(x) => return node::loop_leaves(x, it) } } -mod iterator { - #[legacy_exports]; - mod leaf { - #[legacy_exports]; - fn start(rope: Rope) -> node::leaf_iterator::T { +pub mod iterator { + pub mod leaf { + pub fn start(rope: Rope) -> node::leaf_iterator::T { match (rope) { node::Empty => return node::leaf_iterator::empty(), node::Content(x) => return node::leaf_iterator::start(x) } } - fn next(it: &node::leaf_iterator::T) -> Option { + pub fn next(it: &node::leaf_iterator::T) -> Option { return node::leaf_iterator::next(it); } } - mod char { - #[legacy_exports]; - fn start(rope: Rope) -> node::char_iterator::T { + pub mod char { + pub fn start(rope: Rope) -> node::char_iterator::T { match (rope) { node::Empty => return node::char_iterator::empty(), node::Content(x) => return node::char_iterator::start(x) } } - fn next(it: &node::char_iterator::T) -> Option { + pub fn next(it: &node::char_iterator::T) -> Option { return node::char_iterator::next(it) } } @@ -473,7 +469,7 @@ mod iterator { * * Constant time. */ -fn height(rope: Rope) -> uint { +pub fn height(rope: Rope) -> uint { match (rope) { node::Empty => return 0u, node::Content(x) => return node::height(x) @@ -489,7 +485,7 @@ fn height(rope: Rope) -> uint { * * Constant time. */ -pure fn char_len(rope: Rope) -> uint { +pub pure fn char_len(rope: Rope) -> uint { match (rope) { node::Empty => return 0u, node::Content(x) => return node::char_len(x) @@ -503,7 +499,7 @@ pure fn char_len(rope: Rope) -> uint { * * Constant time. */ -pure fn byte_len(rope: Rope) -> uint { +pub pure fn byte_len(rope: Rope) -> uint { match (rope) { node::Empty => return 0u, node::Content(x) => return node::byte_len(x) @@ -526,7 +522,7 @@ pure fn byte_len(rope: Rope) -> uint { * This function executes in a time proportional to the height of the * rope + the (bounded) length of the largest leaf. */ -fn char_at(rope: Rope, pos: uint) -> char { +pub fn char_at(rope: Rope, pos: uint) -> char { match (rope) { node::Empty => fail, node::Content(x) => return node::char_at(x, pos) @@ -538,10 +534,9 @@ fn char_at(rope: Rope, pos: uint) -> char { Section: Implementation */ mod node { - #[legacy_exports]; /// Implementation of type `rope` - enum Root { + pub enum Root { /// An empty rope Empty, /// A non-empty rope @@ -565,7 +560,7 @@ mod node { * string can be shared between several ropes, e.g. for indexing * purposes. */ - type Leaf = { + pub type Leaf = { byte_offset: uint, byte_len: uint, char_len: uint, @@ -589,7 +584,7 @@ mod node { * * Used for rebalancing and to allocate stacks for traversals. */ - type Concat = { + pub type Concat = { //FIXME (#2744): Perhaps a `vec` instead of `left`/`right` left: @Node, right: @Node, @@ -598,7 +593,7 @@ mod node { height: uint }; - enum Node { + pub enum Node { /// A leaf consisting in a `str` Leaf(Leaf), /// The concatenation of two ropes @@ -610,14 +605,14 @@ mod node { * * This is not a strict value */ - const hint_max_leaf_char_len: uint = 256u; + pub const hint_max_leaf_char_len: uint = 256u; /** * The maximal height that _should_ be permitted in a tree. * * This is not a strict value */ - const hint_max_node_height: uint = 16u; + pub const hint_max_node_height: uint = 16u; /** * Adopt a string as a node. @@ -629,7 +624,7 @@ mod node { * Performance note: The complexity of this function is linear in * the length of `str`. */ - fn of_str(str: @~str) -> @Node { + pub fn of_str(str: @~str) -> @Node { return of_substr(str, 0u, str::len(*str)); } @@ -650,7 +645,7 @@ mod node { * Behavior is undefined if `byte_start` or `byte_len` do not represent * valid positions in `str` */ - fn of_substr(str: @~str, byte_start: uint, byte_len: uint) -> @Node { + pub fn of_substr(str: @~str, byte_start: uint, byte_len: uint) -> @Node { return of_substr_unsafer(str, byte_start, byte_len, str::count_chars(*str, byte_start, byte_len)); } @@ -676,8 +671,8 @@ mod node { * * Behavior is undefined if `char_len` does not accurately represent the * number of chars between byte_start and byte_start+byte_len */ - fn of_substr_unsafer(str: @~str, byte_start: uint, byte_len: uint, - char_len: uint) -> @Node { + pub fn of_substr_unsafer(str: @~str, byte_start: uint, byte_len: uint, + char_len: uint) -> @Node { assert(byte_start + byte_len <= str::len(*str)); let candidate = @Leaf({ byte_offset: byte_start, @@ -734,18 +729,18 @@ mod node { } } - pure fn byte_len(node: @Node) -> uint { + pub pure fn byte_len(node: @Node) -> uint { //FIXME (#2744): Could we do this without the pattern-matching? match (*node) { Leaf(y) => return y.byte_len, - Concat(y) => return y.byte_len + Concat(ref y) => return y.byte_len } } - pure fn char_len(node: @Node) -> uint { + pub pure fn char_len(node: @Node) -> uint { match (*node) { Leaf(y) => return y.char_len, - Concat(y) => return y.char_len + Concat(ref y) => return y.char_len } } @@ -757,7 +752,7 @@ mod node { * * forest - The forest. This vector is progressively rewritten during * execution and should be discarded as meaningless afterwards. */ - fn tree_from_forest_destructive(forest: &[mut @Node]) -> @Node { + pub fn tree_from_forest_destructive(forest: &[mut @Node]) -> @Node { let mut i; let mut len = vec::len(forest); while len > 1u { @@ -801,7 +796,7 @@ mod node { return forest[0]; } - fn serialize_node(node: @Node) -> ~str unsafe { + pub fn serialize_node(node: @Node) -> ~str unsafe { let mut buf = vec::to_mut(vec::from_elem(byte_len(node), 0u8)); let mut offset = 0u;//Current position in the buffer let it = leaf_iterator::start(node); @@ -832,10 +827,10 @@ mod node { * * This function executes in linear time. */ - fn flatten(node: @Node) -> @Node unsafe { + pub fn flatten(node: @Node) -> @Node unsafe { match (*node) { Leaf(_) => return node, - Concat(x) => { + Concat(ref x) => { return @Leaf({ byte_offset: 0u, byte_len: x.byte_len, @@ -861,7 +856,7 @@ mod node { * * `option::some(x)` otherwise, in which case `x` has the same contents * as `node` bot lower height and/or fragmentation. */ - fn bal(node: @Node) -> Option<@Node> { + pub fn bal(node: @Node) -> Option<@Node> { if height(node) < hint_max_node_height { return option::None; } //1. Gather all leaves as a forest let mut forest = ~[]; @@ -869,7 +864,7 @@ mod node { loop { match (leaf_iterator::next(&it)) { option::None => break, - option::Some(x) => vec::push(forest, @Leaf(x)) + option::Some(x) => forest.push(@Leaf(x)) } } //2. Rebuild tree from forest @@ -897,7 +892,8 @@ mod node { * This function fails if `byte_offset` or `byte_len` do not represent * valid positions in `node`. */ - fn sub_bytes(node: @Node, byte_offset: uint, byte_len: uint) -> @Node { + pub fn sub_bytes(node: @Node, byte_offset: uint, + byte_len: uint) -> @Node { let mut node = node; let mut byte_offset = byte_offset; loop { @@ -913,7 +909,7 @@ mod node { char_len: char_len, content: x.content}); } - node::Concat(x) => { + node::Concat(ref x) => { let left_len: uint = node::byte_len(x.left); if byte_offset <= left_len { if byte_offset + byte_len <= left_len { @@ -958,7 +954,8 @@ mod node { * This function fails if `char_offset` or `char_len` do not represent * valid positions in `node`. */ - fn sub_chars(node: @Node, char_offset: uint, char_len: uint) -> @Node { + pub fn sub_chars(node: @Node, char_offset: uint, + char_len: uint) -> @Node { let mut node = node; let mut char_offset = char_offset; loop { @@ -976,7 +973,7 @@ mod node { char_len: char_len, content: x.content}); } - node::Concat(x) => { + node::Concat(ref x) => { if char_offset == 0u && char_len == x.char_len {return node;} let left_len : uint = node::char_len(x.left); if char_offset <= left_len { @@ -1003,7 +1000,7 @@ mod node { }; } - fn concat2(left: @Node, right: @Node) -> @Node { + pub fn concat2(left: @Node, right: @Node) -> @Node { return @Concat({left : left, right : right, char_len: char_len(left) + char_len(right), @@ -1012,14 +1009,14 @@ mod node { }) } - fn height(node: @Node) -> uint { + pub fn height(node: @Node) -> uint { match (*node) { Leaf(_) => return 0u, - Concat(x) => return x.height + Concat(ref x) => return x.height } } - fn cmp(a: @Node, b: @Node) -> int { + pub fn cmp(a: @Node, b: @Node) -> int { let ita = char_iterator::start(a); let itb = char_iterator::start(b); let mut result = 0; @@ -1040,7 +1037,7 @@ mod node { return result; } - fn loop_chars(node: @Node, it: fn(char) -> bool) -> bool { + pub fn loop_chars(node: @Node, it: fn(c: char) -> bool) -> bool { return loop_leaves(node,|leaf| { str::all_between(*leaf.content, leaf.byte_offset, @@ -1062,12 +1059,12 @@ mod node { * `true` If execution proceeded correctly, `false` if it was interrupted, * that is if `it` returned `false` at any point. */ - fn loop_leaves(node: @Node, it: fn(Leaf) -> bool) -> bool{ + pub fn loop_leaves(node: @Node, it: fn(Leaf) -> bool) -> bool{ let mut current = node; loop { match (*current) { Leaf(x) => return it(x), - Concat(x) => if loop_leaves(x.left, it) { //non tail call + Concat(ref x) => if loop_leaves(x.left, it) { //non tail call current = x.right; //tail call } else { return false; @@ -1093,7 +1090,7 @@ mod node { * proportional to the height of the rope + the (bounded) * length of the largest leaf. */ - fn char_at(node: @Node, pos: uint) -> char { + pub fn char_at(node: @Node, pos: uint) -> char { let mut node = node; let mut pos = pos; loop { @@ -1108,19 +1105,18 @@ mod node { }; } - mod leaf_iterator { - #[legacy_exports]; - type T = { + pub mod leaf_iterator { + pub type T = { stack: ~[mut @Node], mut stackpos: int }; - fn empty() -> T { + pub fn empty() -> T { let stack : ~[mut @Node] = ~[mut]; return {stack: move stack, mut stackpos: -1} } - fn start(node: @Node) -> T { + pub fn start(node: @Node) -> T { let stack = vec::to_mut(vec::from_elem(height(node)+1u, node)); return { stack: move stack, @@ -1128,13 +1124,13 @@ mod node { } } - fn next(it: &T) -> Option { + pub fn next(it: &T) -> Option { if it.stackpos < 0 { return option::None; } loop { let current = it.stack[it.stackpos]; it.stackpos -= 1; match (*current) { - Concat(x) => { + Concat(ref x) => { it.stackpos += 1; it.stack[it.stackpos] = x.right; it.stackpos += 1; @@ -1146,15 +1142,14 @@ mod node { } } - mod char_iterator { - #[legacy_exports]; - type T = { + pub mod char_iterator { + pub type T = { leaf_iterator: leaf_iterator::T, mut leaf: Option, mut leaf_byte_pos: uint }; - fn start(node: @Node) -> T { + pub fn start(node: @Node) -> T { return { leaf_iterator: leaf_iterator::start(node), mut leaf: option::None, @@ -1162,7 +1157,7 @@ mod node { } } - fn empty() -> T { + pub fn empty() -> T { return { leaf_iterator: leaf_iterator::empty(), mut leaf: option::None, @@ -1170,7 +1165,7 @@ mod node { } } - fn next(it: &T) -> Option { + pub fn next(it: &T) -> Option { loop { match (get_current_or_next_leaf(it)) { option::None => return option::None, @@ -1185,7 +1180,7 @@ mod node { }; } - fn get_current_or_next_leaf(it: &T) -> Option { + pub fn get_current_or_next_leaf(it: &T) -> Option { match ((*it).leaf) { option::Some(_) => return (*it).leaf, option::None => { @@ -1202,7 +1197,7 @@ mod node { } } - fn get_next_char_in_leaf(it: &T) -> Option { + pub fn get_next_char_in_leaf(it: &T) -> Option { match copy (*it).leaf { option::None => return option::None, option::Some(aleaf) => { @@ -1225,7 +1220,6 @@ mod node { #[cfg(test)] mod tests { - #[legacy_exports]; //Utility function, used for sanity check fn rope_to_string(r: Rope) -> ~str { @@ -1240,7 +1234,7 @@ mod tests { *x.content, x.byte_offset, x.byte_offset + x.byte_len); } - node::Concat(x) => { + node::Concat(ref x) => { aux(str, x.left); aux(str, x.right); } diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index af581ba49581..e9067bc64042 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -63,7 +63,7 @@ trait Deserializer { fn read_float() -> float; // Compound types: - fn read_enum(name: ~str, f: fn() -> T) -> T; + fn read_enum(name: &str, f: fn() -> T) -> T; fn read_enum_variant(f: fn(uint) -> T) -> T; fn read_enum_variant_arg(idx: uint, f: fn() -> T) -> T; fn read_vec(f: fn(uint) -> T) -> T; @@ -71,7 +71,7 @@ trait Deserializer { fn read_box(f: fn() -> T) -> T; fn read_uniq(f: fn() -> T) -> T; fn read_rec(f: fn() -> T) -> T; - fn read_rec_field(f_name: ~str, f_idx: uint, f: fn() -> T) -> T; + fn read_rec_field(f_name: &str, f_idx: uint, f: fn() -> T) -> T; fn read_tup(sz: uint, f: fn() -> T) -> T; fn read_tup_elt(idx: uint, f: fn() -> T) -> T; } @@ -81,7 +81,7 @@ trait Deserializer { // // In some cases, these should eventually be coded as traits. -fn emit_from_vec(s: S, v: ~[T], f: fn(T)) { +fn emit_from_vec(&&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 +91,7 @@ fn emit_from_vec(s: S, v: ~[T], f: fn(T)) { } } -fn read_to_vec(d: D, f: fn() -> T) -> ~[T] { +fn read_to_vec(&&d: D, f: fn() -> T) -> ~[T] { do d.read_vec |len| { do vec::from_fn(len) |i| { d.read_vec_elt(i, || f()) @@ -100,11 +100,11 @@ fn read_to_vec(d: D, f: fn() -> T) -> ~[T] { } trait SerializerHelpers { - fn emit_from_vec(v: ~[T], f: fn(T)); + fn emit_from_vec(&&v: ~[T], f: fn(&&x: T)); } impl S: SerializerHelpers { - fn emit_from_vec(v: ~[T], f: fn(T)) { + fn emit_from_vec(&&v: ~[T], f: fn(&&x: T)) { emit_from_vec(self, v, f) } } @@ -119,142 +119,142 @@ impl D: DeserializerHelpers { } } -fn serialize_uint(s: S, v: uint) { +fn serialize_uint(&&s: S, v: uint) { s.emit_uint(v); } -fn deserialize_uint(d: D) -> uint { +fn deserialize_uint(&&d: D) -> uint { d.read_uint() } -fn serialize_u8(s: S, v: u8) { +fn serialize_u8(&&s: S, v: u8) { s.emit_u8(v); } -fn deserialize_u8(d: D) -> u8 { +fn deserialize_u8(&&d: D) -> u8 { d.read_u8() } -fn serialize_u16(s: S, v: u16) { +fn serialize_u16(&&s: S, v: u16) { s.emit_u16(v); } -fn deserialize_u16(d: D) -> u16 { +fn deserialize_u16(&&d: D) -> u16 { d.read_u16() } -fn serialize_u32(s: S, v: u32) { +fn serialize_u32(&&s: S, v: u32) { s.emit_u32(v); } -fn deserialize_u32(d: D) -> u32 { +fn deserialize_u32(&&d: D) -> u32 { d.read_u32() } -fn serialize_u64(s: S, v: u64) { +fn serialize_u64(&&s: S, v: u64) { s.emit_u64(v); } -fn deserialize_u64(d: D) -> u64 { +fn deserialize_u64(&&d: D) -> u64 { d.read_u64() } -fn serialize_int(s: S, v: int) { +fn serialize_int(&&s: S, v: int) { s.emit_int(v); } -fn deserialize_int(d: D) -> int { +fn deserialize_int(&&d: D) -> int { d.read_int() } -fn serialize_i8(s: S, v: i8) { +fn serialize_i8(&&s: S, v: i8) { s.emit_i8(v); } -fn deserialize_i8(d: D) -> i8 { +fn deserialize_i8(&&d: D) -> i8 { d.read_i8() } -fn serialize_i16(s: S, v: i16) { +fn serialize_i16(&&s: S, v: i16) { s.emit_i16(v); } -fn deserialize_i16(d: D) -> i16 { +fn deserialize_i16(&&d: D) -> i16 { d.read_i16() } -fn serialize_i32(s: S, v: i32) { +fn serialize_i32(&&s: S, v: i32) { s.emit_i32(v); } -fn deserialize_i32(d: D) -> i32 { +fn deserialize_i32(&&d: D) -> i32 { d.read_i32() } -fn serialize_i64(s: S, v: i64) { +fn serialize_i64(&&s: S, v: i64) { s.emit_i64(v); } -fn deserialize_i64(d: D) -> i64 { +fn deserialize_i64(&&d: D) -> i64 { d.read_i64() } -fn serialize_str(s: S, v: &str) { +fn serialize_str(&&s: S, v: &str) { s.emit_str(v); } -fn deserialize_str(d: D) -> ~str { +fn deserialize_str(&&d: D) -> ~str { d.read_str() } -fn serialize_float(s: S, v: float) { +fn serialize_float(&&s: S, v: float) { s.emit_float(v); } -fn deserialize_float(d: D) -> float { +fn deserialize_float(&&d: D) -> float { d.read_float() } -fn serialize_f32(s: S, v: f32) { +fn serialize_f32(&&s: S, v: f32) { s.emit_f32(v); } -fn deserialize_f32(d: D) -> f32 { +fn deserialize_f32(&&d: D) -> f32 { d.read_f32() } -fn serialize_f64(s: S, v: f64) { +fn serialize_f64(&&s: S, v: f64) { s.emit_f64(v); } -fn deserialize_f64(d: D) -> f64 { +fn deserialize_f64(&&d: D) -> f64 { d.read_f64() } -fn serialize_bool(s: S, v: bool) { +fn serialize_bool(&&s: S, v: bool) { s.emit_bool(v); } -fn deserialize_bool(d: D) -> bool { +fn deserialize_bool(&&d: D) -> bool { d.read_bool() } -fn serialize_Option(s: S, v: Option, st: fn(T)) { +fn serialize_Option(&&s: S, &&v: Option, st: fn(&&x: T)) { do s.emit_enum(~"option") { match v { None => do s.emit_enum_variant(~"none", 0u, 0u) { }, - Some(v) => do s.emit_enum_variant(~"some", 1u, 1u) { + Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { do s.emit_enum_variant_arg(0u) { - st(v) + st(*v) } } } } } -fn deserialize_Option(d: D, st: fn() -> T) +fn deserialize_Option(&&d: D, st: fn() -> T) -> Option { do d.read_enum(~"option") { do d.read_enum_variant |i| { diff --git a/src/libstd/serialization2.rs b/src/libstd/serialization2.rs new file mode 100644 index 000000000000..5173ef163a22 --- /dev/null +++ b/src/libstd/serialization2.rs @@ -0,0 +1,563 @@ +//! Support code for serialization. + +/* +Core serialization interfaces. +*/ + +#[forbid(deprecated_mode)]; +#[forbid(non_camel_case_types)]; + +pub trait Serializer { + // Primitive types: + fn emit_nil(&self); + fn emit_uint(&self, v: uint); + fn emit_u64(&self, v: u64); + fn emit_u32(&self, v: u32); + fn emit_u16(&self, v: u16); + fn emit_u8(&self, v: u8); + fn emit_int(&self, v: int); + fn emit_i64(&self, v: i64); + fn emit_i32(&self, v: i32); + fn emit_i16(&self, v: i16); + fn emit_i8(&self, v: i8); + fn emit_bool(&self, v: bool); + fn emit_float(&self, v: float); + fn emit_f64(&self, v: f64); + fn emit_f32(&self, v: f32); + fn emit_char(&self, v: char); + fn emit_borrowed_str(&self, v: &str); + fn emit_owned_str(&self, v: &str); + fn emit_managed_str(&self, v: &str); + + // Compound types: + fn emit_borrowed(&self, f: fn()); + fn emit_owned(&self, f: fn()); + fn emit_managed(&self, f: fn()); + + fn emit_enum(&self, name: &str, f: fn()); + fn emit_enum_variant(&self, v_name: &str, v_id: uint, sz: uint, f: fn()); + fn emit_enum_variant_arg(&self, idx: uint, f: fn()); + + fn emit_borrowed_vec(&self, len: uint, f: fn()); + fn emit_owned_vec(&self, len: uint, f: fn()); + fn emit_managed_vec(&self, len: uint, f: fn()); + fn emit_vec_elt(&self, idx: uint, f: fn()); + + fn emit_rec(&self, f: fn()); + fn emit_struct(&self, name: &str, f: fn()); + fn emit_field(&self, f_name: &str, f_idx: uint, f: fn()); + + fn emit_tup(&self, len: uint, f: fn()); + fn emit_tup_elt(&self, idx: uint, f: fn()); +} + +pub trait Deserializer { + // Primitive types: + fn read_nil(&self) -> (); + fn read_uint(&self) -> uint; + fn read_u64(&self) -> u64; + fn read_u32(&self) -> u32; + fn read_u16(&self) -> u16; + fn read_u8(&self) -> u8; + fn read_int(&self) -> int; + fn read_i64(&self) -> i64; + fn read_i32(&self) -> i32; + fn read_i16(&self) -> i16; + fn read_i8(&self) -> i8; + fn read_bool(&self) -> bool; + fn read_f64(&self) -> f64; + fn read_f32(&self) -> f32; + fn read_float(&self) -> float; + fn read_char(&self) -> char; + fn read_owned_str(&self) -> ~str; + fn read_managed_str(&self) -> @str; + + // Compound types: + fn read_enum(&self, name: &str, f: fn() -> T) -> T; + fn read_enum_variant(&self, f: fn(uint) -> T) -> T; + fn read_enum_variant_arg(&self, idx: uint, f: fn() -> T) -> T; + + fn read_owned(&self, f: fn() -> T) -> T; + fn read_managed(&self, f: fn() -> T) -> T; + + fn read_owned_vec(&self, f: fn(uint) -> T) -> T; + fn read_managed_vec(&self, f: fn(uint) -> T) -> T; + fn read_vec_elt(&self, idx: uint, f: fn() -> T) -> T; + + fn read_rec(&self, f: fn() -> T) -> T; + fn read_struct(&self, name: &str, f: fn() -> T) -> T; + fn read_field(&self, name: &str, idx: uint, f: fn() -> T) -> T; + + fn read_tup(&self, sz: uint, f: fn() -> T) -> T; + fn read_tup_elt(&self, idx: uint, f: fn() -> T) -> T; +} + +pub trait Serializable { + fn serialize(&self, s: &S); +} + +pub trait Deserializable { + static fn deserialize(&self, d: &D) -> self; +} + +pub impl uint: Serializable { + fn serialize(&self, s: &S) { s.emit_uint(*self) } +} + +pub impl uint: Deserializable { + static fn deserialize(&self, d: &D) -> uint { + d.read_uint() + } +} + +pub impl u8: Serializable { + fn serialize(&self, s: &S) { s.emit_u8(*self) } +} + +pub impl u8: Deserializable { + static fn deserialize(&self, d: &D) -> u8 { + d.read_u8() + } +} + +pub impl u16: Serializable { + fn serialize(&self, s: &S) { s.emit_u16(*self) } +} + +pub impl u16: Deserializable { + static fn deserialize(&self, d: &D) -> u16 { + d.read_u16() + } +} + +pub impl u32: Serializable { + fn serialize(&self, s: &S) { s.emit_u32(*self) } +} + +pub impl u32: Deserializable { + static fn deserialize(&self, d: &D) -> u32 { + d.read_u32() + } +} + +pub impl u64: Serializable { + fn serialize(&self, s: &S) { s.emit_u64(*self) } +} + +pub impl u64: Deserializable { + static fn deserialize(&self, d: &D) -> u64 { + d.read_u64() + } +} + +pub impl int: Serializable { + fn serialize(&self, s: &S) { s.emit_int(*self) } +} + +pub impl int: Deserializable { + static fn deserialize(&self, d: &D) -> int { + d.read_int() + } +} + +pub impl i8: Serializable { + fn serialize(&self, s: &S) { s.emit_i8(*self) } +} + +pub impl i8: Deserializable { + static fn deserialize(&self, d: &D) -> i8 { + d.read_i8() + } +} + +pub impl i16: Serializable { + fn serialize(&self, s: &S) { s.emit_i16(*self) } +} + +pub impl i16: Deserializable { + static fn deserialize(&self, d: &D) -> i16 { + d.read_i16() + } +} + +pub impl i32: Serializable { + fn serialize(&self, s: &S) { s.emit_i32(*self) } +} + +pub impl i32: Deserializable { + static fn deserialize(&self, d: &D) -> i32 { + d.read_i32() + } +} + +pub impl i64: Serializable { + fn serialize(&self, s: &S) { s.emit_i64(*self) } +} + +pub impl i64: Deserializable { + static fn deserialize(&self, d: &D) -> i64 { + d.read_i64() + } +} + +pub impl &str: Serializable { + fn serialize(&self, s: &S) { s.emit_borrowed_str(*self) } +} + +pub impl ~str: Serializable { + fn serialize(&self, s: &S) { s.emit_owned_str(*self) } +} + +pub impl ~str: Deserializable { + static fn deserialize(&self, d: &D) -> ~str { + d.read_owned_str() + } +} + +pub impl @str: Serializable { + fn serialize(&self, s: &S) { s.emit_managed_str(*self) } +} + +pub impl @str: Deserializable { + static fn deserialize(&self, d: &D) -> @str { + d.read_managed_str() + } +} + +pub impl float: Serializable { + fn serialize(&self, s: &S) { s.emit_float(*self) } +} + +pub impl float: Deserializable { + static fn deserialize(&self, d: &D) -> float { + d.read_float() + } +} + +pub impl f32: Serializable { + fn serialize(&self, s: &S) { s.emit_f32(*self) } +} + +pub impl f32: Deserializable { + static fn deserialize(&self, d: &D) -> f32 { + d.read_f32() } +} + +pub impl f64: Serializable { + fn serialize(&self, s: &S) { s.emit_f64(*self) } +} + +pub impl f64: Deserializable { + static fn deserialize(&self, d: &D) -> f64 { + d.read_f64() + } +} + +pub impl bool: Serializable { + fn serialize(&self, s: &S) { s.emit_bool(*self) } +} + +pub impl bool: Deserializable { + static fn deserialize(&self, d: &D) -> bool { + d.read_bool() + } +} + +pub impl (): Serializable { + fn serialize(&self, s: &S) { s.emit_nil() } +} + +pub impl (): Deserializable { + static fn deserialize(&self, d: &D) -> () { + d.read_nil() + } +} + +pub impl &T: Serializable { + fn serialize(&self, s: &S) { + s.emit_borrowed(|| (**self).serialize(s)) + } +} + +pub impl ~T: Serializable { + fn serialize(&self, s: &S) { + s.emit_owned(|| (**self).serialize(s)) + } +} + +pub impl ~T: Deserializable { + static fn deserialize(&self, d: &D) -> ~T { + d.read_owned(|| ~deserialize(d)) + } +} + +pub impl @T: Serializable { + fn serialize(&self, s: &S) { + s.emit_managed(|| (**self).serialize(s)) + } +} + +pub impl @T: Deserializable { + static fn deserialize(&self, d: &D) -> @T { + d.read_managed(|| @deserialize(d)) + } +} + +pub impl &[T]: Serializable { + fn serialize(&self, s: &S) { + do s.emit_borrowed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl ~[T]: Serializable { + fn serialize(&self, s: &S) { + do s.emit_owned_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl ~[T]: Deserializable { + static fn deserialize(&self, d: &D) -> ~[T] { + do d.read_owned_vec |len| { + do vec::from_fn(len) |i| { + d.read_vec_elt(i, || deserialize(d)) + } + } + } +} + +pub impl @[T]: Serializable { + fn serialize(&self, s: &S) { + do s.emit_managed_vec(self.len()) { + for self.eachi |i, e| { + s.emit_vec_elt(i, || e.serialize(s)) + } + } + } +} + +pub impl @[T]: Deserializable { + static fn deserialize(&self, d: &D) -> @[T] { + do d.read_managed_vec |len| { + do at_vec::from_fn(len) |i| { + d.read_vec_elt(i, || deserialize(d)) + } + } + } +} + +pub impl Option: Serializable { + fn serialize(&self, s: &S) { + do s.emit_enum(~"option") { + match *self { + None => do s.emit_enum_variant(~"none", 0u, 0u) { + }, + + Some(ref v) => do s.emit_enum_variant(~"some", 1u, 1u) { + s.emit_enum_variant_arg(0u, || v.serialize(s)) + } + } + } + } +} + +pub impl Option: Deserializable { + static fn deserialize(&self, d: &D) -> Option { + do d.read_enum(~"option") { + do d.read_enum_variant |i| { + match i { + 0 => None, + 1 => Some(d.read_enum_variant_arg(0u, || deserialize(d))), + _ => fail(#fmt("Bad variant for option: %u", i)) + } + } + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable +> (T0, T1): Serializable { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1) => { + do s.emit_tup(2) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable +> (T0, T1): Deserializable { + static fn deserialize(&self, d: &D) -> (T0, T1) { + do d.read_tup(2) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable +> (T0, T1, T2): Serializable { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2) => { + do s.emit_tup(3) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable +> (T0, T1, T2): Deserializable { + static fn deserialize(&self, d: &D) -> (T0, T1, T2) { + do d.read_tup(3) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable, + T3: Serializable +> (T0, T1, T2, T3): Serializable { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3) => { + do s.emit_tup(4) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + s.emit_tup_elt(3, || t3.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable, + T3: Deserializable +> (T0, T1, T2, T3): Deserializable { + static fn deserialize(&self, d: &D) -> (T0, T1, T2, T3) { + do d.read_tup(4) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)), + d.read_tup_elt(3, || deserialize(d)) + ) + } + } +} + +pub impl< + T0: Serializable, + T1: Serializable, + T2: Serializable, + T3: Serializable, + T4: Serializable +> (T0, T1, T2, T3, T4): Serializable { + fn serialize(&self, s: &S) { + match *self { + (ref t0, ref t1, ref t2, ref t3, ref t4) => { + do s.emit_tup(5) { + s.emit_tup_elt(0, || t0.serialize(s)); + s.emit_tup_elt(1, || t1.serialize(s)); + s.emit_tup_elt(2, || t2.serialize(s)); + s.emit_tup_elt(3, || t3.serialize(s)); + s.emit_tup_elt(4, || t4.serialize(s)); + } + } + } + } +} + +pub impl< + T0: Deserializable, + T1: Deserializable, + T2: Deserializable, + T3: Deserializable, + T4: Deserializable +> (T0, T1, T2, T3, T4): Deserializable { + static fn deserialize(&self, d: &D) + -> (T0, T1, T2, T3, T4) { + do d.read_tup(5) { + ( + d.read_tup_elt(0, || deserialize(d)), + d.read_tup_elt(1, || deserialize(d)), + d.read_tup_elt(2, || deserialize(d)), + d.read_tup_elt(3, || deserialize(d)), + d.read_tup_elt(4, || deserialize(d)) + ) + } + } +} + +// ___________________________________________________________________________ +// Helper routines +// +// In some cases, these should eventually be coded as traits. + +pub trait SerializerHelpers { + fn emit_from_vec(&self, v: &[T], f: fn(&T)); +} + +pub impl S: SerializerHelpers { + fn emit_from_vec(&self, v: &[T], f: fn(&T)) { + do self.emit_owned_vec(v.len()) { + for v.eachi |i, e| { + do self.emit_vec_elt(i) { + f(e) + } + } + } + } +} + +pub trait DeserializerHelpers { + fn read_to_vec(&self, f: fn() -> T) -> ~[T]; +} + +pub impl D: DeserializerHelpers { + fn read_to_vec(&self, f: fn() -> T) -> ~[T] { + do self.read_owned_vec |len| { + do vec::from_fn(len) |i| { + self.read_vec_elt(i, || f()) + } + } + } +} diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs index a40db2c1f1fc..05890035273d 100644 --- a/src/libstd/sha1.rs +++ b/src/libstd/sha1.rs @@ -13,14 +13,12 @@ */ #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; /* * A SHA-1 implementation derived from Paul E. Jones's reference * implementation, which is written for clarity, not speed. At some * point this will want to be rewritten. */ -export sha1; /// The SHA-1 interface trait Sha1 { @@ -53,7 +51,7 @@ const k3: u32 = 0xCA62C1D6u32; /// Construct a `sha` object -fn sha1() -> Sha1 { +pub fn sha1() -> Sha1 { type Sha1State = {h: ~[mut u32], mut len_low: u32, diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 8ce1ebde127a..58ecbb0d6c3a 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -2,8 +2,7 @@ * A simple map based on a vector for small integer keys. Space requirements * are O(highest integer key). */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap use core::option; use core::option::{Some, None}; @@ -14,12 +13,12 @@ use map::Map; // requires this to be. type SmallIntMap_ = {v: DVec>}; -enum SmallIntMap { +pub enum SmallIntMap { SmallIntMap_(@SmallIntMap_) } /// Create a smallintmap -fn mk() -> SmallIntMap { +pub fn mk() -> SmallIntMap { let v = DVec(); return SmallIntMap_(@{v: move v}); } @@ -29,16 +28,16 @@ fn mk() -> SmallIntMap { * the specified key then the original value is replaced. */ #[inline(always)] -fn insert(self: SmallIntMap, key: uint, +val: T) { +pub fn insert(self: SmallIntMap, key: uint, val: T) { //io::println(fmt!("%?", key)); - self.v.grow_set_elt(key, None, Some(val)); + self.v.grow_set_elt(key, &None, Some(val)); } /** * Get the value for the specified key. If the key does not exist * in the map then returns none */ -pure fn find(self: SmallIntMap, key: uint) -> Option { +pub pure fn find(self: SmallIntMap, key: uint) -> Option { if key < self.v.len() { return self.v.get_elt(key); } return None::; } @@ -50,18 +49,18 @@ pure fn find(self: SmallIntMap, key: uint) -> Option { * * If the key does not exist in the map */ -pure fn get(self: SmallIntMap, key: uint) -> T { +pub pure fn get(self: SmallIntMap, key: uint) -> T { match find(self, key) { None => { error!("smallintmap::get(): key not present"); fail; } - Some(v) => return v + Some(move v) => return v } } /// Returns true if the map contains a value for the specified key -fn contains_key(self: SmallIntMap, key: uint) -> bool { +pub fn contains_key(self: SmallIntMap, key: uint) -> bool { return !find(self, key).is_none(); } @@ -78,12 +77,12 @@ impl SmallIntMap: map::Map { sz } #[inline(always)] - fn insert(+key: uint, +value: V) -> bool { + fn insert(key: uint, value: V) -> bool { let exists = contains_key(self, key); insert(self, key, value); return !exists; } - fn remove(+key: uint) -> bool { + fn remove(key: uint) -> bool { if key >= self.v.len() { return false; } @@ -94,30 +93,30 @@ impl SmallIntMap: map::Map { fn clear() { self.v.set(~[]); } - fn contains_key(+key: uint) -> bool { + fn contains_key(key: uint) -> bool { contains_key(self, key) } fn contains_key_ref(key: &uint) -> bool { contains_key(self, *key) } - fn get(+key: uint) -> V { get(self, key) } - pure fn find(+key: uint) -> Option { find(self, key) } + fn get(key: uint) -> V { get(self, key) } + pure fn find(key: uint) -> Option { 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) { + pure fn each_key(it: fn(key: uint) -> bool) { self.each_ref(|k, _v| it(*k)) } - pure fn each_value(it: fn(+value: V) -> bool) { + pure fn each_value(it: fn(value: V) -> bool) { self.each_ref(|_k, v| it(*v)) } pure fn each_ref(it: fn(key: &uint, value: &V) -> bool) { let mut idx = 0u, l = self.v.len(); while idx < l { match self.v.get_elt(idx) { - Some(elt) => if !it(&idx, &elt) { break }, + Some(ref elt) => if !it(&idx, elt) { break }, None => () } idx += 1u; @@ -132,7 +131,7 @@ impl SmallIntMap: map::Map { } impl SmallIntMap: ops::Index { - pure fn index(&&key: uint) -> V { + pure fn index(+key: uint) -> V { unsafe { get(self, key) } @@ -140,6 +139,6 @@ impl SmallIntMap: ops::Index { } /// Cast the given smallintmap to a map::map -fn as_map(s: SmallIntMap) -> map::Map { +pub fn as_map(s: SmallIntMap) -> map::Map { s as map::Map:: } diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index ed7e3f0f6d9e..6a292402dac3 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -1,18 +1,10 @@ //! Sorting methods #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use vec::{len, push}; use core::cmp::{Eq, Ord}; use dvec::DVec; -export le; -export merge_sort; -export quick_sort; -export quick_sort3; -export tim_sort; -export Sort; - type Le = pure fn(v1: &T, v2: &T) -> bool; /** @@ -21,7 +13,7 @@ type Le = pure fn(v1: &T, v2: &T) -> bool; * Has worst case O(n log n) performance, best case O(n), but * is not space efficient. This is a stable sort. */ -fn merge_sort(v: &[const T], le: Le) -> ~[T] { +pub fn merge_sort(v: &[const T], le: Le) -> ~[T] { type Slice = (uint, uint); return merge_sort_(v, (0u, len(v)), le); @@ -49,9 +41,9 @@ fn merge_sort(v: &[const T], le: Le) -> ~[T] { let mut b_ix = 0u; while a_ix < a_len && b_ix < b_len { if le(&a[a_ix], &b[b_ix]) { - vec::push(rs, a[a_ix]); + rs.push(a[a_ix]); a_ix += 1u; - } else { vec::push(rs, b[b_ix]); b_ix += 1u; } + } else { rs.push(b[b_ix]); b_ix += 1u; } } rs = vec::append(rs, vec::slice(a, a_ix, a_len)); rs = vec::append(rs, vec::slice(b, b_ix, b_len)); @@ -95,7 +87,7 @@ fn qsort(arr: &[mut T], left: uint, * Has worst case O(n^2) performance, average case O(n log n). * This is an unstable sort. */ -fn quick_sort(arr: &[mut T], compare_func: Le) { +pub fn quick_sort(arr: &[mut T], compare_func: Le) { if len::(arr) == 0u { return; } qsort::(arr, 0u, len::(arr) - 1u, compare_func); } @@ -157,12 +149,12 @@ fn qsort3(arr: &[mut T], left: int, right: int) { * * This is an unstable sort. */ -fn quick_sort3(arr: &[mut T]) { +pub fn quick_sort3(arr: &[mut T]) { if arr.len() <= 1 { return; } qsort3(arr, 0, (arr.len() - 1) as int); } -trait Sort { +pub trait Sort { fn qsort(self); } @@ -923,7 +915,7 @@ mod tests { fn check_sort(v1: &[int], v2: &[int]) { let len = vec::len::(v1); - pure fn le(a: &int, b: &int) -> bool { *a <= *b } + pub pure fn le(a: &int, b: &int) -> bool { *a <= *b } let f = le; let v3 = merge_sort::(v1, f); let mut i = 0u; @@ -953,7 +945,7 @@ mod tests { #[test] fn test_merge_sort_mutable() { - pure fn le(a: &int, b: &int) -> bool { *a <= *b } + pub pure fn le(a: &int, b: &int) -> bool { *a <= *b } let v1 = ~[mut 3, 2, 1]; let v2 = merge_sort(v1, le); assert v2 == ~[1, 2, 3]; diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 422ff81b9fec..6a5658d24eb0 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -18,11 +18,11 @@ not required in or otherwise suitable for the core library. #[no_core]; -#[legacy_modes]; #[legacy_exports]; #[allow(vecs_implicitly_copyable)]; #[deny(non_camel_case_types)]; +#[forbid(deprecated_pattern)]; extern mod core(vers = "0.4"); use core::*; @@ -34,116 +34,81 @@ export sync, arc, comm; export bitv, deque, fun_treemap, list, map; export smallintmap, sort, treemap; export rope, arena, par; -export ebml, dbg, getopts, json, rand, sha1, term, time, prettyprint; -export test, tempfile, serialization; +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 -#[legacy_exports] mod net; -#[legacy_exports] mod net_ip; -#[legacy_exports] mod net_tcp; -#[legacy_exports] mod net_url; // libuv modules -#[legacy_exports] mod uv; -#[legacy_exports] mod uv_ll; -#[legacy_exports] mod uv_iotask; -#[legacy_exports] mod uv_global_loop; // Utility modules -#[legacy_exports] mod c_vec; -#[legacy_exports] mod timer; -#[legacy_exports] mod cell; // Concurrency -#[legacy_exports] mod sync; -#[legacy_exports] mod arc; -#[legacy_exports] mod comm; // Collections -#[legacy_exports] mod bitv; -#[legacy_exports] mod deque; -#[legacy_exports] mod fun_treemap; -#[legacy_exports] mod list; -#[legacy_exports] mod map; -#[legacy_exports] mod rope; -#[legacy_exports] mod smallintmap; -#[legacy_exports] mod sort; -#[legacy_exports] mod treemap; -#[legacy_exports] // And ... other stuff -#[legacy_exports] mod ebml; -#[legacy_exports] +mod ebml2; mod dbg; -#[legacy_exports] mod getopts; -#[legacy_exports] mod json; -#[legacy_exports] mod sha1; -#[legacy_exports] mod md4; -#[legacy_exports] mod tempfile; -#[legacy_exports] mod term; -#[legacy_exports] mod time; -#[legacy_exports] mod prettyprint; -#[legacy_exports] +mod prettyprint2; mod arena; -#[legacy_exports] mod par; -#[legacy_exports] mod cmp; -#[legacy_exports] mod base64; #[cfg(unicode)] -#[legacy_exports] mod unicode; // Compiler support modules -#[legacy_exports] mod test; #[legacy_exports] mod serialization; +mod serialization2; // Local Variables: // mode: rust; diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index 8fdcc22b4c1a..f66134d38923 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -1,6 +1,5 @@ // NB: transitionary, de-mode-ing. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap /** * The concurrency primitives you know and love. * @@ -8,9 +7,6 @@ * in std. */ -export Condvar, Semaphore, Mutex, mutex_with_condvars; -export RWlock, rwlock_with_condvars, RWlockReadMode, RWlockWriteMode; - use private::{Exclusive, exclusive}; /**************************************************************************** @@ -73,7 +69,7 @@ struct SemInner { enum Sem = Exclusive>; #[doc(hidden)] -fn new_sem(count: int, +q: Q) -> Sem { +fn new_sem(count: int, q: Q) -> Sem { Sem(exclusive(SemInner { mut count: count, waiters: new_waitqueue(), blocked: q })) } @@ -82,7 +78,7 @@ fn new_sem_and_signal(count: int, num_condvars: uint) -> Sem<~[mut Waitqueue]> { let mut queues = ~[]; for num_condvars.times { - vec::push(queues, new_waitqueue()); + queues.push(new_waitqueue()); } new_sem(count, vec::to_mut(move queues)) } @@ -177,7 +173,7 @@ fn SemAndSignalRelease(sem: &r/Sem<~[mut Waitqueue]>) } /// A mechanism for atomic-unlock-and-deschedule blocking and signalling. -struct Condvar { priv sem: &Sem<~[mut Waitqueue]>, drop { } } +pub struct Condvar { priv sem: &Sem<~[mut Waitqueue]>, drop { } } impl &Condvar { /** @@ -380,14 +376,14 @@ impl &Semaphore { struct Mutex { priv sem: Sem<~[mut Waitqueue]> } /// Create a new mutex, with one associated condvar. -fn Mutex() -> Mutex { mutex_with_condvars(1) } +pub fn Mutex() -> Mutex { mutex_with_condvars(1) } /** * Create a new mutex, with a specified number of associated condvars. This * will allow calling wait_on/signal_on/broadcast_on with condvar IDs between * 0 and num_condvars-1. (If num_condvars is 0, lock_cond will be allowed but * any operations on the condvar will fail.) */ -fn mutex_with_condvars(num_condvars: uint) -> Mutex { +pub fn mutex_with_condvars(num_condvars: uint) -> Mutex { Mutex { sem: new_sem_and_signal(1, num_condvars) } } @@ -430,13 +426,13 @@ struct RWlock { } /// Create a new rwlock, with one associated condvar. -fn RWlock() -> RWlock { rwlock_with_condvars(1) } +pub fn RWlock() -> RWlock { rwlock_with_condvars(1) } /** * Create a new rwlock, with a specified number of associated condvars. * Similar to mutex_with_condvars. */ -fn rwlock_with_condvars(num_condvars: uint) -> RWlock { +pub fn rwlock_with_condvars(num_condvars: uint) -> RWlock { RWlock { order_lock: semaphore(1), access_lock: new_sem_and_signal(1, num_condvars), state: exclusive(RWlockInner { read_mode: false, @@ -539,7 +535,7 @@ impl &RWlock { * } * ~~~ */ - fn write_downgrade(blk: fn(+v: RWlockWriteMode) -> U) -> U { + fn write_downgrade(blk: fn(v: RWlockWriteMode) -> U) -> U { // Implementation slightly different from the slicker 'write's above. // The exit path is conditional on whether the caller downgrades. let mut _release = None; @@ -555,7 +551,7 @@ impl &RWlock { } /// To be called inside of the write_downgrade block. - fn downgrade(+token: RWlockWriteMode/&a) -> RWlockReadMode/&a { + fn downgrade(token: RWlockWriteMode/&a) -> RWlockReadMode/&a { if !ptr::ref_eq(self, token.lock) { fail ~"Can't downgrade() with a different rwlock's write_mode!"; } @@ -647,9 +643,9 @@ fn RWlockReleaseDowngrade(lock: &r/RWlock) -> RWlockReleaseDowngrade/&r { } /// The "write permission" token used for rwlock.write_downgrade(). -struct RWlockWriteMode { /* priv */ lock: &RWlock, drop { } } +pub struct RWlockWriteMode { /* priv */ lock: &RWlock, drop { } } /// The "read permission" token used for rwlock.write_downgrade(). -struct RWlockReadMode { priv lock: &RWlock, drop { } } +pub struct RWlockReadMode { priv lock: &RWlock, drop { } } impl &RWlockWriteMode { /// Access the pre-downgrade rwlock in write mode. @@ -777,7 +773,7 @@ mod tests { let m = ~Mutex(); let m2 = ~m.clone(); let mut sharedstate = ~0; - let ptr = ptr::addr_of(*sharedstate); + let ptr = ptr::p2::addr_of(&(*sharedstate)); do task::spawn { let sharedstate: &mut int = unsafe { cast::reinterpret_cast(&ptr) }; @@ -840,7 +836,7 @@ mod tests { for num_waiters.times { let mi = ~m.clone(); let (chan, port) = pipes::stream(); - vec::push(ports, port); + ports.push(port); do task::spawn { do mi.lock_cond |cond| { chan.send(()); @@ -930,7 +926,7 @@ mod tests { for 2.times { let (c,p) = pipes::stream(); let c = ~mut Some(c); - vec::push(sibling_convos, p); + sibling_convos.push(p); let mi = ~m2.clone(); // spawn sibling task do task::spawn { // linked @@ -961,7 +957,7 @@ mod tests { drop { self.c.send(()); } } - fn SendOnFailure(+c: pipes::Chan<()>) -> SendOnFailure { + fn SendOnFailure(c: pipes::Chan<()>) -> SendOnFailure { SendOnFailure { c: c } @@ -1042,14 +1038,14 @@ mod tests { } } #[cfg(test)] - fn test_rwlock_exclusion(+x: ~RWlock, mode1: RWlockMode, + fn test_rwlock_exclusion(x: ~RWlock, mode1: RWlockMode, mode2: RWlockMode) { // Test mutual exclusion between readers and writers. Just like the // mutex mutual exclusion test, a ways above. let (c,p) = pipes::stream(); let x2 = ~x.clone(); let mut sharedstate = ~0; - let ptr = ptr::addr_of(*sharedstate); + let ptr = ptr::p2::addr_of(&(*sharedstate)); do task::spawn { let sharedstate: &mut int = unsafe { cast::reinterpret_cast(&ptr) }; @@ -1087,7 +1083,7 @@ mod tests { test_rwlock_exclusion(~RWlock(), Downgrade, Downgrade); } #[cfg(test)] - fn test_rwlock_handshake(+x: ~RWlock, mode1: RWlockMode, + fn test_rwlock_handshake(x: ~RWlock, mode1: RWlockMode, mode2: RWlockMode, make_mode2_go_first: bool) { // Much like sem_multi_resource. let x2 = ~x.clone(); @@ -1194,7 +1190,7 @@ mod tests { for num_waiters.times { let xi = ~x.clone(); let (chan, port) = pipes::stream(); - vec::push(ports, port); + ports.push(port); do task::spawn { do lock_cond(xi, dg1) |cond| { chan.send(()); diff --git a/src/libstd/tempfile.rs b/src/libstd/tempfile.rs index 8b6b306d6b61..37fcbf6f4caa 100644 --- a/src/libstd/tempfile.rs +++ b/src/libstd/tempfile.rs @@ -1,12 +1,11 @@ //! Temporary files and directories #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use core::option; use option::{None, Some}; -fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option { +pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option { let r = rand::Rng(); let mut i = 0u; while (i < 1000u) { @@ -24,8 +23,8 @@ fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option { fn test_mkdtemp() { let r = mkdtemp(&Path("."), "foobar"); match r { - Some(p) => { - os::remove_dir(&p); + Some(ref p) => { + os::remove_dir(p); assert(str::ends_with(p.to_str(), "foobar")); } _ => assert(false) diff --git a/src/libstd/term.rs b/src/libstd/term.rs index 6a264161bc75..2c12fd11e6ee 100644 --- a/src/libstd/term.rs +++ b/src/libstd/term.rs @@ -1,46 +1,45 @@ //! Simple ANSI color library #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; use core::Option; // FIXME (#2807): Windows support. -const color_black: u8 = 0u8; -const color_red: u8 = 1u8; -const color_green: u8 = 2u8; -const color_yellow: u8 = 3u8; -const color_blue: u8 = 4u8; -const color_magenta: u8 = 5u8; -const color_cyan: u8 = 6u8; -const color_light_gray: u8 = 7u8; -const color_light_grey: u8 = 7u8; -const color_dark_gray: u8 = 8u8; -const color_dark_grey: u8 = 8u8; -const color_bright_red: u8 = 9u8; -const color_bright_green: u8 = 10u8; -const color_bright_yellow: u8 = 11u8; -const color_bright_blue: u8 = 12u8; -const color_bright_magenta: u8 = 13u8; -const color_bright_cyan: u8 = 14u8; -const color_bright_white: u8 = 15u8; +pub const color_black: u8 = 0u8; +pub const color_red: u8 = 1u8; +pub const color_green: u8 = 2u8; +pub const color_yellow: u8 = 3u8; +pub const color_blue: u8 = 4u8; +pub const color_magenta: u8 = 5u8; +pub const color_cyan: u8 = 6u8; +pub const color_light_gray: u8 = 7u8; +pub const color_light_grey: u8 = 7u8; +pub const color_dark_gray: u8 = 8u8; +pub const color_dark_grey: u8 = 8u8; +pub const color_bright_red: u8 = 9u8; +pub const color_bright_green: u8 = 10u8; +pub const color_bright_yellow: u8 = 11u8; +pub const color_bright_blue: u8 = 12u8; +pub const color_bright_magenta: u8 = 13u8; +pub const color_bright_cyan: u8 = 14u8; +pub const color_bright_white: u8 = 15u8; -fn esc(writer: io::Writer) { writer.write(~[0x1bu8, '[' as u8]); } +pub fn esc(writer: io::Writer) { writer.write(~[0x1bu8, '[' as u8]); } /// Reset the foreground and background colors to default -fn reset(writer: io::Writer) { +pub fn reset(writer: io::Writer) { esc(writer); writer.write(~['0' as u8, 'm' as u8]); } /// Returns true if the terminal supports color -fn color_supported() -> bool { +pub fn color_supported() -> bool { let supported_terms = ~[~"xterm-color", ~"xterm", ~"screen-bce", ~"xterm-256color"]; return match os::getenv(~"TERM") { - option::Some(env) => { + option::Some(ref env) => { for vec::each(supported_terms) |term| { - if *term == env { return true; } + if *term == *env { return true; } } false } @@ -48,7 +47,7 @@ fn color_supported() -> bool { }; } -fn set_color(writer: io::Writer, first_char: u8, color: u8) { +pub fn set_color(writer: io::Writer, first_char: u8, color: u8) { assert (color < 16u8); esc(writer); let mut color = color; @@ -57,12 +56,12 @@ fn set_color(writer: io::Writer, first_char: u8, color: u8) { } /// Set the foreground color -fn fg(writer: io::Writer, color: u8) { +pub fn fg(writer: io::Writer, color: u8) { return set_color(writer, '3' as u8, color); } /// Set the background color -fn bg(writer: io::Writer, color: u8) { +pub fn bg(writer: io::Writer, color: u8) { return set_color(writer, '4' as u8, color); } diff --git a/src/libstd/test.rs b/src/libstd/test.rs index faa22ae09671..5fb7df1f68c6 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -5,8 +5,7 @@ // simplest interface possible for representing and running tests // while providing a base that other test frameworks may build off of. -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +#[warn(deprecated_mode)]; use core::cmp::Eq; use either::Either; @@ -16,17 +15,6 @@ use libc::size_t; use task::TaskBuilder; use comm = core::comm; -export TestName; -export TestFn; -export TestDesc; -export test_main; -export TestResult; -export TestOpts; -export TrOk; -export TrFailed; -export TrIgnored; -export run_tests_console; - #[abi = "cdecl"] extern mod rustrt { #[legacy_exports]; @@ -37,17 +25,17 @@ extern mod rustrt { // paths; i.e. it should be a series of identifiers seperated by double // colons. This way if some test runner wants to arrange the tests // hierarchically it may. -type TestName = ~str; +pub type TestName = ~str; // A function that runs a test. If the function returns successfully, // the test succeeds; if the function fails then the test fails. We // may need to come up with a more clever definition of test in order // to support isolation of tests into tasks. -type TestFn = fn~(); +pub type TestFn = fn~(); // The definition of a single test. A test runner will run a list of // these. -type TestDesc = { +pub type TestDesc = { name: TestName, testfn: TestFn, ignore: bool, @@ -56,16 +44,16 @@ type TestDesc = { // The default console test runner. It accepts the command line // arguments and a vector of test_descs (generated at compile time). -fn test_main(args: &[~str], tests: &[TestDesc]) { +pub fn test_main(args: &[~str], tests: &[TestDesc]) { let opts = match parse_opts(args) { - either::Left(o) => o, - either::Right(m) => fail m + either::Left(move o) => o, + either::Right(move m) => fail m }; if !run_tests_console(&opts, tests) { fail ~"Some tests failed"; } } -type TestOpts = {filter: Option<~str>, run_ignored: bool, +pub type TestOpts = {filter: Option<~str>, run_ignored: bool, logfile: Option<~str>}; type OptRes = Either; @@ -76,8 +64,8 @@ fn parse_opts(args: &[~str]) -> OptRes { let opts = ~[getopts::optflag(~"ignored"), getopts::optopt(~"logfile")]; let matches = match getopts::getopts(args_, opts) { - Ok(m) => m, - Err(f) => return either::Right(getopts::fail_str(f)) + Ok(move m) => m, + Err(move f) => return either::Right(getopts::fail_str(f)) }; let filter = @@ -94,7 +82,7 @@ fn parse_opts(args: &[~str]) -> OptRes { return either::Left(test_opts); } -enum TestResult { TrOk, TrFailed, TrIgnored, } +pub enum TestResult { TrOk, TrFailed, TrIgnored, } impl TestResult : Eq { pure fn eq(other: &TestResult) -> bool { @@ -114,19 +102,20 @@ type ConsoleTestState = mut failures: ~[TestDesc]}; // A simple console test runner -fn run_tests_console(opts: &TestOpts, +pub fn run_tests_console(opts: &TestOpts, tests: &[TestDesc]) -> bool { fn callback(event: &TestEvent, st: ConsoleTestState) { debug!("callback(event=%?)", event); match *event { - TeFiltered(filtered_tests) => { - st.total = vec::len(filtered_tests); + TeFiltered(ref filtered_tests) => { + st.total = filtered_tests.len(); let noun = if st.total != 1u { ~"tests" } else { ~"test" }; st.out.write_line(fmt!("\nrunning %u %s", st.total, noun)); } - TeWait(test) => st.out.write_str(fmt!("test %s ... ", test.name)), - TeResult(test, result) => { + TeWait(ref test) => st.out.write_str( + fmt!("test %s ... ", test.name)), + TeResult(copy test, result) => { match st.log_out { Some(f) => write_log(f, result, &test), None => () @@ -141,7 +130,7 @@ fn run_tests_console(opts: &TestOpts, st.failed += 1u; write_failed(st.out, st.use_color); st.out.write_line(~""); - vec::push(st.failures, copy test); + st.failures.push(test); } TrIgnored => { st.ignored += 1u; @@ -154,11 +143,11 @@ fn run_tests_console(opts: &TestOpts, } let log_out = match opts.logfile { - Some(path) => match io::file_writer(&Path(path), + Some(ref path) => match io::file_writer(&Path(*path), ~[io::Create, io::Truncate]) { result::Ok(w) => Some(w), - result::Err(s) => { - fail(fmt!("can't open output file: %s", s)) + result::Err(ref s) => { + fail(fmt!("can't open output file: %s", *s)) } }, None => None @@ -281,7 +270,7 @@ enum TestEvent { type MonitorMsg = (TestDesc, TestResult); fn run_tests(opts: &TestOpts, tests: &[TestDesc], - callback: fn@(TestEvent)) { + callback: fn@(e: TestEvent)) { let mut filtered_tests = filter_tests(opts, tests); callback(TeFiltered(copy filtered_tests)); @@ -347,7 +336,7 @@ fn filter_tests(opts: &TestOpts, } else { let filter_str = match opts.filter { - option::Some(f) => f, + option::Some(copy f) => f, option::None => ~"" }; @@ -358,7 +347,7 @@ fn filter_tests(opts: &TestOpts, } else { return option::None; } } - vec::filter_map(filtered, |x| filter_fn(&x, filter_str)) + vec::filter_map(filtered, |x| filter_fn(x, filter_str)) }; // Maybe pull out the ignored test and unignore them @@ -374,7 +363,7 @@ fn filter_tests(opts: &TestOpts, } else { return option::None; } }; - vec::filter_map(filtered, |x| filter(&x)) + vec::filter_map(filtered, |x| filter(x)) }; // Sort the tests alphabetically @@ -390,7 +379,7 @@ fn filter_tests(opts: &TestOpts, type TestFuture = {test: TestDesc, wait: fn@() -> TestResult}; -fn run_test(+test: TestDesc, monitor_ch: comm::Chan) { +fn run_test(test: TestDesc, monitor_ch: comm::Chan) { if test.ignore { core::comm::send(monitor_ch, (copy test, TrIgnored)); return; @@ -491,7 +480,7 @@ mod tests { fn first_free_arg_should_be_a_filter() { let args = ~[~"progname", ~"filter"]; let opts = match parse_opts(args) { - either::Left(o) => o, + either::Left(copy o) => o, _ => fail ~"Malformed arg in first_free_arg_should_be_a_filter" }; assert ~"filter" == opts.filter.get(); @@ -501,7 +490,7 @@ mod tests { fn parse_ignored_flag() { let args = ~[~"progname", ~"filter", ~"--ignored"]; let opts = match parse_opts(args) { - either::Left(o) => o, + either::Left(copy o) => o, _ => fail ~"Malformed arg in parse_ignored_flag" }; assert (opts.run_ignored); @@ -545,7 +534,7 @@ mod tests { for vec::each(names) |name| { let test = {name: *name, testfn: copy testfn, ignore: false, should_fail: false}; - vec::push(tests, test); + tests.push(test); } tests }; @@ -564,7 +553,7 @@ mod tests { for vec::each(pairs) |p| { match *p { - (a, b) => { assert (a == b.name); } + (ref a, ref b) => { assert (*a == b.name); } } } } diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 64f65d15a93e..aef3bb2ac0ad 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -1,25 +1,10 @@ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap use core::cmp::Eq; use libc::{c_char, c_int, c_long, size_t, time_t}; -use io::Reader; +use io::{Reader, ReaderUtil}; use result::{Result, Ok, Err}; -export - Timespec, - get_time, - precise_time_ns, - precise_time_s, - tzset, - Tm, - empty_tm, - now, - at, - now_utc, - at_utc, - strptime; - #[abi = "cdecl"] extern mod rustrt { #[legacy_exports]; @@ -35,7 +20,7 @@ extern mod rustrt { } /// A record specifying a time value in seconds and nanoseconds. -type Timespec = {sec: i64, nsec: i32}; +pub type Timespec = {sec: i64, nsec: i32}; impl Timespec : Eq { pure fn eq(other: &Timespec) -> bool { @@ -48,7 +33,7 @@ impl Timespec : Eq { * Returns the current time as a `timespec` containing the seconds and * nanoseconds since 1970-01-01T00:00:00Z. */ -fn get_time() -> Timespec { +pub fn get_time() -> Timespec { let mut sec = 0i64; let mut nsec = 0i32; rustrt::get_time(sec, nsec); @@ -59,7 +44,7 @@ fn get_time() -> Timespec { * Returns the current value of a high-resolution performance counter * in nanoseconds since an unspecified epoch. */ -fn precise_time_ns() -> u64 { +pub fn precise_time_ns() -> u64 { let mut ns = 0u64; rustrt::precise_time_ns(ns); ns @@ -69,11 +54,11 @@ fn precise_time_ns() -> u64 { * Returns the current value of a high-resolution performance counter * in seconds since an unspecified epoch. */ -fn precise_time_s() -> float { +pub fn precise_time_s() -> float { return (precise_time_ns() as float) / 1000000000.; } -fn tzset() { +pub fn tzset() { rustrt::rust_tzset(); } @@ -110,7 +95,7 @@ impl Tm_ : Eq { pure fn ne(other: &Tm_) -> bool { !self.eq(other) } } -enum Tm { +pub enum Tm { Tm_(Tm_) } @@ -119,7 +104,7 @@ impl Tm : Eq { pure fn ne(other: &Tm) -> bool { *self != *(*other) } } -fn empty_tm() -> Tm { +pub fn empty_tm() -> Tm { Tm_({ tm_sec: 0_i32, tm_min: 0_i32, @@ -137,7 +122,7 @@ fn empty_tm() -> Tm { } /// Returns the specified time in UTC -fn at_utc(clock: Timespec) -> Tm { +pub fn at_utc(clock: Timespec) -> Tm { let mut {sec, nsec} = clock; let mut tm = empty_tm(); rustrt::rust_gmtime(sec, nsec, tm); @@ -145,12 +130,12 @@ fn at_utc(clock: Timespec) -> Tm { } /// Returns the current time in UTC -fn now_utc() -> Tm { +pub fn now_utc() -> Tm { at_utc(get_time()) } /// Returns the specified time in the local timezone -fn at(clock: Timespec) -> Tm { +pub fn at(clock: Timespec) -> Tm { let mut {sec, nsec} = clock; let mut tm = empty_tm(); rustrt::rust_localtime(sec, nsec, tm); @@ -158,12 +143,12 @@ fn at(clock: Timespec) -> Tm { } /// Returns the current time in the local timezone -fn now() -> Tm { +pub fn now() -> Tm { at(get_time()) } /// Parses the time from the string according to the format string. -fn strptime(s: &str, format: &str) -> Result { +pub fn strptime(s: &str, format: &str) -> Result { type TmMut = { mut tm_sec: i32, mut tm_min: i32, @@ -576,7 +561,7 @@ fn strptime(s: &str, format: &str) -> Result { match rdr.read_char() { '%' => match parse_type(s, pos, rdr.read_char(), &tm) { Ok(next) => pos = next, - Err(e) => { result = Err(e); break; } + Err(copy e) => { result = Err(e); break; } }, c => { if c != ch { break } @@ -604,7 +589,7 @@ fn strptime(s: &str, format: &str) -> Result { } } -fn strftime(format: &str, +tm: Tm) -> ~str { +fn strftime(format: &str, tm: Tm) -> ~str { fn parse_type(ch: char, tm: &Tm) -> ~str { //FIXME (#2350): Implement missing types. let die = || #fmt("strftime: can't understand this format %c ", @@ -979,7 +964,7 @@ mod tests { tzset(); match strptime(~"", ~"") { - Ok(tm) => { + Ok(ref tm) => { assert tm.tm_sec == 0_i32; assert tm.tm_min == 0_i32; assert tm.tm_hour == 0_i32; @@ -1001,8 +986,8 @@ mod tests { == Err(~"Invalid time"); match strptime(~"Fri Feb 13 15:31:30 2009", format) { - Err(e) => fail e, - Ok(tm) => { + Err(copy e) => fail e, + Ok(ref tm) => { assert tm.tm_sec == 30_i32; assert tm.tm_min == 31_i32; assert tm.tm_hour == 15_i32; @@ -1020,8 +1005,8 @@ mod tests { fn test(s: &str, format: &str) -> bool { match strptime(s, format) { - Ok(tm) => tm.strftime(format) == str::from_slice(s), - Err(e) => fail e + Ok(ref tm) => tm.strftime(format) == str::from_slice(s), + Err(copy e) => fail e } } diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs index 1476d6bdf313..2aca87b942ec 100644 --- a/src/libstd/timer.rs +++ b/src/libstd/timer.rs @@ -1,15 +1,12 @@ //! Utilities that leverage libuv's `uv_timer_*` API -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +// tjc: forbid deprecated modes again after snap use uv = uv; use uv::iotask; use iotask::IoTask; use comm = core::comm; -export delayed_send, sleep, recv_timeout; - /** * Wait for timeout period then send provided value over a channel * @@ -26,14 +23,14 @@ export delayed_send, sleep, recv_timeout; * * ch - a channel of type T to send a `val` on * * val - a value of type T to send over the provided `ch` */ -fn delayed_send(iotask: IoTask, - msecs: uint, ch: comm::Chan, +val: T) { +pub fn delayed_send(iotask: IoTask, + msecs: uint, ch: comm::Chan, val: T) { unsafe { let timer_done_po = core::comm::Port::<()>(); let timer_done_ch = core::comm::Chan(timer_done_po); - let timer_done_ch_ptr = ptr::addr_of(timer_done_ch); + let timer_done_ch_ptr = ptr::addr_of(&timer_done_ch); let timer = uv::ll::timer_t(); - let timer_ptr = ptr::addr_of(timer); + let timer_ptr = ptr::addr_of(&timer); do iotask::interact(iotask) |loop_ptr| unsafe { let init_result = uv::ll::timer_init(loop_ptr, timer_ptr); if (init_result == 0i32) { @@ -75,7 +72,7 @@ fn delayed_send(iotask: IoTask, * * `iotask` - a `uv::iotask` that the tcp request will run on * * msecs - an amount of time, in milliseconds, for the current task to block */ -fn sleep(iotask: IoTask, msecs: uint) { +pub fn sleep(iotask: IoTask, msecs: uint) { let exit_po = core::comm::Port::<()>(); let exit_ch = core::comm::Chan(exit_po); delayed_send(iotask, msecs, exit_ch, ()); @@ -102,7 +99,7 @@ fn sleep(iotask: IoTask, msecs: uint) { * on the provided port in the allotted timeout period, then the result will * be a `some(T)`. If not, then `none` will be returned. */ -fn recv_timeout(iotask: IoTask, +pub fn recv_timeout(iotask: IoTask, msecs: uint, wait_po: comm::Port) -> Option { let timeout_po = comm::Port::<()>(); diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 598a680f7068..184dfd362796 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -5,19 +5,13 @@ * very naive algorithm, but it will probably be updated to be a * red-black tree or something else. */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; +#[warn(deprecated_mode)]; use core::cmp::{Eq, Ord}; use core::option::{Some, None}; use Option = core::Option; -export TreeMap; -export insert; -export find; -export traverse; - -type TreeMap = @mut TreeEdge; +pub type TreeMap = @mut TreeEdge; type TreeEdge = Option<@TreeNode>; @@ -29,10 +23,10 @@ enum TreeNode = { }; /// Create a treemap -fn TreeMap() -> TreeMap { @mut None } +pub fn TreeMap() -> TreeMap { @mut None } /// Insert a value into the map -fn insert(m: &mut TreeEdge, +k: K, +v: V) { +pub fn insert(m: &mut TreeEdge, +k: K, +v: V) { match copy *m { None => { *m = Some(@TreeNode({key: k, @@ -54,7 +48,7 @@ fn insert(m: &mut TreeEdge, +k: K, +v: V) { } /// Find a value based on the key -fn find(m: &const TreeEdge, +k: K) +pub fn find(m: &const TreeEdge, +k: K) -> Option { match copy *m { None => None, @@ -73,13 +67,13 @@ fn find(m: &const TreeEdge, +k: K) } /// Visit all pairs in the map in order. -fn traverse(m: &const TreeEdge, f: fn(K, V)) { +pub fn traverse(m: &const TreeEdge, f: fn((&K), (&V))) { match copy *m { None => (), Some(node) => { traverse(&const node.left, f); // copy of value is req'd as f() requires an immutable ptr - f(node.key, copy node.value); + f(&node.key, © node.value); traverse(&const node.right, f); } } @@ -130,7 +124,7 @@ mod tests { fn t(n: @mut int, +k: int, +_v: ()) { assert (*n == k); *n += 1; } - traverse(m, |x,y| t(n, x, y)); + traverse(m, |x,y| t(n, *x, *y)); } #[test] diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs index e76b85297302..bafe385ed19d 100644 --- a/src/libstd/unicode.rs +++ b/src/libstd/unicode.rs @@ -1,158 +1,155 @@ #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; -mod icu { - #[legacy_exports]; - type UBool = u8; - type UProperty = int; - type UChar32 = char; +pub mod icu { + pub type UBool = u8; + pub type UProperty = int; + pub type UChar32 = char; - const TRUE : u8 = 1u8; - const FALSE : u8 = 1u8; + pub const TRUE : u8 = 1u8; + pub const FALSE : u8 = 1u8; - const UCHAR_ALPHABETIC : UProperty = 0; - const UCHAR_BINARY_START : UProperty = 0; // = UCHAR_ALPHABETIC - const UCHAR_ASCII_HEX_DIGIT : UProperty = 1; - const UCHAR_BIDI_CONTROL : UProperty = 2; + pub const UCHAR_ALPHABETIC : UProperty = 0; + pub const UCHAR_BINARY_START : UProperty = 0; // = UCHAR_ALPHABETIC + pub const UCHAR_ASCII_HEX_DIGIT : UProperty = 1; + pub const UCHAR_BIDI_CONTROL : UProperty = 2; - const UCHAR_BIDI_MIRRORED : UProperty = 3; - const UCHAR_DASH : UProperty = 4; - const UCHAR_DEFAULT_IGNORABLE_CODE_POINT : UProperty = 5; - const UCHAR_DEPRECATED : UProperty = 6; + pub const UCHAR_BIDI_MIRRORED : UProperty = 3; + pub const UCHAR_DASH : UProperty = 4; + pub const UCHAR_DEFAULT_IGNORABLE_CODE_POINT : UProperty = 5; + pub const UCHAR_DEPRECATED : UProperty = 6; - const UCHAR_DIACRITIC : UProperty = 7; - const UCHAR_EXTENDER : UProperty = 8; - const UCHAR_FULL_COMPOSITION_EXCLUSION : UProperty = 9; - const UCHAR_GRAPHEME_BASE : UProperty = 10; + pub const UCHAR_DIACRITIC : UProperty = 7; + pub const UCHAR_EXTENDER : UProperty = 8; + pub const UCHAR_FULL_COMPOSITION_EXCLUSION : UProperty = 9; + pub const UCHAR_GRAPHEME_BASE : UProperty = 10; - const UCHAR_GRAPHEME_EXTEND : UProperty = 11; - const UCHAR_GRAPHEME_LINK : UProperty = 12; - const UCHAR_HEX_DIGIT : UProperty = 13; - const UCHAR_HYPHEN : UProperty = 14; + pub const UCHAR_GRAPHEME_EXTEND : UProperty = 11; + pub const UCHAR_GRAPHEME_LINK : UProperty = 12; + pub const UCHAR_HEX_DIGIT : UProperty = 13; + pub const UCHAR_HYPHEN : UProperty = 14; - const UCHAR_ID_CONTINUE : UProperty = 15; - const UCHAR_ID_START : UProperty = 16; - const UCHAR_IDEOGRAPHIC : UProperty = 17; - const UCHAR_IDS_BINARY_OPERATOR : UProperty = 18; + pub const UCHAR_ID_CONTINUE : UProperty = 15; + pub const UCHAR_ID_START : UProperty = 16; + pub const UCHAR_IDEOGRAPHIC : UProperty = 17; + pub const UCHAR_IDS_BINARY_OPERATOR : UProperty = 18; - const UCHAR_IDS_TRINARY_OPERATOR : UProperty = 19; - const UCHAR_JOIN_CONTROL : UProperty = 20; - const UCHAR_LOGICAL_ORDER_EXCEPTION : UProperty = 21; - const UCHAR_LOWERCASE : UProperty = 22; + pub const UCHAR_IDS_TRINARY_OPERATOR : UProperty = 19; + pub const UCHAR_JOIN_CONTROL : UProperty = 20; + pub const UCHAR_LOGICAL_ORDER_EXCEPTION : UProperty = 21; + pub const UCHAR_LOWERCASE : UProperty = 22; - const UCHAR_MATH : UProperty = 23; - const UCHAR_NONCHARACTER_CODE_POINT : UProperty = 24; - const UCHAR_QUOTATION_MARK : UProperty = 25; - const UCHAR_RADICAL : UProperty = 26; + pub const UCHAR_MATH : UProperty = 23; + pub const UCHAR_NONCHARACTER_CODE_POINT : UProperty = 24; + pub const UCHAR_QUOTATION_MARK : UProperty = 25; + pub const UCHAR_RADICAL : UProperty = 26; - const UCHAR_SOFT_DOTTED : UProperty = 27; - const UCHAR_TERMINAL_PUNCTUATION : UProperty = 28; - const UCHAR_UNIFIED_IDEOGRAPH : UProperty = 29; - const UCHAR_UPPERCASE : UProperty = 30; + pub const UCHAR_SOFT_DOTTED : UProperty = 27; + pub const UCHAR_TERMINAL_PUNCTUATION : UProperty = 28; + pub const UCHAR_UNIFIED_IDEOGRAPH : UProperty = 29; + pub const UCHAR_UPPERCASE : UProperty = 30; - const UCHAR_WHITE_SPACE : UProperty = 31; - const UCHAR_XID_CONTINUE : UProperty = 32; - const UCHAR_XID_START : UProperty = 33; - const UCHAR_CASE_SENSITIVE : UProperty = 34; + pub const UCHAR_WHITE_SPACE : UProperty = 31; + pub const UCHAR_XID_CONTINUE : UProperty = 32; + pub const UCHAR_XID_START : UProperty = 33; + pub const UCHAR_CASE_SENSITIVE : UProperty = 34; - const UCHAR_S_TERM : UProperty = 35; - const UCHAR_VARIATION_SELECTOR : UProperty = 36; - const UCHAR_NFD_INERT : UProperty = 37; - const UCHAR_NFKD_INERT : UProperty = 38; + pub const UCHAR_S_TERM : UProperty = 35; + pub const UCHAR_VARIATION_SELECTOR : UProperty = 36; + pub const UCHAR_NFD_INERT : UProperty = 37; + pub const UCHAR_NFKD_INERT : UProperty = 38; - const UCHAR_NFC_INERT : UProperty = 39; - const UCHAR_NFKC_INERT : UProperty = 40; - const UCHAR_SEGMENT_STARTER : UProperty = 41; - const UCHAR_PATTERN_SYNTAX : UProperty = 42; + pub const UCHAR_NFC_INERT : UProperty = 39; + pub const UCHAR_NFKC_INERT : UProperty = 40; + pub const UCHAR_SEGMENT_STARTER : UProperty = 41; + pub const UCHAR_PATTERN_SYNTAX : UProperty = 42; - const UCHAR_PATTERN_WHITE_SPACE : UProperty = 43; - const UCHAR_POSIX_ALNUM : UProperty = 44; - const UCHAR_POSIX_BLANK : UProperty = 45; - const UCHAR_POSIX_GRAPH : UProperty = 46; + pub const UCHAR_PATTERN_WHITE_SPACE : UProperty = 43; + pub const UCHAR_POSIX_ALNUM : UProperty = 44; + pub const UCHAR_POSIX_BLANK : UProperty = 45; + pub const UCHAR_POSIX_GRAPH : UProperty = 46; - const UCHAR_POSIX_PRINT : UProperty = 47; - const UCHAR_POSIX_XDIGIT : UProperty = 48; - const UCHAR_CASED : UProperty = 49; - const UCHAR_CASE_IGNORABLE : UProperty = 50; + pub const UCHAR_POSIX_PRINT : UProperty = 47; + pub const UCHAR_POSIX_XDIGIT : UProperty = 48; + pub const UCHAR_CASED : UProperty = 49; + pub const UCHAR_CASE_IGNORABLE : UProperty = 50; - const UCHAR_CHANGES_WHEN_LOWERCASED : UProperty = 51; - const UCHAR_CHANGES_WHEN_UPPERCASED : UProperty = 52; - const UCHAR_CHANGES_WHEN_TITLECASED : UProperty = 53; - const UCHAR_CHANGES_WHEN_CASEFOLDED : UProperty = 54; + pub const UCHAR_CHANGES_WHEN_LOWERCASED : UProperty = 51; + pub const UCHAR_CHANGES_WHEN_UPPERCASED : UProperty = 52; + pub const UCHAR_CHANGES_WHEN_TITLECASED : UProperty = 53; + pub const UCHAR_CHANGES_WHEN_CASEFOLDED : UProperty = 54; - const UCHAR_CHANGES_WHEN_CASEMAPPED : UProperty = 55; - const UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED : UProperty = 56; - const UCHAR_BINARY_LIMIT : UProperty = 57; - const UCHAR_BIDI_CLASS : UProperty = 0x1000; + pub const UCHAR_CHANGES_WHEN_CASEMAPPED : UProperty = 55; + pub const UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED : UProperty = 56; + pub const UCHAR_BINARY_LIMIT : UProperty = 57; + pub const UCHAR_BIDI_CLASS : UProperty = 0x1000; - const UCHAR_INT_START : UProperty = 0x1000; // UCHAR_BIDI_CLASS - const UCHAR_BLOCK : UProperty = 0x1001; - const UCHAR_CANONICAL_COMBINING_CLASS : UProperty = 0x1002; - const UCHAR_DECOMPOSITION_TYPE : UProperty = 0x1003; + pub const UCHAR_INT_START : UProperty = 0x1000; // UCHAR_BIDI_CLASS + pub const UCHAR_BLOCK : UProperty = 0x1001; + pub const UCHAR_CANONICAL_COMBINING_CLASS : UProperty = 0x1002; + pub const UCHAR_DECOMPOSITION_TYPE : UProperty = 0x1003; - const UCHAR_EAST_ASIAN_WIDTH : UProperty = 0x1004; - const UCHAR_GENERAL_CATEGORY : UProperty = 0x1005; - const UCHAR_JOINING_GROUP : UProperty = 0x1006; - const UCHAR_JOINING_TYPE : UProperty = 0x1007; + pub const UCHAR_EAST_ASIAN_WIDTH : UProperty = 0x1004; + pub const UCHAR_GENERAL_CATEGORY : UProperty = 0x1005; + pub const UCHAR_JOINING_GROUP : UProperty = 0x1006; + pub const UCHAR_JOINING_TYPE : UProperty = 0x1007; - const UCHAR_LINE_BREAK : UProperty = 0x1008; - const UCHAR_NUMERIC_TYPE : UProperty = 0x1009; - const UCHAR_SCRIPT : UProperty = 0x100A; - const UCHAR_HANGUL_SYLLABLE_TYPE : UProperty = 0x100B; + pub const UCHAR_LINE_BREAK : UProperty = 0x1008; + pub const UCHAR_NUMERIC_TYPE : UProperty = 0x1009; + pub const UCHAR_SCRIPT : UProperty = 0x100A; + pub const UCHAR_HANGUL_SYLLABLE_TYPE : UProperty = 0x100B; - const UCHAR_NFD_QUICK_CHECK : UProperty = 0x100C; - const UCHAR_NFKD_QUICK_CHECK : UProperty = 0x100D; - const UCHAR_NFC_QUICK_CHECK : UProperty = 0x100E; - const UCHAR_NFKC_QUICK_CHECK : UProperty = 0x100F; + pub const UCHAR_NFD_QUICK_CHECK : UProperty = 0x100C; + pub const UCHAR_NFKD_QUICK_CHECK : UProperty = 0x100D; + pub const UCHAR_NFC_QUICK_CHECK : UProperty = 0x100E; + pub const UCHAR_NFKC_QUICK_CHECK : UProperty = 0x100F; - const UCHAR_LEAD_CANONICAL_COMBINING_CLASS : UProperty = 0x1010; - const UCHAR_TRAIL_CANONICAL_COMBINING_CLASS : UProperty = 0x1011; - const UCHAR_GRAPHEME_CLUSTER_BREAK : UProperty = 0x1012; - const UCHAR_SENTENCE_BREAK : UProperty = 0x1013; + pub const UCHAR_LEAD_CANONICAL_COMBINING_CLASS : UProperty = 0x1010; + pub const UCHAR_TRAIL_CANONICAL_COMBINING_CLASS : UProperty = 0x1011; + pub const UCHAR_GRAPHEME_CLUSTER_BREAK : UProperty = 0x1012; + pub const UCHAR_SENTENCE_BREAK : UProperty = 0x1013; - const UCHAR_WORD_BREAK : UProperty = 0x1014; - const UCHAR_INT_LIMIT : UProperty = 0x1015; + pub const UCHAR_WORD_BREAK : UProperty = 0x1014; + pub const UCHAR_INT_LIMIT : UProperty = 0x1015; - const UCHAR_GENERAL_CATEGORY_MASK : UProperty = 0x2000; - const UCHAR_MASK_START : UProperty = 0x2000; + pub const UCHAR_GENERAL_CATEGORY_MASK : UProperty = 0x2000; + pub const UCHAR_MASK_START : UProperty = 0x2000; // = UCHAR_GENERAL_CATEGORY_MASK - const UCHAR_MASK_LIMIT : UProperty = 0x2001; + pub const UCHAR_MASK_LIMIT : UProperty = 0x2001; - const UCHAR_NUMERIC_VALUE : UProperty = 0x3000; - const UCHAR_DOUBLE_START : UProperty = 0x3000; + pub const UCHAR_NUMERIC_VALUE : UProperty = 0x3000; + pub const UCHAR_DOUBLE_START : UProperty = 0x3000; // = UCHAR_NUMERIC_VALUE - const UCHAR_DOUBLE_LIMIT : UProperty = 0x3001; + pub const UCHAR_DOUBLE_LIMIT : UProperty = 0x3001; - const UCHAR_AGE : UProperty = 0x4000; - const UCHAR_STRING_START : UProperty = 0x4000; // = UCHAR_AGE - const UCHAR_BIDI_MIRRORING_GLYPH : UProperty = 0x4001; - const UCHAR_CASE_FOLDING : UProperty = 0x4002; + pub const UCHAR_AGE : UProperty = 0x4000; + pub const UCHAR_STRING_START : UProperty = 0x4000; // = UCHAR_AGE + pub const UCHAR_BIDI_MIRRORING_GLYPH : UProperty = 0x4001; + pub const UCHAR_CASE_FOLDING : UProperty = 0x4002; - const UCHAR_ISO_COMMENT : UProperty = 0x4003; - const UCHAR_LOWERCASE_MAPPING : UProperty = 0x4004; - const UCHAR_NAME : UProperty = 0x4005; - const UCHAR_SIMPLE_CASE_FOLDING : UProperty = 0x4006; + pub const UCHAR_ISO_COMMENT : UProperty = 0x4003; + pub const UCHAR_LOWERCASE_MAPPING : UProperty = 0x4004; + pub const UCHAR_NAME : UProperty = 0x4005; + pub const UCHAR_SIMPLE_CASE_FOLDING : UProperty = 0x4006; - const UCHAR_SIMPLE_LOWERCASE_MAPPING : UProperty = 0x4007; - const UCHAR_SIMPLE_TITLECASE_MAPPING : UProperty = 0x4008; - const UCHAR_SIMPLE_UPPERCASE_MAPPING : UProperty = 0x4009; - const UCHAR_TITLECASE_MAPPING : UProperty = 0x400A; + pub const UCHAR_SIMPLE_LOWERCASE_MAPPING : UProperty = 0x4007; + pub const UCHAR_SIMPLE_TITLECASE_MAPPING : UProperty = 0x4008; + pub const UCHAR_SIMPLE_UPPERCASE_MAPPING : UProperty = 0x4009; + pub const UCHAR_TITLECASE_MAPPING : UProperty = 0x400A; - const UCHAR_UNICODE_1_NAME : UProperty = 0x400B; - const UCHAR_UPPERCASE_MAPPING : UProperty = 0x400C; - const UCHAR_STRING_LIMIT : UProperty = 0x400D; + pub const UCHAR_UNICODE_1_NAME : UProperty = 0x400B; + pub const UCHAR_UPPERCASE_MAPPING : UProperty = 0x400C; + pub const UCHAR_STRING_LIMIT : UProperty = 0x400D; - const UCHAR_SCRIPT_EXTENSIONS : UProperty = 0x7000; - const UCHAR_OTHER_PROPERTY_START : UProperty = 0x7000; + pub const UCHAR_SCRIPT_EXTENSIONS : UProperty = 0x7000; + pub const UCHAR_OTHER_PROPERTY_START : UProperty = 0x7000; // = UCHAR_SCRIPT_EXTENSIONS; - const UCHAR_OTHER_PROPERTY_LIMIT : UProperty = 0x7001; + pub const UCHAR_OTHER_PROPERTY_LIMIT : UProperty = 0x7001; - const UCHAR_INVALID_CODE : UProperty = -1; + pub const UCHAR_INVALID_CODE : UProperty = -1; #[link_name = "icuuc"] #[abi = "cdecl"] - extern mod libicu { - #[legacy_exports]; + pub extern mod libicu { pure fn u_hasBinaryProperty(c: UChar32, which: UProperty) -> UBool; pure fn u_isdigit(c: UChar32) -> UBool; pure fn u_islower(c: UChar32) -> UBool; @@ -163,12 +160,12 @@ mod icu { } } -pure fn is_XID_start(c: char) -> bool { +pub pure fn is_XID_start(c: char) -> bool { return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START) == icu::TRUE; } -pure fn is_XID_continue(c: char) -> bool { +pub pure fn is_XID_continue(c: char) -> bool { return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START) == icu::TRUE; } @@ -178,7 +175,7 @@ Function: is_digit Returns true if a character is a digit. */ -pure fn is_digit(c: char) -> bool { +pub pure fn is_digit(c: char) -> bool { return icu::libicu::u_isdigit(c) == icu::TRUE; } @@ -187,7 +184,7 @@ Function: is_lower Returns true if a character is a lowercase letter. */ -pure fn is_lower(c: char) -> bool { +pub pure fn is_lower(c: char) -> bool { return icu::libicu::u_islower(c) == icu::TRUE; } @@ -196,7 +193,7 @@ Function: is_space Returns true if a character is space. */ -pure fn is_space(c: char) -> bool { +pub pure fn is_space(c: char) -> bool { return icu::libicu::u_isspace(c) == icu::TRUE; } @@ -205,13 +202,12 @@ Function: is_upper Returns true if a character is an uppercase letter. */ -pure fn is_upper(c: char) -> bool { +pub pure fn is_upper(c: char) -> bool { return icu::libicu::u_isupper(c) == icu::TRUE; } #[cfg(test)] mod tests { - #[legacy_exports]; #[test] fn test_is_digit() { diff --git a/src/libstd/uv.rs b/src/libstd/uv.rs index 311c9f28dd84..e0fd013907c8 100644 --- a/src/libstd/uv.rs +++ b/src/libstd/uv.rs @@ -23,11 +23,6 @@ * facilities. */ -use ll = uv_ll; -export ll; - -use iotask = uv_iotask; -export iotask; - -use global_loop = uv_global_loop; -export global_loop; +pub use ll = uv_ll; +pub use iotask = uv_iotask; +pub use global_loop = uv_global_loop; diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs index cde88db031ec..869c3efa38f9 100644 --- a/src/libstd/uv_global_loop.rs +++ b/src/libstd/uv_global_loop.rs @@ -1,9 +1,6 @@ //! A process-wide libuv event loop for library use. #[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - -export get; use ll = uv_ll; use iotask = uv_iotask; @@ -16,7 +13,6 @@ use task::TaskBuilder; use either::{Left, Right}; extern mod rustrt { - #[legacy_exports]; fn rust_uv_get_kernel_global_chan_ptr() -> *libc::uintptr_t; } @@ -32,7 +28,7 @@ extern mod rustrt { * * A `hl::high_level_loop` that encapsulates communication with the global * loop. */ -fn get() -> IoTask { +pub fn get() -> IoTask { return get_monitor_task_gl(); } @@ -113,7 +109,6 @@ fn spawn_loop() -> IoTask { #[cfg(test)] mod test { - #[legacy_exports]; extern fn simple_timer_close_cb(timer_ptr: *ll::uv_timer_t) unsafe { let exit_ch_ptr = ll::get_data_for_uv_handle( timer_ptr as *libc::c_void) as *comm::Chan; @@ -139,11 +134,11 @@ mod test { fn impl_uv_hl_simple_timer(iotask: IoTask) unsafe { let exit_po = core::comm::Port::(); let exit_ch = core::comm::Chan(exit_po); - let exit_ch_ptr = ptr::addr_of(exit_ch); + let exit_ch_ptr = ptr::p2::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::addr_of(timer_handle); + let timer_ptr = ptr::p2::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); diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index 2e0088305588..4a4a34704be2 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -5,30 +5,24 @@ * `interact` function you can execute code in a uv callback. */ -#[forbid(deprecated_mode)]; -#[forbid(deprecated_pattern)]; - -export IoTask; -export spawn_iotask; -export interact; -export exit; +// tjc: forbid deprecated modes again after a snapshot use libc::c_void; -use ptr::addr_of; +use ptr::p2::addr_of; use comm = core::comm; use comm::{Port, Chan, listen}; use task::TaskBuilder; use ll = uv_ll; /// Used to abstract-away direct interaction with a libuv loop. -enum IoTask { +pub enum IoTask { IoTask_({ async_handle: *ll::uv_async_t, op_chan: Chan }) } -fn spawn_iotask(+task: task::TaskBuilder) -> IoTask { +pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask { do listen |iotask_ch| { @@ -65,7 +59,7 @@ fn spawn_iotask(+task: task::TaskBuilder) -> IoTask { * module. It is not safe to send the `loop_ptr` param to this callback out * via ports/chans. */ -unsafe fn interact(iotask: IoTask, +pub unsafe fn interact(iotask: IoTask, +cb: fn~(*c_void)) { send_msg(iotask, Interaction(move cb)); } @@ -77,7 +71,7 @@ unsafe fn interact(iotask: IoTask, * async handle and do a sanity check to make sure that all other handles are * closed, causing a failure otherwise. */ -fn exit(iotask: IoTask) unsafe { +pub fn exit(iotask: IoTask) unsafe { send_msg(iotask, TeardownLoop); } @@ -97,7 +91,7 @@ fn run_loop(iotask_ch: Chan) unsafe { // set up the special async handle we'll use to allow multi-task // communication with this loop let async = ll::async_t(); - let async_handle = addr_of(async); + let async_handle = addr_of(&async); // associate the async handle with the loop ll::async_init(loop_ptr, async_handle, wake_up_cb); @@ -107,7 +101,7 @@ fn run_loop(iotask_ch: Chan) unsafe { async_handle: async_handle, msg_po: Port() }; - ll::set_data_for_uv_handle(async_handle, addr_of(data)); + ll::set_data_for_uv_handle(async_handle, addr_of(&data)); // Send out a handle through which folks can talk to us // while we dwell in the I/O loop @@ -149,7 +143,7 @@ extern fn wake_up_cb(async_handle: *ll::uv_async_t, while msg_po.peek() { match msg_po.recv() { - Interaction(cb) => cb(loop_ptr), + Interaction(ref cb) => (*cb)(loop_ptr), TeardownLoop => begin_teardown(data) } } @@ -171,7 +165,6 @@ extern fn tear_down_close_cb(handle: *ll::uv_async_t) unsafe { #[cfg(test)] mod test { - #[legacy_exports]; extern fn async_close_cb(handle: *ll::uv_async_t) unsafe { log(debug, fmt!("async_close_cb handle %?", handle)); let exit_ch = (*(ll::get_data_for_uv_handle(handle) @@ -189,14 +182,14 @@ mod test { }; fn impl_uv_iotask_async(iotask: IoTask) unsafe { let async_handle = ll::async_t(); - let ah_ptr = ptr::addr_of(async_handle); + let ah_ptr = ptr::addr_of(&async_handle); let exit_po = core::comm::Port::<()>(); let exit_ch = core::comm::Chan(exit_po); let ah_data = { iotask: iotask, exit_ch: exit_ch }; - let ah_data_ptr = ptr::addr_of(ah_data); + let ah_data_ptr = ptr::addr_of(&ah_data); do interact(iotask) |loop_ptr| unsafe { ll::async_init(loop_ptr, ah_ptr, async_handle_cb); ll::set_data_for_uv_handle(ah_ptr, ah_data_ptr as *libc::c_void); diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index 6d212cd7e921..f0594475d04e 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -27,13 +27,13 @@ use comm = core::comm; use ptr::to_unsafe_ptr; // libuv struct mappings -type uv_ip4_addr = { +pub type uv_ip4_addr = { ip: ~[u8], port: int }; -type uv_ip6_addr = uv_ip4_addr; +pub type uv_ip6_addr = uv_ip4_addr; -enum uv_handle_type { +pub enum uv_handle_type { UNKNOWN_HANDLE = 0, UV_TCP, UV_UDP, @@ -51,9 +51,9 @@ enum uv_handle_type { UV_FS_EVENT } -type handle_type = libc::c_uint; +pub type handle_type = libc::c_uint; -type uv_handle_fields = { +pub type uv_handle_fields = { loop_handle: *libc::c_void, type_: handle_type, close_cb: *u8, @@ -61,7 +61,7 @@ type uv_handle_fields = { }; // unix size: 8 -type uv_err_t = { +pub type uv_err_t = { code: libc::c_int, sys_errno_: libc::c_int }; @@ -71,13 +71,13 @@ type uv_err_t = { // in other types as a pointer to be used in other // operations (so mostly treat it as opaque, once you // have it in this form..) -type uv_stream_t = { +pub type uv_stream_t = { fields: uv_handle_fields }; // 64bit unix size: 272 #[cfg(unix)] -type uv_tcp_t = { +pub type uv_tcp_t = { fields: uv_handle_fields, a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, @@ -91,11 +91,11 @@ type uv_tcp_t = { }; // 32bit unix size: 328 (164) #[cfg(target_arch="x86_64")] -type uv_tcp_t_32bit_unix_riders = { +pub type uv_tcp_t_32bit_unix_riders = { a29: *u8 }; #[cfg(target_arch="x86")] -type uv_tcp_t_32bit_unix_riders = { +pub type uv_tcp_t_32bit_unix_riders = { a29: *u8, a30: *u8, a31: *u8, a32: *u8, a33: *u8, a34: *u8, a35: *u8, a36: *u8 @@ -103,7 +103,7 @@ type uv_tcp_t_32bit_unix_riders = { // 32bit win32 size: 240 (120) #[cfg(windows)] -type uv_tcp_t = { +pub type uv_tcp_t = { fields: uv_handle_fields, a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, @@ -116,20 +116,20 @@ type uv_tcp_t = { // unix size: 48 #[cfg(unix)] -type uv_connect_t = { +pub type uv_connect_t = { a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8 }; // win32 size: 88 (44) #[cfg(windows)] -type uv_connect_t = { +pub type uv_connect_t = { a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, a08: *u8, a09: *u8, a10: *u8 }; // unix size: 16 -type uv_buf_t = { +pub type uv_buf_t = { base: *u8, len: libc::size_t }; @@ -138,7 +138,7 @@ type uv_buf_t = { // unix size: 144 #[cfg(unix)] -type uv_write_t = { +pub type uv_write_t = { fields: uv_handle_fields, a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, @@ -147,16 +147,16 @@ type uv_write_t = { a14: uv_write_t_32bit_unix_riders }; #[cfg(target_arch="x86_64")] -type uv_write_t_32bit_unix_riders = { +pub type uv_write_t_32bit_unix_riders = { a13: *u8 }; #[cfg(target_arch="x86")] -type uv_write_t_32bit_unix_riders = { +pub type uv_write_t_32bit_unix_riders = { a13: *u8, a14: *u8 }; // win32 size: 136 (68) #[cfg(windows)] -type uv_write_t = { +pub type uv_write_t = { fields: uv_handle_fields, a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, @@ -166,7 +166,7 @@ type uv_write_t = { // 64bit unix size: 120 // 32bit unix size: 152 (76) #[cfg(unix)] -type uv_async_t = { +pub type uv_async_t = { fields: uv_handle_fields, a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, @@ -174,16 +174,16 @@ type uv_async_t = { a11: uv_async_t_32bit_unix_riders }; #[cfg(target_arch="x86_64")] -type uv_async_t_32bit_unix_riders = { +pub type uv_async_t_32bit_unix_riders = { a10: *u8 }; #[cfg(target_arch="x86")] -type uv_async_t_32bit_unix_riders = { +pub type uv_async_t_32bit_unix_riders = { a10: *u8, a11: *u8, a12: *u8, a13: *u8 }; // win32 size 132 (68) #[cfg(windows)] -type uv_async_t = { +pub type uv_async_t = { fields: uv_handle_fields, a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, @@ -194,7 +194,7 @@ type uv_async_t = { // 64bit unix size: 128 // 32bit unix size: 84 #[cfg(unix)] -type uv_timer_t = { +pub type uv_timer_t = { fields: uv_handle_fields, a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, @@ -202,17 +202,17 @@ type uv_timer_t = { a11: uv_timer_t_32bit_unix_riders }; #[cfg(target_arch="x86_64")] -type uv_timer_t_32bit_unix_riders = { +pub type uv_timer_t_32bit_unix_riders = { a10: *u8, a11: *u8 }; #[cfg(target_arch="x86")] -type uv_timer_t_32bit_unix_riders = { +pub type uv_timer_t_32bit_unix_riders = { a10: *u8, a11: *u8, a12: *u8, a13: *u8, a14: *u8, a15: *u8, a16: *u8 }; // win32 size: 64 #[cfg(windows)] -type uv_timer_t = { +pub type uv_timer_t = { fields: uv_handle_fields, a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, @@ -220,7 +220,7 @@ type uv_timer_t = { }; // unix size: 16 -type sockaddr_in = { +pub type sockaddr_in = { mut sin_family: u16, mut sin_port: u16, mut sin_addr: u32, // in_addr: this is an opaque, per-platform struct @@ -230,12 +230,12 @@ type sockaddr_in = { // unix size: 28 .. FIXME #1645 // stuck with 32 becuse of rust padding structs? #[cfg(target_arch="x86_64")] -type sockaddr_in6 = { +pub type sockaddr_in6 = { a0: *u8, a1: *u8, a2: *u8, a3: *u8 }; #[cfg(target_arch="x86")] -type sockaddr_in6 = { +pub type sockaddr_in6 = { a0: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8, @@ -244,17 +244,16 @@ type sockaddr_in6 = { // unix size: 28 .. FIXME #1645 // stuck with 32 becuse of rust padding structs? -type addr_in = addr_in_impl::addr_in; +pub type addr_in = addr_in_impl::addr_in; #[cfg(unix)] -mod addr_in_impl { - #[legacy_exports]; +pub mod addr_in_impl { #[cfg(target_arch="x86_64")] - type addr_in = { + pub type addr_in = { a0: *u8, a1: *u8, a2: *u8, a3: *u8 }; #[cfg(target_arch="x86")] - type addr_in = { + pub type addr_in = { a0: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, a5: *u8, @@ -262,65 +261,60 @@ mod addr_in_impl { }; } #[cfg(windows)] -mod addr_in_impl { - #[legacy_exports]; - type addr_in = { +pub mod addr_in_impl { + pub type addr_in = { a0: *u8, a1: *u8, a2: *u8, a3: *u8 }; } // unix size: 48, 32bit: 32 -type addrinfo = addrinfo_impl::addrinfo; +pub type addrinfo = addrinfo_impl::addrinfo; #[cfg(target_os="linux")] -mod addrinfo_impl { - #[legacy_exports]; +pub mod addrinfo_impl { #[cfg(target_arch="x86_64")] - type addrinfo = { + pub type addrinfo = { a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8 }; #[cfg(target_arch="x86")] - type addrinfo = { + pub type addrinfo = { a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8 }; } #[cfg(target_os="macos")] #[cfg(target_os="freebsd")] -mod addrinfo_impl { - #[legacy_exports]; - type addrinfo = { +pub mod addrinfo_impl { + pub type addrinfo = { a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8 }; } #[cfg(windows)] -mod addrinfo_impl { - #[legacy_exports]; - type addrinfo = { +pub mod addrinfo_impl { + pub type addrinfo = { a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8 }; } // unix size: 72 -type uv_getaddrinfo_t = { +pub type uv_getaddrinfo_t = { a00: *u8, a01: *u8, a02: *u8, a03: *u8, a04: *u8, a05: *u8, a06: *u8, a07: *u8, a08: *u8 }; -mod uv_ll_struct_stubgen { - #[legacy_exports]; - fn gen_stub_uv_tcp_t() -> uv_tcp_t { +pub mod uv_ll_struct_stubgen { + pub fn gen_stub_uv_tcp_t() -> uv_tcp_t { return gen_stub_os(); #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] #[cfg(target_os = "freebsd")] - fn gen_stub_os() -> uv_tcp_t { + pub fn gen_stub_os() -> uv_tcp_t { return gen_stub_arch(); #[cfg(target_arch="x86_64")] - fn gen_stub_arch() -> uv_tcp_t { + pub fn gen_stub_arch() -> uv_tcp_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -345,7 +339,7 @@ mod uv_ll_struct_stubgen { }; } #[cfg(target_arch="x86")] - fn gen_stub_arch() -> uv_tcp_t { + pub fn gen_stub_arch() -> uv_tcp_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -373,7 +367,7 @@ mod uv_ll_struct_stubgen { } } #[cfg(windows)] - fn gen_stub_os() -> uv_tcp_t { + pub fn gen_stub_os() -> uv_tcp_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -394,7 +388,7 @@ mod uv_ll_struct_stubgen { } } #[cfg(unix)] - fn gen_stub_uv_connect_t() -> uv_connect_t { + pub fn gen_stub_uv_connect_t() -> uv_connect_t { return { a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8, a03: 0 as *u8, @@ -402,7 +396,7 @@ mod uv_ll_struct_stubgen { }; } #[cfg(windows)] - fn gen_stub_uv_connect_t() -> uv_connect_t { + pub fn gen_stub_uv_connect_t() -> uv_connect_t { return { a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8, a03: 0 as *u8, @@ -412,10 +406,10 @@ mod uv_ll_struct_stubgen { }; } #[cfg(unix)] - fn gen_stub_uv_async_t() -> uv_async_t { + pub fn gen_stub_uv_async_t() -> uv_async_t { return gen_stub_arch(); #[cfg(target_arch = "x86_64")] - fn gen_stub_arch() -> uv_async_t { + pub fn gen_stub_arch() -> uv_async_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -430,7 +424,7 @@ mod uv_ll_struct_stubgen { }; } #[cfg(target_arch = "x86")] - fn gen_stub_arch() -> uv_async_t { + pub fn gen_stub_arch() -> uv_async_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -447,7 +441,7 @@ mod uv_ll_struct_stubgen { } } #[cfg(windows)] - fn gen_stub_uv_async_t() -> uv_async_t { + pub fn gen_stub_uv_async_t() -> uv_async_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -461,10 +455,10 @@ mod uv_ll_struct_stubgen { }; } #[cfg(unix)] - fn gen_stub_uv_timer_t() -> uv_timer_t { + pub fn gen_stub_uv_timer_t() -> uv_timer_t { return gen_stub_arch(); #[cfg(target_arch = "x86_64")] - fn gen_stub_arch() -> uv_timer_t { + pub fn gen_stub_arch() -> uv_timer_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -479,7 +473,7 @@ mod uv_ll_struct_stubgen { }; } #[cfg(target_arch = "x86")] - fn gen_stub_arch() -> uv_timer_t { + pub fn gen_stub_arch() -> uv_timer_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -498,7 +492,7 @@ mod uv_ll_struct_stubgen { } } #[cfg(windows)] - fn gen_stub_uv_timer_t() -> uv_timer_t { + pub fn gen_stub_uv_timer_t() -> uv_timer_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -511,10 +505,10 @@ mod uv_ll_struct_stubgen { }; } #[cfg(unix)] - fn gen_stub_uv_write_t() -> uv_write_t { + pub fn gen_stub_uv_write_t() -> uv_write_t { return gen_stub_arch(); #[cfg(target_arch="x86_64")] - fn gen_stub_arch() -> uv_write_t { + pub fn gen_stub_arch() -> uv_write_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -528,7 +522,7 @@ mod uv_ll_struct_stubgen { }; } #[cfg(target_arch="x86")] - fn gen_stub_arch() -> uv_write_t { + pub fn gen_stub_arch() -> uv_write_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -543,7 +537,7 @@ mod uv_ll_struct_stubgen { } } #[cfg(windows)] - fn gen_stub_uv_write_t() -> uv_write_t { + pub fn gen_stub_uv_write_t() -> uv_write_t { return { fields: { loop_handle: ptr::null(), type_: 0u32, close_cb: ptr::null(), mut data: ptr::null() }, @@ -556,7 +550,7 @@ mod uv_ll_struct_stubgen { a12: 0 as *u8 }; } - fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t { + pub fn gen_stub_uv_getaddrinfo_t() -> uv_getaddrinfo_t { { a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8, a03: 0 as *u8, a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8, a07: 0 as *u8, @@ -567,7 +561,6 @@ mod uv_ll_struct_stubgen { #[nolink] extern mod rustrt { - #[legacy_exports]; // libuv public API fn rust_uv_loop_new() -> *libc::c_void; fn rust_uv_loop_delete(lp: *libc::c_void); @@ -686,32 +679,32 @@ extern mod rustrt { fn rust_uv_helper_addr_in_size() -> libc::c_uint; } -unsafe fn loop_new() -> *libc::c_void { +pub unsafe fn loop_new() -> *libc::c_void { return rustrt::rust_uv_loop_new(); } -unsafe fn loop_delete(loop_handle: *libc::c_void) { +pub unsafe fn loop_delete(loop_handle: *libc::c_void) { rustrt::rust_uv_loop_delete(loop_handle); } -unsafe fn loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int { +pub unsafe fn loop_refcount(loop_ptr: *libc::c_void) -> libc::c_int { return rustrt::rust_uv_loop_refcount(loop_ptr); } -unsafe fn run(loop_handle: *libc::c_void) { +pub unsafe fn run(loop_handle: *libc::c_void) { rustrt::rust_uv_run(loop_handle); } -unsafe fn close(handle: *T, cb: *u8) { +pub unsafe fn close(handle: *T, cb: *u8) { rustrt::rust_uv_close(handle as *libc::c_void, cb); } -unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t) +pub unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t) -> libc::c_int { return rustrt::rust_uv_tcp_init(loop_handle, handle); } // FIXME ref #2064 -unsafe fn tcp_connect(connect_ptr: *uv_connect_t, +pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in, after_connect_cb: *u8) @@ -722,7 +715,7 @@ unsafe fn tcp_connect(connect_ptr: *uv_connect_t, after_connect_cb, addr_ptr); } // FIXME ref #2064 -unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, +pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, tcp_handle_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6, after_connect_cb: *u8) @@ -731,30 +724,30 @@ unsafe fn tcp_connect6(connect_ptr: *uv_connect_t, after_connect_cb, addr_ptr); } // FIXME ref #2064 -unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, +pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> libc::c_int { return rustrt::rust_uv_tcp_bind(tcp_server_ptr, addr_ptr); } // FIXME ref #2064 -unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, +pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> libc::c_int { return rustrt::rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr); } -unsafe fn listen(stream: *T, backlog: libc::c_int, +pub unsafe fn listen(stream: *T, backlog: libc::c_int, cb: *u8) -> libc::c_int { return rustrt::rust_uv_listen(stream as *libc::c_void, backlog, cb); } -unsafe fn accept(server: *libc::c_void, client: *libc::c_void) +pub unsafe fn accept(server: *libc::c_void, client: *libc::c_void) -> libc::c_int { return rustrt::rust_uv_accept(server as *libc::c_void, client as *libc::c_void); } -unsafe fn write(req: *uv_write_t, stream: *T, +pub unsafe fn write(req: *uv_write_t, stream: *T, buf_in: *~[uv_buf_t], cb: *u8) -> libc::c_int { let buf_ptr = vec::raw::to_ptr(*buf_in); let buf_cnt = vec::len(*buf_in) as i32; @@ -762,28 +755,28 @@ unsafe fn write(req: *uv_write_t, stream: *T, stream as *libc::c_void, buf_ptr, buf_cnt, cb); } -unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, +pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, on_read: *u8) -> libc::c_int { return rustrt::rust_uv_read_start(stream as *libc::c_void, on_alloc, on_read); } -unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int { +pub unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int { return rustrt::rust_uv_read_stop(stream as *libc::c_void); } -unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t { +pub unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t { return rustrt::rust_uv_last_error(loop_handle); } -unsafe fn strerror(err: *uv_err_t) -> *libc::c_char { +pub unsafe fn strerror(err: *uv_err_t) -> *libc::c_char { return rustrt::rust_uv_strerror(err); } -unsafe fn err_name(err: *uv_err_t) -> *libc::c_char { +pub unsafe fn err_name(err: *uv_err_t) -> *libc::c_char { return rustrt::rust_uv_err_name(err); } -unsafe fn async_init(loop_handle: *libc::c_void, +pub unsafe fn async_init(loop_handle: *libc::c_void, async_handle: *uv_async_t, cb: *u8) -> libc::c_int { return rustrt::rust_uv_async_init(loop_handle, @@ -791,12 +784,12 @@ unsafe fn async_init(loop_handle: *libc::c_void, cb); } -unsafe fn async_send(async_handle: *uv_async_t) { +pub unsafe fn async_send(async_handle: *uv_async_t) { return rustrt::rust_uv_async_send(async_handle); } -unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t { +pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t { let out_buf = { base: ptr::null(), len: 0 as libc::size_t }; - let out_buf_ptr = ptr::addr_of(out_buf); + let out_buf_ptr = ptr::addr_of(&out_buf); log(debug, fmt!("buf_init - input %u len %u out_buf: %u", input as uint, len as uint, @@ -814,21 +807,21 @@ unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t { return out_buf; //return result; } -unsafe fn ip4_addr(ip: &str, port: int) +pub unsafe fn ip4_addr(ip: &str, port: int) -> sockaddr_in { do str::as_c_str(ip) |ip_buf| { rustrt::rust_uv_ip4_addr(ip_buf as *u8, port as libc::c_int) } } -unsafe fn ip6_addr(ip: &str, port: int) +pub unsafe fn ip6_addr(ip: &str, port: int) -> sockaddr_in6 { do str::as_c_str(ip) |ip_buf| { rustrt::rust_uv_ip6_addr(ip_buf as *u8, port as libc::c_int) } } -unsafe fn ip4_name(src: &sockaddr_in) -> ~str { +pub unsafe fn ip4_name(src: &sockaddr_in) -> ~str { // ipv4 addr max size: 15 + 1 trailing null byte let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8]; @@ -844,7 +837,7 @@ unsafe fn ip4_name(src: &sockaddr_in) -> ~str { str::raw::from_buf(dst_buf) } } -unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { +pub unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { // ipv6 addr max size: 45 + 1 trailing null byte let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, 0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8, @@ -865,19 +858,19 @@ unsafe fn ip6_name(src: &sockaddr_in6) -> ~str { } } -unsafe fn timer_init(loop_ptr: *libc::c_void, +pub unsafe fn timer_init(loop_ptr: *libc::c_void, timer_ptr: *uv_timer_t) -> libc::c_int { return rustrt::rust_uv_timer_init(loop_ptr, timer_ptr); } -unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint, +pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: uint, repeat: uint) -> libc::c_int { return rustrt::rust_uv_timer_start(timer_ptr, cb, timeout as libc::c_uint, repeat as libc::c_uint); } -unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int { +pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> libc::c_int { return rustrt::rust_uv_timer_stop(timer_ptr); } -unsafe fn getaddrinfo(loop_ptr: *libc::c_void, +pub unsafe fn getaddrinfo(loop_ptr: *libc::c_void, handle: *uv_getaddrinfo_t, cb: *u8, node_name_ptr: *u8, @@ -890,126 +883,127 @@ unsafe fn getaddrinfo(loop_ptr: *libc::c_void, service_name_ptr, hints) } -unsafe fn freeaddrinfo(res: *addrinfo) { +pub unsafe fn freeaddrinfo(res: *addrinfo) { rustrt::rust_uv_freeaddrinfo(res); } // libuv struct initializers -unsafe fn tcp_t() -> uv_tcp_t { +pub unsafe fn tcp_t() -> uv_tcp_t { return uv_ll_struct_stubgen::gen_stub_uv_tcp_t(); } -unsafe fn connect_t() -> uv_connect_t { +pub unsafe fn connect_t() -> uv_connect_t { return uv_ll_struct_stubgen::gen_stub_uv_connect_t(); } -unsafe fn write_t() -> uv_write_t { +pub unsafe fn write_t() -> uv_write_t { return uv_ll_struct_stubgen::gen_stub_uv_write_t(); } -unsafe fn async_t() -> uv_async_t { +pub unsafe fn async_t() -> uv_async_t { return uv_ll_struct_stubgen::gen_stub_uv_async_t(); } -unsafe fn timer_t() -> uv_timer_t { +pub unsafe fn timer_t() -> uv_timer_t { return uv_ll_struct_stubgen::gen_stub_uv_timer_t(); } -unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t { +pub unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t { return uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t(); } // data access helpers -unsafe fn get_loop_for_uv_handle(handle: *T) +pub unsafe fn get_loop_for_uv_handle(handle: *T) -> *libc::c_void { return rustrt::rust_uv_get_loop_for_uv_handle(handle as *libc::c_void); } -unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) +pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t { return rustrt::rust_uv_get_stream_handle_from_connect_req( connect); } -unsafe fn get_stream_handle_from_write_req( +pub unsafe fn get_stream_handle_from_write_req( write_req: *uv_write_t) -> *uv_stream_t { return rustrt::rust_uv_get_stream_handle_from_write_req( write_req); } -unsafe fn get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void { +pub unsafe fn get_data_for_uv_loop(loop_ptr: *libc::c_void) -> *libc::c_void { rustrt::rust_uv_get_data_for_uv_loop(loop_ptr) } -unsafe fn set_data_for_uv_loop(loop_ptr: *libc::c_void, data: *libc::c_void) { +pub unsafe fn set_data_for_uv_loop(loop_ptr: *libc::c_void, + data: *libc::c_void) { rustrt::rust_uv_set_data_for_uv_loop(loop_ptr, data); } -unsafe fn get_data_for_uv_handle(handle: *T) -> *libc::c_void { +pub unsafe fn get_data_for_uv_handle(handle: *T) -> *libc::c_void { return rustrt::rust_uv_get_data_for_uv_handle(handle as *libc::c_void); } -unsafe fn set_data_for_uv_handle(handle: *T, +pub unsafe fn set_data_for_uv_handle(handle: *T, data: *U) { rustrt::rust_uv_set_data_for_uv_handle(handle as *libc::c_void, data as *libc::c_void); } -unsafe fn get_data_for_req(req: *T) -> *libc::c_void { +pub unsafe fn get_data_for_req(req: *T) -> *libc::c_void { return rustrt::rust_uv_get_data_for_req(req as *libc::c_void); } -unsafe fn set_data_for_req(req: *T, +pub unsafe fn set_data_for_req(req: *T, data: *U) { rustrt::rust_uv_set_data_for_req(req as *libc::c_void, data as *libc::c_void); } -unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 { +pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 { return rustrt::rust_uv_get_base_from_buf(buf); } -unsafe fn get_len_from_buf(buf: uv_buf_t) -> libc::size_t { +pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> libc::size_t { return rustrt::rust_uv_get_len_from_buf(buf); } -unsafe fn malloc_buf_base_of(suggested_size: libc::size_t) +pub unsafe fn malloc_buf_base_of(suggested_size: libc::size_t) -> *u8 { return rustrt::rust_uv_malloc_buf_base_of(suggested_size); } -unsafe fn free_base_of_buf(buf: uv_buf_t) { +pub unsafe fn free_base_of_buf(buf: uv_buf_t) { rustrt::rust_uv_free_base_of_buf(buf); } -unsafe fn get_last_err_info(uv_loop: *libc::c_void) -> ~str { +pub unsafe fn get_last_err_info(uv_loop: *libc::c_void) -> ~str { let err = last_error(uv_loop); - let err_ptr = ptr::addr_of(err); + let err_ptr = ptr::addr_of(&err); let err_name = str::raw::from_c_str(err_name(err_ptr)); let err_msg = str::raw::from_c_str(strerror(err_ptr)); return fmt!("LIBUV ERROR: name: %s msg: %s", err_name, err_msg); } -unsafe fn get_last_err_data(uv_loop: *libc::c_void) -> uv_err_data { +pub unsafe fn get_last_err_data(uv_loop: *libc::c_void) -> uv_err_data { let err = last_error(uv_loop); - let err_ptr = ptr::addr_of(err); + let err_ptr = ptr::addr_of(&err); let err_name = str::raw::from_c_str(err_name(err_ptr)); let err_msg = str::raw::from_c_str(strerror(err_ptr)); { err_name: err_name, err_msg: err_msg } } -type uv_err_data = { +pub type uv_err_data = { err_name: ~str, err_msg: ~str }; -unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool { +pub unsafe fn is_ipv4_addrinfo(input: *addrinfo) -> bool { rustrt::rust_uv_is_ipv4_addrinfo(input) } -unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool { +pub unsafe fn is_ipv6_addrinfo(input: *addrinfo) -> bool { rustrt::rust_uv_is_ipv6_addrinfo(input) } -unsafe fn get_INADDR_NONE() -> u32 { +pub unsafe fn get_INADDR_NONE() -> u32 { rustrt::rust_uv_helper_get_INADDR_NONE() } -unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo { +pub unsafe fn get_next_addrinfo(input: *addrinfo) -> *addrinfo { rustrt::rust_uv_get_next_addrinfo(input) } -unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in { +pub unsafe fn addrinfo_as_sockaddr_in(input: *addrinfo) -> *sockaddr_in { rustrt::rust_uv_addrinfo_as_sockaddr_in(input) } -unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 { +pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 { rustrt::rust_uv_addrinfo_as_sockaddr_in6(input) } #[cfg(test)] -mod test { - #[legacy_exports]; +pub mod test { + enum tcp_read_data { tcp_read_eof, tcp_read_more(~[u8]), @@ -1120,9 +1114,9 @@ mod test { client_chan: *comm::Chan<~str>) unsafe { let test_loop = loop_new(); let tcp_handle = tcp_t(); - let tcp_handle_ptr = ptr::addr_of(tcp_handle); + let tcp_handle_ptr = ptr::addr_of(&tcp_handle); let connect_handle = connect_t(); - let connect_req_ptr = ptr::addr_of(connect_handle); + let connect_req_ptr = ptr::addr_of(&connect_handle); // this is the persistent payload of data that we // need to pass around to get this example to work. @@ -1138,12 +1132,12 @@ mod test { // this is the enclosing record, we'll pass a ptr to // this to C.. let write_handle = write_t(); - let write_handle_ptr = ptr::addr_of(write_handle); + let write_handle_ptr = ptr::addr_of(&write_handle); log(debug, fmt!("tcp req: tcp stream: %d write_handle: %d", tcp_handle_ptr as int, write_handle_ptr as int)); let client_data = { writer_handle: write_handle_ptr, - req_buf: ptr::addr_of(req_msg), + req_buf: ptr::addr_of(&req_msg), read_chan: client_chan }; let tcp_init_result = tcp_init( @@ -1154,7 +1148,7 @@ mod test { log(debug, ~"building addr..."); let addr = ip4_addr(ip, port); // FIXME ref #2064 - let addr_ptr = ptr::addr_of(addr); + let addr_ptr = ptr::addr_of(&addr); log(debug, fmt!("after build addr in rust. port: %u", addr.sin_port as uint)); @@ -1169,10 +1163,10 @@ mod test { // until its initialized set_data_for_req( connect_req_ptr as *libc::c_void, - ptr::addr_of(client_data) as *libc::c_void); + ptr::addr_of(&client_data) as *libc::c_void); set_data_for_uv_handle( tcp_handle_ptr as *libc::c_void, - ptr::addr_of(client_data) as *libc::c_void); + ptr::addr_of(&client_data) as *libc::c_void); log(debug, ~"before run tcp req loop"); run(test_loop); log(debug, ~"after run tcp req loop"); @@ -1369,13 +1363,13 @@ mod test { continue_chan: *comm::Chan) unsafe { let test_loop = loop_new(); let tcp_server = tcp_t(); - let tcp_server_ptr = ptr::addr_of(tcp_server); + let tcp_server_ptr = ptr::addr_of(&tcp_server); let tcp_client = tcp_t(); - let tcp_client_ptr = ptr::addr_of(tcp_client); + let tcp_client_ptr = ptr::addr_of(&tcp_client); let server_write_req = write_t(); - let server_write_req_ptr = ptr::addr_of(server_write_req); + let server_write_req_ptr = ptr::addr_of(&server_write_req); let resp_str_bytes = str::to_bytes(server_resp_msg); let resp_msg_ptr: *u8 = vec::raw::to_ptr(resp_str_bytes); @@ -1386,20 +1380,20 @@ mod test { let continue_async_handle = async_t(); let continue_async_handle_ptr = - ptr::addr_of(continue_async_handle); + ptr::addr_of(&continue_async_handle); let async_data = { continue_chan: continue_chan }; - let async_data_ptr = ptr::addr_of(async_data); + let async_data_ptr = ptr::addr_of(&async_data); let server_data: tcp_server_data = { client: tcp_client_ptr, server: tcp_server_ptr, server_kill_msg: kill_server_msg, - server_resp_buf: ptr::addr_of(resp_msg), + server_resp_buf: ptr::addr_of(&resp_msg), server_chan: server_chan, server_write_req: server_write_req_ptr }; - let server_data_ptr = ptr::addr_of(server_data); + let server_data_ptr = ptr::addr_of(&server_data); set_data_for_uv_handle(tcp_server_ptr as *libc::c_void, server_data_ptr as *libc::c_void); @@ -1409,7 +1403,7 @@ mod test { if (tcp_init_result == 0i32) { let server_addr = ip4_addr(server_ip, server_port); // FIXME ref #2064 - let server_addr_ptr = ptr::addr_of(server_addr); + let server_addr_ptr = ptr::addr_of(&server_addr); // uv_tcp_bind() let bind_result = tcp_bind(tcp_server_ptr, @@ -1478,13 +1472,13 @@ mod test { let continue_port = core::comm::Port::(); let continue_chan = core::comm::Chan::(continue_port); - let continue_chan_ptr = ptr::addr_of(continue_chan); + let continue_chan_ptr = ptr::addr_of(&continue_chan); - do task::spawn_sched(task::ManualThreads(1u)) { + do task::spawn_sched(task::ManualThreads(1)) { impl_uv_tcp_server(bind_ip, port, kill_server_msg, server_resp_msg, - ptr::addr_of(server_chan), + ptr::addr_of(&server_chan), continue_chan_ptr); }; @@ -1496,7 +1490,7 @@ mod test { do task::spawn_sched(task::ManualThreads(1u)) { impl_uv_tcp_request(request_ip, port, kill_server_msg, - ptr::addr_of(client_chan)); + ptr::addr_of(&client_chan)); }; let msg_from_client = core::comm::recv(server_port); @@ -1510,22 +1504,19 @@ mod test { #[cfg(target_os="win32")] #[cfg(target_os="darwin")] #[cfg(target_os="linux")] - mod tcp_and_server_client_test { - #[legacy_exports]; + pub mod tcp_and_server_client_test { #[cfg(target_arch="x86_64")] - mod impl64 { - #[legacy_exports]; + pub mod impl64 { #[test] - fn test_uv_ll_tcp_server_and_request() unsafe { + pub fn test_uv_ll_tcp_server_and_request() unsafe { impl_uv_tcp_server_and_request(); } } #[cfg(target_arch="x86")] - mod impl32 { - #[legacy_exports]; + pub mod impl32 { #[test] #[ignore(cfg(target_os = "linux"))] - fn test_uv_ll_tcp_server_and_request() unsafe { + pub fn test_uv_ll_tcp_server_and_request() unsafe { impl_uv_tcp_server_and_request(); } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 75a2081bc14f..e17b52fb27d1 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -38,6 +38,10 @@ macro_rules! interner_key ( (-3 as uint, 0u))) ) +// FIXME(#3534): Replace with the struct-based newtype when it's been +// implemented. +struct ident { repr: uint } + fn serialize_ident(s: S, i: ident) { let intr = match unsafe{ task::local_data::local_data_get(interner_key!()) @@ -59,7 +63,16 @@ fn deserialize_ident(d: D) -> ident { (*intr).intern(@d.read_str()) } -type ident = token::str_num; +impl ident: cmp::Eq { + pure fn eq(other: &ident) -> bool { self.repr == other.repr } + pure fn ne(other: &ident) -> bool { !self.eq(other) } +} + +impl ident: to_bytes::IterBytes { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { + self.repr.iter_bytes(lsb0, f) + } +} // Functions may or may not have names. #[auto_serialize] @@ -315,7 +328,7 @@ enum binding_mode { } impl binding_mode : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { bind_by_value => 0u8.iter_bytes(lsb0, f), @@ -389,7 +402,7 @@ enum pat_ { enum mutability { m_mutbl, m_imm, m_const, } impl mutability : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -528,7 +541,7 @@ enum inferable { } impl inferable : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { expl(ref t) => to_bytes::iter_bytes_2(&0u8, t, lsb0, f), @@ -564,7 +577,7 @@ impl inferable : cmp::Eq { enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy } impl rmode : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -924,7 +937,7 @@ enum trait_method { enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } impl int_ty : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -953,7 +966,7 @@ impl int_ty : cmp::Eq { enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } impl uint_ty : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -980,7 +993,7 @@ impl uint_ty : cmp::Eq { enum float_ty { ty_f, ty_f32, ty_f64, } impl float_ty : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -1081,15 +1094,15 @@ enum ty_ { // since we only care about this for normalizing them to "real" types. impl ty : cmp::Eq { pure fn eq(other: &ty) -> bool { - ptr::addr_of(self) == ptr::addr_of((*other)) + ptr::addr_of(&self) == ptr::addr_of(&(*other)) } pure fn ne(other: &ty) -> bool { - ptr::addr_of(self) != ptr::addr_of((*other)) + ptr::addr_of(&self) != ptr::addr_of(&(*other)) } } impl ty : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f); } } @@ -1113,7 +1126,7 @@ enum purity { } impl purity : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -1133,7 +1146,7 @@ enum ret_style { } impl ret_style : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -1430,7 +1443,7 @@ enum item_ { enum class_mutability { class_mutable, class_immutable } impl class_mutability : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -1472,7 +1485,8 @@ type foreign_item = attrs: ~[attribute], node: foreign_item_, id: node_id, - span: span}; + span: span, + vis: visibility}; #[auto_serialize] enum foreign_item_ { diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index 9a3e94b737fa..d05c6eadaf6a 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -34,7 +34,7 @@ impl path_elt : cmp::Eq { type path = ~[path_elt]; /* FIXMEs that say "bad" are as per #2543 */ -fn path_to_str_with_sep(p: path, sep: ~str, itr: ident_interner) -> ~str { +fn path_to_str_with_sep(p: path, sep: ~str, itr: @ident_interner) -> ~str { let strs = do vec::map(p) |e| { match *e { path_mod(s) => *itr.get(s), @@ -44,7 +44,7 @@ fn path_to_str_with_sep(p: path, sep: ~str, itr: ident_interner) -> ~str { str::connect(strs, sep) } -fn path_ident_to_str(p: path, i: ident, itr: ident_interner) -> ~str { +fn path_ident_to_str(p: path, i: ident, itr: @ident_interner) -> ~str { if vec::is_empty(p) { //FIXME /* FIXME (#2543) */ copy *i *itr.get(i) @@ -53,7 +53,7 @@ fn path_ident_to_str(p: path, i: ident, itr: ident_interner) -> ~str { } } -fn path_to_str(p: path, itr: ident_interner) -> ~str { +fn path_to_str(p: path, itr: @ident_interner) -> ~str { path_to_str_with_sep(p, ~"::", itr) } @@ -273,12 +273,12 @@ fn map_item(i: @item, cx: ctx, v: vt) { } match i.node { item_mod(_) | item_foreign_mod(_) => { - vec::push(cx.path, path_mod(i.ident)); + cx.path.push(path_mod(i.ident)); } - _ => vec::push(cx.path, path_name(i.ident)) + _ => cx.path.push(path_name(i.ident)) } visit::visit_item(i, cx, v); - vec::pop(cx.path); + cx.path.pop(); } fn map_struct_def(struct_def: @ast::struct_def, parent_node: ast_node, @@ -326,7 +326,7 @@ fn map_stmt(stmt: @stmt, cx: ctx, v: vt) { visit::visit_stmt(stmt, cx, v); } -fn node_id_to_str(map: map, id: node_id, itr: ident_interner) -> ~str { +fn node_id_to_str(map: map, id: node_id, itr: @ident_interner) -> ~str { match map.find(id) { None => { fmt!("unknown node (id=%d)", id) diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index b0df0ea1c8d0..e8099de246cc 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -23,7 +23,7 @@ pure fn dummy_sp() -> span { return mk_sp(0u, 0u); } -pure fn path_name_i(idents: ~[ident], intr: token::ident_interner) -> ~str { +pure fn path_name_i(idents: ~[ident], intr: @token::ident_interner) -> ~str { // FIXME: Bad copies (#2543 -- same for everything else that says "bad") str::connect(idents.map(|i| *intr.get(*i)), ~"::") } @@ -254,7 +254,7 @@ pure fn is_call_expr(e: @expr) -> bool { // This makes def_id hashable impl def_id : core::to_bytes::IterBytes { #[inline(always)] - pure fn iter_bytes(lsb0: bool, f: core::to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: core::to_bytes::Cb) { core::to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f); } } @@ -275,14 +275,14 @@ fn ident_to_path(s: span, +i: ident) -> @path { rp: None, types: ~[]} } -pure fn is_unguarded(&&a: arm) -> bool { +pure fn is_unguarded(a: &arm) -> bool { match a.guard { None => true, _ => false } } -pure fn unguarded_pat(a: arm) -> Option<~[@pat]> { +pure fn unguarded_pat(a: &arm) -> Option<~[@pat]> { if is_unguarded(a) { Some(/* FIXME (#2543) */ copy a.pats) } else { None } } @@ -313,8 +313,8 @@ fn split_trait_methods(trait_methods: ~[trait_method]) let mut reqd = ~[], provd = ~[]; for trait_methods.each |trt_method| { match *trt_method { - required(tm) => vec::push(reqd, tm), - provided(m) => vec::push(provd, m) + required(tm) => reqd.push(tm), + provided(m) => provd.push(m) } }; (reqd, provd) @@ -398,10 +398,8 @@ fn operator_prec(op: ast::binop) -> uint { fn dtor_dec() -> fn_decl { let nil_t = @{id: 0, node: ty_nil, span: dummy_sp()}; - // dtor has one argument, of type () - {inputs: ~[{mode: ast::expl(ast::by_ref), - ty: nil_t, ident: parse::token::special_idents::underscore, - id: 0}], + // dtor has no args + {inputs: ~[], output: nil_t, cf: return_val} } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index a291501ef5fd..374300f07c73 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -91,7 +91,7 @@ fn attr_meta(attr: ast::attribute) -> @ast::meta_item { @attr.node.value } // Get the meta_items from inside a vector of attributes fn attr_metas(attrs: ~[ast::attribute]) -> ~[@ast::meta_item] { let mut mitems = ~[]; - for attrs.each |a| { vec::push(mitems, attr_meta(*a)); } + for attrs.each |a| { mitems.push(attr_meta(*a)); } return mitems; } @@ -163,9 +163,9 @@ fn get_name_value_str_pair(item: @ast::meta_item) -> Option<(~str, ~str)> { fn find_attrs_by_name(attrs: ~[ast::attribute], name: ~str) -> ~[ast::attribute] { let filter = ( - fn@(a: ast::attribute) -> Option { - if get_attr_name(a) == name { - option::Some(a) + fn@(a: &ast::attribute) -> Option { + if get_attr_name(*a) == name { + option::Some(*a) } else { option::None } } ); @@ -175,9 +175,9 @@ fn find_attrs_by_name(attrs: ~[ast::attribute], name: ~str) -> /// Searcha list of meta items and return only those with a specific name fn find_meta_items_by_name(metas: ~[@ast::meta_item], name: ~str) -> ~[@ast::meta_item] { - let filter = fn@(&&m: @ast::meta_item) -> Option<@ast::meta_item> { - if get_meta_item_name(m) == name { - option::Some(m) + let filter = fn@(m: &@ast::meta_item) -> Option<@ast::meta_item> { + if get_meta_item_name(*m) == name { + option::Some(*m) } else { option::None } }; return vec::filter_map(metas, filter); @@ -289,8 +289,8 @@ fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) -> ~[@ast::meta_item] { return vec::filter_map(items, |item| { - if get_meta_item_name(item) != name { - option::Some(/* FIXME (#2543) */ copy item) + if get_meta_item_name(*item) != name { + option::Some(/* FIXME (#2543) */ copy *item) } else { option::None } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index ae49e19c8628..e07985119ec4 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -84,7 +84,7 @@ fn mk_substr_filename(cm: codemap, sp: span) -> ~str } fn next_line(file: filemap, chpos: uint, byte_pos: uint) { - vec::push(file.lines, {ch: chpos, byte: byte_pos + file.start_pos.byte}); + file.lines.push({ch: chpos, byte: byte_pos + file.start_pos.byte}); } type lookup_fn = pure fn(file_pos) -> uint; @@ -204,7 +204,7 @@ fn span_to_lines(sp: span, cm: codemap::codemap) -> @file_lines { let hi = lookup_char_pos(cm, sp.hi); let mut lines = ~[]; for uint::range(lo.line - 1u, hi.line as uint) |i| { - vec::push(lines, i); + lines.push(i); }; return @{file: lo.file, lines: lines}; } diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index ca9db6d25ad8..7f208a3a710c 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -10,30 +10,30 @@ export ice_msg; export expect; type emitter = fn@(cmsp: Option<(codemap::codemap, span)>, - msg: ~str, lvl: level); + msg: &str, lvl: level); trait span_handler { - fn span_fatal(sp: span, msg: ~str) -> !; - fn span_err(sp: span, msg: ~str); - fn span_warn(sp: span, msg: ~str); - fn span_note(sp: span, msg: ~str); - fn span_bug(sp: span, msg: ~str) -> !; - fn span_unimpl(sp: span, msg: ~str) -> !; + fn span_fatal(sp: span, msg: &str) -> !; + fn span_err(sp: span, msg: &str); + fn span_warn(sp: span, msg: &str); + fn span_note(sp: span, msg: &str); + fn span_bug(sp: span, msg: &str) -> !; + fn span_unimpl(sp: span, msg: &str) -> !; fn handler() -> handler; } trait handler { - fn fatal(msg: ~str) -> !; - fn err(msg: ~str); + fn fatal(msg: &str) -> !; + fn err(msg: &str); fn bump_err_count(); fn has_errors() -> bool; fn abort_if_errors(); - fn warn(msg: ~str); - fn note(msg: ~str); - fn bug(msg: ~str) -> !; - fn unimpl(msg: ~str) -> !; - fn emit(cmsp: Option<(codemap::codemap, span)>, msg: ~str, lvl: level); + fn warn(msg: &str); + fn note(msg: &str); + fn bug(msg: &str) -> !; + fn unimpl(msg: &str) -> !; + fn emit(cmsp: Option<(codemap::codemap, span)>, msg: &str, lvl: level); } type handler_t = @{ @@ -47,24 +47,24 @@ type codemap_t = @{ }; impl codemap_t: span_handler { - fn span_fatal(sp: span, msg: ~str) -> ! { + fn span_fatal(sp: span, msg: &str) -> ! { self.handler.emit(Some((self.cm, sp)), msg, fatal); fail; } - fn span_err(sp: span, msg: ~str) { + fn span_err(sp: span, msg: &str) { self.handler.emit(Some((self.cm, sp)), msg, error); self.handler.bump_err_count(); } - fn span_warn(sp: span, msg: ~str) { + fn span_warn(sp: span, msg: &str) { self.handler.emit(Some((self.cm, sp)), msg, warning); } - fn span_note(sp: span, msg: ~str) { + fn span_note(sp: span, msg: &str) { self.handler.emit(Some((self.cm, sp)), msg, note); } - fn span_bug(sp: span, msg: ~str) -> ! { + fn span_bug(sp: span, msg: &str) -> ! { self.span_fatal(sp, ice_msg(msg)); } - fn span_unimpl(sp: span, msg: ~str) -> ! { + fn span_unimpl(sp: span, msg: &str) -> ! { self.span_bug(sp, ~"unimplemented " + msg); } fn handler() -> handler { @@ -73,11 +73,11 @@ impl codemap_t: span_handler { } impl handler_t: handler { - fn fatal(msg: ~str) -> ! { + fn fatal(msg: &str) -> ! { self.emit(None, msg, fatal); fail; } - fn err(msg: ~str) { + fn err(msg: &str) { self.emit(None, msg, error); self.bump_err_count(); } @@ -97,22 +97,22 @@ impl handler_t: handler { } self.fatal(s); } - fn warn(msg: ~str) { + fn warn(msg: &str) { self.emit(None, msg, warning); } - fn note(msg: ~str) { + fn note(msg: &str) { self.emit(None, msg, note); } - fn bug(msg: ~str) -> ! { + fn bug(msg: &str) -> ! { self.fatal(ice_msg(msg)); } - fn unimpl(msg: ~str) -> ! { self.bug(~"unimplemented " + msg); } - fn emit(cmsp: Option<(codemap::codemap, span)>, msg: ~str, lvl: level) { + fn unimpl(msg: &str) -> ! { self.bug(~"unimplemented " + msg); } + fn emit(cmsp: Option<(codemap::codemap, span)>, msg: &str, lvl: level) { self.emit(cmsp, msg, lvl); } } -fn ice_msg(msg: ~str) -> ~str { +fn ice_msg(msg: &str) -> ~str { fmt!("internal compiler error: %s", msg) } @@ -126,17 +126,19 @@ fn mk_handler(emitter: Option) -> handler { Some(e) => e, None => { let f = fn@(cmsp: Option<(codemap::codemap, span)>, - msg: ~str, t: level) { + msg: &str, t: level) { emit(cmsp, msg, t); }; f } }; - @{ - mut err_count: 0u, + let x: handler_t = @{ + mut err_count: 0, emit: emit - } as handler + }; + + x as handler } enum level { @@ -171,7 +173,7 @@ fn diagnosticcolor(lvl: level) -> u8 { } } -fn print_diagnostic(topic: ~str, lvl: level, msg: ~str) { +fn print_diagnostic(topic: ~str, lvl: level, msg: &str) { let use_color = term::color_supported() && io::stderr().get_type() == io::Screen; if str::is_not_empty(topic) { @@ -188,7 +190,7 @@ fn print_diagnostic(topic: ~str, lvl: level, msg: ~str) { } fn emit(cmsp: Option<(codemap::codemap, span)>, - msg: ~str, lvl: level) { + msg: &str, lvl: level) { match cmsp { Some((cm, sp)) => { let sp = codemap::adjust_span(cm,sp); @@ -262,7 +264,7 @@ fn highlight_lines(cm: codemap::codemap, sp: span, fn print_macro_backtrace(cm: codemap::codemap, sp: span) { do option::iter(&sp.expn_info) |ei| { let ss = option::map_default(&ei.callie.span, @~"", - |span| @codemap::span_to_str(span, cm)); + |span| @codemap::span_to_str(*span, cm)); print_diagnostic(*ss, note, fmt!("in expansion of #%s", ei.callie.name)); let ss = codemap::span_to_str(ei.call_site, cm); diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index 4ebb85010411..64915c607425 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -90,8 +90,8 @@ fn expand(cx: ext_ctxt, span: span, _mitem: ast::meta_item, in_items: ~[@ast::item]) -> ~[@ast::item] { - fn not_auto_serialize(a: ast::attribute) -> bool { - attr::get_attr_name(a) != ~"auto_serialize" + fn not_auto_serialize(a: &ast::attribute) -> bool { + attr::get_attr_name(*a) != ~"auto_serialize" } fn filter_attrs(item: @ast::item) -> @ast::item { @@ -102,12 +102,12 @@ fn expand(cx: ext_ctxt, do vec::flat_map(in_items) |in_item| { match in_item.node { ast::item_ty(ty, tps) => { - vec::append(~[filter_attrs(in_item)], + vec::append(~[filter_attrs(*in_item)], ty_fns(cx, in_item.ident, ty, tps)) } ast::item_enum(enum_definition, tps) => { - vec::append(~[filter_attrs(in_item)], + vec::append(~[filter_attrs(*in_item)], enum_fns(cx, in_item.ident, in_item.span, enum_definition.variants, tps)) } @@ -116,7 +116,7 @@ fn expand(cx: ext_ctxt, cx.span_err(span, ~"#[auto_serialize] can only be \ applied to type and enum \ definitions"); - ~[in_item] + ~[*in_item] } } } @@ -566,7 +566,7 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: ast::ident, tp_inputs); let tps_map = map::HashMap(); - do vec::iter2(tps, tp_inputs) |tp, arg| { + for vec::each2(tps, tp_inputs) |tp, arg| { let arg_ident = arg.ident; tps_map.insert( tp.ident, @@ -773,7 +773,7 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, tp_inputs); let tps_map = map::HashMap(); - do vec::iter2(tps, tp_inputs) |tp, arg| { + for vec::each2(tps, tp_inputs) |tp, arg| { let arg_ident = arg.ident; tps_map.insert( tp.ident, diff --git a/src/libsyntax/ext/auto_serialize2.rs b/src/libsyntax/ext/auto_serialize2.rs new file mode 100644 index 000000000000..99f837a4c844 --- /dev/null +++ b/src/libsyntax/ext/auto_serialize2.rs @@ -0,0 +1,1025 @@ +/* + +The compiler code necessary to implement the #[auto_serialize2] and +#[auto_deserialize2] extension. The idea here is that type-defining items may +be tagged with #[auto_serialize2] and #[auto_deserialize2], which will cause +us to generate a little companion module with the same name as the item. + +For example, a type like: + + #[auto_serialize2] + #[auto_deserialize2] + struct Node {id: uint} + +would generate two implementations like: + + impl Node: Serializable { + fn serialize(s: &S) { + do s.emit_struct("Node") { + s.emit_field("id", 0, || s.emit_uint(self)) + } + } + } + + impl node_id: Deserializable { + static fn deserialize(d: &D) -> Node { + do d.read_struct("Node") { + Node { + id: d.read_field(~"x", 0, || deserialize(d)) + } + } + } + } + +Other interesting scenarios are whe the item has type parameters or +references other non-built-in types. A type definition like: + + #[auto_serialize2] + #[auto_deserialize2] + type spanned = {node: T, span: span}; + +would yield functions like: + + impl spanned: Serializable { + fn serialize(s: &S) { + do s.emit_rec { + s.emit_field("node", 0, || self.node.serialize(s)); + s.emit_field("span", 1, || self.span.serialize(s)); + } + } + } + + impl spanned: Deserializable { + static fn deserialize(d: &D) -> spanned { + do d.read_rec { + { + node: d.read_field(~"node", 0, || deserialize(d)), + span: d.read_field(~"span", 1, || deserialize(d)), + } + } + } + } + +FIXME (#2810)--Hygiene. Search for "__" strings. We also assume "std" is the +standard library. + +Misc notes: +----------- + +I use move mode arguments for ast nodes that will get inserted as is +into the tree. This is intended to prevent us from inserting the same +node twice. + +*/ + +use base::*; +use codemap::span; +use std::map; +use std::map::HashMap; + +export expand_auto_serialize; +export expand_auto_deserialize; + +// Transitional reexports so qquote can find the paths it is looking for +mod syntax { + pub use ext; + pub use parse; +} + +fn expand_auto_serialize( + cx: ext_ctxt, + span: span, + _mitem: ast::meta_item, + in_items: ~[@ast::item] +) -> ~[@ast::item] { + fn is_auto_serialize2(a: &ast::attribute) -> bool { + attr::get_attr_name(*a) == ~"auto_serialize2" + } + + fn filter_attrs(item: @ast::item) -> @ast::item { + @{attrs: vec::filter(item.attrs, |a| !is_auto_serialize2(a)), + .. *item} + } + + do vec::flat_map(in_items) |item| { + if item.attrs.any(is_auto_serialize2) { + match item.node { + ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => { + let ser_impl = mk_rec_ser_impl( + cx, + item.span, + item.ident, + fields, + tps + ); + + ~[filter_attrs(*item), ser_impl] + }, + ast::item_class(@{ fields, _}, tps) => { + let ser_impl = mk_struct_ser_impl( + cx, + item.span, + item.ident, + fields, + tps + ); + + ~[filter_attrs(*item), ser_impl] + }, + ast::item_enum(enum_def, tps) => { + let ser_impl = mk_enum_ser_impl( + cx, + item.span, + item.ident, + enum_def, + tps + ); + + ~[filter_attrs(*item), ser_impl] + }, + _ => { + cx.span_err(span, ~"#[auto_serialize2] can only be \ + applied to structs, record types, \ + and enum definitions"); + ~[*item] + } + } + } else { + ~[*item] + } + } +} + +fn expand_auto_deserialize( + cx: ext_ctxt, + span: span, + _mitem: ast::meta_item, + in_items: ~[@ast::item] +) -> ~[@ast::item] { + fn is_auto_deserialize2(a: &ast::attribute) -> bool { + attr::get_attr_name(*a) == ~"auto_deserialize2" + } + + fn filter_attrs(item: @ast::item) -> @ast::item { + @{attrs: vec::filter(item.attrs, |a| !is_auto_deserialize2(a)), + .. *item} + } + + do vec::flat_map(in_items) |item| { + if item.attrs.any(is_auto_deserialize2) { + match item.node { + ast::item_ty(@{node: ast::ty_rec(fields), _}, tps) => { + let deser_impl = mk_rec_deser_impl( + cx, + item.span, + item.ident, + fields, + tps + ); + + ~[filter_attrs(*item), deser_impl] + }, + ast::item_class(@{ fields, _}, tps) => { + let deser_impl = mk_struct_deser_impl( + cx, + item.span, + item.ident, + fields, + tps + ); + + ~[filter_attrs(*item), deser_impl] + }, + ast::item_enum(enum_def, tps) => { + let deser_impl = mk_enum_deser_impl( + cx, + item.span, + item.ident, + enum_def, + tps + ); + + ~[filter_attrs(*item), deser_impl] + }, + _ => { + cx.span_err(span, ~"#[auto_deserialize2] can only be \ + applied to structs, record types, \ + and enum definitions"); + ~[*item] + } + } + } else { + ~[*item] + } + } +} + +priv impl ext_ctxt { + fn expr_path(span: span, strs: ~[ast::ident]) -> @ast::expr { + self.expr(span, ast::expr_path(self.path(span, strs))) + } + + fn expr_var(span: span, var: ~str) -> @ast::expr { + self.expr_path(span, ~[self.ident_of(var)]) + } + + fn expr_field( + span: span, + expr: @ast::expr, + ident: ast::ident + ) -> @ast::expr { + self.expr(span, ast::expr_field(expr, ident, ~[])) + } + + fn expr_call( + span: span, + expr: @ast::expr, + args: ~[@ast::expr] + ) -> @ast::expr { + self.expr(span, ast::expr_call(expr, args, false)) + } + + fn lambda_expr(expr: @ast::expr) -> @ast::expr { + self.lambda(self.expr_blk(expr)) + } + + fn lambda_stmts(span: span, stmts: ~[@ast::stmt]) -> @ast::expr { + self.lambda(self.blk(span, stmts)) + } +} + +fn mk_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + path: @ast::path, + tps: ~[ast::ty_param], + f: fn(@ast::ty) -> @ast::method +) -> @ast::item { + // All the type parameters need to bound to the trait. + let trait_tps = do tps.map |tp| { + let t_bound = ast::bound_trait(@{ + id: cx.next_id(), + node: ast::ty_path(path, cx.next_id()), + span: span, + }); + + { + ident: tp.ident, + id: cx.next_id(), + bounds: @vec::append(~[t_bound], *tp.bounds) + } + }; + + let opt_trait = Some(@{ + path: path, + ref_id: cx.next_id(), + impl_id: cx.next_id(), + }); + + let ty = cx.ty_path( + span, + ~[ident], + tps.map(|tp| cx.ty_path(span, ~[tp.ident], ~[])) + ); + + @{ + // This is a new-style impl declaration. + // XXX: clownshoes + ident: ast::token::special_idents::clownshoes_extensions, + attrs: ~[], + id: cx.next_id(), + node: ast::item_impl(trait_tps, opt_trait, ty, ~[f(ty)]), + vis: ast::public, + span: span, + } +} + +fn mk_ser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + tps: ~[ast::ty_param], + body: @ast::expr +) -> @ast::item { + // Make a path to the std::serialization2::Serializable trait. + let path = cx.path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization2"), + cx.ident_of(~"Serializable"), + ] + ); + + mk_impl( + cx, + span, + ident, + path, + tps, + |_ty| mk_ser_method(cx, span, cx.expr_blk(body)) + ) +} + +fn mk_deser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + tps: ~[ast::ty_param], + body: @ast::expr +) -> @ast::item { + // Make a path to the std::serialization2::Deserializable trait. + let path = cx.path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization2"), + cx.ident_of(~"Deserializable"), + ] + ); + + mk_impl( + cx, + span, + ident, + path, + tps, + |ty| mk_deser_method(cx, span, ty, cx.expr_blk(body)) + ) +} + +fn mk_ser_method( + cx: ext_ctxt, + span: span, + ser_body: ast::blk +) -> @ast::method { + let ser_bound = cx.ty_path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization2"), + cx.ident_of(~"Serializer"), + ], + ~[] + ); + + let ser_tps = ~[{ + ident: cx.ident_of(~"__S"), + id: cx.next_id(), + bounds: @~[ast::bound_trait(ser_bound)], + }]; + + let ty_s = @{ + id: cx.next_id(), + node: ast::ty_rptr( + @{ + id: cx.next_id(), + node: ast::re_anon, + }, + { + ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), + mutbl: ast::m_imm + } + ), + span: span, + }; + + let ser_inputs = ~[{ + mode: ast::infer(cx.next_id()), + ty: ty_s, + ident: cx.ident_of(~"__s"), + id: cx.next_id(), + }]; + + let ser_output = @{ + id: cx.next_id(), + node: ast::ty_nil, + span: span, + }; + + let ser_decl = { + inputs: ser_inputs, + output: ser_output, + cf: ast::return_val, + }; + + @{ + ident: cx.ident_of(~"serialize"), + attrs: ~[], + tps: ser_tps, + self_ty: { node: ast::sty_region(ast::m_imm), span: span }, + purity: ast::impure_fn, + decl: ser_decl, + body: ser_body, + id: cx.next_id(), + span: span, + self_id: cx.next_id(), + vis: ast::public, + } +} + +fn mk_deser_method( + cx: ext_ctxt, + span: span, + ty: @ast::ty, + deser_body: ast::blk +) -> @ast::method { + let deser_bound = cx.ty_path( + span, + ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization2"), + cx.ident_of(~"Deserializer"), + ], + ~[] + ); + + let deser_tps = ~[{ + ident: cx.ident_of(~"__D"), + id: cx.next_id(), + bounds: @~[ast::bound_trait(deser_bound)], + }]; + + let ty_d = @{ + id: cx.next_id(), + node: ast::ty_rptr( + @{ + id: cx.next_id(), + node: ast::re_anon, + }, + { + ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), + mutbl: ast::m_imm + } + ), + span: span, + }; + + let deser_inputs = ~[{ + mode: ast::infer(cx.next_id()), + ty: ty_d, + ident: cx.ident_of(~"__d"), + id: cx.next_id(), + }]; + + let deser_decl = { + inputs: deser_inputs, + output: ty, + cf: ast::return_val, + }; + + @{ + ident: cx.ident_of(~"deserialize"), + attrs: ~[], + tps: deser_tps, + self_ty: { node: ast::sty_static, span: span }, + purity: ast::impure_fn, + decl: deser_decl, + body: deser_body, + id: cx.next_id(), + span: span, + self_id: cx.next_id(), + vis: ast::public, + } +} + +fn mk_rec_ser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + fields: ~[ast::ty_field], + tps: ~[ast::ty_param] +) -> @ast::item { + let fields = mk_ser_fields(cx, span, mk_rec_fields(fields)); + + // ast for `__s.emit_rec(|| $(fields))` + let body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_rec") + ), + ~[cx.lambda_stmts(span, fields)] + ); + + mk_ser_impl(cx, span, ident, tps, body) +} + +fn mk_rec_deser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + fields: ~[ast::ty_field], + tps: ~[ast::ty_param] +) -> @ast::item { + let fields = mk_deser_fields(cx, span, mk_rec_fields(fields)); + + // ast for `read_rec(|| $(fields))` + let body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_rec") + ), + ~[ + cx.lambda_expr( + cx.expr( + span, + ast::expr_rec(fields, None) + ) + ) + ] + ); + + mk_deser_impl(cx, span, ident, tps, body) +} + +fn mk_struct_ser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + fields: ~[@ast::struct_field], + tps: ~[ast::ty_param] +) -> @ast::item { + let fields = mk_ser_fields(cx, span, mk_struct_fields(fields)); + + // ast for `__s.emit_struct($(name), || $(fields))` + let ser_body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_struct") + ), + ~[ + cx.lit_str(span, @cx.str_of(ident)), + cx.lambda_stmts(span, fields), + ] + ); + + mk_ser_impl(cx, span, ident, tps, ser_body) +} + +fn mk_struct_deser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + fields: ~[@ast::struct_field], + tps: ~[ast::ty_param] +) -> @ast::item { + let fields = mk_deser_fields(cx, span, mk_struct_fields(fields)); + + // ast for `read_struct($(name), || $(fields))` + let body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_struct") + ), + ~[ + cx.lit_str(span, @cx.str_of(ident)), + cx.lambda_expr( + cx.expr( + span, + ast::expr_struct( + cx.path(span, ~[ident]), + fields, + None + ) + ) + ), + ] + ); + + mk_deser_impl(cx, span, ident, tps, body) +} + +// Records and structs don't have the same fields types, but they share enough +// that if we extract the right subfields out we can share the serialization +// generator code. +type field = { span: span, ident: ast::ident, mutbl: ast::mutability }; + +fn mk_rec_fields(fields: ~[ast::ty_field]) -> ~[field] { + do fields.map |field| { + { + span: field.span, + ident: field.node.ident, + mutbl: field.node.mt.mutbl, + } + } +} + +fn mk_struct_fields(fields: ~[@ast::struct_field]) -> ~[field] { + do fields.map |field| { + let (ident, mutbl) = match field.node.kind { + ast::named_field(ident, mutbl, _) => (ident, mutbl), + _ => fail ~"[auto_serialize2] does not support \ + unnamed fields", + }; + + { + span: field.span, + ident: ident, + mutbl: match mutbl { + ast::class_mutable => ast::m_mutbl, + ast::class_immutable => ast::m_imm, + }, + } + } +} + +fn mk_ser_fields( + cx: ext_ctxt, + span: span, + fields: ~[field] +) -> ~[@ast::stmt] { + do fields.mapi |idx, field| { + // ast for `|| self.$(name).serialize(__s)` + let expr_lambda = cx.lambda_expr( + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"self"), + field.ident + ), + cx.ident_of(~"serialize") + ), + ~[cx.expr_var(span, ~"__s")] + ) + ); + + // ast for `__s.emit_field($(name), $(idx), $(expr_lambda))` + cx.stmt( + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_field") + ), + ~[ + cx.lit_str(span, @cx.str_of(field.ident)), + cx.lit_uint(span, idx), + expr_lambda, + ] + ) + ) + } +} + +fn mk_deser_fields( + cx: ext_ctxt, + span: span, + fields: ~[{ span: span, ident: ast::ident, mutbl: ast::mutability }] +) -> ~[ast::field] { + do fields.mapi |idx, field| { + // ast for `|| std::serialization2::deserialize(__d)` + let expr_lambda = cx.lambda( + cx.expr_blk( + cx.expr_call( + span, + cx.expr_path(span, ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization2"), + cx.ident_of(~"deserialize"), + ]), + ~[cx.expr_var(span, ~"__d")] + ) + ) + ); + + // ast for `__d.read_field($(name), $(idx), $(expr_lambda))` + let expr: @ast::expr = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_field") + ), + ~[ + cx.lit_str(span, @cx.str_of(field.ident)), + cx.lit_uint(span, idx), + expr_lambda, + ] + ); + + { + node: { mutbl: field.mutbl, ident: field.ident, expr: expr }, + span: span, + } + } +} + +fn mk_enum_ser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + enum_def: ast::enum_def, + tps: ~[ast::ty_param] +) -> @ast::item { + let body = mk_enum_ser_body( + cx, + span, + ident, + enum_def.variants + ); + + mk_ser_impl(cx, span, ident, tps, body) +} + +fn mk_enum_deser_impl( + cx: ext_ctxt, + span: span, + ident: ast::ident, + enum_def: ast::enum_def, + tps: ~[ast::ty_param] +) -> @ast::item { + let body = mk_enum_deser_body( + cx, + span, + ident, + enum_def.variants + ); + + mk_deser_impl(cx, span, ident, tps, body) +} + +fn ser_variant( + cx: ext_ctxt, + span: span, + v_name: ast::ident, + v_idx: uint, + args: ~[ast::variant_arg] +) -> ast::arm { + // Name the variant arguments. + let names = args.mapi(|i, _arg| cx.ident_of(fmt!("__v%u", i))); + + // Bind the names to the variant argument type. + let pats = args.mapi(|i, arg| cx.binder_pat(arg.ty.span, names[i])); + + let pat_node = if pats.is_empty() { + ast::pat_ident( + ast::bind_by_implicit_ref, + cx.path(span, ~[v_name]), + None + ) + } else { + ast::pat_enum( + cx.path(span, ~[v_name]), + Some(pats) + ) + }; + + let pat = @{ + id: cx.next_id(), + node: pat_node, + span: span, + }; + + let stmts = do args.mapi |a_idx, _arg| { + // ast for `__s.emit_enum_variant_arg` + let expr_emit = cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_enum_variant_arg") + ); + + // ast for `|| $(v).serialize(__s)` + let expr_serialize = cx.lambda_expr( + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_path(span, ~[names[a_idx]]), + cx.ident_of(~"serialize") + ), + ~[cx.expr_var(span, ~"__s")] + ) + ); + + // ast for `$(expr_emit)($(a_idx), $(expr_serialize))` + cx.stmt( + cx.expr_call( + span, + expr_emit, + ~[cx.lit_uint(span, a_idx), expr_serialize] + ) + ) + }; + + // ast for `__s.emit_enum_variant($(name), $(idx), $(sz), $(lambda))` + let body = cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_enum_variant") + ), + ~[ + cx.lit_str(span, @cx.str_of(v_name)), + cx.lit_uint(span, v_idx), + cx.lit_uint(span, stmts.len()), + cx.lambda_stmts(span, stmts), + ] + ); + + { pats: ~[pat], guard: None, body: cx.expr_blk(body) } +} + +fn mk_enum_ser_body( + cx: ext_ctxt, + span: span, + name: ast::ident, + variants: ~[ast::variant] +) -> @ast::expr { + let arms = do variants.mapi |v_idx, variant| { + match variant.node.kind { + ast::tuple_variant_kind(args) => + ser_variant(cx, span, variant.node.name, v_idx, args), + ast::struct_variant_kind(*) => + fail ~"struct variants unimplemented", + ast::enum_variant_kind(*) => + fail ~"enum variants unimplemented", + } + }; + + // ast for `match *self { $(arms) }` + let match_expr = cx.expr( + span, + ast::expr_match( + cx.expr( + span, + ast::expr_unary(ast::deref, cx.expr_var(span, ~"self")) + ), + arms + ) + ); + + // ast for `__s.emit_enum($(name), || $(match_expr))` + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__s"), + cx.ident_of(~"emit_enum") + ), + ~[ + cx.lit_str(span, @cx.str_of(name)), + cx.lambda_expr(match_expr), + ] + ) +} + +fn mk_enum_deser_variant_nary( + cx: ext_ctxt, + span: span, + name: ast::ident, + args: ~[ast::variant_arg] +) -> @ast::expr { + let args = do args.mapi |idx, _arg| { + // ast for `|| std::serialization2::deserialize(__d)` + let expr_lambda = cx.lambda_expr( + cx.expr_call( + span, + cx.expr_path(span, ~[ + cx.ident_of(~"std"), + cx.ident_of(~"serialization2"), + cx.ident_of(~"deserialize"), + ]), + ~[cx.expr_var(span, ~"__d")] + ) + ); + + // ast for `__d.read_enum_variant_arg($(a_idx), $(expr_lambda))` + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_enum_variant_arg") + ), + ~[cx.lit_uint(span, idx), expr_lambda] + ) + }; + + // ast for `$(name)($(args))` + cx.expr_call(span, cx.expr_path(span, ~[name]), args) +} + +fn mk_enum_deser_body( + cx: ext_ctxt, + span: span, + name: ast::ident, + variants: ~[ast::variant] +) -> @ast::expr { + let mut arms = do variants.mapi |v_idx, variant| { + let body = match variant.node.kind { + ast::tuple_variant_kind(args) => { + if args.is_empty() { + // for a nullary variant v, do "v" + cx.expr_path(span, ~[variant.node.name]) + } else { + // for an n-ary variant v, do "v(a_1, ..., a_n)" + mk_enum_deser_variant_nary( + cx, + span, + variant.node.name, + args + ) + } + }, + ast::struct_variant_kind(*) => + fail ~"struct variants unimplemented", + ast::enum_variant_kind(*) => + fail ~"enum variants unimplemented", + }; + + let pat = @{ + id: cx.next_id(), + node: ast::pat_lit(cx.lit_uint(span, v_idx)), + span: span, + }; + + { + pats: ~[pat], + guard: None, + body: cx.expr_blk(body), + } + }; + + let impossible_case = { + pats: ~[@{ id: cx.next_id(), node: ast::pat_wild, span: span}], + guard: None, + + // FIXME(#3198): proper error message + body: cx.expr_blk(cx.expr(span, ast::expr_fail(None))), + }; + + arms.push(impossible_case); + + // ast for `|i| { match i { $(arms) } }` + let expr_lambda = cx.expr( + span, + ast::expr_fn_block( + { + inputs: ~[{ + mode: ast::infer(cx.next_id()), + ty: @{ + id: cx.next_id(), + node: ast::ty_infer, + span: span + }, + ident: cx.ident_of(~"i"), + id: cx.next_id(), + }], + output: @{ + id: cx.next_id(), + node: ast::ty_infer, + span: span, + }, + cf: ast::return_val, + }, + cx.expr_blk( + cx.expr( + span, + ast::expr_match(cx.expr_var(span, ~"i"), arms) + ) + ), + @~[] + ) + ); + + // ast for `__d.read_enum_variant($(expr_lambda))` + let expr_lambda = cx.lambda_expr( + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_enum_variant") + ), + ~[expr_lambda] + ) + ); + + // ast for `__d.read_enum($(e_name), $(expr_lambda))` + cx.expr_call( + span, + cx.expr_field( + span, + cx.expr_var(span, ~"__d"), + cx.ident_of(~"read_enum") + ), + ~[ + cx.lit_str(span, @cx.str_of(name)), + expr_lambda + ] + ) +} diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index a3ab35d77f0e..9a31cc1d8f67 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -73,7 +73,7 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> { fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension { item_tt({expander: f, span: None}) } - let syntax_expanders = HashMap::<~str,syntax_extension>(); + let syntax_expanders = HashMap(); syntax_expanders.insert(~"macro", macro_defining(ext::simplext::add_new_extension)); syntax_expanders.insert(~"macro_rules", @@ -82,6 +82,12 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> { syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext)); syntax_expanders.insert(~"auto_serialize", item_decorator(ext::auto_serialize::expand)); + syntax_expanders.insert( + ~"auto_serialize2", + item_decorator(ext::auto_serialize2::expand_auto_serialize)); + syntax_expanders.insert( + ~"auto_deserialize2", + item_decorator(ext::auto_serialize2::expand_auto_deserialize)); syntax_expanders.insert(~"env", builtin(ext::env::expand_syntax_ext)); syntax_expanders.insert(~"concat_idents", builtin(ext::concat_idents::expand_syntax_ext)); @@ -131,12 +137,12 @@ trait ext_ctxt { fn mod_path() -> ~[ast::ident]; fn bt_push(ei: codemap::expn_info_); fn bt_pop(); - fn span_fatal(sp: span, msg: ~str) -> !; - fn span_err(sp: span, msg: ~str); - fn span_warn(sp: span, msg: ~str); - fn span_unimpl(sp: span, msg: ~str) -> !; - fn span_bug(sp: span, msg: ~str) -> !; - fn bug(msg: ~str) -> !; + fn span_fatal(sp: span, msg: &str) -> !; + fn span_err(sp: span, msg: &str); + fn span_warn(sp: span, msg: &str); + fn span_unimpl(sp: span, msg: &str) -> !; + fn span_bug(sp: span, msg: &str) -> !; + fn bug(msg: &str) -> !; fn next_id() -> ast::node_id; pure fn trace_macros() -> bool; fn set_trace_macros(x: bool); @@ -158,8 +164,8 @@ fn mk_ctxt(parse_sess: parse::parse_sess, fn cfg() -> ast::crate_cfg { self.cfg } fn print_backtrace() { } fn backtrace() -> expn_info { self.backtrace } - fn mod_push(i: ast::ident) { vec::push(self.mod_path, i); } - fn mod_pop() { vec::pop(self.mod_path); } + fn mod_push(i: ast::ident) { self.mod_path.push(i); } + fn mod_pop() { self.mod_path.pop(); } fn mod_path() -> ~[ast::ident] { return self.mod_path; } fn bt_push(ei: codemap::expn_info_) { match ei { @@ -180,27 +186,27 @@ fn mk_ctxt(parse_sess: parse::parse_sess, _ => self.bug(~"tried to pop without a push") } } - fn span_fatal(sp: span, msg: ~str) -> ! { + fn span_fatal(sp: span, msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.span_fatal(sp, msg); } - fn span_err(sp: span, msg: ~str) { + fn span_err(sp: span, msg: &str) { self.print_backtrace(); self.parse_sess.span_diagnostic.span_err(sp, msg); } - fn span_warn(sp: span, msg: ~str) { + fn span_warn(sp: span, msg: &str) { self.print_backtrace(); self.parse_sess.span_diagnostic.span_warn(sp, msg); } - fn span_unimpl(sp: span, msg: ~str) -> ! { + fn span_unimpl(sp: span, msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.span_unimpl(sp, msg); } - fn span_bug(sp: span, msg: ~str) -> ! { + fn span_bug(sp: span, msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.span_bug(sp, msg); } - fn bug(msg: ~str) -> ! { + fn bug(msg: &str) -> ! { self.print_backtrace(); self.parse_sess.span_diagnostic.handler().bug(msg); } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 8574c0c90820..a43b0cb69f4b 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -50,6 +50,10 @@ fn mk_access(cx: ext_ctxt, sp: span, p: ~[ast::ident], m: ast::ident) let pathexpr = mk_path(cx, sp, p); return mk_access_(cx, sp, pathexpr, m); } +fn mk_addr_of(cx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr { + return mk_expr(cx, sp, ast::expr_addr_of(ast::m_imm, e)); +} + fn mk_call_(cx: ext_ctxt, sp: span, fn_expr: @ast::expr, args: ~[@ast::expr]) -> @ast::expr { mk_expr(cx, sp, ast::expr_call(fn_expr, args, false)) @@ -96,7 +100,7 @@ fn mk_rec_e(cx: ext_ctxt, sp: span, let val = field.ex; let astfield = {node: {mutbl: ast::m_imm, ident: ident, expr: val}, span: sp}; - vec::push(astfields, astfield); + astfields.push(astfield); } let recexpr = ast::expr_rec(astfields, option::None::<@ast::expr>); mk_expr(cx, sp, recexpr) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index dbe475c1b509..22e2cfcde6b5 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -144,7 +144,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, // decorated with "item decorators", then use that function to transform // the item into a new set of items. let new_items = do vec::flat_map(module_.items) |item| { - do vec::foldr(item.attrs, ~[item]) |attr, items| { + do vec::foldr(item.attrs, ~[*item]) |attr, items| { let mname = match attr.node.value.node { ast::meta_word(n) => n, ast::meta_name_value(n, _) => n, @@ -160,7 +160,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, } }; - return {items: new_items,.. module_}; + return {items: new_items, ..module_}; } diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 3ea0493239f0..ea493eab5617 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -20,10 +20,10 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg, let fmtspan = args[0].span; debug!("Format string:"); log(debug, fmt); - fn parse_fmt_err_(cx: ext_ctxt, sp: span, msg: ~str) -> ! { + fn parse_fmt_err_(cx: ext_ctxt, sp: span, msg: &str) -> ! { cx.span_fatal(sp, msg); } - let parse_fmt_err = fn@(s: ~str) -> ! { + let parse_fmt_err = fn@(s: &str) -> ! { parse_fmt_err_(cx, fmtspan, s) }; let pieces = parse_fmt_string(fmt, parse_fmt_err); @@ -187,7 +187,8 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, TyFloat => { return make_conv_call(cx, arg.span, ~"float", cnv, arg); } - TyPoly => return make_conv_call(cx, arg.span, ~"poly", cnv, arg) + TyPoly => return make_conv_call(cx, arg.span, ~"poly", cnv, + mk_addr_of(cx, sp, arg)) } } fn log_conv(c: Conv) { @@ -245,7 +246,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, for pieces.each |pc| { match *pc { PieceString(s) => { - vec::push(piece_exprs, mk_uniq_str(cx, fmt_sp, s)) + piece_exprs.push(mk_uniq_str(cx, fmt_sp, s)) } PieceConv(conv) => { n += 1u; @@ -258,7 +259,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, log_conv(conv); let arg_expr = args[n]; let c_expr = make_new_conv(cx, fmt_sp, conv, arg_expr); - vec::push(piece_exprs, c_expr); + piece_exprs.push(c_expr); } } } diff --git a/src/libsyntax/ext/pipes/liveness.rs b/src/libsyntax/ext/pipes/liveness.rs index 8b17ffc11041..a9bfd87ab0eb 100644 --- a/src/libsyntax/ext/pipes/liveness.rs +++ b/src/libsyntax/ext/pipes/liveness.rs @@ -65,7 +65,7 @@ fn analyze(proto: protocol, _cx: ext_ctxt) { let mut self_live = ~[]; for colive.eachi |i, bv| { if bv.get(i) { - vec::push(self_live, proto.get_state_by_id(i)) + self_live.push(proto.get_state_by_id(i)) } } diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 11250cfbf38d..9c10d228a23f 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -47,7 +47,7 @@ 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_mode(*n, *t, ast::by_copy) ); let pipe_ty = cx.ty_path_ast_builder( @@ -71,10 +71,10 @@ impl message: gen_send { body += ~"let b = pipe.reuse_buffer();\n"; body += fmt!("let %s = pipes::SendPacketBuffered(\ - ptr::addr_of(b.buffer.data.%s));\n", + ptr::addr_of(&(b.buffer.data.%s)));\n", sp, next.name); body += fmt!("let %s = pipes::RecvPacketBuffered(\ - ptr::addr_of(b.buffer.data.%s));\n", + ptr::addr_of(&(b.buffer.data.%s)));\n", rp, next.name); } else { @@ -129,7 +129,7 @@ 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_mode(cx.ident_of(*n), *t, ast::by_copy) ); let args_ast = vec::append( @@ -226,7 +226,7 @@ impl state: to_type_decls { let v = cx.variant(cx.ident_of(name), span, tys); - vec::push(items_msg, v); + items_msg.push(v); } ~[cx.item_enum_poly(name, @@ -245,44 +245,44 @@ impl state: to_type_decls { let mut items = ~[]; for self.messages.each |m| { if dir == send { - vec::push(items, m.gen_send(cx, true)); - vec::push(items, m.gen_send(cx, false)); + items.push(m.gen_send(cx, true)); + items.push(m.gen_send(cx, false)); } } if !self.proto.is_bounded() { - vec::push(items, - cx.item_ty_poly( - self.data_name(), - self.span, - cx.ty_path_ast_builder( - path(~[cx.ident_of(~"pipes"), - cx.ident_of(dir.to_str() + ~"Packet")], - empty_span()) - .add_ty(cx.ty_path_ast_builder( - path(~[cx.ident_of(self.proto.name), - self.data_name()], - empty_span()) - .add_tys(cx.ty_vars(self.ty_params))))), - self.ty_params)); + items.push( + cx.item_ty_poly( + self.data_name(), + self.span, + cx.ty_path_ast_builder( + path(~[cx.ident_of(~"pipes"), + cx.ident_of(dir.to_str() + ~"Packet")], + empty_span()) + .add_ty(cx.ty_path_ast_builder( + path(~[cx.ident_of(self.proto.name), + self.data_name()], + empty_span()) + .add_tys(cx.ty_vars(self.ty_params))))), + self.ty_params)); } else { - vec::push(items, - cx.item_ty_poly( - self.data_name(), - self.span, - cx.ty_path_ast_builder( - path(~[cx.ident_of(~"pipes"), - cx.ident_of(dir.to_str() - + ~"PacketBuffered")], - empty_span()) - .add_tys(~[cx.ty_path_ast_builder( - path(~[cx.ident_of(self.proto.name), - self.data_name()], - empty_span()) - .add_tys(cx.ty_vars(self.ty_params))), - self.proto.buffer_ty_path(cx)])), - self.ty_params)); + items.push( + cx.item_ty_poly( + self.data_name(), + self.span, + cx.ty_path_ast_builder( + path(~[cx.ident_of(~"pipes"), + cx.ident_of(dir.to_str() + + ~"PacketBuffered")], + empty_span()) + .add_tys(~[cx.ty_path_ast_builder( + path(~[cx.ident_of(self.proto.name), + self.data_name()], + empty_span()) + .add_tys(cx.ty_vars(self.ty_params))), + self.proto.buffer_ty_path(cx)])), + self.ty_params)); }; items } @@ -351,7 +351,7 @@ impl protocol: gen_init { fmt!("data.%s.set_buffer_(buffer)", s.name))), ext_cx.parse_expr( - fmt!("ptr::addr_of(data.%s)", + fmt!("ptr::addr_of(&(data.%s))", self.states[0].name)))); #ast {{ @@ -367,7 +367,7 @@ impl protocol: gen_init { for (copy self.states).each |s| { for s.ty_params.each |tp| { match params.find(|tpp| tp.ident == tpp.ident) { - None => vec::push(params, *tp), + None => params.push(*tp), _ => () } } @@ -383,7 +383,7 @@ impl protocol: gen_init { let fields = do (copy self.states).map_to_vec |s| { for s.ty_params.each |tp| { match params.find(|tpp| tp.ident == tpp.ident) { - None => vec::push(params, *tp), + None => params.push(*tp), _ => () } } @@ -415,17 +415,15 @@ impl protocol: gen_init { } if self.is_bounded() { - vec::push(items, self.gen_buffer_type(cx)) + items.push(self.gen_buffer_type(cx)) } - vec::push(items, - cx.item_mod(cx.ident_of(~"client"), - self.span, - client_states)); - vec::push(items, - cx.item_mod(cx.ident_of(~"server"), - self.span, - server_states)); + items.push(cx.item_mod(cx.ident_of(~"client"), + self.span, + client_states)); + items.push(cx.item_mod(cx.ident_of(~"server"), + self.span, + server_states)); cx.item_mod(cx.ident_of(self.name), self.span, items) } diff --git a/src/libsyntax/ext/pipes/proto.rs b/src/libsyntax/ext/pipes/proto.rs index 70b38e83ad59..6d58d209fcfc 100644 --- a/src/libsyntax/ext/pipes/proto.rs +++ b/src/libsyntax/ext/pipes/proto.rs @@ -210,10 +210,10 @@ fn visit>( // the copy keywords prevent recursive use of dvec let states = do (copy proto.states).map_to_vec |s| { let messages = do (copy s.messages).map_to_vec |m| { - let message(name, span, tys, this, next) = *m; + let message(name, span, tys, this, next) = m; visitor.visit_message(name, span, tys, this, next) }; - visitor.visit_state(*s, messages) + visitor.visit_state(s, messages) }; visitor.visit_proto(proto, states) } diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs index 3af9cfe852dc..e16e1c553499 100644 --- a/src/libsyntax/ext/simplext.rs +++ b/src/libsyntax/ext/simplext.rs @@ -94,7 +94,7 @@ fn option_flatten_map(f: fn@(T) -> Option, v: ~[T]) -> for v.each |elem| { match f(*elem) { None => return None, - Some(fv) => vec::push(res, fv) + Some(fv) => res.push(fv) } } return Some(res); @@ -237,7 +237,7 @@ fn follow_for_trans(cx: ext_ctxt, mmaybe: Option>, /* helper for transcribe_exprs: what vars from `b` occur in `e`? */ fn free_vars(b: bindings, e: @expr, it: fn(ident)) { - let idents: HashMap = HashMap(); + let idents = HashMap(); fn mark_ident(&&i: ident, _fld: ast_fold, b: bindings, idents: HashMap) -> ident { if b.contains_key(i) { idents.insert(i, ()); } @@ -305,9 +305,9 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], /* Whew, we now know how how many times to repeat */ let mut idx: uint = 0u; while idx < rc { - vec::push(*idx_path, idx); - vec::push(res, recur(repeat_me)); // whew! - vec::pop(*idx_path); + idx_path.push(idx); + res.push(recur(repeat_me)); // whew! + idx_path.pop(); idx += 1u; } } @@ -567,7 +567,7 @@ fn p_t_s_r_ellipses(cx: ext_ctxt, repeat_me: @expr, offset: uint, s: selector, let mut elts = ~[]; let mut idx = offset; while idx < vec::len(arg_elts) { - vec::push(elts, leaf(match_expr(arg_elts[idx]))); + elts.push(leaf(match_expr(arg_elts[idx]))); idx += 1u; } @@ -672,9 +672,8 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, None => cx.span_fatal(mac.span, ~"macro must have arguments") }; - vec::push(clauses, - @{params: pattern_to_selectors(cx, arg), - body: elts[1u]}); + clauses.push(@{params: pattern_to_selectors(cx, arg), + body: elts[1u]}); // FIXME (#2251): check duplicates (or just simplify // the macro arg situation) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 74c36dcf1b7f..16e3454ca2c4 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -185,7 +185,7 @@ fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@named_match]) } } } - let ret_val = HashMap::(); + let ret_val = HashMap(); for ms.each() |m| { n_rec(p_s, *m, res, ret_val) } return ret_val; } @@ -208,7 +208,7 @@ fn parse_or_else(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) -> parse_result { let mut cur_eis = ~[]; - vec::push(cur_eis, initial_matcher_pos(ms, None, rdr.peek().sp.lo)); + cur_eis.push(initial_matcher_pos(ms, None, rdr.peek().sp.lo)); loop { let mut bb_eis = ~[]; // black-box parsed by parser.rs @@ -219,7 +219,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) /* we append new items to this while we go */ while cur_eis.len() > 0u { /* for each Earley Item */ - let mut ei = vec::pop(cur_eis); + let mut ei = cur_eis.pop(); let idx = ei.idx; let len = ei.elts.len(); @@ -256,7 +256,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) } new_pos.idx += 1; - vec::push(cur_eis, move new_pos); + cur_eis.push(move new_pos); } // can we go around again? @@ -267,17 +267,17 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) if tok == t { //pass the separator let ei_t <- ei; ei_t.idx += 1; - vec::push(next_eis, move ei_t); + next_eis.push(move ei_t); } } _ => { // we don't need a separator let ei_t <- ei; ei_t.idx = 0; - vec::push(cur_eis, move ei_t); + cur_eis.push(move ei_t); } } } else { - vec::push(eof_eis, move ei); + eof_eis.push(move ei); } } else { match copy ei.elts[idx].node { @@ -292,13 +292,13 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) new_ei.matches[idx].push(@matched_seq(~[], sp)); } - vec::push(cur_eis, move new_ei); + cur_eis.push(move new_ei); } let matches = vec::map(ei.matches, // fresh, same size: |_m| DVec::<@named_match>()); let ei_t <- ei; - vec::push(cur_eis, ~{ + cur_eis.push(~{ elts: matchers, sep: sep, mut idx: 0u, mut up: matcher_pos_up(Some(move ei_t)), matches: move matches, @@ -306,12 +306,12 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) sp_lo: sp.lo }); } - match_nonterminal(_,_,_) => { vec::push(bb_eis, move ei) } + match_nonterminal(_,_,_) => { bb_eis.push(move ei) } match_tok(t) => { let ei_t <- ei; if t == tok { ei_t.idx += 1; - vec::push(next_eis, move ei_t); + next_eis.push(move ei_t); } } } @@ -323,7 +323,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) if eof_eis.len() == 1u { return success( nameize(sess, ms, - vec::map(eof_eis[0u].matches, |dv| dv.pop()))); + eof_eis[0u].matches.map(|dv| dv.pop()))); } else if eof_eis.len() > 1u { return error(sp, ~"Ambiguity: multiple successful parses"); } else { @@ -350,13 +350,13 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) } else if (next_eis.len() > 0u) { /* Now process the next token */ while(next_eis.len() > 0u) { - vec::push(cur_eis, vec::pop(next_eis)); + cur_eis.push(next_eis.pop()); } rdr.next_token(); } else /* bb_eis.len() == 1 */ { let rust_parser = parser(sess, cfg, rdr.dup(), SOURCE_FILE); - let ei = vec::pop(bb_eis); + let ei = bb_eis.pop(); match ei.elts[ei.idx].node { match_nonterminal(_, name, idx) => { ei.matches[idx].push(@matched_nonterminal( @@ -365,7 +365,7 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher]) } _ => fail } - vec::push(cur_eis, move ei); + cur_eis.push(move ei); /* this would fail if zero-length tokens existed */ while rdr.peek().sp.lo < rust_parser.span.lo { diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 7fb910cd4b62..a8a41cca6cbd 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -25,7 +25,7 @@ type tt_frame = @{ type tt_reader = @{ sp_diag: span_handler, - interner: ident_interner, + interner: @ident_interner, mut cur: tt_frame, /* for MBE-style macro transcription */ interpolations: std::map::HashMap, @@ -39,7 +39,7 @@ type tt_reader = @{ /** This can do Macro-By-Example transcription. On the other hand, if * `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and * should) be none. */ -fn new_tt_reader(sp_diag: span_handler, itr: ident_interner, +fn new_tt_reader(sp_diag: span_handler, itr: @ident_interner, interp: Option>, src: ~[ast::token_tree]) -> tt_reader { @@ -47,7 +47,7 @@ fn new_tt_reader(sp_diag: span_handler, itr: ident_interner, mut cur: @{readme: src, mut idx: 0u, dotdotdoted: false, sep: None, up: tt_frame_up(option::None)}, interpolations: match interp { /* just a convienience */ - None => std::map::HashMap::(), + None => std::map::HashMap(), Some(x) => x }, mut repeat_idx: ~[], @@ -82,13 +82,13 @@ pure fn dup_tt_reader(&&r: tt_reader) -> tt_reader { pure fn lookup_cur_matched_by_matched(r: tt_reader, start: @named_match) -> @named_match { - pure fn red(&&ad: @named_match, &&idx: uint) -> @named_match { + pure fn red(+ad: @named_match, idx: &uint) -> @named_match { match *ad { matched_nonterminal(_) => { // end of the line; duplicate henceforth ad } - matched_seq(ads, _) => ads[idx] + matched_seq(ads, _) => ads[*idx] } } vec::foldl(start, r.repeat_idx, red) @@ -122,8 +122,8 @@ fn lockstep_iter_size(t: token_tree, r: tt_reader) -> lis { } match t { tt_delim(tts) | tt_seq(_, tts, _, _) => { - vec::foldl(lis_unconstrained, tts, {|lis, tt| - lis_merge(lis, lockstep_iter_size(tt, r), r) }) + vec::foldl(lis_unconstrained, tts, |lis, tt| + lis_merge(lis, lockstep_iter_size(*tt, r), r)) } tt_tok(*) => lis_unconstrained, tt_nonterminal(_, name) => match *lookup_cur_matched(r, name) { @@ -148,7 +148,8 @@ fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} { } tt_frame_up(Some(tt_f)) => { if r.cur.dotdotdoted { - vec::pop(r.repeat_idx); vec::pop(r.repeat_len); + r.repeat_idx.pop(); + r.repeat_len.pop(); } r.cur = tt_f; @@ -205,8 +206,8 @@ fn tt_next_token(&&r: tt_reader) -> {tok: token, sp: span} { r.cur.idx += 1u; return tt_next_token(r); } else { - vec::push(r.repeat_len, len); - vec::push(r.repeat_idx, 0u); + r.repeat_len.push(len); + r.repeat_idx.push(0u); r.cur = @{readme: tts, mut idx: 0u, dotdotdoted: true, sep: sep, up: tt_frame_up(option::Some(r.cur))}; } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index f8f481c8f66b..088df01985ee 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -114,7 +114,7 @@ fn fold_mac_(m: mac, fld: ast_fold) -> mac { match m.node { mac_invoc(pth, arg, body) => { mac_invoc(fld.fold_path(pth), - option::map(&arg, |x| fld.fold_expr(x)), body) + option::map(&arg, |x| fld.fold_expr(*x)), body) } mac_invoc_tt(*) => m.node, mac_ellipsis => mac_ellipsis, @@ -203,7 +203,8 @@ fn noop_fold_foreign_item(&&ni: @foreign_item, fld: ast_fold) } }, id: fld.new_id(ni.id), - span: fld.new_span(ni.span)}; + span: fld.new_span(ni.span), + vis: ni.vis}; } fn noop_fold_item(&&i: @item, fld: ast_fold) -> Option<@item> { @@ -243,7 +244,7 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { variants: vec::map(enum_definition.variants, |x| fld.fold_variant(*x)), common: option::map(&enum_definition.common, - |x| fold_struct_def(x, fld)) + |x| fold_struct_def(*x, fld)) }), fold_ty_params(typms, fld)) } item_class(struct_def, typms) => { @@ -252,7 +253,7 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { } item_impl(tps, ifce, ty, methods) => { item_impl(fold_ty_params(tps, fld), - ifce.map(|p| fold_trait_ref(p, fld)), + ifce.map(|p| fold_trait_ref(*p, fld)), fld.fold_ty(ty), vec::map(methods, |x| fld.fold_method(*x))) } @@ -292,7 +293,7 @@ fn fold_struct_def(struct_def: @ast::struct_def, fld: ast_fold) let dtor_id = fld.new_id(dtor.node.id); {node: {body: dtor_body, id: dtor_id,.. dtor.node}, - .. dtor}}; + .. *dtor}}; return @{ traits: vec::map(struct_def.traits, |p| fold_trait_ref(*p, fld)), fields: vec::map(struct_def.fields, |f| fold_struct_field(*f, fld)), @@ -332,7 +333,7 @@ fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method { fn noop_fold_block(b: blk_, fld: ast_fold) -> blk_ { return {view_items: vec::map(b.view_items, |x| fld.fold_view_item(*x)), stmts: vec::map(b.stmts, |x| fld.fold_stmt(*x)), - expr: option::map(&b.expr, |x| fld.fold_expr(x)), + expr: option::map(&b.expr, |x| fld.fold_expr(*x)), id: fld.new_id(b.id), rules: b.rules}; } @@ -347,7 +348,7 @@ fn noop_fold_stmt(s: stmt_, fld: ast_fold) -> stmt_ { fn noop_fold_arm(a: arm, fld: ast_fold) -> arm { return {pats: vec::map(a.pats, |x| fld.fold_pat(*x)), - guard: option::map(&a.guard, |x| fld.fold_expr(x)), + guard: option::map(&a.guard, |x| fld.fold_expr(*x)), body: fld.fold_block(a.body)}; } @@ -357,19 +358,18 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ { pat_ident(binding_mode, pth, sub) => { pat_ident(binding_mode, fld.fold_path(pth), - option::map(&sub, |x| fld.fold_pat(x))) + option::map(&sub, |x| fld.fold_pat(*x))) } pat_lit(e) => pat_lit(fld.fold_expr(e)), pat_enum(pth, pats) => { pat_enum(fld.fold_path(pth), option::map(&pats, - |pats| vec::map(pats, |x| fld.fold_pat(*x)))) + |pats| vec::map(*pats, |x| fld.fold_pat(*x)))) } pat_rec(fields, etc) => { let mut fs = ~[]; for fields.each |f| { - vec::push(fs, - {ident: /* FIXME (#2543) */ copy f.ident, - pat: fld.fold_pat(f.pat)}); + fs.push({ident: /* FIXME (#2543) */ copy f.ident, + pat: fld.fold_pat(f.pat)}); } pat_rec(fs, etc) } @@ -377,9 +377,8 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ { let pth_ = fld.fold_path(pth); let mut fs = ~[]; for fields.each |f| { - vec::push(fs, - {ident: /* FIXME (#2543) */ copy f.ident, - pat: fld.fold_pat(f.pat)}); + fs.push({ident: /* FIXME (#2543) */ copy f.ident, + pat: fld.fold_pat(f.pat)}); } pat_struct(pth_, fs, etc) } @@ -434,7 +433,7 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_repeat(fld.fold_expr(expr), fld.fold_expr(count), mutt), expr_rec(fields, maybe_expr) => { expr_rec(vec::map(fields, |x| fold_field(*x)), - option::map(&maybe_expr, |x| fld.fold_expr(x))) + option::map(&maybe_expr, |x| fld.fold_expr(*x))) } expr_tup(elts) => expr_tup(vec::map(elts, |x| fld.fold_expr(*x))), expr_call(f, args, blk) => { @@ -453,14 +452,14 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_addr_of(m, ohs) => expr_addr_of(m, fld.fold_expr(ohs)), expr_if(cond, tr, fl) => { expr_if(fld.fold_expr(cond), fld.fold_block(tr), - option::map(&fl, |x| fld.fold_expr(x))) + option::map(&fl, |x| fld.fold_expr(*x))) } expr_while(cond, body) => { expr_while(fld.fold_expr(cond), fld.fold_block(body)) } expr_loop(body, opt_ident) => { expr_loop(fld.fold_block(body), - option::map(&opt_ident, |x| fld.fold_ident(x))) + option::map(&opt_ident, |x| fld.fold_ident(*x))) } expr_match(expr, arms) => { expr_match(fld.fold_expr(expr), @@ -502,12 +501,12 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_index(fld.fold_expr(el), fld.fold_expr(er)) } expr_path(pth) => expr_path(fld.fold_path(pth)), - expr_fail(e) => expr_fail(option::map(&e, |x| fld.fold_expr(x))), + expr_fail(e) => expr_fail(option::map(&e, |x| fld.fold_expr(*x))), expr_break(opt_ident) => - expr_break(option::map(&opt_ident, |x| fld.fold_ident(x))), + expr_break(option::map(&opt_ident, |x| fld.fold_ident(*x))), expr_again(opt_ident) => - expr_again(option::map(&opt_ident, |x| fld.fold_ident(x))), - expr_ret(e) => expr_ret(option::map(&e, |x| fld.fold_expr(x))), + expr_again(option::map(&opt_ident, |x| fld.fold_ident(*x))), + expr_ret(e) => expr_ret(option::map(&e, |x| fld.fold_expr(*x))), expr_log(i, lv, e) => expr_log(i, fld.fold_expr(lv), fld.fold_expr(e)), expr_assert(e) => expr_assert(fld.fold_expr(e)), @@ -515,7 +514,7 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_struct(path, fields, maybe_expr) => { expr_struct(fld.fold_path(path), vec::map(fields, |x| fold_field(*x)), - option::map(&maybe_expr, |x| fld.fold_expr(x))) + option::map(&maybe_expr, |x| fld.fold_expr(*x))) } } } @@ -553,7 +552,7 @@ fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ { // ...nor do modules fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod { return {view_items: vec::map(m.view_items, |x| fld.fold_view_item(*x)), - items: vec::filter_map(m.items, |x| fld.fold_item(x))}; + items: vec::filter_map(m.items, |x| fld.fold_item(*x))}; } fn noop_fold_foreign_mod(nm: foreign_mod, fld: ast_fold) -> foreign_mod { @@ -579,7 +578,7 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { let dtor_id = fld.new_id(dtor.node.id); {node: {body: dtor_body, id: dtor_id,.. dtor.node}, - .. dtor}}; + .. *dtor}}; kind = struct_variant_kind(@{ traits: ~[], fields: vec::map(struct_def.fields, @@ -595,7 +594,7 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { let variants = vec::map(enum_definition.variants, |x| fld.fold_variant(*x)); let common = option::map(&enum_definition.common, - |x| fold_struct_def(x, fld)); + |x| fold_struct_def(*x, fld)); kind = enum_variant_kind(ast::enum_def({ variants: variants, common: common })); } diff --git a/src/libsyntax/parse.rs b/src/libsyntax/parse.rs index 312c78085acf..2c04b2a14190 100644 --- a/src/libsyntax/parse.rs +++ b/src/libsyntax/parse.rs @@ -25,7 +25,7 @@ type parse_sess = @{ cm: codemap::codemap, mut next_id: node_id, span_diagnostic: span_handler, - interner: ident_interner, + interner: @ident_interner, // these two must be kept up to date mut chpos: uint, mut byte_pos: uint @@ -73,7 +73,7 @@ fn parse_crate_from_crate_file(input: &Path, cfg: ast::crate_cfg, sess.chpos = rdr.chpos; sess.byte_pos = sess.byte_pos + rdr.pos; let cx = @{sess: sess, cfg: /* FIXME (#2543) */ copy p.cfg}; - let companionmod = input.filestem().map(|s| Path(s)); + let companionmod = input.filestem().map(|s| Path(*s)); let (m, attrs) = eval::eval_crate_directives_to_mod( cx, cdirs, &prefix, &companionmod); let mut hi = p.span.hi; diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 9c705cff7bbb..cb8416501b37 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -1,4 +1,5 @@ use io::println;//XXXXXXXXxxx +use io::ReaderUtil; use util::interner; use lexer::{string_reader, bump, is_eof, nextch, is_whitespace, get_str_from, reader}; @@ -129,7 +130,7 @@ fn consume_non_eol_whitespace(rdr: string_reader) { fn push_blank_line_comment(rdr: string_reader, &comments: ~[cmnt]) { debug!(">>> blank-line comment"); let v: ~[~str] = ~[]; - vec::push(comments, {style: blank_line, lines: v, pos: rdr.chpos}); + comments.push({style: blank_line, lines: v, pos: rdr.chpos}); } fn consume_whitespace_counting_blank_lines(rdr: string_reader, @@ -148,7 +149,7 @@ fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool, debug!(">>> shebang comment"); let p = rdr.chpos; debug!("<<< shebang comment"); - vec::push(comments, { + comments.push({ style: if code_to_the_left { trailing } else { isolated }, lines: ~[read_one_line_comment(rdr)], pos: p @@ -166,12 +167,12 @@ fn read_line_comments(rdr: string_reader, code_to_the_left: bool, if is_doc_comment(line) { // doc-comments are not put in comments break; } - vec::push(lines, line); + lines.push(line); consume_non_eol_whitespace(rdr); } debug!("<<< line comments"); if !lines.is_empty() { - vec::push(comments, { + comments.push({ style: if code_to_the_left { trailing } else { isolated }, lines: lines, pos: p @@ -197,7 +198,7 @@ fn trim_whitespace_prefix_and_push_line(&lines: ~[~str], } else { s1 = ~""; } } else { s1 = s; } log(debug, ~"pushing line: " + s1); - vec::push(lines, s1); + lines.push(s1); } fn read_block_comment(rdr: string_reader, code_to_the_left: bool, @@ -256,7 +257,7 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool, style = mixed; } debug!("<<< block comment"); - vec::push(comments, {style: style, lines: lines, pos: p}); + comments.push({style: style, lines: lines, pos: p}); } fn peeking_at_comment(rdr: string_reader) -> bool { @@ -314,7 +315,7 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler, let {tok: tok, sp: sp} = rdr.peek(); if token::is_lit(tok) { let s = get_str_from(rdr, bstart); - vec::push(literals, {lit: s, pos: sp.lo}); + literals.push({lit: s, pos: sp.lo}); log(debug, ~"tok lit: " + s); } else { log(debug, ~"tok: " + token::to_str(rdr.interner, tok)); diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index 4b8bfcda848a..c8c30ee7fa9c 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -229,7 +229,7 @@ impl parser: parser_common { } _ => () } - vec::push(v, f(self)); + v.push(f(self)); } return v; @@ -274,7 +274,7 @@ impl parser: parser_common { _ => () } if sep.trailing_sep_allowed && self.token == ket { break; } - vec::push(v, f(self)); + v.push(f(self)); } return v; } diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs index 7127e2747eb7..14dc490346eb 100644 --- a/src/libsyntax/parse/eval.rs +++ b/src/libsyntax/parse/eval.rs @@ -107,7 +107,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path, // Thread defids, chpos and byte_pos through the parsers cx.sess.chpos = r0.chpos; cx.sess.byte_pos = cx.sess.byte_pos + r0.pos; - vec::push(items, i); + items.push(i); } ast::cdir_dir_mod(vis, id, cdirs, attrs) => { let path = Path(cdir_path_opt(*cx.sess.interner.get(id), attrs)); @@ -126,9 +126,9 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path, vis: vis, span: cdir.span}; cx.sess.next_id += 1; - vec::push(items, i); + items.push(i); } - ast::cdir_view_item(vi) => vec::push(view_items, vi), + ast::cdir_view_item(vi) => view_items.push(vi), ast::cdir_syntax(*) => () } } diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index c9b10c7b7547..06fcc1cf9589 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -13,7 +13,7 @@ trait reader { fn next_token() -> {tok: token::token, sp: span}; fn fatal(~str) -> !; fn span_diag() -> span_handler; - pure fn interner() -> token::ident_interner; + pure fn interner() -> @token::ident_interner; fn peek() -> {tok: token::token, sp: span}; fn dup() -> reader; } @@ -26,7 +26,7 @@ type string_reader = @{ mut curr: char, mut chpos: uint, filemap: codemap::filemap, - interner: token::ident_interner, + interner: @token::ident_interner, /* cached: */ mut peek_tok: token::token, mut peek_span: span @@ -34,7 +34,7 @@ type string_reader = @{ fn new_string_reader(span_diagnostic: span_handler, filemap: codemap::filemap, - itr: token::ident_interner) -> string_reader { + itr: @token::ident_interner) -> string_reader { let r = new_low_level_string_reader(span_diagnostic, filemap, itr); string_advance_token(r); /* fill in peek_* */ return r; @@ -43,7 +43,7 @@ fn new_string_reader(span_diagnostic: span_handler, /* For comments.rs, which hackily pokes into 'pos' and 'curr' */ fn new_low_level_string_reader(span_diagnostic: span_handler, filemap: codemap::filemap, - itr: token::ident_interner) + itr: @token::ident_interner) -> string_reader { let r = @{span_diagnostic: span_diagnostic, src: filemap.src, mut col: 0u, mut pos: 0u, mut curr: -1 as char, @@ -78,7 +78,7 @@ impl string_reader: reader { self.span_diagnostic.span_fatal(copy self.peek_span, m) } fn span_diag() -> span_handler { self.span_diagnostic } - pure fn interner() -> token::ident_interner { self.interner } + pure fn interner() -> @token::ident_interner { self.interner } fn peek() -> {tok: token::token, sp: span} { {tok: self.peek_tok, sp: self.peek_span} } @@ -100,7 +100,7 @@ impl tt_reader: reader { self.sp_diag.span_fatal(copy self.cur_span, m); } fn span_diag() -> span_handler { self.sp_diag } - pure fn interner() -> token::ident_interner { self.interner } + pure fn interner() -> @token::ident_interner { self.interner } fn peek() -> {tok: token::token, sp: span} { { tok: self.cur_tok, sp: self.cur_span } } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 9cfa84ad9e01..782535f5c2b2 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -36,7 +36,7 @@ impl ObsoleteSyntax : cmp::Eq { impl ObsoleteSyntax: to_bytes::IterBytes { #[inline(always)] - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as uint).iter_bytes(lsb0, f); } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 681d6296d4ea..8860d1b5cea8 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -237,7 +237,7 @@ struct parser { mut restriction: restriction, mut quote_depth: uint, // not (yet) related to the quasiquoter reader: reader, - interner: interner<@~str>, + interner: @token::ident_interner, keywords: HashMap<~str, ()>, strict_keywords: HashMap<~str, ()>, reserved_keywords: HashMap<~str, ()>, @@ -496,7 +496,7 @@ impl parser { let mut ts = ~[self.parse_ty(false)]; while self.token == token::COMMA { self.bump(); - vec::push(ts, self.parse_ty(false)); + ts.push(self.parse_ty(false)); } let t = if vec::len(ts) == 1u { ts[0].node } else { ty_tup(ts) }; @@ -584,6 +584,29 @@ impl parser { } else { infer(self.get_id()) } } + fn is_named_argument() -> bool { + let offset = if self.token == token::BINOP(token::AND) { + 1 + } else if self.token == token::BINOP(token::MINUS) { + 1 + } else if self.token == token::ANDAND { + 1 + } else if self.token == token::BINOP(token::PLUS) { + if self.look_ahead(1) == token::BINOP(token::PLUS) { + 2 + } else { + 1 + } + } else { 0 }; + if offset == 0 { + is_plain_ident(self.token) + && self.look_ahead(1) == token::COLON + } else { + is_plain_ident(self.look_ahead(offset)) + && self.look_ahead(offset + 1) == token::COLON + } + } + fn parse_capture_item_or(parse_arg_fn: fn(parser) -> arg_or_capture_item) -> arg_or_capture_item { @@ -605,29 +628,17 @@ impl parser { // This version of parse arg doesn't necessarily require // identifier names. fn parse_arg_general(require_name: bool) -> arg { - let m = self.parse_arg_mode(); - let i = if require_name { + let mut m; + let i = if require_name || self.is_named_argument() { + m = self.parse_arg_mode(); let name = self.parse_value_ident(); self.expect(token::COLON); name } else { - if is_plain_ident(self.token) - && self.look_ahead(1u) == token::COLON { - let name = self.parse_value_ident(); - self.bump(); - name - } else { special_idents::invalid } + m = infer(self.get_id()); + special_idents::invalid }; - match m { - expl(_) => { - if i == special_idents::invalid { - self.obsolete(copy self.span, ObsoleteModeInFnType); - } - } - _ => {} - } - let t = self.parse_ty(false); {mode: m, ty: t, ident: i, id: self.get_id()} @@ -760,10 +771,10 @@ impl parser { && self.look_ahead(1u) == token::MOD_SEP; if is_not_last { - vec::push(ids, parse_ident(self)); + ids.push(parse_ident(self)); self.expect(token::MOD_SEP); } else { - vec::push(ids, parse_last_ident(self)); + ids.push(parse_last_ident(self)); break; } } @@ -892,7 +903,7 @@ impl parser { } let mut es = ~[self.parse_expr()]; while self.token == token::COMMA { - self.bump(); vec::push(es, self.parse_expr()); + self.bump(); es.push(self.parse_expr()); } hi = self.span.hi; self.expect(token::RPAREN); @@ -1038,7 +1049,7 @@ impl parser { self.bump(); let mut fields = ~[]; let mut base = None; - vec::push(fields, self.parse_field(token::COLON)); + fields.push(self.parse_field(token::COLON)); while self.token != token::RBRACE { if self.try_parse_obsolete_with() { @@ -1056,7 +1067,7 @@ impl parser { // Accept an optional trailing comma. break; } - vec::push(fields, self.parse_field(token::COLON)); + fields.push(self.parse_field(token::COLON)); } hi = pth.span.hi; @@ -1305,7 +1316,7 @@ impl parser { while self.token != ket || lparens > 0u { if self.token == token::LPAREN { lparens += 1u; } if self.token == token::RPAREN { lparens -= 1u; } - vec::push(ret_val, self.parse_matcher(name_idx)); + ret_val.push(self.parse_matcher(name_idx)); } self.bump(); @@ -1711,7 +1722,7 @@ impl parser { // record ends by an optional trailing comma break; } - vec::push(fields, self.parse_field(token::COLON)); + fields.push(self.parse_field(token::COLON)); } self.expect(token::RBRACE); return expr_rec(fields, base); @@ -1746,7 +1757,7 @@ impl parser { rules: default_blk}, span: expr.span}; - vec::push(arms, {pats: pats, guard: guard, body: blk}); + arms.push({pats: pats, guard: guard, body: blk}); } let mut hi = self.span.hi; self.bump(); @@ -1791,7 +1802,7 @@ impl parser { fn parse_pats() -> ~[@pat] { let mut pats = ~[]; loop { - vec::push(pats, self.parse_pat(true)); + pats.push(self.parse_pat(true)); if self.token == token::BINOP(token::OR) { self.bump(); } else { return pats; } }; @@ -1838,7 +1849,7 @@ impl parser { span: self.last_span }; } - vec::push(fields, {ident: fieldname, pat: subpat}); + fields.push({ident: fieldname, pat: subpat}); } return (fields, etc); } @@ -1926,7 +1937,7 @@ impl parser { let mut fields = ~[self.parse_pat(refutable)]; while self.token == token::COMMA { self.bump(); - vec::push(fields, self.parse_pat(refutable)); + fields.push(self.parse_pat(refutable)); } if vec::len(fields) == 1u { self.expect(token::COMMA); } hi = self.span.hi; @@ -2115,7 +2126,7 @@ impl parser { let lo = self.span.lo; let mut locals = ~[self.parse_local(is_mutbl, true)]; while self.eat(token::COMMA) { - vec::push(locals, self.parse_local(is_mutbl, true)); + locals.push(self.parse_local(is_mutbl, true)); } return @spanned(lo, self.last_span.hi, decl_local(locals)); } @@ -2216,17 +2227,12 @@ impl parser { } let lo = self.span.lo; - if self.eat_keyword(~"unsafe") { - self.expect(token::LBRACE); - let {inner, next} = maybe_parse_inner_attrs_and_next(self, - parse_attrs); - return (inner, self.parse_block_tail_(lo, unsafe_blk, next)); - } else { - self.expect(token::LBRACE); - let {inner, next} = maybe_parse_inner_attrs_and_next(self, - parse_attrs); - return (inner, self.parse_block_tail_(lo, default_blk, next)); - } + let us = self.eat_keyword(~"unsafe"); + self.expect(token::LBRACE); + let {inner, next} = maybe_parse_inner_attrs_and_next(self, + parse_attrs); + let blk_check_mode = if us { unsafe_blk } else { default_blk }; + return (inner, self.parse_block_tail_(lo, blk_check_mode, next)); } fn parse_block_no_value() -> blk { @@ -2255,8 +2261,8 @@ impl parser { for items.each |item| { let decl = @spanned(item.span.lo, item.span.hi, decl_item(*item)); - push(stmts, @spanned(item.span.lo, item.span.hi, - stmt_decl(decl, self.get_id()))); + stmts.push(@spanned(item.span.lo, item.span.hi, + stmt_decl(decl, self.get_id()))); } let mut initial_attrs = attrs_remaining; @@ -2267,43 +2273,46 @@ impl parser { while self.token != token::RBRACE { match self.token { - token::SEMI => { - self.bump(); // empty - } - _ => { - let stmt = self.parse_stmt(initial_attrs); - initial_attrs = ~[]; - match stmt.node { - stmt_expr(e, stmt_id) => { // Expression without semicolon: - match self.token { - token::SEMI => { - self.bump(); - push(stmts, - @{node: stmt_semi(e, stmt_id),.. *stmt}); - } - token::RBRACE => { - expr = Some(e); - } - t => { - if classify::stmt_ends_with_semi(*stmt) { - self.fatal(~"expected `;` or `}` after \ - expression but found `" - + token_to_str(self.reader, t) + ~"`"); - } - vec::push(stmts, stmt); - } - } - } - - _ => { // All other kinds of statements: - vec::push(stmts, stmt); - - if classify::stmt_ends_with_semi(*stmt) { - self.expect(token::SEMI); - } - } + token::SEMI => { + self.bump(); // empty + } + _ => { + let stmt = self.parse_stmt(initial_attrs); + initial_attrs = ~[]; + match stmt.node { + stmt_expr(e, stmt_id) => { + // Expression without semicolon + match self.token { + token::SEMI => { + self.bump(); + stmts.push(@{node: stmt_semi(e, stmt_id), + ..*stmt}); + } + token::RBRACE => { + expr = Some(e); + } + t => { + if classify::stmt_ends_with_semi(*stmt) { + self.fatal( + ~"expected `;` or `}` after \ + expression but found `" + + token_to_str(self.reader, t) + + ~"`"); + } + stmts.push(stmt); + } + } + } + + _ => { // All other kinds of statements: + stmts.push(stmt); + + if classify::stmt_ends_with_semi(*stmt) { + self.expect(token::SEMI); + } + } + } } - } } } let mut hi = self.span.hi; @@ -2345,16 +2354,16 @@ impl parser { }; match maybe_bound { - Some(bound) => { - self.bump(); - push(bounds, bound); - } - None => { - push(bounds, bound_trait(self.parse_ty(false))); - } + Some(bound) => { + self.bump(); + bounds.push(bound); + } + None => { + bounds.push(bound_trait(self.parse_ty(false))); + } } } else { - push(bounds, bound_trait(self.parse_ty(false))); + bounds.push(bound_trait(self.parse_ty(false))); } } } @@ -2625,7 +2634,7 @@ impl parser { self.expect(token::LBRACE); while !self.eat(token::RBRACE) { let vis = self.parse_visibility(); - vec::push(meths, self.parse_method(vis)); + meths.push(self.parse_method(vis)); } (ident, item_impl(tps, opt_trait, ty, meths), None) } @@ -2711,9 +2720,9 @@ impl parser { for mms.each |mm| { match *mm { @field_member(struct_field) => - vec::push(fields, struct_field), + fields.push(struct_field), @method_member(the_method_member) => - vec::push(methods, the_method_member) + methods.push(the_method_member) } } } @@ -2744,7 +2753,7 @@ impl parser { } let actual_dtor = do the_dtor.map |dtor| { - let (d_body, d_attrs, d_s) = dtor; + let (d_body, d_attrs, d_s) = *dtor; {node: {id: self.get_id(), attrs: d_attrs, self_id: self.get_id(), @@ -2885,7 +2894,7 @@ impl parser { debug!("parse_mod_items: parse_item_or_view_item(attrs=%?)", attrs); match self.parse_item_or_view_item(attrs, true) { - iovi_item(item) => vec::push(items, item), + iovi_item(item) => items.push(item), iovi_view_item(view_item) => { self.span_fatal(view_item.span, ~"view items must be \ declared at the top of the \ @@ -2926,7 +2935,8 @@ impl parser { (id, item_mod(m), Some(inner_attrs.inner)) } - fn parse_item_foreign_fn(+attrs: ~[attribute]) -> @foreign_item { + fn parse_item_foreign_fn(vis: ast::visibility, + +attrs: ~[attribute]) -> @foreign_item { let lo = self.span.lo; let purity = self.parse_fn_purity(); let t = self.parse_fn_header(); @@ -2937,10 +2947,12 @@ impl parser { attrs: attrs, node: foreign_item_fn(decl, purity, t.tps), id: self.get_id(), - span: mk_sp(lo, hi)}; + span: mk_sp(lo, hi), + vis: vis}; } - fn parse_item_foreign_const(+attrs: ~[attribute]) -> @foreign_item { + fn parse_item_foreign_const(vis: ast::visibility, + +attrs: ~[attribute]) -> @foreign_item { let lo = self.span.lo; self.expect_keyword(~"const"); let ident = self.parse_ident(); @@ -2952,7 +2964,8 @@ impl parser { attrs: attrs, node: foreign_item_const(move ty), id: self.get_id(), - span: mk_sp(lo, hi)}; + span: mk_sp(lo, hi), + vis: vis}; } fn parse_fn_purity() -> purity { @@ -2968,10 +2981,11 @@ impl parser { } fn parse_foreign_item(+attrs: ~[attribute]) -> @foreign_item { + let vis = self.parse_visibility(); if self.is_keyword(~"const") { - self.parse_item_foreign_const(move attrs) + self.parse_item_foreign_const(vis, move attrs) } else { - self.parse_item_foreign_fn(move attrs) + self.parse_item_foreign_fn(vis, move attrs) } } @@ -2989,7 +3003,7 @@ impl parser { let attrs = vec::append(initial_attrs, self.parse_outer_attributes()); initial_attrs = ~[]; - vec::push(items, self.parse_foreign_item(attrs)); + items.push(self.parse_foreign_item(attrs)); } return {sort: sort, view_items: view_items, items: items}; @@ -3102,9 +3116,9 @@ impl parser { for mms.each |mm| { match *mm { @field_member(struct_field) => - vec::push(fields, struct_field), + fields.push(struct_field), @method_member(the_method_member) => - vec::push(methods, the_method_member) + methods.push(the_method_member) } } } @@ -3112,7 +3126,7 @@ impl parser { } self.bump(); let mut actual_dtor = do the_dtor.map |dtor| { - let (d_body, d_attrs, d_s) = dtor; + let (d_body, d_attrs, d_s) = *dtor; {node: {id: self.get_id(), attrs: d_attrs, self_id: self.get_id(), @@ -3173,7 +3187,7 @@ impl parser { seq_sep_trailing_disallowed(token::COMMA), |p| p.parse_ty(false)); for arg_tys.each |ty| { - vec::push(args, {ty: *ty, id: self.get_id()}); + args.push({ty: *ty, id: self.get_id()}); } kind = tuple_variant_kind(args); } else if self.eat(token::EQ) { @@ -3189,7 +3203,7 @@ impl parser { let vr = {name: ident, attrs: variant_attrs, kind: kind, id: self.get_id(), disr_expr: disr_expr, vis: vis}; - vec::push(variants, spanned(vlo, self.last_span.hi, vr)); + variants.push(spanned(vlo, self.last_span.hi, vr)); if needs_comma && !self.eat(token::COMMA) { break; } } @@ -3416,7 +3430,7 @@ impl parser { while self.token == token::MOD_SEP { self.bump(); let id = self.parse_ident(); - vec::push(path, id); + path.push(id); } let path = @{span: mk_sp(lo, self.span.hi), global: false, idents: path, rp: None, types: ~[]}; @@ -3434,7 +3448,7 @@ impl parser { token::IDENT(i, _) => { self.bump(); - vec::push(path, i); + path.push(i); } // foo::bar::{a,b,c} @@ -3477,7 +3491,7 @@ impl parser { let mut vp = ~[self.parse_view_path()]; while self.token == token::COMMA { self.bump(); - vec::push(vp, self.parse_view_path()); + vp.push(self.parse_view_path()); } return vp; } @@ -3497,8 +3511,8 @@ impl parser { self.token_is_keyword(~"mod", next_tok)) } - fn parse_view_item(+attrs: ~[attribute]) -> @view_item { - let lo = self.span.lo, vis = self.parse_visibility(); + fn parse_view_item(+attrs: ~[attribute], vis: visibility) -> @view_item { + let lo = self.span.lo; let node = if self.eat_keyword(~"use") { self.parse_use() } else if self.eat_keyword(~"export") { @@ -3630,7 +3644,7 @@ impl parser { _ => self.unexpected() } } else if self.is_view_item() { - let vi = self.parse_view_item(outer_attrs); + let vi = self.parse_view_item(outer_attrs, vis); return spanned(lo, vi.span.hi, cdir_view_item(vi)); } return self.fatal(~"expected crate directive"); @@ -3651,7 +3665,7 @@ impl parser { let mut first_outer_attr = first_outer_attr; while self.token != term { let cdir = @self.parse_crate_directive(first_outer_attr); - vec::push(cdirs, cdir); + cdirs.push(cdir); first_outer_attr = ~[]; } return cdirs; diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 0f9041a2fcdd..a328ff1bdf64 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -12,9 +12,6 @@ use std::serialization::{Serializer, serialize_bool, deserialize_bool}; -#[auto_serialize] -type str_num = uint; - #[auto_serialize] enum binop { PLUS, @@ -72,17 +69,17 @@ enum token { LIT_INT(i64, ast::int_ty), LIT_UINT(u64, ast::uint_ty), LIT_INT_UNSUFFIXED(i64), - LIT_FLOAT(str_num, ast::float_ty), - LIT_STR(str_num), + LIT_FLOAT(ast::ident, ast::float_ty), + LIT_STR(ast::ident), /* Name components */ - IDENT(str_num, bool), + IDENT(ast::ident, bool), UNDERSCORE, /* For interpolation */ INTERPOLATED(nonterminal), - DOC_COMMENT(str_num), + DOC_COMMENT(ast::ident), EOF, } @@ -95,7 +92,7 @@ enum nonterminal { nt_pat( @ast::pat), nt_expr(@ast::expr), nt_ty( @ast::ty), - nt_ident(str_num, bool), + nt_ident(ast::ident, bool), nt_path(@ast::path), nt_tt( @ast::token_tree), //needs @ed to break a circularity nt_matchers(~[ast::matcher]) @@ -116,7 +113,7 @@ fn binop_to_str(o: binop) -> ~str { } } -fn to_str(in: interner<@~str>, t: token) -> ~str { +fn to_str(in: @ident_interner, t: token) -> ~str { match t { EQ => ~"=", LT => ~"<", @@ -174,7 +171,7 @@ fn to_str(in: interner<@~str>, t: token) -> ~str { } body + ast_util::float_ty_to_str(t) } - LIT_STR(s) => { ~"\"" + str::escape_default( *in.get(s)) + ~"\"" } + LIT_STR(s) => { ~"\"" + str::escape_default(*in.get(s)) + ~"\"" } /* Name components */ IDENT(s, _) => *in.get(s), @@ -281,49 +278,66 @@ pure fn is_bar(t: token) -> bool { mod special_idents { #[legacy_exports]; use ast::ident; - const underscore : ident = 0u; - const anon : ident = 1u; - const dtor : ident = 2u; // 'drop', but that's reserved - const invalid : ident = 3u; // '' - const unary : ident = 4u; - const not_fn : ident = 5u; - const idx_fn : ident = 6u; - const unary_minus_fn : ident = 7u; - const clownshoes_extensions : ident = 8u; + const underscore : ident = ident { repr: 0u }; + const anon : ident = ident { repr: 1u }; + const dtor : ident = ident { repr: 2u }; // 'drop', but that's reserved + const invalid : ident = ident { repr: 3u }; // '' + const unary : ident = ident { repr: 4u }; + const not_fn : ident = ident { repr: 5u }; + const idx_fn : ident = ident { repr: 6u }; + const unary_minus_fn : ident = ident { repr: 7u }; + const clownshoes_extensions : ident = ident { repr: 8u }; - const self_ : ident = 9u; // 'self' + const self_ : ident = ident { repr: 9u }; // 'self' /* for matcher NTs */ - const item : ident = 10u; - const block : ident = 11u; - const stmt : ident = 12u; - const pat : ident = 13u; - const expr : ident = 14u; - const ty : ident = 15u; - const ident : ident = 16u; - const path : ident = 17u; - const tt : ident = 18u; - const matchers : ident = 19u; + const item : ident = ident { repr: 10u }; + const block : ident = ident { repr: 11u }; + const stmt : ident = ident { repr: 12u }; + const pat : ident = ident { repr: 13u }; + const expr : ident = ident { repr: 14u }; + const ty : ident = ident { repr: 15u }; + const ident : ident = ident { repr: 16u }; + const path : ident = ident { repr: 17u }; + const tt : ident = ident { repr: 18u }; + const matchers : ident = ident { repr: 19u }; - const str : ident = 20u; // for the type + const str : ident = ident { repr: 20u }; // for the type /* outside of libsyntax */ - const ty_visitor : ident = 21u; - const arg : ident = 22u; - const descrim : ident = 23u; - const clownshoe_abi : ident = 24u; - const clownshoe_stack_shim : ident = 25u; - const tydesc : ident = 26u; - const literally_dtor : ident = 27u; - const main : ident = 28u; - const opaque : ident = 29u; - const blk : ident = 30u; - const static : ident = 31u; - const intrinsic : ident = 32u; - const clownshoes_foreign_mod: ident = 33; + const ty_visitor : ident = ident { repr: 21u }; + const arg : ident = ident { repr: 22u }; + const descrim : ident = ident { repr: 23u }; + const clownshoe_abi : ident = ident { repr: 24u }; + const clownshoe_stack_shim : ident = ident { repr: 25u }; + const tydesc : ident = ident { repr: 26u }; + const literally_dtor : ident = ident { repr: 27u }; + const main : ident = ident { repr: 28u }; + const opaque : ident = ident { repr: 29u }; + const blk : ident = ident { repr: 30u }; + const static : ident = ident { repr: 31u }; + const intrinsic : ident = ident { repr: 32u }; + const clownshoes_foreign_mod: ident = ident { repr: 33 }; } -type ident_interner = util::interner::interner<@~str>; +struct ident_interner { + priv interner: util::interner::interner<@~str>, +} + +impl ident_interner { + fn intern(val: @~str) -> ast::ident { + ast::ident { repr: self.interner.intern(val) } + } + fn gensym(val: @~str) -> ast::ident { + ast::ident { repr: self.interner.gensym(val) } + } + pure fn get(idx: ast::ident) -> @~str { + self.interner.get(idx.repr) + } + fn len() -> uint { + self.interner.len() + } +} /** Key for thread-local data for sneaking interner information to the * serializer/deserializer. It sounds like a hack because it is one. @@ -335,7 +349,7 @@ macro_rules! interner_key ( (-3 as uint, 0u))) ) -fn mk_ident_interner() -> ident_interner { +fn mk_ident_interner() -> @ident_interner { /* the indices here must correspond to the numbers in special_idents */ let init_vec = ~[@~"_", @~"anon", @~"drop", @~"", @~"unary", @~"!", @~"[]", @~"unary-", @~"__extensions__", @~"self", @@ -346,7 +360,9 @@ fn mk_ident_interner() -> ident_interner { @~"dtor", @~"main", @~"", @~"blk", @~"static", @~"intrinsic", @~"__foreign_mod__"]; - let rv = interner::mk_prefill::<@~str>(init_vec); + let rv = @ident_interner { + interner: interner::mk_prefill::<@~str>(init_vec) + }; /* having multiple interners will just confuse the serializer */ unsafe { @@ -360,8 +376,8 @@ fn mk_ident_interner() -> ident_interner { /* for when we don't care about the contents; doesn't interact with TLD or serialization */ -fn mk_fake_ident_interner() -> ident_interner { - interner::mk::<@~str>() +fn mk_fake_ident_interner() -> @ident_interner { + @ident_interner { interner: interner::mk::<@~str>() } } /** diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3630ba8c5c6b..d08b20eed843 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -25,7 +25,7 @@ fn no_ann() -> pp_ann { type ps = @{s: pp::printer, cm: Option, - intr: token::ident_interner, + intr: @token::ident_interner, comments: Option<~[comments::cmnt]>, literals: Option<~[comments::lit]>, mut cur_cmnt: uint, @@ -43,7 +43,7 @@ fn end(s: ps) { pp::end(s.s); } -fn rust_printer(writer: io::Writer, intr: ident_interner) -> ps { +fn rust_printer(writer: io::Writer, intr: @ident_interner) -> ps { return @{s: pp::mk_printer(writer, default_columns), cm: None::, intr: intr, @@ -63,7 +63,7 @@ const default_columns: uint = 78u; // Requires you to pass an input filename and reader so that // it can scan the input text for comments and literals to // copy forward. -fn print_crate(cm: codemap, intr: ident_interner, +fn print_crate(cm: codemap, intr: @ident_interner, span_diagnostic: diagnostic::span_handler, crate: @ast::crate, filename: ~str, in: io::Reader, out: io::Writer, ann: pp_ann, is_expanded: bool) { @@ -91,40 +91,40 @@ fn print_crate_(s: ps, &&crate: @ast::crate) { eof(s.s); } -fn ty_to_str(ty: @ast::ty, intr: ident_interner) -> ~str { +fn ty_to_str(ty: @ast::ty, intr: @ident_interner) -> ~str { to_str(ty, print_type, intr) } -fn pat_to_str(pat: @ast::pat, intr: ident_interner) -> ~str { +fn pat_to_str(pat: @ast::pat, intr: @ident_interner) -> ~str { to_str(pat, print_pat, intr) } -fn expr_to_str(e: @ast::expr, intr: ident_interner) -> ~str { +fn expr_to_str(e: @ast::expr, intr: @ident_interner) -> ~str { to_str(e, print_expr, intr) } -fn tt_to_str(tt: ast::token_tree, intr: ident_interner) -> ~str { +fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str { to_str(tt, print_tt, intr) } -fn stmt_to_str(s: ast::stmt, intr: ident_interner) -> ~str { +fn stmt_to_str(s: ast::stmt, intr: @ident_interner) -> ~str { to_str(s, print_stmt, intr) } -fn item_to_str(i: @ast::item, intr: ident_interner) -> ~str { +fn item_to_str(i: @ast::item, intr: @ident_interner) -> ~str { to_str(i, print_item, intr) } -fn typarams_to_str(tps: ~[ast::ty_param], intr: ident_interner) -> ~str { +fn typarams_to_str(tps: ~[ast::ty_param], intr: @ident_interner) -> ~str { to_str(tps, print_type_params, intr) } -fn path_to_str(&&p: @ast::path, intr: ident_interner) -> ~str { +fn path_to_str(&&p: @ast::path, intr: @ident_interner) -> ~str { to_str(p, |a,b| print_path(a, b, false), intr) } fn fun_to_str(decl: ast::fn_decl, name: ast::ident, - params: ~[ast::ty_param], intr: ident_interner) -> ~str { + params: ~[ast::ty_param], intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); print_fn(s, decl, None, name, params, None, ast::inherited); @@ -147,7 +147,7 @@ fn test_fun_to_str() { assert fun_to_str(decl, "a", ~[]) == "fn a()"; } -fn block_to_str(blk: ast::blk, intr: ident_interner) -> ~str { +fn block_to_str(blk: ast::blk, intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); // containing cbox, will be closed by print-block at } @@ -159,15 +159,15 @@ fn block_to_str(blk: ast::blk, intr: ident_interner) -> ~str { } } -fn meta_item_to_str(mi: @ast::meta_item, intr: ident_interner) -> ~str { +fn meta_item_to_str(mi: @ast::meta_item, intr: @ident_interner) -> ~str { to_str(mi, print_meta_item, intr) } -fn attribute_to_str(attr: ast::attribute, intr: ident_interner) -> ~str { +fn attribute_to_str(attr: ast::attribute, intr: @ident_interner) -> ~str { to_str(attr, print_attribute, intr) } -fn variant_to_str(var: ast::variant, intr: ident_interner) -> ~str { +fn variant_to_str(var: ast::variant, intr: @ident_interner) -> ~str { to_str(var, print_variant, intr) } @@ -443,6 +443,7 @@ fn print_item(s: ps, &&item: @ast::item) { print_outer_attributes(s, item.attrs); let ann_node = node_item(s, item); s.ann.pre(ann_node); + print_visibility(s, item.vis); match item.node { ast::item_const(ty, expr) => { head(s, visibility_qualified(item.vis, ~"const")); @@ -979,7 +980,7 @@ fn print_mac(s: ps, m: ast::mac) { Some(@{node: ast::expr_vec(_, _), _}) => (), _ => word(s.s, ~" ") } - arg.iter(|a| print_expr(s, a)); + arg.iter(|a| print_expr(s, *a)); // FIXME: extension 'body' (#2339) } ast::mac_invoc_tt(pth, tts) => { @@ -1111,7 +1112,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) { ast::expr_call(func, args, has_block) => { let mut base_args = args; let blk = if has_block { - let blk_arg = vec::pop(base_args); + let blk_arg = base_args.pop(); match blk_arg.node { ast::expr_loop_body(_) => { head(s, ~"for"); } ast::expr_do_body(_) => { head(s, ~"do"); } @@ -1177,7 +1178,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) { ast::expr_loop(blk, opt_ident) => { head(s, ~"loop"); space(s.s); - opt_ident.iter(|ident| {print_ident(s, ident); space(s.s)}); + opt_ident.iter(|ident| {print_ident(s, *ident); space(s.s)}); print_block(s, blk); } ast::expr_match(expr, arms) => { @@ -1360,12 +1361,12 @@ fn print_expr(s: ps, &&expr: @ast::expr) { ast::expr_break(opt_ident) => { word(s.s, ~"break"); space(s.s); - opt_ident.iter(|ident| {print_ident(s, ident); space(s.s)}); + opt_ident.iter(|ident| {print_ident(s, *ident); space(s.s)}); } ast::expr_again(opt_ident) => { word(s.s, ~"loop"); space(s.s); - opt_ident.iter(|ident| {print_ident(s, ident); space(s.s)}); + opt_ident.iter(|ident| {print_ident(s, *ident); space(s.s)}); } ast::expr_ret(result) => { word(s.s, ~"return"); @@ -2059,7 +2060,7 @@ fn print_string(s: ps, st: ~str) { word(s.s, ~"\""); } -fn to_str(t: T, f: fn@(ps, T), intr: ident_interner) -> ~str { +fn to_str(t: T, f: fn@(ps, T), intr: @ident_interner) -> ~str { do io::with_str_writer |wr| { let s = rust_printer(wr, intr); f(s, t); diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index c62ec28f3595..38abf5f445c2 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -13,6 +13,8 @@ #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; +#[allow(deprecated_mode)]; +#[allow(deprecated_pattern)]; extern mod core(vers = "0.4"); extern mod std(vers = "0.4"); @@ -129,6 +131,8 @@ mod ext { #[legacy_exports] mod auto_serialize; #[legacy_exports] + mod auto_serialize2; + #[legacy_exports] mod source_util; mod pipes { diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 15b9e34566fb..021c25e3dd71 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -59,4 +59,4 @@ impl hash_interner: interner { pure fn get(idx: uint) -> T { self.vect.get_elt(idx) } fn len() -> uint { return self.vect.len(); } -} \ No newline at end of file +} diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index de9caf48b63f..e6fd65eb458a 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -241,7 +241,7 @@ fn visit_pat(p: @pat, e: E, v: vt) { v.visit_pat(inner, e, v), pat_ident(_, path, inner) => { visit_path(path, e, v); - do option::iter(&inner) |subpat| { v.visit_pat(subpat, e, v)}; + do option::iter(&inner) |subpat| { v.visit_pat(*subpat, e, v)}; } pat_lit(ex) => v.visit_expr(ex, e, v), pat_range(e1, e2) => { v.visit_expr(e1, e, v); v.visit_expr(e2, e, v); } @@ -342,10 +342,10 @@ fn visit_struct_def(sd: @struct_def, nm: ast::ident, tps: ~[ty_param], visit_path(p.path, e, v); } do option::iter(&sd.ctor) |ctor| { - visit_class_ctor_helper(ctor, nm, tps, ast_util::local_def(id), e, v); + visit_class_ctor_helper(*ctor, nm, tps, ast_util::local_def(id), e, v); }; do option::iter(&sd.dtor) |dtor| { - visit_class_dtor_helper(dtor, tps, ast_util::local_def(id), e, v) + visit_class_dtor_helper(*dtor, tps, ast_util::local_def(id), e, v) }; } @@ -395,7 +395,7 @@ fn visit_exprs(exprs: ~[@expr], e: E, v: vt) { fn visit_mac(m: mac, e: E, v: vt) { match m.node { ast::mac_invoc(_, arg, _) => { - option::map(&arg, |arg| v.visit_expr(arg, e, v)); } + option::map(&arg, |arg| v.visit_expr(*arg, e, v)); } ast::mac_invoc_tt(*) => { /* no user-serviceable parts inside */ } ast::mac_ellipsis => (), ast::mac_aq(*) => { /* FIXME: maybe visit (Issue #2340) */ } diff --git a/src/llvm b/src/llvm index b55be285d18e..c51053bf71de 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit b55be285d18e9b3537fc9d29af44e83be2171326 +Subproject commit c51053bf71de475df6a91204acd9ad78f4747c38 diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index dc28f6244155..11e65347f11b 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -86,7 +86,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { // Load runtime configuration options from the environment. // FIXME #1497: Should provide a way to get these from the command // line as well. - rust_env *env = load_env(); + rust_env *env = load_env(argc, argv); global_crate_map = crate_map; diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 91c5760d3e9d..5baa95c7323f 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -180,6 +180,11 @@ rand_new_seeded(rust_vec_box* seed) { return rctx; } +extern "C" CDECL void * +rand_new_seeded2(rust_vec_box** seed) { + return rand_new_seeded(*seed); +} + extern "C" CDECL size_t rand_next(randctx *rctx) { return isaac_rand(rctx); @@ -371,6 +376,11 @@ rust_list_files(rust_str *path) { return vec; } +extern "C" CDECL rust_vec_box* +rust_list_files2(rust_str **path) { + return rust_list_files(*path); +} + extern "C" CDECL int rust_path_is_dir(char *path) { struct stat buf; @@ -578,6 +588,18 @@ rust_num_threads() { return task->kernel->env->num_sched_threads; } +extern "C" CDECL int +rust_get_argc() { + rust_task *task = rust_get_current_task(); + return task->kernel->env->argc; +} + +extern "C" CDECL char** +rust_get_argv() { + rust_task *task = rust_get_current_task(); + return task->kernel->env->argv; +} + extern "C" CDECL rust_sched_id rust_new_sched(uintptr_t threads) { rust_task *task = rust_get_current_task(); diff --git a/src/rt/rust_env.cpp b/src/rt/rust_env.cpp index a54dc27c71f4..4e653c8f9e63 100644 --- a/src/rt/rust_env.cpp +++ b/src/rt/rust_env.cpp @@ -107,7 +107,7 @@ copyenv(const char* name) { } rust_env* -load_env() { +load_env(int argc, char **argv) { rust_env *env = (rust_env*)malloc(sizeof(rust_env)); env->num_sched_threads = (size_t)get_num_threads(); @@ -118,7 +118,8 @@ load_env() { env->detailed_leaks = getenv(DETAILED_LEAKS) != NULL; env->rust_seed = copyenv(RUST_SEED); env->poison_on_free = getenv(RUST_POISON_ON_FREE) != NULL; - + env->argc = argc; + env->argv = argv; return env; } diff --git a/src/rt/rust_env.h b/src/rt/rust_env.h index 007ac9b1e0b1..0e3af9eae60c 100644 --- a/src/rt/rust_env.h +++ b/src/rt/rust_env.h @@ -13,9 +13,11 @@ struct rust_env { bool detailed_leaks; char* rust_seed; bool poison_on_free; + int argc; + char **argv; }; -rust_env* load_env(); +rust_env* load_env(int argc, char **argv); void free_env(rust_env *rust_env); #endif diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in index 43f24f4dd4fa..7412f06d8cd8 100644 --- a/src/rt/rustrt.def.in +++ b/src/rt/rustrt.def.in @@ -27,9 +27,12 @@ rust_port_select rand_free rand_new rand_new_seeded +rand_new_seeded2 rand_next rand_seed rust_get_sched_id +rust_get_argc +rust_get_argv rust_new_sched rust_new_task_in_sched rust_num_threads @@ -40,6 +43,7 @@ rust_get_stdin rust_get_stdout rust_get_stderr rust_list_files +rust_list_files2 rust_log_console_on rust_log_console_off rust_port_begin_detach diff --git a/src/rt/sync/rust_thread.cpp b/src/rt/sync/rust_thread.cpp index 5d533acde3db..02fecd440f8e 100644 --- a/src/rt/sync/rust_thread.cpp +++ b/src/rt/sync/rust_thread.cpp @@ -32,10 +32,10 @@ rust_thread::start() { thread = CreateThread(NULL, stack_sz, rust_thread_start, this, 0, NULL); #else pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setstacksize(&attr, stack_sz); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_create(&thread, &attr, rust_thread_start, (void *) this); + CHECKED(pthread_attr_init(&attr)); + CHECKED(pthread_attr_setstacksize(&attr, stack_sz)); + CHECKED(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)); + CHECKED(pthread_create(&thread, &attr, rust_thread_start, (void *) this)); #endif } @@ -46,7 +46,7 @@ rust_thread::join() { WaitForSingleObject(thread, INFINITE); #else if (thread) - pthread_join(thread, NULL); + CHECKED(pthread_join(thread, NULL)); #endif thread = 0; } @@ -56,6 +56,6 @@ rust_thread::detach() { #if !defined(__WIN32__) // Don't leak pthread resources. // http://crosstantine.blogspot.com/2010/01/pthreadcreate-memory-leak.html - pthread_detach(thread); + CHECKED(pthread_detach(thread)); #endif } diff --git a/src/rustc/back/link.rs b/src/rustc/back/link.rs index fb3d749673c1..2e310785306c 100644 --- a/src/rustc/back/link.rs +++ b/src/rustc/back/link.rs @@ -74,17 +74,47 @@ mod jit { m: ModuleRef, opt: c_int, stacks: bool) unsafe { - let ptr = llvm::LLVMRustJIT(rusti::morestack_addr(), - pm, m, opt, stacks); + let manager = llvm::LLVMRustPrepareJIT(rusti::morestack_addr()); - if ptr::is_null(ptr) { + // We need to tell JIT where to resolve all linked + // symbols from. The equivalent of -lstd, -lcore, etc. + // By default the JIT will resolve symbols from the std and + // core linked into rustc. We don't want that, + // incase the user wants to use an older std library. + + let cstore = sess.cstore; + for cstore::get_used_crate_files(cstore).each |cratepath| { + let path = cratepath.to_str(); + + debug!("linking: %s", path); + + let _: () = str::as_c_str( + path, + |buf_t| { + if !llvm::LLVMRustLoadCrate(manager, buf_t) { + llvm_err(sess, ~"Could not link"); + } + debug!("linked: %s", path); + }); + } + + // The execute function will return a void pointer + // to the _rust_main function. We can do closure + // magic here to turn it straight into a callable rust + // closure. It will also cleanup the memory manager + // for us. + + let entry = llvm::LLVMRustExecuteJIT(manager, + pm, m, opt, stacks); + + if ptr::is_null(entry) { llvm_err(sess, ~"Could not JIT"); } else { let closure = Closure { - code: ptr, + code: entry, env: ptr::null() }; - let func: fn(~[~str]) = cast::transmute(move closure); + let func: fn(++argv: ~[~str]) = cast::transmute(move closure); func(~[sess.opts.binary]); } @@ -193,25 +223,6 @@ mod write { // JIT execution takes ownership of the module, // so don't dispose and return. - // We need to tell LLVM where to resolve all linked - // symbols from. The equivalent of -lstd, -lcore, etc. - // By default the JIT will resolve symbols from the std and - // core linked into rustc. We don't want that, - // incase the user wants to use an older std library. - /*let cstore = sess.cstore; - for cstore::get_used_crate_files(cstore).each |cratepath| { - debug!{"linking: %s", cratepath}; - - let _: () = str::as_c_str( - cratepath, - |buf_t| { - if !llvm::LLVMRustLoadLibrary(buf_t) { - llvm_err(sess, ~"Could not link"); - } - debug!{"linked: %s", cratepath}; - }); - }*/ - jit::exec(sess, pm.llpm, llmod, CodeGenOptLevel, true); if sess.time_llvm_passes() { @@ -392,14 +403,14 @@ fn build_link_meta(sess: session, c: ast::crate, output: &Path, if attr::get_meta_item_name(*meta) == ~"name" { match attr::get_meta_item_value_str(*meta) { Some(v) => { name = Some(v); } - None => vec::push(cmh_items, *meta) + None => cmh_items.push(*meta) } } else if attr::get_meta_item_name(*meta) == ~"vers" { match attr::get_meta_item_value_str(*meta) { Some(v) => { vers = Some(v); } - None => vec::push(cmh_items, *meta) + None => cmh_items.push(*meta) } - } else { vec::push(cmh_items, *meta); } + } else { cmh_items.push(*meta); } } return {name: name, vers: vers, cmh_items: cmh_items}; } @@ -607,7 +618,7 @@ fn mangle_internal_name_by_path(ccx: @crate_ctxt, path: path) -> ~str { } fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: ~str) -> ~str { - return fmt!("%s_%u", flav, ccx.names(flav)); + return fmt!("%s_%u", flav, ccx.names(flav).repr); } // If the user wants an exe generated we need to invoke @@ -657,9 +668,9 @@ fn link_binary(sess: session, let mut cc_args = vec::append(~[stage], sess.targ_cfg.target_strs.cc_args); - vec::push(cc_args, ~"-o"); - vec::push(cc_args, output.to_str()); - vec::push(cc_args, obj_filename.to_str()); + cc_args.push(~"-o"); + cc_args.push(output.to_str()); + cc_args.push(obj_filename.to_str()); let mut lib_cmd; let os = sess.targ_cfg.os; @@ -674,17 +685,17 @@ fn link_binary(sess: session, let cstore = sess.cstore; for cstore::get_used_crate_files(cstore).each |cratepath| { if cratepath.filetype() == Some(~".rlib") { - vec::push(cc_args, cratepath.to_str()); + cc_args.push(cratepath.to_str()); loop; } let dir = cratepath.dirname(); - if dir != ~"" { vec::push(cc_args, ~"-L" + dir); } + if dir != ~"" { cc_args.push(~"-L" + dir); } let libarg = unlib(sess.targ_cfg, cratepath.filestem().get()); - vec::push(cc_args, ~"-l" + libarg); + cc_args.push(~"-l" + libarg); } let ula = cstore::get_used_link_args(cstore); - for ula.each |arg| { vec::push(cc_args, *arg); } + for ula.each |arg| { cc_args.push(*arg); } // # Extern library linking @@ -695,41 +706,41 @@ fn link_binary(sess: session, // forces to make sure that library can be found at runtime. let addl_paths = sess.opts.addl_lib_search_paths; - for addl_paths.each |path| { vec::push(cc_args, ~"-L" + path.to_str()); } + for addl_paths.each |path| { cc_args.push(~"-L" + path.to_str()); } // The names of the extern libraries let used_libs = cstore::get_used_libraries(cstore); - for used_libs.each |l| { vec::push(cc_args, ~"-l" + *l); } + for used_libs.each |l| { cc_args.push(~"-l" + *l); } if sess.building_library { - vec::push(cc_args, lib_cmd); + cc_args.push(lib_cmd); // On mac we need to tell the linker to let this library // be rpathed if sess.targ_cfg.os == session::os_macos { - vec::push(cc_args, ~"-Wl,-install_name,@rpath/" + cc_args.push(~"-Wl,-install_name,@rpath/" + output.filename().get()); } } if !sess.debugging_opt(session::no_rt) { // Always want the runtime linked in - vec::push(cc_args, ~"-lrustrt"); + cc_args.push(~"-lrustrt"); } // On linux librt and libdl are an indirect dependencies via rustrt, // and binutils 2.22+ won't add them automatically if sess.targ_cfg.os == session::os_linux { - vec::push_all(cc_args, ~[~"-lrt", ~"-ldl"]); + cc_args.push_all(~[~"-lrt", ~"-ldl"]); // LLVM implements the `frem` instruction as a call to `fmod`, // which lives in libm. Similar to above, on some linuxes we // have to be explicit about linking to it. See #2510 - vec::push(cc_args, ~"-lm"); + cc_args.push(~"-lm"); } if sess.targ_cfg.os == session::os_freebsd { - vec::push_all(cc_args, ~[~"-pthread", ~"-lrt", + cc_args.push_all(~[~"-pthread", ~"-lrt", ~"-L/usr/local/lib", ~"-lexecinfo", ~"-L/usr/local/lib/gcc46", ~"-L/usr/local/lib/gcc44", ~"-lstdc++", @@ -743,15 +754,15 @@ fn link_binary(sess: session, // understand how to unwind our __morestack frame, so we have to turn it // off. This has impacted some other projects like GHC. if sess.targ_cfg.os == session::os_macos { - vec::push(cc_args, ~"-Wl,-no_compact_unwind"); + cc_args.push(~"-Wl,-no_compact_unwind"); } // Stack growth requires statically linking a __morestack function - vec::push(cc_args, ~"-lmorestack"); + cc_args.push(~"-lmorestack"); // FIXME (#2397): At some point we want to rpath our guesses as to where // extern libraries might live, based on the addl_lib_search_paths - vec::push_all(cc_args, rpath::get_rpath_flags(sess, &output)); + cc_args.push_all(rpath::get_rpath_flags(sess, &output)); debug!("%s link args: %s", cc_prog, str::connect(cc_args, ~" ")); // We run 'cc' here diff --git a/src/rustc/back/rpath.rs b/src/rustc/back/rpath.rs index 132bbc96344f..8aa7caefc7a5 100644 --- a/src/rustc/back/rpath.rs +++ b/src/rustc/back/rpath.rs @@ -81,8 +81,8 @@ fn get_rpaths(os: session::os, log_rpaths(~"fallback", fallback_rpaths); let mut rpaths = rel_rpaths; - vec::push_all(rpaths, abs_rpaths); - vec::push_all(rpaths, fallback_rpaths); + rpaths.push_all(abs_rpaths); + rpaths.push_all(fallback_rpaths); // Remove duplicates let rpaths = minimize_rpaths(rpaths); @@ -136,9 +136,9 @@ fn get_relative_to(abs1: &Path, abs2: &Path) -> Path { } let mut path = ~[]; - for uint::range(start_idx, len1 - 1) |_i| { vec::push(path, ~".."); }; + for uint::range(start_idx, len1 - 1) |_i| { path.push(~".."); }; - vec::push_all(path, vec::view(split2, start_idx, len2 - 1)); + path.push_all(vec::view(split2, start_idx, len2 - 1)); if vec::is_not_empty(path) { return Path("").push_many(path); @@ -172,7 +172,7 @@ fn minimize_rpaths(rpaths: &[Path]) -> ~[Path] { for rpaths.each |rpath| { let s = rpath.to_str(); if !set.contains_key(s) { - vec::push(minimized, *rpath); + minimized.push(*rpath); set.insert(s, ()); } } diff --git a/src/rustc/back/upcall.rs b/src/rustc/back/upcall.rs index f289a0bdf273..a2c864f6f465 100644 --- a/src/rustc/back/upcall.rs +++ b/src/rustc/back/upcall.rs @@ -28,7 +28,7 @@ fn declare_upcalls(targ_cfg: @session::config, tys: ~[TypeRef], rv: TypeRef) -> ValueRef { let mut arg_tys: ~[TypeRef] = ~[]; - for tys.each |t| { vec::push(arg_tys, *t); } + for tys.each |t| { arg_tys.push(*t); } let fn_ty = T_fn(arg_tys, rv); return base::decl_cdecl_fn(llmod, prefix + name, fn_ty); } diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index f890fa85eb35..e389f3a4bdf7 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -94,7 +94,7 @@ fn parse_cfgspecs(cfgspecs: ~[~str]) -> ast::crate_cfg { // meta_word variant. let mut words = ~[]; for cfgspecs.each |s| { - vec::push(words, attr::mk_word_item(*s)); + words.push(attr::mk_word_item(*s)); } return words; } @@ -466,7 +466,7 @@ fn build_session_options(binary: ~str, level_name, lint_name)); } Some(lint) => { - vec::push(lint_opts, (lint.lint, *level)); + lint_opts.push((lint.lint, *level)); } } } @@ -507,7 +507,7 @@ fn build_session_options(binary: ~str, let extra_debuginfo = opt_present(matches, ~"xg"); let debuginfo = opt_present(matches, ~"g") || extra_debuginfo; let sysroot_opt = getopts::opt_maybe_str(matches, ~"sysroot"); - let sysroot_opt = sysroot_opt.map(|m| Path(m)); + let sysroot_opt = sysroot_opt.map(|m| Path(*m)); let target_opt = getopts::opt_maybe_str(matches, ~"target"); let save_temps = getopts::opt_present(matches, ~"save-temps"); match output_type { diff --git a/src/rustc/driver/rustc.rs b/src/rustc/driver/rustc.rs index 1b4b47f1014a..c6b93fc0603a 100644 --- a/src/rustc/driver/rustc.rs +++ b/src/rustc/driver/rustc.rs @@ -12,6 +12,7 @@ use core::*; // -*- rust -*- use result::{Ok, Err}; +use io::ReaderUtil; use std::getopts; use std::map::HashMap; use getopts::{opt_present}; @@ -60,7 +61,7 @@ Options: --save-temps Write intermediate files (.bc, .opt.bc, .o) in addition to normal output --static Use or produce static libraries or binaries - --stats Print compilation statistics + (experimental) --sysroot Override the system root --test Build a test harness --target Target cpu-manufacturer-kernel[-os] to compile for @@ -121,7 +122,7 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) { logging::console_off(); let mut args = args; - let binary = vec::shift(args); + let binary = args.shift(); if vec::len(args) == 0u { usage(binary); return; } @@ -140,12 +141,12 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) { let lint_flags = vec::append(getopts::opt_strs(matches, ~"W"), getopts::opt_strs(matches, ~"warn")); - if lint_flags.contains(~"help") { + if lint_flags.contains(&~"help") { describe_warnings(); return; } - if getopts::opt_strs(matches, ~"Z").contains(~"help") { + if getopts::opt_strs(matches, ~"Z").contains(&~"help") { describe_debug_flags(); return; } @@ -171,14 +172,14 @@ fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) { let sopts = build_session_options(binary, matches, demitter); let sess = build_session(sopts, demitter); let odir = getopts::opt_maybe_str(matches, ~"out-dir"); - let odir = odir.map(|o| Path(o)); + let odir = odir.map(|o| Path(*o)); let ofile = getopts::opt_maybe_str(matches, ~"o"); - let ofile = ofile.map(|o| Path(o)); + let ofile = ofile.map(|o| Path(*o)); let cfg = build_configuration(sess, binary, input); let pretty = option::map(&getopts::opt_default(matches, ~"pretty", ~"normal"), - |a| parse_pretty(sess, a) ); + |a| parse_pretty(sess, *a) ); match pretty { Some::(ppm) => { pretty_print_input(sess, cfg, input, ppm); @@ -235,7 +236,7 @@ fn monitor(+f: fn~(diagnostic::emitter)) { // The 'diagnostics emitter'. Every error, warning, etc. should // go through this function. let demitter = fn@(cmsp: Option<(codemap::codemap, codemap::span)>, - msg: ~str, lvl: diagnostic::level) { + msg: &str, lvl: diagnostic::level) { if lvl == diagnostic::fatal { comm::send(ch, fatal); } diff --git a/src/rustc/driver/session.rs b/src/rustc/driver/session.rs index 335e10040783..c6c0ff2826a5 100644 --- a/src/rustc/driver/session.rs +++ b/src/rustc/driver/session.rs @@ -243,7 +243,7 @@ impl session { fn ident_of(st: ~str) -> ast::ident { self.parse_sess.interner.intern(@st) } - fn intr() -> syntax::parse::token::ident_interner { + fn intr() -> @syntax::parse::token::ident_interner { self.parse_sess.interner } } diff --git a/src/rustc/front/config.rs b/src/rustc/front/config.rs index 4c262e3dc650..4577b54fb5c7 100644 --- a/src/rustc/front/config.rs +++ b/src/rustc/front/config.rs @@ -50,13 +50,12 @@ fn filter_view_item(cx: ctxt, &&view_item: @ast::view_item fn fold_mod(cx: ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { - let item_filter = |a| filter_item(cx, a); - let filtered_items = vec::filter_map(m.items, item_filter); - let view_item_filter = |a| filter_view_item(cx, a); - let filtered_view_items = vec::filter_map(m.view_items, view_item_filter); + let filtered_items = vec::filter_map(m.items, |a| filter_item(cx, *a)); + let filtered_view_items = vec::filter_map(m.view_items, + |a| filter_view_item(cx, *a)); return { view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(*x)), - items: vec::filter_map(filtered_items, |x| fld.fold_item(x)) + items: vec::filter_map(filtered_items, |x| fld.fold_item(*x)) }; } @@ -69,11 +68,10 @@ fn filter_foreign_item(cx: ctxt, &&item: @ast::foreign_item) -> fn fold_foreign_mod(cx: ctxt, nm: ast::foreign_mod, fld: fold::ast_fold) -> ast::foreign_mod { - let item_filter = |a| filter_foreign_item(cx, a); - let filtered_items = vec::filter_map(nm.items, item_filter); - let view_item_filter = |a| filter_view_item(cx, a); - let filtered_view_items = vec::filter_map( - nm.view_items, view_item_filter); + let filtered_items = vec::filter_map(nm.items, + |a| filter_foreign_item(cx, *a)); + let filtered_view_items = vec::filter_map(nm.view_items, + |a| filter_view_item(cx, *a)); return { sort: nm.sort, view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(*x)), @@ -100,11 +98,10 @@ fn filter_stmt(cx: ctxt, &&stmt: @ast::stmt) -> fn fold_block(cx: ctxt, b: ast::blk_, fld: fold::ast_fold) -> ast::blk_ { - let filter = |a| filter_stmt(cx, a); - let filtered_stmts = vec::filter_map(b.stmts, filter); + let filtered_stmts = vec::filter_map(b.stmts, |a| filter_stmt(cx, *a)); return {view_items: b.view_items, stmts: vec::map(filtered_stmts, |x| fld.fold_stmt(*x)), - expr: option::map(&b.expr, |x| fld.fold_expr(x)), + expr: option::map(&b.expr, |x| fld.fold_expr(*x)), id: b.id, rules: b.rules}; } @@ -136,7 +133,7 @@ fn metas_in_cfg(cfg: ast::crate_cfg, metas: ~[@ast::meta_item]) -> bool { // so we can match against them. This is the list of configurations for // which the item is valid let cfg_metas = vec::concat(vec::filter_map(cfg_metas, - |&&i| attr::get_meta_item_list(i) )); + |i| attr::get_meta_item_list(*i))); let has_cfg_metas = vec::len(cfg_metas) > 0u; if !has_cfg_metas { return true; } diff --git a/src/rustc/front/test.rs b/src/rustc/front/test.rs index e1441d9ee5e3..952d7b9ab793 100644 --- a/src/rustc/front/test.rs +++ b/src/rustc/front/test.rs @@ -81,8 +81,8 @@ fn fold_mod(cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { } let mod_nomain = - {view_items: m.view_items, items: vec::filter_map(m.items, - |i| nomain(cx, i))}; + {view_items: m.view_items, + items: vec::filter_map(m.items, |i| nomain(cx, *i))}; return fold::noop_fold_mod(mod_nomain, fld); } @@ -99,7 +99,7 @@ fn fold_crate(cx: test_ctxt, c: ast::crate_, fld: fold::ast_fold) -> fn fold_item(cx: test_ctxt, &&i: @ast::item, fld: fold::ast_fold) -> Option<@ast::item> { - vec::push(cx.path, i.ident); + cx.path.push(i.ident); debug!("current path: %s", ast_util::path_name_i(cx.path, cx.sess.parse_sess.interner)); @@ -122,7 +122,7 @@ fn fold_item(cx: test_ctxt, &&i: @ast::item, fld: fold::ast_fold) -> } let res = fold::noop_fold_item(i, fld); - vec::pop(cx.path); + cx.path.pop(); return res; } @@ -152,7 +152,7 @@ fn is_ignored(cx: test_ctxt, i: @ast::item) -> bool { let ignoreattrs = attr::find_attrs_by_name(i.attrs, ~"ignore"); let ignoreitems = attr::attr_metas(ignoreattrs); let cfg_metas = vec::concat(vec::filter_map(ignoreitems, - |&&i| attr::get_meta_item_list(i) )); + |i| attr::get_meta_item_list(*i))); return if vec::is_not_empty(ignoreitems) { config::metas_in_cfg(cx.crate.node.config, cfg_metas) } else { @@ -286,7 +286,7 @@ fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr { debug!("building test vector from %u tests", cx.testfns.len()); let mut descs = ~[]; for cx.testfns.each |test| { - vec::push(descs, mk_test_desc_rec(cx, *test)); + descs.push(mk_test_desc_rec(cx, *test)); } let inner_expr = @{id: cx.sess.next_node_id(), diff --git a/src/rustc/lib/llvm.rs b/src/rustc/lib/llvm.rs index 031ce2193080..0d92c19b9521 100644 --- a/src/rustc/lib/llvm.rs +++ b/src/rustc/lib/llvm.rs @@ -28,19 +28,19 @@ enum Linkage { AvailableExternallyLinkage = 1, LinkOnceAnyLinkage = 2, LinkOnceODRLinkage = 3, - WeakAnyLinkage = 4, - WeakODRLinkage = 5, - AppendingLinkage = 6, - InternalLinkage = 7, - PrivateLinkage = 8, - DLLImportLinkage = 9, - DLLExportLinkage = 10, - ExternalWeakLinkage = 11, - GhostLinkage = 12, - CommonLinkage = 13, - LinkerPrivateLinkage = 14, - LinkerPrivateWeakLinkage = 15, - LinkerPrivateWeakDefAutoLinkage = 16, + LinkOnceODRAutoHideLinkage = 4, + WeakAnyLinkage = 5, + WeakODRLinkage = 6, + AppendingLinkage = 7, + InternalLinkage = 8, + PrivateLinkage = 9, + DLLImportLinkage = 10, + DLLExportLinkage = 11, + ExternalWeakLinkage = 12, + GhostLinkage = 13, + CommonLinkage = 14, + LinkerPrivateLinkage = 15, + LinkerPrivateWeakLinkage = 16, } enum Attribute { @@ -91,6 +91,7 @@ enum IntPredicate { // enum for the LLVM RealPredicate type enum RealPredicate { + RealPredicateFalse = 0, RealOEQ = 1, RealOGT = 2, RealOGE = 3, @@ -105,6 +106,7 @@ enum RealPredicate { RealULT = 12, RealULE = 13, RealUNE = 14, + RealPredicateTrue = 15, } // enum for the LLVM TypeKind type - must stay in sync with the def of @@ -990,15 +992,19 @@ extern mod llvm { call. */ fn LLVMRustGetLastError() -> *c_char; - /** Load a shared library to resolve symbols against. */ - fn LLVMRustLoadLibrary(Filename: *c_char) -> bool; + /** Prepare the JIT. Returns a memory manager that can load crates. */ + fn LLVMRustPrepareJIT(__morestack: *()) -> *(); - /** Create and execute the JIT engine. */ - fn LLVMRustJIT(__morestack: *(), - PM: PassManagerRef, - M: ModuleRef, - OptLevel: c_int, - EnableSegmentedStacks: bool) -> *(); + /** Load a crate into the memory manager. */ + fn LLVMRustLoadCrate(MM: *(), + Filename: *c_char) -> bool; + + /** Execute the JIT engine. */ + fn LLVMRustExecuteJIT(MM: *(), + PM: PassManagerRef, + M: ModuleRef, + OptLevel: c_int, + EnableSegmentedStacks: bool) -> *(); /** Parses the bitcode in the given memory buffer. */ fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef) -> ModuleRef; diff --git a/src/rustc/metadata/common.rs b/src/rustc/metadata/common.rs index 2d62bf7b4a2f..1857abf2cf2f 100644 --- a/src/rustc/metadata/common.rs +++ b/src/rustc/metadata/common.rs @@ -120,7 +120,8 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f tag_table_spill = 0x5f, tag_table_method_map = 0x60, tag_table_vtable_map = 0x61, - tag_table_adjustments = 0x62 + tag_table_adjustments = 0x62, + tag_table_legacy_boxed_trait = 0x63 } type link_meta = {name: ~str, vers: ~str, extras_hash: ~str}; diff --git a/src/rustc/metadata/creader.rs b/src/rustc/metadata/creader.rs index f6c2bf7d5a11..3ed56a1953e6 100644 --- a/src/rustc/metadata/creader.rs +++ b/src/rustc/metadata/creader.rs @@ -18,7 +18,7 @@ export read_crates; // libraries necessary for later resolving, typechecking, linking, etc. fn read_crates(diag: span_handler, crate: ast::crate, cstore: cstore::cstore, filesearch: filesearch, - os: loader::os, static: bool, intr: ident_interner) { + os: loader::os, static: bool, intr: @ident_interner) { let e = @{diag: diag, filesearch: filesearch, cstore: cstore, @@ -63,9 +63,9 @@ fn warn_if_multiple_versions(e: env, diag: span_handler, partition(crate_cache.map_to_vec(|entry| { let othername = loader::crate_name_from_metas(*entry.metas); if name == othername { - Left(*entry) + Left(entry) } else { - Right(*entry) + Right(entry) } })); @@ -94,7 +94,7 @@ type env = @{diag: span_handler, static: bool, crate_cache: DVec, mut next_crate_num: ast::crate_num, - intr: ident_interner}; + intr: @ident_interner}; fn visit_view_item(e: env, i: @ast::view_item) { match i.node { @@ -248,7 +248,7 @@ fn resolve_crate_deps(e: env, cdata: @~[u8]) -> cstore::cnum_map { debug!("resolving deps of external crate"); // The map from crate numbers in the crate we're resolving to local crate // numbers - let cnum_map = HashMap::(); + let cnum_map = HashMap(); for decoder::get_crate_deps(e.intr, cdata).each |dep| { let extrn_cnum = dep.cnum; let cname = dep.name; diff --git a/src/rustc/metadata/cstore.rs b/src/rustc/metadata/cstore.rs index c5686153c000..d59464d58c73 100644 --- a/src/rustc/metadata/cstore.rs +++ b/src/rustc/metadata/cstore.rs @@ -58,7 +58,7 @@ type cstore_private = mut used_crate_files: ~[Path], mut used_libraries: ~[~str], mut used_link_args: ~[~str], - intr: ident_interner}; + intr: @ident_interner}; // Map from node_id's of local use statements to crate numbers type use_crate_map = map::HashMap; @@ -68,9 +68,9 @@ pure fn p(cstore: cstore) -> cstore_private { match cstore { private(p) => p } } -fn mk_cstore(intr: ident_interner) -> cstore { - let meta_cache = map::HashMap::(); - let crate_map = map::HashMap::(); +fn mk_cstore(intr: @ident_interner) -> cstore { + let meta_cache = map::HashMap(); + let crate_map = map::HashMap(); let mod_path_map = HashMap(); return private(@{metas: meta_cache, use_crate_map: crate_map, @@ -114,8 +114,8 @@ fn iter_crate_data(cstore: cstore, i: fn(ast::crate_num, crate_metadata)) { } fn add_used_crate_file(cstore: cstore, lib: &Path) { - if !vec::contains(p(cstore).used_crate_files, copy *lib) { - vec::push(p(cstore).used_crate_files, copy *lib); + if !vec::contains(p(cstore).used_crate_files, lib) { + p(cstore).used_crate_files.push(copy *lib); } } @@ -126,8 +126,8 @@ fn get_used_crate_files(cstore: cstore) -> ~[Path] { fn add_used_library(cstore: cstore, lib: ~str) -> bool { assert lib != ~""; - if vec::contains(p(cstore).used_libraries, lib) { return false; } - vec::push(p(cstore).used_libraries, lib); + if vec::contains(p(cstore).used_libraries, &lib) { return false; } + p(cstore).used_libraries.push(lib); return true; } @@ -136,7 +136,7 @@ fn get_used_libraries(cstore: cstore) -> ~[~str] { } fn add_used_link_args(cstore: cstore, args: ~str) { - vec::push_all(p(cstore).used_link_args, str::split_char(args, ' ')); + p(cstore).used_link_args.push_all(str::split_char(args, ' ')); } fn get_used_link_args(cstore: cstore) -> ~[~str] { @@ -163,7 +163,7 @@ fn get_dep_hashes(cstore: cstore) -> ~[~str] { let cdata = cstore::get_crate_data(cstore, cnum); let hash = decoder::get_crate_hash(cdata.data); debug!("Add hash[%s]: %s", cdata.name, hash); - vec::push(result, {name: cdata.name, hash: hash}); + result.push({name: cdata.name, hash: hash}); }; pure fn lteq(a: &crate_hash, b: &crate_hash) -> bool {a.name <= b.name} let sorted = std::sort::merge_sort(result, lteq); @@ -177,7 +177,7 @@ fn get_dep_hashes(cstore: cstore) -> ~[~str] { fn get_path(cstore: cstore, d: ast::def_id) -> ~[~str] { option::map_default(&p(cstore).mod_path_map.find(d), ~[], - |ds| str::split_str(*ds, ~"::")) + |ds| str::split_str(**ds, ~"::")) } // Local Variables: // mode: rust diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index c631e4044722..0e6bc2aee15a 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -196,7 +196,7 @@ fn field_mutability(d: ebml::Doc) -> ast::class_mutability { &ebml::maybe_get_doc(d, tag_class_mut), ast::class_immutable, |d| { - match ebml::doc_as_u8(d) as char { + match ebml::doc_as_u8(*d) as char { 'm' => ast::class_mutable, _ => ast::class_immutable } @@ -204,7 +204,7 @@ fn field_mutability(d: ebml::Doc) -> ast::class_mutability { } fn variant_disr_val(d: ebml::Doc) -> Option { - do option::chain(&ebml::maybe_get_doc(d, tag_disr_val)) |val_doc| { + do option::chain(ebml::maybe_get_doc(d, tag_disr_val)) |val_doc| { int::parse_bytes(ebml::doc_data(val_doc), 10u) } } @@ -227,7 +227,7 @@ fn item_type(item_id: ast::def_id, item: ebml::Doc, fn item_impl_traits(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ~[ty::t] { let mut results = ~[]; for ebml::tagged_docs(item, tag_impl_trait) |ity| { - vec::push(results, doc_type(ity, tcx, cdata)); + results.push(doc_type(ity, tcx, cdata)); }; results } @@ -239,14 +239,14 @@ fn item_ty_param_bounds(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd) let bd = parse_bounds_data(p.data, p.start, cdata.cnum, tcx, |did| { translate_def_id(cdata, did) }); - vec::push(bounds, bd); + bounds.push(bd); } @bounds } fn item_ty_region_param(item: ebml::Doc) -> Option { ebml::maybe_get_doc(item, tag_region_param).map(|doc| { - let d = ebml::ebml_deserializer(doc); + let d = ebml::ebml_deserializer(*doc); ty::deserialize_region_variance(d) }) } @@ -263,12 +263,12 @@ fn enum_variant_ids(item: ebml::Doc, cdata: cmd) -> ~[ast::def_id] { let v = tag_items_data_item_variant; for ebml::tagged_docs(item, v) |p| { let ext = ebml::with_doc_data(p, |d| parse_def_id(d)); - vec::push(ids, {crate: cdata.cnum, node: ext.node}); + ids.push({crate: cdata.cnum, node: ext.node}); }; return ids; } -fn item_path(intr: ident_interner, item_doc: ebml::Doc) -> ast_map::path { +fn item_path(intr: @ident_interner, item_doc: ebml::Doc) -> ast_map::path { let path_doc = ebml::get_doc(item_doc, tag_path); let len_doc = ebml::get_doc(path_doc, tag_path_len); @@ -278,10 +278,10 @@ fn item_path(intr: ident_interner, item_doc: ebml::Doc) -> ast_map::path { for ebml::docs(path_doc) |tag, elt_doc| { if tag == tag_path_elt_mod { let str = ebml::doc_as_str(elt_doc); - vec::push(result, ast_map::path_mod(intr.intern(@str))); + result.push(ast_map::path_mod(intr.intern(@str))); } else if tag == tag_path_elt_name { let str = ebml::doc_as_str(elt_doc); - vec::push(result, ast_map::path_name(intr.intern(@str))); + result.push(ast_map::path_name(intr.intern(@str))); } else { // ignore tag_path_len element } @@ -290,7 +290,7 @@ fn item_path(intr: ident_interner, item_doc: ebml::Doc) -> ast_map::path { return result; } -fn item_name(intr: ident_interner, item: ebml::Doc) -> ast::ident { +fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident { let name = ebml::get_doc(item, tag_paths_data_name); intr.intern(@str::from_bytes(ebml::doc_data(name))) } @@ -365,7 +365,7 @@ fn get_impl_traits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> ~[ty::t] { item_impl_traits(lookup_item(id, cdata.data), tcx, cdata) } -fn get_impl_method(intr: ident_interner, cdata: cmd, id: ast::node_id, +fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, name: ast::ident) -> ast::def_id { let items = ebml::get_doc(ebml::Doc(cdata.data), tag_items); let mut found = None; @@ -378,7 +378,7 @@ fn get_impl_method(intr: ident_interner, cdata: cmd, id: ast::node_id, found.get() } -fn get_class_method(intr: ident_interner, cdata: cmd, id: ast::node_id, +fn get_class_method(intr: @ident_interner, cdata: cmd, id: ast::node_id, name: ast::ident) -> ast::def_id { let items = ebml::get_doc(ebml::Doc(cdata.data), tag_items); let mut found = None; @@ -451,7 +451,7 @@ fn path_entry(path_string: ~str, def_like: def_like) -> path_entry { } /// Iterates over all the paths in the given crate. -fn each_path(intr: ident_interner, cdata: cmd, f: fn(path_entry) -> bool) { +fn each_path(intr: @ident_interner, cdata: cmd, f: fn(path_entry) -> bool) { let root = ebml::Doc(cdata.data); let items = ebml::get_doc(root, tag_items); let items_data = ebml::get_doc(items, tag_items_data); @@ -531,7 +531,7 @@ fn each_path(intr: ident_interner, cdata: cmd, f: fn(path_entry) -> bool) { } } -fn get_item_path(intr: ident_interner, cdata: cmd, id: ast::node_id) +fn get_item_path(intr: @ident_interner, cdata: cmd, id: ast::node_id) -> ast_map::path { item_path(intr, lookup_item(id, cdata.data)) } @@ -542,7 +542,7 @@ type decode_inlined_item = fn( path: ast_map::path, par_doc: ebml::Doc) -> Option; -fn maybe_get_item_ast(intr: ident_interner, cdata: cmd, tcx: ty::ctxt, +fn maybe_get_item_ast(intr: @ident_interner, cdata: cmd, tcx: ty::ctxt, id: ast::node_id, decode_inlined_item: decode_inlined_item ) -> csearch::found_ast { @@ -568,7 +568,7 @@ fn maybe_get_item_ast(intr: ident_interner, cdata: cmd, tcx: ty::ctxt, } } -fn get_enum_variants(intr: ident_interner, cdata: cmd, id: ast::node_id, +fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> ~[ty::variant_info] { let data = cdata.data; let items = ebml::get_doc(ebml::Doc(data), tag_items); @@ -584,7 +584,7 @@ fn get_enum_variants(intr: ident_interner, cdata: cmd, id: ast::node_id, let mut arg_tys: ~[ty::t] = ~[]; match ty::get(ctor_ty).sty { ty::ty_fn(f) => { - for f.sig.inputs.each |a| { vec::push(arg_tys, a.ty); } + for f.sig.inputs.each |a| { arg_tys.push(a.ty); } } _ => { /* Nullary enum variant. */ } } @@ -592,7 +592,7 @@ fn get_enum_variants(intr: ident_interner, cdata: cmd, id: ast::node_id, Some(val) => { disr_val = val; } _ => { /* empty */ } } - vec::push(infos, @{args: arg_tys, ctor_ty: ctor_ty, name: name, + infos.push(@{args: arg_tys, ctor_ty: ctor_ty, name: name, id: *did, disr_val: disr_val}); disr_val += 1; } @@ -638,14 +638,14 @@ fn get_self_ty(item: ebml::Doc) -> ast::self_ty_ { } } -fn item_impl_methods(intr: ident_interner, cdata: cmd, item: ebml::Doc, +fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc, base_tps: uint) -> ~[@method_info] { let mut rslt = ~[]; for ebml::tagged_docs(item, tag_item_impl_method) |doc| { let m_did = ebml::with_doc_data(doc, |d| parse_def_id(d)); let mth_item = lookup_item(m_did.node, cdata.data); let self_ty = get_self_ty(mth_item); - vec::push(rslt, @{did: translate_def_id(cdata, m_did), + rslt.push(@{did: translate_def_id(cdata, m_did), /* FIXME (maybe #2323) tjc: take a look at this. */ n_tps: item_ty_param_count(mth_item) - base_tps, ident: item_name(intr, mth_item), @@ -654,7 +654,7 @@ fn item_impl_methods(intr: ident_interner, cdata: cmd, item: ebml::Doc, rslt } -fn get_impls_for_mod(intr: ident_interner, cdata: cmd, +fn get_impls_for_mod(intr: @ident_interner, cdata: cmd, m_id: ast::node_id, name: Option, get_cdata: fn(ast::crate_num) -> cmd) -> @~[@_impl] { @@ -675,7 +675,7 @@ fn get_impls_for_mod(intr: ident_interner, cdata: cmd, let nm = item_name(intr, item); if match name { Some(n) => { n == nm } None => { true } } { let base_tps = item_ty_param_count(item); - vec::push(result, @{ + result.push(@{ did: local_did, ident: nm, methods: item_impl_methods(intr, impl_cdata, item, base_tps) }); @@ -685,7 +685,7 @@ fn get_impls_for_mod(intr: ident_interner, cdata: cmd, } /* Works for both classes and traits */ -fn get_trait_methods(intr: ident_interner, cdata: cmd, id: ast::node_id, +fn get_trait_methods(intr: @ident_interner, cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> @~[ty::method] { let data = cdata.data; let item = lookup_item(id, data); @@ -701,7 +701,7 @@ fn get_trait_methods(intr: ident_interner, cdata: cmd, id: ast::node_id, ~"get_trait_methods: id has non-function type"); } }; let self_ty = get_self_ty(mth); - vec::push(result, {ident: name, tps: bounds, fty: fty, + result.push({ident: name, tps: bounds, fty: fty, self_ty: self_ty, vis: ast::public}); } @@ -712,7 +712,7 @@ fn get_trait_methods(intr: ident_interner, cdata: cmd, id: ast::node_id, // If the item in question is a trait, returns its set of methods and // their self types. Otherwise, returns none. This overlaps in an // annoying way with get_trait_methods. -fn get_method_names_if_trait(intr: ident_interner, cdata: cmd, +fn get_method_names_if_trait(intr: @ident_interner, cdata: cmd, node_id: ast::node_id) -> Option<@DVec<(ast::ident, ast::self_ty_)>> { @@ -742,7 +742,7 @@ fn get_item_attrs(cdata: cmd, } // Helper function that gets either fields or methods -fn get_class_members(intr: ident_interner, cdata: cmd, id: ast::node_id, +fn get_class_members(intr: @ident_interner, cdata: cmd, id: ast::node_id, p: fn(Family) -> bool) -> ~[ty::field_ty] { let data = cdata.data; let item = lookup_item(id, data); @@ -753,7 +753,7 @@ fn get_class_members(intr: ident_interner, cdata: cmd, id: ast::node_id, let name = item_name(intr, an_item); let did = item_def_id(an_item, cdata); let mt = field_mutability(an_item); - vec::push(result, {ident: name, id: did, vis: + result.push({ident: name, id: did, vis: family_to_visibility(f), mutability: mt}); } } @@ -769,7 +769,7 @@ pure fn family_to_visibility(family: Family) -> ast::visibility { } } -fn get_class_fields(intr: ident_interner, cdata: cmd, id: ast::node_id) +fn get_class_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id) -> ~[ty::field_ty] { get_class_members(intr, cdata, id, |f| f == PublicField || f == PrivateField || f == InheritedField) @@ -835,7 +835,7 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { for ebml::tagged_docs(md, tag_meta_item_word) |meta_item_doc| { let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); let n = str::from_bytes(ebml::doc_data(nd)); - vec::push(items, attr::mk_word_item(n)); + items.push(attr::mk_word_item(n)); }; for ebml::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| { let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); @@ -844,13 +844,13 @@ fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] { let v = str::from_bytes(ebml::doc_data(vd)); // FIXME (#623): Should be able to decode meta_name_value variants, // but currently the encoder just drops them - vec::push(items, attr::mk_name_value_item_str(n, v)); + items.push(attr::mk_name_value_item_str(n, v)); }; for ebml::tagged_docs(md, tag_meta_item_list) |meta_item_doc| { let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name); let n = str::from_bytes(ebml::doc_data(nd)); let subitems = get_meta_items(meta_item_doc); - vec::push(items, attr::mk_list_item(n, subitems)); + items.push(attr::mk_list_item(n, subitems)); }; return items; } @@ -865,10 +865,10 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] { // an attribute assert (vec::len(meta_items) == 1u); let meta_item = meta_items[0]; - vec::push(attrs, - {node: {style: ast::attr_outer, value: *meta_item, - is_sugared_doc: false}, - span: ast_util::dummy_sp()}); + attrs.push( + {node: {style: ast::attr_outer, value: *meta_item, + is_sugared_doc: false}, + span: ast_util::dummy_sp()}); }; } option::None => () @@ -876,14 +876,14 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] { return attrs; } -fn list_meta_items(intr: ident_interner, +fn list_meta_items(intr: @ident_interner, meta_items: ebml::Doc, out: io::Writer) { for get_meta_items(meta_items).each |mi| { out.write_str(fmt!("%s\n", pprust::meta_item_to_str(*mi, intr))); } } -fn list_crate_attributes(intr: ident_interner, md: ebml::Doc, hash: ~str, +fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: ~str, out: io::Writer) { out.write_str(fmt!("=Crate Attributes (%s)=\n", hash)); @@ -901,7 +901,7 @@ fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] { type crate_dep = {cnum: ast::crate_num, name: ast::ident, vers: ~str, hash: ~str}; -fn get_crate_deps(intr: ident_interner, data: @~[u8]) -> ~[crate_dep] { +fn get_crate_deps(intr: @ident_interner, data: @~[u8]) -> ~[crate_dep] { let mut deps: ~[crate_dep] = ~[]; let cratedoc = ebml::Doc(data); let depsdoc = ebml::get_doc(cratedoc, tag_crate_deps); @@ -910,7 +910,7 @@ fn get_crate_deps(intr: ident_interner, data: @~[u8]) -> ~[crate_dep] { str::from_bytes(ebml::doc_data(ebml::get_doc(doc, tag_))) } for ebml::tagged_docs(depsdoc, tag_crate_dep) |depdoc| { - vec::push(deps, {cnum: crate_num, + deps.push({cnum: crate_num, name: intr.intern(@docstr(depdoc, tag_crate_dep_name)), vers: docstr(depdoc, tag_crate_dep_vers), hash: docstr(depdoc, tag_crate_dep_hash)}); @@ -919,7 +919,7 @@ fn get_crate_deps(intr: ident_interner, data: @~[u8]) -> ~[crate_dep] { return deps; } -fn list_crate_deps(intr: ident_interner, data: @~[u8], out: io::Writer) { +fn list_crate_deps(intr: @ident_interner, data: @~[u8], out: io::Writer) { out.write_str(~"=External Dependencies=\n"); for get_crate_deps(intr, data).each |dep| { @@ -946,7 +946,7 @@ fn get_crate_vers(data: @~[u8]) -> ~str { }; } -fn iter_crate_items(intr: ident_interner, +fn iter_crate_items(intr: @ident_interner, cdata: cmd, proc: fn(~str, ast::def_id)) { for each_path(intr, cdata) |path_entry| { match path_entry.def_like { @@ -958,7 +958,7 @@ fn iter_crate_items(intr: ident_interner, } } -fn get_crate_module_paths(intr: ident_interner, cdata: cmd) +fn get_crate_module_paths(intr: @ident_interner, cdata: cmd) -> ~[(ast::def_id, ~str)] { fn mod_of_path(p: ~str) -> ~str { str::connect(vec::init(str::split_str(p, ~"::")), ~"::") @@ -967,7 +967,7 @@ fn get_crate_module_paths(intr: ident_interner, cdata: cmd) // find all module (path, def_ids), which are not // fowarded path due to renamed import or reexport let mut res = ~[]; - let mods = map::HashMap::<~str,bool>(); + let mods = map::HashMap(); do iter_crate_items(intr, cdata) |path, did| { let m = mod_of_path(path); if str::is_not_empty(m) { @@ -977,15 +977,15 @@ fn get_crate_module_paths(intr: ident_interner, cdata: cmd) // Collect everything by now. There might be multiple // paths pointing to the same did. Those will be // unified later by using the mods map - vec::push(res, (did, path)); + res.push((did, path)); } return do vec::filter(res) |x| { - let (_, xp) = x; + let (_, xp) = *x; mods.contains_key(xp) } } -fn list_crate_metadata(intr: ident_interner, bytes: @~[u8], +fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8], out: io::Writer) { let hash = get_crate_hash(bytes); let md = ebml::Doc(bytes); diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 8da5fa0aee20..17d686b41d1a 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -118,12 +118,12 @@ type entry = {val: T, pos: uint}; fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: &[ident], &index: ~[entry<~str>], name: ident) { let mut full_path = ~[]; - vec::push_all(full_path, path); - vec::push(full_path, name); - vec::push(index, - {val: ast_util::path_name_i(full_path, - ecx.tcx.sess.parse_sess.interner), - pos: ebml_w.writer.tell()}); + full_path.push_all(path); + full_path.push(name); + index.push( + {val: ast_util::path_name_i(full_path, + ecx.tcx.sess.parse_sess.interner), + pos: ebml_w.writer.tell()}); } fn encode_trait_ref(ebml_w: ebml::Writer, ecx: @encode_ctxt, t: @trait_ref) { @@ -225,7 +225,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::Writer, let mut i = 0; let vi = ty::enum_variants(ecx.tcx, {crate: local_crate, node: id}); for variants.each |variant| { - vec::push(*index, {val: variant.node.id, pos: ebml_w.writer.tell()}); + index.push({val: variant.node.id, pos: ebml_w.writer.tell()}); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(variant.node.id)); encode_family(ebml_w, 'v'); @@ -390,9 +390,9 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::Writer, match field.node.kind { named_field(nm, mt, vis) => { let id = field.node.id; - vec::push(*index, {val: id, pos: ebml_w.writer.tell()}); - vec::push(*global_index, {val: id, - pos: ebml_w.writer.tell()}); + index.push({val: id, pos: ebml_w.writer.tell()}); + global_index.push({val: id, + pos: ebml_w.writer.tell()}); ebml_w.start_tag(tag_items_data_item); debug!("encode_info_for_class: doing %s %d", tcx.sess.str_of(nm), id); @@ -411,9 +411,9 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::Writer, for methods.each |m| { match m.vis { public | inherited => { - vec::push(*index, {val: m.id, pos: ebml_w.writer.tell()}); - vec::push(*global_index, - {val: m.id, pos: ebml_w.writer.tell()}); + index.push({val: m.id, pos: ebml_w.writer.tell()}); + global_index.push( + {val: m.id, pos: ebml_w.writer.tell()}); let impl_path = vec::append_one(path, ast_map::path_name(m.ident)); debug!("encode_info_for_class: doing %s %d", @@ -519,7 +519,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item, fn add_to_index_(item: @item, ebml_w: ebml::Writer, index: @mut ~[entry]) { - vec::push(*index, {val: item.id, pos: ebml_w.writer.tell()}); + index.push({val: item.id, pos: ebml_w.writer.tell()}); } let add_to_index = |copy ebml_w| add_to_index_(item, ebml_w, index); @@ -603,13 +603,13 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item, index); /* Encode the dtor */ do struct_def.dtor.iter |dtor| { - vec::push(*index, {val: dtor.node.id, pos: ebml_w.writer.tell()}); + index.push({val: dtor.node.id, pos: ebml_w.writer.tell()}); encode_info_for_ctor(ecx, ebml_w, dtor.node.id, ecx.tcx.sess.ident_of( ecx.tcx.sess.str_of(item.ident) + ~"_dtor"), path, if tps.len() > 0u { - Some(ii_dtor(dtor, item.ident, tps, + Some(ii_dtor(*dtor, item.ident, tps, local_def(item.id))) } else { None }, tps); } @@ -688,7 +688,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item, for struct_def.ctor.each |ctor| { debug!("encoding info for ctor %s %d", ecx.tcx.sess.str_of(item.ident), ctor.node.id); - vec::push(*index, { + index.push({ val: ctor.node.id, pos: ebml_w.writer.tell() }); @@ -715,7 +715,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item, ebml_w.end_tag(); } do opt_trait.iter() |associated_trait| { - encode_trait_ref(ebml_w, ecx, associated_trait) + encode_trait_ref(ebml_w, ecx, *associated_trait) } encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); ebml_w.end_tag(); @@ -723,7 +723,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item, let impl_path = vec::append_one(path, ast_map::path_name(item.ident)); for methods.each |m| { - vec::push(*index, {val: m.id, pos: ebml_w.writer.tell()}); + index.push({val: m.id, pos: ebml_w.writer.tell()}); encode_info_for_method(ecx, ebml_w, impl_path, should_inline(m.attrs), item.id, *m, vec::append(tps, m.tps)); @@ -774,7 +774,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item, let ty_m = ast_util::trait_method_to_ty_method(*m); if ty_m.self_ty.node != ast::sty_static { loop; } - vec::push(*index, {val: ty_m.id, pos: ebml_w.writer.tell()}); + index.push({val: ty_m.id, pos: ebml_w.writer.tell()}); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(ty_m.id)); @@ -799,7 +799,7 @@ fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, index: @mut ~[entry], path: ast_map::path, abi: foreign_abi) { if !reachable(ecx, nitem.id) { return; } - vec::push(*index, {val: nitem.id, pos: ebml_w.writer.tell()}); + index.push({val: nitem.id, pos: ebml_w.writer.tell()}); ebml_w.start_tag(tag_items_data_item); match nitem.node { @@ -831,7 +831,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::Writer, crate: @crate) -> ~[entry] { let index = @mut ~[]; ebml_w.start_tag(tag_items_data); - vec::push(*index, {val: crate_node_id, pos: ebml_w.writer.tell()}); + index.push({val: crate_node_id, pos: ebml_w.writer.tell()}); encode_info_for_mod(ecx, ebml_w, crate.node.module, crate_node_id, ~[], syntax::parse::token::special_idents::invalid); @@ -869,15 +869,15 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::Writer, fn create_index(index: ~[entry]) -> ~[@~[entry]] { let mut buckets: ~[@mut ~[entry]] = ~[]; - for uint::range(0u, 256u) |_i| { vec::push(buckets, @mut ~[]); }; + for uint::range(0u, 256u) |_i| { buckets.push(@mut ~[]); }; for index.each |elt| { let h = elt.val.hash() as uint; - vec::push(*buckets[h % 256], *elt); + buckets[h % 256].push(*elt); } let mut buckets_frozen = ~[]; for buckets.each |bucket| { - vec::push(buckets_frozen, @**bucket); + buckets_frozen.push(@**bucket); } return buckets_frozen; } @@ -889,7 +889,7 @@ fn encode_index(ebml_w: ebml::Writer, buckets: ~[@~[entry]], let mut bucket_locs: ~[uint] = ~[]; ebml_w.start_tag(tag_index_buckets); for buckets.each |bucket| { - vec::push(bucket_locs, ebml_w.writer.tell()); + bucket_locs.push(ebml_w.writer.tell()); ebml_w.start_tag(tag_index_buckets_bucket); for vec::each(**bucket) |elt| { ebml_w.start_tag(tag_index_buckets_bucket_elt); @@ -996,8 +996,7 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] { let mut attrs: ~[attribute] = ~[]; let mut found_link_attr = false; for crate.node.attrs.each |attr| { - vec::push( - attrs, + attrs.push( if attr::get_attr_name(*attr) != ~"link" { *attr } else { @@ -1011,7 +1010,7 @@ fn synthesize_crate_attrs(ecx: @encode_ctxt, crate: @crate) -> ~[attribute] { }); } - if !found_link_attr { vec::push(attrs, synthesize_link_attr(ecx, ~[])); } + if !found_link_attr { attrs.push(synthesize_link_attr(ecx, ~[])); } return attrs; } @@ -1031,7 +1030,7 @@ fn encode_crate_deps(ecx: @encode_ctxt, ebml_w: ebml::Writer, let dep = {cnum: key, name: ecx.tcx.sess.ident_of(val.name), vers: decoder::get_crate_vers(val.data), hash: decoder::get_crate_hash(val.data)}; - vec::push(deps, dep); + deps.push(dep); }; // Sort by cnum @@ -1176,7 +1175,7 @@ fn encode_metadata(parms: encode_parms, crate: @crate) -> ~[u8] { // vec::from_slice(metadata_encoding_version) + (do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| { - vec::slice(bytes, 0, 8) + vec::slice(*bytes, 0, 8) }) + flate::deflate_bytes(wr.buf.check_out(|buf| buf)) } diff --git a/src/rustc/metadata/filesearch.rs b/src/rustc/metadata/filesearch.rs index 77d06bd2d29e..63370b093210 100644 --- a/src/rustc/metadata/filesearch.rs +++ b/src/rustc/metadata/filesearch.rs @@ -39,15 +39,15 @@ fn mk_filesearch(maybe_sysroot: Option, fn lib_search_paths() -> ~[Path] { let mut paths = self.addl_lib_search_paths; - vec::push(paths, - make_target_lib_path(&self.sysroot, - self.target_triple)); + paths.push( + make_target_lib_path(&self.sysroot, + self.target_triple)); match get_cargo_lib_path_nearest() { - result::Ok(p) => vec::push(paths, p), + result::Ok(p) => paths.push(p), result::Err(_) => () } match get_cargo_lib_path() { - result::Ok(p) => vec::push(paths, p), + result::Ok(p) => paths.push(p), result::Err(_) => () } paths diff --git a/src/rustc/metadata/loader.rs b/src/rustc/metadata/loader.rs index e11793a36d01..0a8354be71f7 100644 --- a/src/rustc/metadata/loader.rs +++ b/src/rustc/metadata/loader.rs @@ -35,7 +35,7 @@ type ctxt = { hash: ~str, os: os, static: bool, - intr: ident_interner + intr: @ident_interner }; fn load_library_crate(cx: ctxt) -> {ident: ~str, data: @~[u8]} { @@ -90,7 +90,7 @@ fn find_library_crate_aux(cx: ctxt, option::None::<()> } else { debug!("found %s with matching metadata", path.to_str()); - vec::push(matches, {ident: path.to_str(), data: cvec}); + matches.push({ident: path.to_str(), data: cvec}); option::None::<()> } } @@ -135,7 +135,7 @@ fn crate_name_from_metas(metas: ~[@ast::meta_item]) -> ~str { } } -fn note_linkage_attrs(intr: ident_interner, diag: span_handler, +fn note_linkage_attrs(intr: @ident_interner, diag: span_handler, attrs: ~[ast::attribute]) { for attr::find_linkage_metas(attrs).each |mi| { diag.handler().note(fmt!("meta: %s", @@ -193,7 +193,7 @@ fn get_metadata_section(os: os, vlen); let minsz = uint::min(vlen, csz); let mut version_ok = false; - do vec::raw::form_slice(cvbuf, minsz) |buf0| { + do vec::raw::buf_as_slice(cvbuf, minsz) |buf0| { version_ok = (buf0 == encoder::metadata_encoding_version); } @@ -202,7 +202,7 @@ fn get_metadata_section(os: os, let cvbuf1 = ptr::offset(cvbuf, vlen); debug!("inflating %u bytes of compressed metadata", csz - vlen); - do vec::raw::form_slice(cvbuf1, csz-vlen) |bytes| { + do vec::raw::buf_as_slice(cvbuf1, csz-vlen) |bytes| { let inflated = flate::inflate_bytes(bytes); found = move Some(@(move inflated)); } @@ -226,7 +226,7 @@ fn meta_section_name(os: os) -> ~str { } // A diagnostic function for dumping crate metadata to an output stream -fn list_file_metadata(intr: ident_interner, +fn list_file_metadata(intr: @ident_interner, os: os, path: &Path, out: io::Writer) { match get_metadata_section(os, path) { option::Some(bytes) => decoder::list_crate_metadata(intr, bytes, out), diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs index 5cf24aef558e..f3fa0e3f3507 100644 --- a/src/rustc/metadata/tydecode.rs +++ b/src/rustc/metadata/tydecode.rs @@ -84,7 +84,7 @@ fn parse_ret_ty(st: @pstate, conv: conv_did) -> (ast::ret_style, ty::t) { fn parse_path(st: @pstate) -> @ast::path { let mut idents: ~[ast::ident] = ~[]; fn is_last(c: char) -> bool { return c == '(' || c == ':'; } - vec::push(idents, parse_ident_(st, is_last)); + idents.push(parse_ident_(st, is_last)); loop { match peek(st) { ':' => { next(st); next(st); } @@ -93,7 +93,7 @@ fn parse_path(st: @pstate) -> @ast::path { return @{span: ast_util::dummy_sp(), global: false, idents: idents, rp: None, types: ~[]}; - } else { vec::push(idents, parse_ident_(st, is_last)); } + } else { idents.push(parse_ident_(st, is_last)); } } } }; @@ -136,7 +136,7 @@ fn parse_substs(st: @pstate, conv: conv_did) -> ty::substs { assert next(st) == '['; let mut params: ~[ty::t] = ~[]; - while peek(st) != ']' { vec::push(params, parse_ty(st, conv)); } + while peek(st) != ']' { params.push(parse_ty(st, conv)); } st.pos = st.pos + 1u; return {self_r: self_r, @@ -273,7 +273,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { let mut fields: ~[ty::field] = ~[]; while peek(st) != ']' { let name = st.tcx.sess.ident_of(parse_str(st, '=')); - vec::push(fields, {ident: name, mt: parse_mt(st, conv)}); + fields.push({ident: name, mt: parse_mt(st, conv)}); } st.pos = st.pos + 1u; return ty::mk_rec(st.tcx, fields); @@ -281,7 +281,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { 'T' => { assert (next(st) == '['); let mut params = ~[]; - while peek(st) != ']' { vec::push(params, parse_ty(st, conv)); } + while peek(st) != ']' { params.push(parse_ty(st, conv)); } st.pos = st.pos + 1u; return ty::mk_tup(st.tcx, params); } @@ -348,7 +348,7 @@ fn parse_mt(st: @pstate, conv: conv_did) -> ty::mt { fn parse_def(st: @pstate, conv: conv_did) -> ast::def_id { let mut def = ~[]; - while peek(st) != '|' { vec::push(def, next_byte(st)); } + while peek(st) != '|' { def.push(next_byte(st)); } st.pos = st.pos + 1u; return conv(parse_def_id(def)); } @@ -412,7 +412,7 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy { let mut inputs: ~[ty::arg] = ~[]; while peek(st) != ']' { let mode = parse_mode(st); - vec::push(inputs, {mode: mode, ty: parse_ty(st, conv)}); + inputs.push({mode: mode, ty: parse_ty(st, conv)}); } st.pos += 1u; // eat the ']' let (ret_style, ret_ty) = parse_ret_ty(st, conv); @@ -464,7 +464,7 @@ fn parse_bounds_data(data: @~[u8], start: uint, fn parse_bounds(st: @pstate, conv: conv_did) -> @~[ty::param_bound] { let mut bounds = ~[]; loop { - vec::push(bounds, match next(st) { + bounds.push(match next(st) { 'S' => ty::bound_send, 'C' => ty::bound_copy, 'K' => ty::bound_const, diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index acb7bb1bf2c3..29368ae95b80 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -723,7 +723,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_def) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - ast::serialize_def(ebml_w, def) + ast::serialize_def(ebml_w, *def) } } } @@ -731,7 +731,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_node_type) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - ebml_w.emit_ty(ecx, ty); + ebml_w.emit_ty(ecx, *ty); } } } @@ -740,7 +740,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_node_type_subst) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - ebml_w.emit_tys(ecx, tys) + ebml_w.emit_tys(ecx, *tys) } } } @@ -749,7 +749,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_freevars) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - do ebml_w.emit_from_vec(*fv) |fv_entry| { + do ebml_w.emit_from_vec(**fv) |fv_entry| { encode_freevar_entry(ebml_w, *fv_entry) } } @@ -761,7 +761,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_tcache) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - ebml_w.emit_tpbt(ecx, tpbt); + ebml_w.emit_tpbt(ecx, *tpbt); } } } @@ -770,7 +770,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_param_bounds) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - ebml_w.emit_bounds(ecx, pbs) + ebml_w.emit_bounds(ecx, *pbs) } } } @@ -810,7 +810,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_method_map) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - serialize_method_map_entry(ecx, ebml_w, mme) + serialize_method_map_entry(ecx, ebml_w, *mme) } } } @@ -819,7 +819,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_vtable_map) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - encode_vtable_res(ecx, ebml_w, dr); + encode_vtable_res(ecx, ebml_w, *dr); } } } @@ -828,10 +828,16 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt, do ebml_w.tag(c::tag_table_adjustments) { ebml_w.id(id); do ebml_w.tag(c::tag_table_val) { - ty::serialize_AutoAdjustment(ebml_w, *adj) + ty::serialize_AutoAdjustment(ebml_w, **adj) } } } + + do option::iter(&tcx.legacy_boxed_traits.find(id)) |_x| { + do ebml_w.tag(c::tag_table_legacy_boxed_trait) { + ebml_w.id(id); + } + } } trait doc_decoder_helpers { @@ -923,6 +929,8 @@ fn decode_side_tables(xcx: extended_decode_ctxt, if tag == (c::tag_table_mutbl as uint) { dcx.maps.mutbl_map.insert(id, ()); + } else if tag == (c::tag_table_legacy_boxed_trait as uint) { + dcx.tcx.legacy_boxed_traits.insert(id, ()); } else { let val_doc = entry_doc[c::tag_table_val as uint]; let val_dsr = ebml::ebml_deserializer(val_doc); diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs index 4906eb4a0a3a..414890cbd7c6 100644 --- a/src/rustc/middle/borrowck.rs +++ b/src/rustc/middle/borrowck.rs @@ -415,7 +415,7 @@ impl root_map_key : cmp::Eq { } impl root_map_key : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f); } } diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs index c0aaa041d189..0c79c0fcd7f3 100644 --- a/src/rustc/middle/borrowck/check_loans.rs +++ b/src/rustc/middle/borrowck/check_loans.rs @@ -183,7 +183,7 @@ impl check_loan_ctxt { debug!("check_pure_callee_or_arg(pc=%?, expr=%?, \ callee_id=%d, ty=%s)", pc, - opt_expr.map(|e| pprust::expr_to_str(e, tcx.sess.intr()) ), + opt_expr.map(|e| pprust::expr_to_str(*e, tcx.sess.intr()) ), callee_id, ty_to_str(self.tcx(), ty::node_id_to_type(tcx, callee_id))); @@ -204,7 +204,7 @@ impl check_loan_ctxt { let did = ast_util::def_id_of_def(def); let is_fn_arg = did.crate == ast::local_crate && - (*self.fn_args).contains(did.node); + (*self.fn_args).contains(&(did.node)); if is_fn_arg { return; } // case (a) above } ast::expr_fn_block(*) | ast::expr_fn(*) | @@ -251,7 +251,7 @@ impl check_loan_ctxt { let def = self.tcx().def_map.get(expr.id); let did = ast_util::def_id_of_def(def); did.crate == ast::local_crate && - (*self.fn_args).contains(did.node) + (*self.fn_args).contains(&(did.node)) } ast::expr_fn_block(*) | ast::expr_fn(*) => { self.is_stack_closure(expr.id) @@ -524,10 +524,10 @@ impl check_loan_ctxt { let arg_tys = ty::ty_fn_args( ty::node_id_to_type(self.tcx(), callee_id)); - do vec::iter2(args, arg_tys) |arg, arg_ty| { + for vec::each2(args, arg_tys) |arg, arg_ty| { match ty::resolved_mode(self.tcx(), arg_ty.mode) { ast::by_move => { - self.check_move_out(arg); + self.check_move_out(*arg); } ast::by_mutbl_ref | ast::by_ref | ast::by_copy | ast::by_val => { diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs index b3f846d47fdb..327db51518be 100644 --- a/src/rustc/middle/borrowck/gather_loans.rs +++ b/src/rustc/middle/borrowck/gather_loans.rs @@ -113,14 +113,14 @@ fn req_loans_in_expr(ex: @ast::expr, ast::expr_call(f, args, _) => { let arg_tys = ty::ty_fn_args(ty::expr_ty(self.tcx(), f)); let scope_r = ty::re_scope(ex.id); - do vec::iter2(args, arg_tys) |arg, arg_ty| { + for vec::each2(args, arg_tys) |arg, arg_ty| { match ty::resolved_mode(self.tcx(), arg_ty.mode) { ast::by_mutbl_ref => { - let arg_cmt = self.bccx.cat_expr(arg); + let arg_cmt = self.bccx.cat_expr(*arg); self.guarantee_valid(arg_cmt, m_mutbl, scope_r); } ast::by_ref => { - let arg_cmt = self.bccx.cat_expr(arg); + let arg_cmt = self.bccx.cat_expr(*arg); self.guarantee_valid(arg_cmt, m_imm, scope_r); } ast::by_val => { diff --git a/src/rustc/middle/capture.rs b/src/rustc/middle/capture.rs index 1e8856051715..618d43e121a3 100644 --- a/src/rustc/middle/capture.rs +++ b/src/rustc/middle/capture.rs @@ -122,6 +122,6 @@ fn compute_capture_vars(tcx: ty::ctxt, } let mut result = ~[]; - for cap_map.each_value |cap_var| { vec::push(result, cap_var); } + for cap_map.each_value |cap_var| { result.push(cap_var); } return result; } diff --git a/src/rustc/middle/check_alt.rs b/src/rustc/middle/check_alt.rs index 0d8d8b8dfe09..f71b82a2be7e 100644 --- a/src/rustc/middle/check_alt.rs +++ b/src/rustc/middle/check_alt.rs @@ -67,7 +67,7 @@ fn check_arms(tcx: ty::ctxt, arms: ~[arm]) { } _ => () } - if arm.guard.is_none() { vec::push(seen, v); } + if arm.guard.is_none() { seen.push(v); } } } } @@ -195,7 +195,7 @@ fn is_useful(tcx: ty::ctxt, m: matrix, v: ~[@pat]) -> useful { } } Some(ctor) => { - match is_useful(tcx, vec::filter_map(m, |r| default(tcx, r) ), + match is_useful(tcx, vec::filter_map(m, |r| default(tcx, *r) ), vec::tail(v)) { useful_ => useful(left_ty, ctor), u => u @@ -212,7 +212,7 @@ fn is_useful(tcx: ty::ctxt, m: matrix, v: ~[@pat]) -> useful { fn is_useful_specialized(tcx: ty::ctxt, m: matrix, v: ~[@pat], ctor: ctor, arity: uint, lty: ty::t) -> useful { - let ms = vec::filter_map(m, |r| specialize(tcx, r, ctor, arity, lty) ); + let ms = vec::filter_map(m, |r| specialize(tcx, *r, ctor, arity, lty) ); let could_be_useful = is_useful( tcx, ms, specialize(tcx, v, ctor, arity, lty).get()); match could_be_useful { @@ -269,13 +269,15 @@ fn missing_ctor(tcx: ty::ctxt, m: matrix, left_ty: ty::t) -> Option { let mut found = ~[]; for m.each |r| { do option::iter(&pat_ctor_id(tcx, r[0])) |id| { - if !vec::contains(found, id) { vec::push(found, id); } + if !vec::contains(found, id) { + found.push(*id); + } } } let variants = ty::enum_variants(tcx, eid); if found.len() != (*variants).len() { for vec::each(*variants) |v| { - if !found.contains(variant(v.id)) { + if !found.contains(&(variant(v.id))) { return Some(variant(v.id)); } } @@ -430,7 +432,7 @@ fn check_local(tcx: ty::ctxt, loc: @local, &&s: (), v: visit::vt<()>) { } } -fn is_refutable(tcx: ty::ctxt, pat: @pat) -> bool { +fn is_refutable(tcx: ty::ctxt, pat: &pat) -> bool { match tcx.def_map.find(pat.id) { Some(def_variant(enum_id, _)) => { if vec::len(*ty::enum_variants(tcx, enum_id)) != 1u { @@ -455,10 +457,10 @@ fn is_refutable(tcx: ty::ctxt, pat: @pat) -> bool { fields.any(|f| is_refutable(tcx, f.pat)) } pat_tup(elts) => { - elts.any(|elt| is_refutable(tcx, elt)) + elts.any(|elt| is_refutable(tcx, *elt)) } pat_enum(_, Some(args)) => { - args.any(|a| is_refutable(tcx, a)) + args.any(|a| is_refutable(tcx, *a)) } pat_enum(_,_) => { false } } diff --git a/src/rustc/middle/check_const.rs b/src/rustc/middle/check_const.rs index e194a907ffda..bd3abe201349 100644 --- a/src/rustc/middle/check_const.rs +++ b/src/rustc/middle/check_const.rs @@ -28,7 +28,7 @@ fn check_item(sess: session, ast_map: ast_map::map, item_enum(enum_definition, _) => { for enum_definition.variants.each |var| { do option::iter(&var.node.disr_expr) |ex| { - v.visit_expr(ex, true, v); + v.visit_expr(*ex, true, v); } } } @@ -169,7 +169,7 @@ fn check_item_recursion(sess: session, ast_map: ast_map::map, visitor.visit_item(it, env, visitor); fn visit_item(it: @item, &&env: env, v: visit::vt) { - if (*env.idstack).contains(it.id) { + if (*env.idstack).contains(&(it.id)) { env.sess.span_fatal(env.root_it.span, ~"recursive constant"); } (*env.idstack).push(it.id); diff --git a/src/rustc/middle/const_eval.rs b/src/rustc/middle/const_eval.rs index 463bf502036a..5def18cacc31 100644 --- a/src/rustc/middle/const_eval.rs +++ b/src/rustc/middle/const_eval.rs @@ -41,7 +41,7 @@ enum constness { } fn join(a: constness, b: constness) -> constness { - match (a,b) { + match (a, b) { (integral_const, integral_const) => integral_const, (integral_const, general_const) | (general_const, integral_const) @@ -51,7 +51,7 @@ fn join(a: constness, b: constness) -> constness { } fn join_all(cs: &[constness]) -> constness { - vec::foldl(integral_const, cs, join) + vec::foldl(integral_const, cs, |a, b| join(a, *b)) } fn classify(e: @expr, diff --git a/src/rustc/middle/freevars.rs b/src/rustc/middle/freevars.rs index 251ef2c89b79..7e925d7d8d84 100644 --- a/src/rustc/middle/freevars.rs +++ b/src/rustc/middle/freevars.rs @@ -63,7 +63,7 @@ fn collect_freevars(def_map: resolve::DefMap, blk: ast::blk) if i == depth { // Made it to end of loop let dnum = ast_util::def_id_of_def(def).node; if !seen.contains_key(dnum) { - vec::push(*refs, @{def:def, span:expr.span}); + refs.push(@{def:def, span:expr.span}); seen.insert(dnum, ()); } } diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs index 0f918ba92a94..9aff382775c8 100644 --- a/src/rustc/middle/kind.rs +++ b/src/rustc/middle/kind.rs @@ -42,17 +42,17 @@ fn kind_to_str(k: kind) -> ~str { let mut kinds = ~[]; if ty::kind_lteq(kind_const(), k) { - vec::push(kinds, ~"const"); + kinds.push(~"const"); } if ty::kind_can_be_copied(k) { - vec::push(kinds, ~"copy"); + kinds.push(~"copy"); } if ty::kind_can_be_sent(k) { - vec::push(kinds, ~"send"); + kinds.push(~"send"); } else if ty::kind_is_owned(k) { - vec::push(kinds, ~"owned"); + kinds.push(~"owned"); } str::connect(kinds, ~" ") @@ -199,13 +199,13 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span, let id = ast_util::def_id_of_def(fv.def).node; // skip over free variables that appear in the cap clause - if captured_vars.contains(id) { loop; } + if captured_vars.contains(&id) { loop; } // if this is the last use of the variable, then it will be // a move and not a copy let is_move = { match cx.last_use_map.find(fn_id) { - Some(vars) => (*vars).contains(id), + Some(vars) => (*vars).contains(&id), None => false } }; @@ -264,16 +264,16 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) { ~"non path/method call expr has type substs??") } }; - if vec::len(ts) != vec::len(*bounds) { + if vec::len(*ts) != vec::len(*bounds) { // Fail earlier to make debugging easier fail fmt!("Internal error: in kind::check_expr, length \ mismatch between actual and declared bounds: actual = \ %s (%u tys), declared = %? (%u tys)", - tys_to_str(cx.tcx, ts), ts.len(), + tys_to_str(cx.tcx, *ts), ts.len(), *bounds, (*bounds).len()); } - do vec::iter2(ts, *bounds) |ty, bound| { - check_bounds(cx, id_to_use, e.span, ty, bound) + for vec::each2(*ts, *bounds) |ty, bound| { + check_bounds(cx, id_to_use, e.span, *ty, *bound) } } @@ -376,8 +376,8 @@ fn check_ty(aty: @ty, cx: ctx, v: visit::vt) { do option::iter(&cx.tcx.node_type_substs.find(id)) |ts| { let did = ast_util::def_id_of_def(cx.tcx.def_map.get(id)); let bounds = ty::lookup_item_type(cx.tcx, did).bounds; - do vec::iter2(ts, *bounds) |ty, bound| { - check_bounds(cx, aty.id, aty.span, ty, bound) + for vec::each2(*ts, *bounds) |ty, bound| { + check_bounds(cx, aty.id, aty.span, *ty, *bound) } } } @@ -588,7 +588,7 @@ fn check_cast_for_escaping_regions( do ty::walk_ty(source_ty) |ty| { match ty::get(ty).sty { ty::ty_param(source_param) => { - if target_params.contains(source_param) { + if target_params.contains(&source_param) { /* case (2) */ } else { check_owned(cx.tcx, ty, source.span); /* case (3) */ diff --git a/src/rustc/middle/lang_items.rs b/src/rustc/middle/lang_items.rs index ea22e3a78097..7cb2c9eb9cf1 100644 --- a/src/rustc/middle/lang_items.rs +++ b/src/rustc/middle/lang_items.rs @@ -179,7 +179,7 @@ impl LanguageItemCollector { } fn collect_local_language_items() { - let this = unsafe { ptr::addr_of(self) }; + let this = unsafe { ptr::addr_of(&self) }; visit_crate(*self.crate, (), mk_simple_visitor(@{ visit_item: |item| { for item.attrs.each |attribute| { diff --git a/src/rustc/middle/lint.rs b/src/rustc/middle/lint.rs index a6778d83b996..0f31f2056a14 100644 --- a/src/rustc/middle/lint.rs +++ b/src/rustc/middle/lint.rs @@ -149,7 +149,7 @@ fn get_lint_dict() -> lint_dict { (~"deprecated_mode", @{lint: deprecated_mode, desc: ~"warn about deprecated uses of modes", - default: allow}), + default: warn}), (~"deprecated_pattern", @{lint: deprecated_pattern, @@ -159,7 +159,7 @@ fn get_lint_dict() -> lint_dict { (~"non_camel_case_types", @{lint: non_camel_case_types, desc: ~"types, variants and traits should have camel case names", - default: warn}), + default: allow}), (~"managed_heap_memory", @{lint: managed_heap_memory, @@ -288,7 +288,7 @@ impl ctxt { for metas.each |meta| { match meta.node { ast::meta_word(lintname) => { - vec::push(triples, (*meta, *level, lintname)); + triples.push((*meta, *level, lintname)); } _ => { self.sess.span_err( @@ -396,6 +396,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) { check_item_non_camel_case_types(cx, i); check_item_heap(cx, i); check_item_structural_records(cx, i); + check_item_deprecated_modes(cx, i); } // Take a visitor, and modify it so that it will not proceed past subitems. @@ -666,43 +667,114 @@ fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl, } let fn_ty = ty::node_id_to_type(tcx, id); + check_fn_deprecated_modes(tcx, fn_ty, decl, span, id); +} + +fn check_fn_deprecated_modes(tcx: ty::ctxt, fn_ty: ty::t, decl: ast::fn_decl, + span: span, id: ast::node_id) { match ty::get(fn_ty).sty { - ty::ty_fn(fn_ty) => { - let mut counter = 0; - do vec::iter2(fn_ty.sig.inputs, decl.inputs) |arg_ty, arg_ast| { - counter += 1; - debug!("arg %d, ty=%s, mode=%s", - counter, - ty_to_str(tcx, arg_ty.ty), - mode_to_str(arg_ast.mode)); - match arg_ast.mode { - ast::expl(ast::by_copy) => { - /* always allow by-copy */ - } + ty::ty_fn(fn_ty) => { + let mut counter = 0; + for vec::each2(fn_ty.sig.inputs, decl.inputs) |arg_ty, arg_ast| { + counter += 1; + debug!("arg %d, ty=%s, mode=%s", + counter, + ty_to_str(tcx, arg_ty.ty), + mode_to_str(arg_ast.mode)); + match arg_ast.mode { + ast::expl(ast::by_copy) => { + if !tcx.legacy_modes { + tcx.sess.span_lint( + deprecated_mode, id, id, span, + fmt!("argument %d uses by-copy mode", + counter)); + } + } - ast::expl(_) => { - tcx.sess.span_lint( - deprecated_mode, id, id, - span, - fmt!("argument %d uses an explicit mode", counter)); - } + ast::expl(_) => { + tcx.sess.span_lint( + deprecated_mode, id, id, + span, + fmt!("argument %d uses an explicit mode", counter)); + } - ast::infer(_) => { - let kind = ty::type_kind(tcx, arg_ty.ty); - if !ty::kind_is_safe_for_default_mode(kind) { - tcx.sess.span_lint( - deprecated_mode, id, id, - span, - fmt!("argument %d uses the default mode \ - but shouldn't", - counter)); + ast::infer(_) => { + if tcx.legacy_modes { + let kind = ty::type_kind(tcx, arg_ty.ty); + if !ty::kind_is_safe_for_default_mode(kind) { + tcx.sess.span_lint( + deprecated_mode, id, id, + span, + fmt!("argument %d uses the default mode \ + but shouldn't", + counter)); + } + } + } + } + + match ty::get(arg_ty.ty).sty { + ty::ty_fn(*) => { + let span = arg_ast.ty.span; + // Recurse to check fn-type argument + match arg_ast.ty.node { + ast::ty_fn(_, _, _, decl) => { + check_fn_deprecated_modes(tcx, arg_ty.ty, + decl, span, id); + } + ast::ty_path(*) => { + // This is probably a typedef, so we can't + // see the actual fn decl + // e.g. fn foo(f: InitOp) + } + ast::ty_rptr(_, mt) + | ast::ty_box(mt) + | ast::ty_uniq(mt) => { + // Functions with preceding sigil are parsed + // as pointers of functions + match mt.ty.node { + ast::ty_fn(_, _, _, decl) => { + check_fn_deprecated_modes( + tcx, arg_ty.ty, + decl, span, id); + } + _ => fail + } + } + _ => { + tcx.sess.span_warn(span, ~"what"); + error!("arg %d, ty=%s, mode=%s", + counter, + ty_to_str(tcx, arg_ty.ty), + mode_to_str(arg_ast.mode)); + error!("%?",arg_ast.ty.node); + fail + } + }; + } + _ => () } - } } } - } - _ => tcx.sess.impossible_case(span, ~"check_fn: function has \ - non-fn type") + + _ => tcx.sess.impossible_case(span, ~"check_fn: function has \ + non-fn type") + } +} + +fn check_item_deprecated_modes(tcx: ty::ctxt, it: @ast::item) { + match it.node { + ast::item_ty(ty, _) => { + match ty.node { + ast::ty_fn(_, _, _, decl) => { + let fn_ty = ty::node_id_to_type(tcx, it.id); + check_fn_deprecated_modes( + tcx, fn_ty, decl, ty.span, it.id) + } + _ => () + } + } + _ => () } } diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index a4c9b5f4b355..69b325b03a4a 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -302,7 +302,7 @@ fn IrMaps(tcx: ty::ctxt, method_map: typeck::method_map, impl IrMaps { fn add_live_node(lnk: LiveNodeKind) -> LiveNode { let ln = LiveNode(self.num_live_nodes); - vec::push(self.lnks, lnk); + self.lnks.push(lnk); self.num_live_nodes += 1u; debug!("%s is of kind %?", ln.to_str(), lnk); @@ -319,7 +319,7 @@ impl IrMaps { fn add_variable(vk: VarKind) -> Variable { let v = Variable(self.num_vars); - vec::push(self.var_kinds, vk); + self.var_kinds.push(vk); self.num_vars += 1u; match vk { @@ -416,7 +416,7 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, let fn_maps = @IrMaps(self.tcx, self.method_map, self.last_use_map); - debug!("creating fn_maps: %x", ptr::addr_of(*fn_maps) as uint); + debug!("creating fn_maps: %x", ptr::addr_of(&(*fn_maps)) as uint); for decl.inputs.each |arg| { debug!("adding argument %d", arg.id); @@ -540,7 +540,7 @@ fn visit_expr(expr: @expr, &&self: @IrMaps, vt: vt<@IrMaps>) { cap_move | cap_drop => true, // var must be dead afterwards cap_copy | cap_ref => false // var can still be used }; - vec::push(call_caps, {ln: cv_ln, is_move: is_move, rv: rv}); + call_caps.push({ln: cv_ln, is_move: is_move, rv: rv}); } None => {} } @@ -659,7 +659,7 @@ impl Liveness { expr_path(_) => { let def = self.tcx.def_map.get(expr.id); relevant_def(def).map( - |rdef| self.variable_from_rdef(rdef, expr.span) + |rdef| self.variable_from_rdef(*rdef, expr.span) ) } _ => None @@ -675,7 +675,7 @@ impl Liveness { match self.tcx.def_map.find(node_id) { Some(def) => { relevant_def(def).map( - |rdef| self.variable_from_rdef(rdef, span) + |rdef| self.variable_from_rdef(*rdef, span) ) } None => { @@ -955,7 +955,7 @@ impl Liveness { fn propagate_through_block(blk: blk, succ: LiveNode) -> LiveNode { let succ = self.propagate_through_opt_expr(blk.node.expr, succ); do blk.node.stmts.foldr(succ) |stmt, succ| { - self.propagate_through_stmt(stmt, succ) + self.propagate_through_stmt(*stmt, succ) } } @@ -975,7 +975,7 @@ impl Liveness { match decl.node { decl_local(locals) => { do locals.foldr(succ) |local, succ| { - self.propagate_through_local(local, succ) + self.propagate_through_local(*local, succ) } } decl_item(_) => { @@ -1007,14 +1007,14 @@ impl Liveness { fn propagate_through_exprs(exprs: ~[@expr], succ: LiveNode) -> LiveNode { do exprs.foldr(succ) |expr, succ| { - self.propagate_through_expr(expr, succ) + self.propagate_through_expr(*expr, succ) } } fn propagate_through_opt_expr(opt_expr: Option<@expr>, succ: LiveNode) -> LiveNode { do opt_expr.foldl(succ) |succ, expr| { - self.propagate_through_expr(expr, succ) + self.propagate_through_expr(*expr, *succ) } } @@ -1396,7 +1396,7 @@ impl Liveness { // Note: the field_map is empty unless we are in a ctor return self.ir.field_map.find(fld).map(|var| { let ln = self.live_node(expr.id, expr.span); - (ln, var) + (ln, *var) }); } _ => return None @@ -1571,11 +1571,11 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) { expr_call(f, args, _) => { let targs = ty::ty_fn_args(ty::expr_ty(self.tcx, f)); - do vec::iter2(args, targs) |arg_expr, arg_ty| { + for vec::each2(args, targs) |arg_expr, arg_ty| { match ty::resolved_mode(self.tcx, arg_ty.mode) { by_val | by_copy | by_ref | by_mutbl_ref => {} by_move => { - self.check_move_from_expr(arg_expr, vt); + self.check_move_from_expr(*arg_expr, vt); } } } diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs index 03d453a84f55..fe465db1312c 100644 --- a/src/rustc/middle/mem_categorization.rs +++ b/src/rustc/middle/mem_categorization.rs @@ -612,7 +612,7 @@ impl &mem_categorization_ctxt { cmt: cmt) -> cmt { @{id: arg.id(), span: arg.span(), cat: cat_comp(cmt, comp_variant(enum_did)), - lp: cmt.lp.map(|l| @lp_comp(l, comp_variant(enum_did)) ), + lp: cmt.lp.map(|l| @lp_comp(*l, comp_variant(enum_did)) ), mutbl: cmt.mutbl, // imm iff in an immutable context ty: self.tcx.ty(arg)} } @@ -649,7 +649,7 @@ impl &mem_categorization_ctxt { }; let m = self.inherited_mutability(base_cmt.mutbl, f_mutbl); let f_comp = comp_field(f_name, f_mutbl); - let lp = base_cmt.lp.map(|lp| @lp_comp(lp, f_comp) ); + let lp = base_cmt.lp.map(|lp| @lp_comp(*lp, f_comp) ); @{id: node.id(), span: node.span(), cat: cat_comp(base_cmt, f_comp), lp:lp, mutbl: m, ty: self.tcx.ty(node)} @@ -670,14 +670,14 @@ impl &mem_categorization_ctxt { match deref_kind(self.tcx, base_cmt.ty) { deref_ptr(ptr) => { - let lp = do base_cmt.lp.chain |l| { + let lp = do base_cmt.lp.chain_ref |l| { // Given that the ptr itself is loanable, we can // loan out deref'd uniq ptrs as the data they are // the only way to reach the data they point at. // Other ptr types admit aliases and are therefore // not loanable. match ptr { - uniq_ptr => {Some(@lp_deref(l, ptr))} + uniq_ptr => {Some(@lp_deref(*l, ptr))} gc_ptr | region_ptr(_) | unsafe_ptr => {None} } }; @@ -699,7 +699,7 @@ impl &mem_categorization_ctxt { } deref_comp(comp) => { - let lp = base_cmt.lp.map(|l| @lp_comp(l, comp) ); + let lp = base_cmt.lp.map(|l| @lp_comp(*l, comp) ); let m = self.inherited_mutability(base_cmt.mutbl, mt.mutbl); @{id:node.id(), span:node.span(), cat:cat_comp(base_cmt, comp), lp:lp, @@ -724,7 +724,7 @@ impl &mem_categorization_ctxt { // (a) the contents are loanable if the base is loanable // and this is a *unique* vector let deref_lp = match ptr { - uniq_ptr => {base_cmt.lp.map(|lp| @lp_deref(lp, uniq_ptr))} + uniq_ptr => {base_cmt.lp.map(|lp| @lp_deref(*lp, uniq_ptr))} _ => {None} }; @@ -756,7 +756,7 @@ impl &mem_categorization_ctxt { fn comp(expr: @ast::expr, of_cmt: cmt, vect: ty::t, mutbl: ast::mutability, ty: ty::t) -> cmt { let comp = comp_index(vect, mutbl); - let index_lp = of_cmt.lp.map(|lp| @lp_comp(lp, comp) ); + let index_lp = of_cmt.lp.map(|lp| @lp_comp(*lp, comp) ); @{id:expr.id, span:expr.span, cat:cat_comp(of_cmt, comp), lp:index_lp, mutbl:mutbl, ty:ty} @@ -766,7 +766,7 @@ impl &mem_categorization_ctxt { fn cat_tuple_elt(elt: N, cmt: cmt) -> cmt { @{id: elt.id(), span: elt.span(), cat: cat_comp(cmt, comp_tuple), - lp: cmt.lp.map(|l| @lp_comp(l, comp_tuple) ), + lp: cmt.lp.map(|l| @lp_comp(*l, comp_tuple) ), mutbl: cmt.mutbl, // imm iff in an immutable context ty: self.tcx.ty(elt)} } @@ -958,7 +958,7 @@ impl &mem_categorization_ctxt { self.cat_to_repr(cmt.cat), cmt.id, self.mut_to_str(cmt.mutbl), - cmt.lp.map_default(~"none", |p| self.lp_to_str(p) ), + cmt.lp.map_default(~"none", |p| self.lp_to_str(*p) ), ty_to_str(self.tcx, cmt.ty)) } diff --git a/src/rustc/middle/pat_util.rs b/src/rustc/middle/pat_util.rs index e67b85b869c7..006065988b92 100644 --- a/src/rustc/middle/pat_util.rs +++ b/src/rustc/middle/pat_util.rs @@ -54,6 +54,6 @@ fn pat_bindings(dm: resolve::DefMap, pat: @pat, fn pat_binding_ids(dm: resolve::DefMap, pat: @pat) -> ~[node_id] { let mut found = ~[]; - pat_bindings(dm, pat, |_bm, b_id, _sp, _pt| vec::push(found, b_id) ); + pat_bindings(dm, pat, |_bm, b_id, _sp, _pt| found.push(b_id) ); return found; } diff --git a/src/rustc/middle/privacy.rs b/src/rustc/middle/privacy.rs index 6b0df4630da2..4d291ceb590d 100644 --- a/src/rustc/middle/privacy.rs +++ b/src/rustc/middle/privacy.rs @@ -56,7 +56,7 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) { if method.vis == private && (impl_id.crate != local_crate || !privileged_items - .contains(impl_id.node)) { + .contains(&(impl_id.node))) { tcx.sess.span_err(span, fmt!("method `%s` is \ private", @@ -95,9 +95,9 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) { } match methods[method_num] { provided(method) - if method.vis == private && - !privileged_items - .contains(trait_id.node) => { + if method.vis == private && + !privileged_items + .contains(&(trait_id.node)) => { tcx.sess.span_err(span, fmt!("method `%s` \ @@ -157,7 +157,7 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) { match ty::get(ty::expr_ty(tcx, base)).sty { ty_class(id, _) if id.crate != local_crate || - !privileged_items.contains(id.node) => { + !privileged_items.contains(&(id.node)) => { match method_map.find(expr.id) { None => { debug!("(privacy checking) checking \ @@ -178,7 +178,7 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) { match ty::get(ty::expr_ty(tcx, expr)).sty { ty_class(id, _) => { if id.crate != local_crate || - !privileged_items.contains(id.node) { + !privileged_items.contains(&(id.node)) { for fields.each |field| { debug!("(privacy checking) checking \ field in struct literal"); @@ -205,7 +205,7 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) { match ty::get(ty::pat_ty(tcx, pattern)).sty { ty_class(id, _) => { if id.crate != local_crate || - !privileged_items.contains(id.node) { + !privileged_items.contains(&(id.node)) { for fields.each |field| { debug!("(privacy checking) checking \ struct pattern"); diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs index cf496ae6683a..ff708b7f4efa 100644 --- a/src/rustc/middle/region.rs +++ b/src/rustc/middle/region.rs @@ -141,7 +141,7 @@ fn nearest_common_ancestor(region_map: region_map, scope_a: ast::node_id, match region_map.find(scope) { None => return result, Some(superscope) => { - vec::push(result, superscope); + result.push(superscope); scope = superscope; } } @@ -485,7 +485,7 @@ impl determine_rp_ctxt { } }; let dep = {ambient_variance: self.ambient_variance, id: self.item_id}; - if !vec.contains(dep) { vec.push(dep); } + if !vec.contains(&dep) { vec.push(dep); } } // Determines whether a reference to a region that appears in the diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index f7c389e67ff8..eca0687f2fda 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -167,8 +167,8 @@ enum CaptureClause { type ResolveVisitor = vt<()>; enum ModuleDef { - NoModuleDef, // Does not define a module. - ModuleDef(@Module), // Defines a module. + NoModuleDef, // Does not define a module. + ModuleDef(Privacy, @Module), // Defines a module. } impl ModuleDef { @@ -191,7 +191,7 @@ impl ImportDirectiveNS : cmp::Eq { /// Contains data for specific types of import directives. enum ImportDirectiveSubclass { - SingleImport(Atom /* target */, Atom /* source */, ImportDirectiveNS), + SingleImport(ident /* target */, ident /* source */, ImportDirectiveNS), GlobImport } @@ -303,29 +303,15 @@ enum EnumVariantOrConstResolution { EnumVariantOrConstNotFound } -// FIXME (issue #2550): Should be a class but then it becomes not implicitly -// copyable due to a kind bug. - -type Atom = uint; - -fn Atom(n: uint) -> Atom { - return n; -} - -/// Creates a hash table of atoms. -fn atom_hashmap() -> HashMap { - HashMap::() -} - /// One local scope. struct Rib { - bindings: HashMap, + bindings: HashMap, kind: RibKind, } fn Rib(kind: RibKind) -> Rib { Rib { - bindings: atom_hashmap(), + bindings: HashMap(), kind: kind } } @@ -333,15 +319,18 @@ fn Rib(kind: RibKind) -> Rib { /// One import directive. struct ImportDirective { - module_path: @DVec, + privacy: Privacy, + module_path: @DVec, subclass: @ImportDirectiveSubclass, span: span, } -fn ImportDirective(module_path: @DVec, +fn ImportDirective(privacy: Privacy, + module_path: @DVec, subclass: @ImportDirectiveSubclass, span: span) -> ImportDirective { ImportDirective { + privacy: privacy, module_path: module_path, subclass: subclass, span: span @@ -362,6 +351,7 @@ fn Target(target_module: @Module, bindings: @NameBindings) -> Target { } struct ImportResolution { + privacy: Privacy, span: span, // The number of outstanding references to this name. When this reaches @@ -377,8 +367,9 @@ struct ImportResolution { mut used: bool, } -fn ImportResolution(span: span) -> ImportResolution { +fn ImportResolution(privacy: Privacy, span: span) -> ImportResolution { ImportResolution { + privacy: privacy, span: span, outstanding_references: 0u, module_target: None, @@ -401,7 +392,7 @@ impl ImportResolution { /// The link from a module up to its nearest parent node. enum ParentLink { NoParentLink, - ModuleParentLink(@Module, Atom), + ModuleParentLink(@Module, ident), BlockParentLink(@Module, node_id) } @@ -410,7 +401,7 @@ struct Module { parent_link: ParentLink, mut def_id: Option, - children: HashMap, + children: HashMap, imports: DVec<@ImportDirective>, // The anonymous children of this node. Anonymous children are pseudo- @@ -433,10 +424,10 @@ struct Module { // XXX: This is about to be reworked so that exports are on individual // items, not names. // - // The atom is the name of the exported item, while the node ID is the + // The ident is the name of the exported item, while the node ID is the // ID of the export path. - exported_names: HashMap, + exported_names: HashMap, // XXX: This is a transition measure to let us switch export-evaluation // logic when compiling modules that have transitioned to listing their @@ -446,7 +437,7 @@ struct Module { legacy_exports: bool, // The status of resolving each import in this module. - import_resolutions: HashMap, + import_resolutions: HashMap, // The number of unresolved globs that this module exports. mut glob_count: uint, @@ -461,12 +452,12 @@ fn Module(parent_link: ParentLink, Module { parent_link: parent_link, def_id: def_id, - children: atom_hashmap(), + children: HashMap(), imports: DVec(), anonymous_children: HashMap(), - exported_names: atom_hashmap(), + exported_names: HashMap(), legacy_exports: legacy_exports, - import_resolutions: atom_hashmap(), + import_resolutions: HashMap(), glob_count: 0u, resolved_import_count: 0u } @@ -533,13 +524,14 @@ struct NameBindings { impl NameBindings { /// Creates a new module in this set of name bindings. - fn define_module(parent_link: ParentLink, + fn define_module(privacy: Privacy, + parent_link: ParentLink, def_id: Option, legacy_exports: bool, sp: span) { if self.module_def.is_none() { let module_ = @Module(parent_link, def_id, legacy_exports); - self.module_def = ModuleDef(module_); + self.module_def = ModuleDef(privacy, module_); self.module_span = Some(sp); } } @@ -560,7 +552,7 @@ impl NameBindings { fn get_module_if_available() -> Option<@Module> { match self.module_def { NoModuleDef => return None, - ModuleDef(module_) => return Some(module_) + ModuleDef(_privacy, module_) => return Some(module_) } } @@ -574,7 +566,7 @@ impl NameBindings { fail ~"get_module called on a node with no module definition!"; } - ModuleDef(module_) => { + ModuleDef(_, module_) => { return module_; } } @@ -599,12 +591,12 @@ impl NameBindings { ValueNS => return self.value_def, ModuleNS => match self.module_def { NoModuleDef => return None, - ModuleDef(module_) => + ModuleDef(privacy, module_) => match module_.def_id { None => return None, Some(def_id) => { return Some(Definition { - privacy: Public, + privacy: privacy, def: def_mod(def_id) }); } @@ -641,20 +633,20 @@ fn NameBindings() -> NameBindings { /// Interns the names of the primitive types. struct PrimitiveTypeTable { - primitive_types: HashMap, + primitive_types: HashMap, } impl PrimitiveTypeTable { - fn intern(intr: ident_interner, string: @~str, + fn intern(intr: @ident_interner, string: @~str, primitive_type: prim_ty) { - let atom = intr.intern(string); - self.primitive_types.insert(atom, primitive_type); + let ident = intr.intern(string); + self.primitive_types.insert(ident, primitive_type); } } -fn PrimitiveTypeTable(intr: ident_interner) -> PrimitiveTypeTable { +fn PrimitiveTypeTable(intr: @ident_interner) -> PrimitiveTypeTable { let table = PrimitiveTypeTable { - primitive_types: atom_hashmap() + primitive_types: HashMap() }; table.intern(intr, @~"bool", ty_bool); @@ -703,7 +695,8 @@ fn Resolver(session: session, lang_items: LanguageItems, let graph_root = @NameBindings(); - (*graph_root).define_module(NoParentLink, + (*graph_root).define_module(Public, + NoParentLink, Some({ crate: 0, node: 0 }), has_legacy_export_attr(crate.node.attrs), crate.span); @@ -735,7 +728,7 @@ fn Resolver(session: session, lang_items: LanguageItems, xray_context: NoXray, current_trait_refs: None, - self_atom: syntax::parse::token::special_idents::self_, + self_ident: syntax::parse::token::special_idents::self_, primitive_type_table: @PrimitiveTypeTable(session. parse_sess.interner), @@ -757,13 +750,13 @@ struct Resolver { lang_items: LanguageItems, crate: @crate, - intr: ident_interner, + intr: @ident_interner, graph_root: @NameBindings, unused_import_lint_level: level, - trait_info: HashMap>, + trait_info: HashMap>, structs: HashMap, // The number of imports that are currently unresolved. @@ -789,10 +782,10 @@ struct Resolver { // The trait that the current context can refer to. mut current_trait_refs: Option<@DVec>, - // The atom for the keyword "self". - self_atom: Atom, + // The ident for the keyword "self". + self_ident: ident, - // The atoms for the primitive types. + // The idents for the primitive types. primitive_type_table: @PrimitiveTypeTable, // The four namespaces. @@ -891,7 +884,7 @@ impl Resolver { * If this node does not have a module definition and we are not inside * a block, fails. */ - fn add_child(name: Atom, + fn add_child(name: ident, reduced_graph_parent: ReducedGraphParent, // Pass in the namespaces for the child item so that we can // check for duplicate items in the same namespace @@ -929,7 +922,7 @@ impl Resolver { namespace_to_str(ns), self.session.str_of(name))); do child.span_for_namespace(ns).iter() |sp| { - self.session.span_note(sp, + self.session.span_note(*sp, #fmt("First definition of %s %s here:", namespace_to_str(ns), self.session.str_of(name))); @@ -973,7 +966,8 @@ impl Resolver { return false; } - fn get_parent_link(parent: ReducedGraphParent, name: Atom) -> ParentLink { + fn get_parent_link(parent: ReducedGraphParent, + name: ident) -> ParentLink { match parent { ModuleReducedGraphParent(module_) => { return ModuleParentLink(module_, name); @@ -986,22 +980,23 @@ impl Resolver { parent: ReducedGraphParent, &&visitor: vt) { - let atom = item.ident; + let ident = item.ident; let sp = item.span; let legacy = match parent { ModuleReducedGraphParent(m) => m.legacy_exports }; + let privacy = self.visibility_to_privacy(item.vis, legacy); match item.node { item_mod(module_) => { let legacy = has_legacy_export_attr(item.attrs); - let (name_bindings, new_parent) = self.add_child(atom, parent, + let (name_bindings, new_parent) = self.add_child(ident, parent, ~[ModuleNS], sp); - let parent_link = self.get_parent_link(new_parent, atom); + let parent_link = self.get_parent_link(new_parent, ident); let def_id = { crate: 0, node: item.id }; - (*name_bindings).define_module(parent_link, Some(def_id), - legacy, sp); + (*name_bindings).define_module(privacy, parent_link, + Some(def_id), legacy, sp); let new_parent = ModuleReducedGraphParent((*name_bindings).get_module()); @@ -1012,13 +1007,13 @@ impl Resolver { let legacy = has_legacy_export_attr(item.attrs); let new_parent = match fm.sort { named => { - let (name_bindings, new_parent) = self.add_child(atom, + let (name_bindings, new_parent) = self.add_child(ident, parent, ~[ModuleNS], sp); - let parent_link = self.get_parent_link(new_parent, atom); + let parent_link = self.get_parent_link(new_parent, ident); let def_id = { crate: 0, node: item.id }; - (*name_bindings).define_module(parent_link, Some(def_id), - legacy, sp); + (*name_bindings).define_module(privacy, parent_link, + Some(def_id), legacy, sp); ModuleReducedGraphParent((*name_bindings).get_module()) } @@ -1032,48 +1027,42 @@ impl Resolver { // These items live in the value namespace. item_const(*) => { - let (name_bindings, _) = self.add_child(atom, parent, + let (name_bindings, _) = self.add_child(ident, parent, ~[ValueNS], sp); (*name_bindings).define_value - (self.visibility_to_privacy(item.vis, legacy), - def_const(local_def(item.id)), - sp); + (privacy, def_const(local_def(item.id)), sp); } item_fn(_, purity, _, _) => { - let (name_bindings, new_parent) = self.add_child(atom, parent, + let (name_bindings, new_parent) = self.add_child(ident, parent, ~[ValueNS], sp); let def = def_fn(local_def(item.id), purity); - (*name_bindings).define_value - (self.visibility_to_privacy(item.vis, legacy), def, sp); + (*name_bindings).define_value(privacy, def, sp); visit_item(item, new_parent, visitor); } // These items live in the type namespace. item_ty(*) => { - let (name_bindings, _) = self.add_child(atom, parent, + let (name_bindings, _) = self.add_child(ident, parent, ~[TypeNS], sp); (*name_bindings).define_type - (self.visibility_to_privacy(item.vis, legacy), - def_ty(local_def(item.id)), - sp); + (privacy, def_ty(local_def(item.id)), sp); } item_enum(enum_definition, _) => { - let (name_bindings, new_parent) = self.add_child(atom, parent, + let (name_bindings, new_parent) = self.add_child(ident, parent, ~[TypeNS], sp); (*name_bindings).define_type - (self.visibility_to_privacy(item.vis, legacy), - def_ty(local_def(item.id)), - sp); + (privacy, def_ty(local_def(item.id)), sp); for enum_definition.variants.each |variant| { self.build_reduced_graph_for_variant(*variant, local_def(item.id), + privacy, new_parent, visitor); } @@ -1085,22 +1074,17 @@ impl Resolver { match struct_definition.ctor { None => { let (name_bindings, new_parent) = - self.add_child(atom, parent, ~[TypeNS], sp); + self.add_child(ident, parent, ~[TypeNS], sp); (*name_bindings).define_type - (self.visibility_to_privacy(item.vis, legacy), - def_ty(local_def(item.id)), - sp); + (privacy, def_ty(local_def(item.id)), sp); new_parent } Some(ctor) => { let (name_bindings, new_parent) = - self.add_child(atom, parent, ~[ValueNS, TypeNS], + self.add_child(ident, parent, ~[ValueNS, TypeNS], sp); - let privacy = self.visibility_to_privacy(item.vis, - legacy); - (*name_bindings).define_type (privacy, def_ty(local_def(item.id)), sp); @@ -1124,22 +1108,22 @@ impl Resolver { } item_trait(_, _, methods) => { - let (name_bindings, new_parent) = self.add_child(atom, parent, + let (name_bindings, new_parent) = self.add_child(ident, parent, ~[TypeNS], sp); // Add the names of all the methods to the trait info. - let method_names = @atom_hashmap(); + let method_names = @HashMap(); for methods.each |method| { let ty_m = trait_method_to_ty_method(*method); - let atom = ty_m.ident; + let ident = ty_m.ident; // Add it to the trait info if not static, // add it as a name in the enclosing module otherwise. match ty_m.self_ty.node { sty_static => { // which parent to use?? let (method_name_bindings, _) = - self.add_child(atom, new_parent, ~[ValueNS], + self.add_child(ident, new_parent, ~[ValueNS], ty_m.span); let def = def_static_method(local_def(ty_m.id), ty_m.purity); @@ -1147,7 +1131,7 @@ impl Resolver { (Public, def, ty_m.span); } _ => { - (*method_names).insert(atom, ()); + (*method_names).insert(ident, ()); } } } @@ -1156,7 +1140,7 @@ impl Resolver { self.trait_info.insert(def_id, method_names); (*name_bindings).define_type - (self.visibility_to_privacy(item.vis, legacy), + (privacy, def_ty(def_id), sp); visit_item(item, new_parent, visitor); @@ -1172,17 +1156,20 @@ impl Resolver { // type and/or value namespaces. fn build_reduced_graph_for_variant(variant: variant, item_id: def_id, + +parent_privacy: Privacy, parent: ReducedGraphParent, &&visitor: vt) { - let legacy = match parent { - ModuleReducedGraphParent(m) => m.legacy_exports - }; - - let atom = variant.node.name; - let (child, _) = self.add_child(atom, parent, ~[ValueNS], + let ident = variant.node.name; + let (child, _) = self.add_child(ident, parent, ~[ValueNS], variant.span); - let privacy = self.visibility_to_privacy(variant.node.vis, legacy); + + let privacy; + match variant.node.vis { + public => privacy = Public, + private => privacy = Private, + inherited => privacy = parent_privacy + } match variant.node.kind { tuple_variant_kind(_) => { @@ -1204,6 +1191,7 @@ impl Resolver { variant.span); for enum_definition.variants.each |variant| { self.build_reduced_graph_for_variant(*variant, item_id, + parent_privacy, parent, visitor); } } @@ -1218,6 +1206,10 @@ impl Resolver { parent: ReducedGraphParent, &&_visitor: vt) { + let legacy = match parent { + ModuleReducedGraphParent(m) => m.legacy_exports + }; + let privacy = self.visibility_to_privacy(view_item.vis, legacy); match view_item.node { view_item_import(view_paths) => { for view_paths.each |view_path| { @@ -1259,7 +1251,8 @@ impl Resolver { let subclass = @SingleImport(binding, source_ident, ns); - self.build_import_directive(module_, + self.build_import_directive(privacy, + module_, module_path, subclass, view_path.span); @@ -1270,14 +1263,16 @@ impl Resolver { let subclass = @SingleImport(name, name, AnyNS); - self.build_import_directive(module_, + self.build_import_directive(privacy, + module_, module_path, subclass, view_path.span); } } view_path_glob(_, _) => { - self.build_import_directive(module_, + self.build_import_directive(privacy, + module_, module_path, @GlobImport, view_path.span); @@ -1334,9 +1329,9 @@ impl Resolver { } for path_list_idents.each |path_list_ident| { - let atom = path_list_ident.node.name; + let ident = path_list_ident.node.name; let id = path_list_ident.node.id; - module_.exported_names.insert(atom, id); + module_.exported_names.insert(ident, id); } } } @@ -1356,7 +1351,8 @@ impl Resolver { let parent_link = ModuleParentLink (self.get_module_from_parent(new_parent), name); - (*child_name_bindings).define_module(parent_link, + (*child_name_bindings).define_module(privacy, + parent_link, Some(def_id), false, view_item.span); @@ -1428,7 +1424,7 @@ impl Resolver { fn handle_external_def(def: def, modules: HashMap, child_name_bindings: @NameBindings, final_ident: ~str, - atom: Atom, new_parent: ReducedGraphParent) { + ident: ident, new_parent: ReducedGraphParent) { match def { def_mod(def_id) | def_foreign_mod(def_id) => { match copy child_name_bindings.module_def { @@ -1436,11 +1432,12 @@ impl Resolver { debug!("(building reduced graph for \ external crate) building module \ %s", final_ident); - let parent_link = self.get_parent_link(new_parent, atom); + let parent_link = self.get_parent_link(new_parent, ident); match modules.find(def_id) { None => { - child_name_bindings.define_module(parent_link, + child_name_bindings.define_module(Public, + parent_link, Some(def_id), false, dummy_sp()); @@ -1452,7 +1449,7 @@ impl Resolver { // avoid creating cycles in the // module graph. - let resolution = @ImportResolution(dummy_sp()); + let resolution = @ImportResolution(Public, dummy_sp()); resolution.outstanding_references = 0; match existing_module.parent_link { @@ -1460,9 +1457,9 @@ impl Resolver { BlockParentLink(*) => { fail ~"can't happen"; } - ModuleParentLink(parent_module, atom) => { + ModuleParentLink(parent_module, ident) => { - let name_bindings = parent_module.children.get(atom); + let name_bindings = parent_module.children.get(ident); resolution.module_target = Some(Target(parent_module, name_bindings)); @@ -1472,11 +1469,11 @@ impl Resolver { debug!("(building reduced graph for external crate) \ ... creating import resolution"); - new_parent.import_resolutions.insert(atom, resolution); + new_parent.import_resolutions.insert(ident, resolution); } } } - ModuleDef(module_) => { + ModuleDef(_priv, module_) => { debug!("(building reduced graph for \ external crate) already created \ module"); @@ -1504,7 +1501,7 @@ impl Resolver { // Nothing to do. } Some(method_names) => { - let interned_method_names = @atom_hashmap(); + let interned_method_names = @HashMap(); for method_names.each |method_data| { let (method_name, self_ty) = *method_data; debug!("(building reduced graph for \ @@ -1562,7 +1559,7 @@ impl Resolver { path_entry.def_like); let mut pieces = split_str(path_entry.path_string, ~"::"); - let final_ident_str = pop(pieces); + let final_ident_str = pieces.pop(); let final_ident = self.session.ident_of(final_ident_str); // Find the module we need, creating modules along the way if we @@ -1585,11 +1582,12 @@ impl Resolver { autovivifying %s", *ident_str); let parent_link = self.get_parent_link(new_parent, ident); - (*child_name_bindings).define_module(parent_link, - None, false, + (*child_name_bindings).define_module(Public, + parent_link, + None, false, dummy_sp()); } - ModuleDef(_) => { /* Fall through. */ } + ModuleDef(*) => { /* Fall through. */ } } current_module = (*child_name_bindings).get_module(); @@ -1625,12 +1623,14 @@ impl Resolver { } /// Creates and adds an import directive to the given module. - fn build_import_directive(module_: @Module, - module_path: @DVec, + fn build_import_directive(privacy: Privacy, + module_: @Module, + module_path: @DVec, subclass: @ImportDirectiveSubclass, span: span) { - let directive = @ImportDirective(module_path, subclass, span); + let directive = @ImportDirective(privacy, module_path, + subclass, span); module_.imports.push(directive); // Bump the reference count on the name. Or, if this is a glob, set @@ -1638,12 +1638,21 @@ impl Resolver { match *subclass { SingleImport(target, _, _) => { + debug!("(building import directive) building import \ + directive: privacy %? %s::%s", + privacy, + self.idents_to_str(module_path.get()), + self.session.str_of(target)); + match module_.import_resolutions.find(target) { Some(resolution) => { + debug!("(building import directive) bumping \ + reference"); resolution.outstanding_references += 1u; } None => { - let resolution = @ImportResolution(span); + debug!("(building import directive) creating new"); + let resolution = @ImportResolution(privacy, span); resolution.outstanding_references = 1u; module_.import_resolutions.insert(target, resolution); } @@ -1755,17 +1764,17 @@ impl Resolver { } } - fn atoms_to_str(atoms: ~[Atom]) -> ~str { + fn idents_to_str(idents: ~[ident]) -> ~str { // XXX: str::connect should do this. let mut result = ~""; let mut first = true; - for atoms.each() |atom| { + for idents.each() |ident| { if first { first = false; } else { result += ~"::"; } - result += self.session.str_of(*atom); + result += self.session.str_of(*ident); } // XXX: Shouldn't copy here. We need string builder functionality. return result; @@ -1786,7 +1795,7 @@ impl Resolver { debug!("(resolving import for module) resolving import `%s::...` in \ `%s`", - self.atoms_to_str((*module_path).get()), + self.idents_to_str((*module_path).get()), self.module_to_str(module_)); // One-level renaming imports of the form `import foo = bar;` are @@ -1829,8 +1838,9 @@ impl Resolver { } GlobImport => { let span = import_directive.span; + let p = import_directive.privacy; resolution_result = - self.resolve_glob_import(module_, + self.resolve_glob_import(p, module_, containing_module, span); } @@ -1872,8 +1882,8 @@ impl Resolver { fn resolve_single_import(module_: @Module, containing_module: @Module, - target: Atom, - source: Atom) + target: ident, + source: ident) -> ResolveResult<()> { debug!("(resolving single import) resolving `%s` = `%s::%s` from \ @@ -1965,6 +1975,12 @@ impl Resolver { namespace: Namespace) -> NamespaceResult { + // Import resolutions must be declared with "pub" + // in order to be exported. + if import_resolution.privacy == Private { + return UnboundResult; + } + match (*import_resolution). target_for_namespace(namespace) { None => { @@ -2062,8 +2078,8 @@ impl Resolver { fn resolve_single_module_import(module_: @Module, containing_module: @Module, - target: Atom, - source: Atom) + target: ident, + source: ident) -> ResolveResult<()> { debug!("(resolving single module import) resolving `%s` = `%s::%s` \ @@ -2196,7 +2212,8 @@ impl Resolver { * succeeds or bails out (as importing * from an empty module or a module * that exports nothing is valid). */ - fn resolve_glob_import(module_: @Module, + fn resolve_glob_import(privacy: Privacy, + module_: @Module, containing_module: @Module, span: span) -> ResolveResult<()> { @@ -2218,11 +2235,11 @@ impl Resolver { // Add all resolved imports from the containing module. for containing_module.import_resolutions.each - |atom, target_import_resolution| { + |ident, target_import_resolution| { - if !self.name_is_exported(containing_module, atom) { + if !self.name_is_exported(containing_module, ident) { debug!("(resolving glob import) name `%s` is unexported", - self.session.str_of(atom)); + self.session.str_of(ident)); loop; } @@ -2232,11 +2249,12 @@ impl Resolver { self.module_to_str(module_)); // Here we merge two import resolutions. - match module_.import_resolutions.find(atom) { + match module_.import_resolutions.find(ident) { None => { // Simple: just copy the old import resolution. let new_import_resolution = - @ImportResolution(target_import_resolution.span); + @ImportResolution(privacy, + target_import_resolution.span); new_import_resolution.module_target = copy target_import_resolution.module_target; new_import_resolution.value_target = @@ -2245,7 +2263,7 @@ impl Resolver { copy target_import_resolution.type_target; module_.import_resolutions.insert - (atom, new_import_resolution); + (ident, new_import_resolution); } Some(dest_import_resolution) => { // Merge the two import resolutions at a finer-grained @@ -2283,20 +2301,21 @@ impl Resolver { } // Add all children from the containing module. - for containing_module.children.each |atom, name_bindings| { - if !self.name_is_exported(containing_module, atom) { + for containing_module.children.each |ident, name_bindings| { + if !self.name_is_exported(containing_module, ident) { debug!("(resolving glob import) name `%s` is unexported", - self.session.str_of(atom)); + self.session.str_of(ident)); loop; } let mut dest_import_resolution; - match module_.import_resolutions.find(atom) { + match module_.import_resolutions.find(ident) { None => { // Create a new import resolution from this child. - dest_import_resolution = @ImportResolution(span); + dest_import_resolution = @ImportResolution(privacy, + span); module_.import_resolutions.insert - (atom, dest_import_resolution); + (ident, dest_import_resolution); } Some(existing_import_resolution) => { dest_import_resolution = existing_import_resolution; @@ -2306,7 +2325,7 @@ impl Resolver { debug!("(resolving glob import) writing resolution `%s` in `%s` \ to `%s`", - self.session.str_of(atom), + self.session.str_of(ident), self.module_to_str(containing_module), self.module_to_str(module_)); @@ -2333,7 +2352,7 @@ impl Resolver { } fn resolve_module_path_from_root(module_: @Module, - module_path: @DVec, + module_path: @DVec, index: uint, xray: XrayFlag, span: span) @@ -2372,7 +2391,7 @@ impl Resolver { str_of(name))); return Failed; } - ModuleDef(copy module_) => { + ModuleDef(_, copy module_) => { search_module = module_; } } @@ -2390,7 +2409,7 @@ impl Resolver { * the given module. */ fn resolve_module_path_for_import(module_: @Module, - module_path: @DVec, + module_path: @DVec, xray: XrayFlag, span: span) -> ResolveResult<@Module> { @@ -2400,7 +2419,7 @@ impl Resolver { debug!("(resolving module path for import) processing `%s` rooted at \ `%s`", - self.atoms_to_str((*module_path).get()), + self.idents_to_str((*module_path).get()), self.module_to_str(module_)); // The first element of the module path must be in the current scope @@ -2431,7 +2450,7 @@ impl Resolver { } fn resolve_item_in_lexical_scope(module_: @Module, - name: Atom, + name: ident, namespace: Namespace) -> ResolveResult { @@ -2517,7 +2536,7 @@ impl Resolver { } } - fn resolve_module_in_lexical_scope(module_: @Module, name: Atom) + fn resolve_module_in_lexical_scope(module_: @Module, name: ident) -> ResolveResult<@Module> { match self.resolve_item_in_lexical_scope(module_, name, ModuleNS) { @@ -2528,7 +2547,7 @@ impl Resolver { wasn't actually a module!"); return Failed; } - ModuleDef(module_) => { + ModuleDef(_, module_) => { return Success(module_); } } @@ -2546,7 +2565,7 @@ impl Resolver { } } - fn name_is_exported(module_: @Module, name: Atom) -> bool { + fn name_is_exported(module_: @Module, name: ident) -> bool { return !module_.legacy_exports || module_.exported_names.size() == 0u || module_.exported_names.contains_key(name); @@ -2558,7 +2577,7 @@ impl Resolver { * the name. */ fn resolve_name_in_module(module_: @Module, - name: Atom, + name: ident, namespace: Namespace, xray: XrayFlag) -> ResolveResult { @@ -2850,7 +2869,7 @@ impl Resolver { self.record_exports_for_module(module_); - for module_.children.each |_atom, child_name_bindings| { + for module_.children.each |_ident, child_name_bindings| { match child_name_bindings.get_module_if_available() { None => { // Nothing to do. @@ -2886,15 +2905,20 @@ impl Resolver { fn add_exports_of_namebindings(exports2: &mut ~[Export2], - atom: Atom, + ident: ident, namebindings: @NameBindings, reexport: bool) { for [ModuleNS, TypeNS, ValueNS].each |ns| { match namebindings.def_for_namespace(*ns) { Some(d) if d.privacy == Public => { - vec::push(*exports2, Export2 { + debug!("(computing exports) YES: %s '%s' \ + => %?", + if reexport { ~"reexport" } else { ~"export"}, + self.session.str_of(ident), + def_id_of_def(d.def)); + exports2.push(Export2 { reexport: reexport, - name: self.session.str_of(atom), + name: self.session.str_of(ident), def_id: def_id_of_def(d.def) }); } @@ -2905,16 +2929,20 @@ impl Resolver { fn add_exports_for_module(exports2: &mut ~[Export2], module_: @Module) { - for module_.children.each_ref |atom, namebindings| { - self.add_exports_of_namebindings(exports2, *atom, + for module_.children.each_ref |ident, namebindings| { + debug!("(computing exports) maybe export '%s'", + self.session.str_of(*ident)); + self.add_exports_of_namebindings(exports2, *ident, *namebindings, false) } - for module_.import_resolutions.each_ref |atom, importresolution| { + for module_.import_resolutions.each_ref |ident, importresolution| { for [ModuleNS, TypeNS, ValueNS].each |ns| { match importresolution.target_for_namespace(*ns) { Some(target) => { - self.add_exports_of_namebindings(exports2, *atom, + debug!("(computing exports) maybe reexport '%s'", + self.session.str_of(*ident)); + self.add_exports_of_namebindings(exports2, *ident, target.bindings, true) } @@ -2936,22 +2964,22 @@ impl Resolver { // Nothing to do. } ChildNameDefinition(target_def) => { - debug!("(computing exports) found child export '%s' \ + debug!("(computing exports) legacy export '%s' \ for %?", self.session.str_of(name), module_.def_id); - vec::push(*exports2, Export2 { + exports2.push(Export2 { reexport: false, name: self.session.str_of(name), def_id: def_id_of_def(target_def) }); } ImportNameDefinition(target_def) => { - debug!("(computing exports) found reexport '%s' for \ + debug!("(computing exports) legacy reexport '%s' for \ %?", self.session.str_of(name), module_.def_id); - vec::push(*exports2, Export2 { + exports2.push(Export2 { reexport: true, name: self.session.str_of(name), def_id: def_id_of_def(target_def) @@ -2980,7 +3008,7 @@ impl Resolver { // generate a fake "implementation scope" containing all the // implementations thus found, for compatibility with old resolve pass. - fn with_scope(name: Option, f: fn()) { + fn with_scope(name: Option, f: fn()) { let orig_module = self.current_module; // Move down in the graph. @@ -3120,7 +3148,7 @@ impl Resolver { return Some(dl_def(def)); } - fn search_ribs(ribs: @DVec<@Rib>, name: Atom, span: span, + fn search_ribs(ribs: @DVec<@Rib>, name: ident, span: span, allow_capturing_self: AllowCapturingSelfFlag) -> Option { @@ -3201,7 +3229,7 @@ impl Resolver { // Create a new rib for the self type. let self_type_rib = @Rib(NormalRibKind); (*self.type_ribs).push(self_type_rib); - self_type_rib.bindings.insert(self.self_atom, + self_type_rib.bindings.insert(self.self_ident, dl_def(def_self(item.id))); // Create a new rib for the trait-wide type parameters. @@ -3461,7 +3489,7 @@ impl Resolver { } HasSelfBinding(self_node_id) => { let def_like = dl_def(def_self(self_node_id)); - (*function_value_rib).bindings.insert(self.self_atom, + (*function_value_rib).bindings.insert(self.self_ident, def_like); } } @@ -3796,7 +3824,7 @@ impl Resolver { fn resolve_arm(arm: arm, visitor: ResolveVisitor) { (*self.value_ribs).push(@Rib(NormalRibKind)); - let bindings_list = atom_hashmap(); + let bindings_list = HashMap(); for arm.pats.each |pattern| { self.resolve_pattern(*pattern, RefutableMode, Immutable, Some(bindings_list), visitor); @@ -3915,7 +3943,7 @@ impl Resolver { mutability: Mutability, // Maps idents to the node ID for the (outermost) // pattern that binds them - bindings_list: Option>, + bindings_list: Option>, visitor: ResolveVisitor) { let pat_id = pattern.id; @@ -3932,13 +3960,13 @@ impl Resolver { // matching such a variant is simply disallowed (since // it's rarely what you want). - let atom = path.idents[0]; + let ident = path.idents[0]; - match self.resolve_enum_variant_or_const(atom) { + match self.resolve_enum_variant_or_const(ident) { FoundEnumVariant(def) if mode == RefutableMode => { debug!("(resolving pattern) resolving `%s` to \ enum variant", - self.session.str_of(atom)); + self.session.str_of(ident)); self.record_def(pattern.id, def); } @@ -3948,7 +3976,7 @@ impl Resolver { shadows an enum \ that's in scope", self.session - .str_of(atom))); + .str_of(ident))); } FoundConst => { self.session.span_err(pattern.span, @@ -3958,7 +3986,7 @@ impl Resolver { } EnumVariantOrConstNotFound => { debug!("(resolving pattern) binding `%s`", - self.session.str_of(atom)); + self.session.str_of(ident)); let is_mutable = mutability == Mutable; @@ -3989,14 +4017,14 @@ impl Resolver { match bindings_list { Some(bindings_list) - if !bindings_list.contains_key(atom) => { + if !bindings_list.contains_key(ident) => { let last_rib = (*self.value_ribs).last(); - last_rib.bindings.insert(atom, + last_rib.bindings.insert(ident, dl_def(def)); - bindings_list.insert(atom, pat_id); + bindings_list.insert(ident, pat_id); } Some(b) => { - if b.find(atom) == Some(pat_id) { + if b.find(ident) == Some(pat_id) { // Then this is a duplicate variable // in the same disjunct, which is an // error @@ -4010,7 +4038,7 @@ impl Resolver { } None => { let last_rib = (*self.value_ribs).last(); - last_rib.bindings.insert(atom, + last_rib.bindings.insert(ident, dl_def(def)); } } @@ -4088,7 +4116,7 @@ impl Resolver { } } - fn resolve_enum_variant_or_const(name: Atom) + fn resolve_enum_variant_or_const(name: ident) -> EnumVariantOrConstResolution { match self.resolve_item_in_lexical_scope(self.current_module, @@ -4183,7 +4211,7 @@ impl Resolver { // XXX: Merge me with resolve_name_in_module? fn resolve_definition_of_name_in_module(containing_module: @Module, - name: Atom, + name: ident, namespace: Namespace, xray: XrayFlag) -> NameDefinition { @@ -4215,7 +4243,8 @@ impl Resolver { // Next, search import resolutions. match containing_module.import_resolutions.find(name) { - Some(import_resolution) => { + Some(import_resolution) if import_resolution.privacy == Public || + xray == Xray => { match (*import_resolution).target_for_namespace(namespace) { Some(target) => { match (*target.bindings) @@ -4238,23 +4267,23 @@ impl Resolver { } } } - None => { + Some(_) | None => { return NoNameDefinition; } } } - fn intern_module_part_of_path(path: @path) -> @DVec { - let module_path_atoms = @DVec(); + fn intern_module_part_of_path(path: @path) -> @DVec { + let module_path_idents = @DVec(); for path.idents.eachi |index, ident| { if index == path.idents.len() - 1u { break; } - (*module_path_atoms).push(*ident); + (*module_path_idents).push(*ident); } - return module_path_atoms; + return module_path_idents; } fn resolve_module_relative_path(path: @path, @@ -4262,19 +4291,19 @@ impl Resolver { namespace: Namespace) -> Option { - let module_path_atoms = self.intern_module_part_of_path(path); + let module_path_idents = self.intern_module_part_of_path(path); let mut containing_module; match self.resolve_module_path_for_import(self.current_module, - module_path_atoms, + module_path_idents, xray, path.span) { Failed => { self.session.span_err(path.span, fmt!("use of undeclared module `%s`", - self.atoms_to_str( - (*module_path_atoms).get()))); + self.idents_to_str( + (*module_path_idents).get()))); return None; } @@ -4307,13 +4336,13 @@ impl Resolver { namespace: Namespace) -> Option { - let module_path_atoms = self.intern_module_part_of_path(path); + let module_path_idents = self.intern_module_part_of_path(path); let root_module = (*self.graph_root).get_module(); let mut containing_module; match self.resolve_module_path_from_root(root_module, - module_path_atoms, + module_path_idents, 0u, xray, path.span) { @@ -4321,8 +4350,8 @@ impl Resolver { Failed => { self.session.span_err(path.span, fmt!("use of undeclared module `::%s`", - self.atoms_to_str - ((*module_path_atoms).get()))); + self.idents_to_str + ((*module_path_idents).get()))); return None; } @@ -4654,7 +4683,7 @@ impl Resolver { } } - fn search_for_traits_containing_method(name: Atom) -> @DVec { + fn search_for_traits_containing_method(name: ident) -> @DVec { let found_traits = @DVec(); let mut search_module = self.current_module; loop { @@ -4693,7 +4722,7 @@ impl Resolver { // Look for imports. for search_module.import_resolutions.each - |_atom, import_resolution| { + |_ident, import_resolution| { match import_resolution.target_for_namespace(TypeNS) { None => { @@ -4739,7 +4768,7 @@ impl Resolver { fn add_trait_info_if_containing_method(found_traits: @DVec, trait_def_id: def_id, - name: Atom) { + name: ident) { match self.trait_info.find(trait_def_id) { Some(trait_info) if trait_info.contains_key(name) => { @@ -4805,7 +4834,7 @@ impl Resolver { self.check_for_unused_imports_in_module(module_); - for module_.children.each |_atom, child_name_bindings| { + for module_.children.each |_ident, child_name_bindings| { match (*child_name_bindings).get_module_if_available() { None => { // Nothing to do. @@ -4854,7 +4883,7 @@ impl Resolver { /// A somewhat inefficient routine to print out the name of a module. fn module_to_str(module_: @Module) -> ~str { - let atoms = DVec(); + let idents = DVec(); let mut current_module = module_; loop { match current_module.parent_link { @@ -4862,27 +4891,27 @@ impl Resolver { break; } ModuleParentLink(module_, name) => { - atoms.push(name); + idents.push(name); current_module = module_; } BlockParentLink(module_, _) => { - atoms.push(syntax::parse::token::special_idents::opaque); + idents.push(syntax::parse::token::special_idents::opaque); current_module = module_; } } } - if atoms.len() == 0u { + if idents.len() == 0u { return ~"???"; } let mut string = ~""; - let mut i = atoms.len() - 1u; + let mut i = idents.len() - 1u; loop { - if i < atoms.len() - 1u { + if i < idents.len() - 1u { string += ~"::"; } - string += self.session.str_of(atoms.get_elt(i)); + string += self.session.str_of(idents.get_elt(i)); if i == 0u { break; diff --git a/src/rustc/middle/trans/alt.rs b/src/rustc/middle/trans/alt.rs index 11b694bcb1d2..73f1e9bd1191 100644 --- a/src/rustc/middle/trans/alt.rs +++ b/src/rustc/middle/trans/alt.rs @@ -305,7 +305,7 @@ fn enter_match(bcx: block, dm: DefMap, m: &[@Match/&r], _ => {} } - vec::push(result, @Match {pats: pats, data: br.data}); + result.push(@Match {pats: pats, data: br.data}); } None => () } @@ -398,8 +398,8 @@ fn enter_rec_or_struct(bcx: block, dm: DefMap, m: &[@Match/&r], col: uint, let mut pats = ~[]; for vec::each(fields) |fname| { match fpats.find(|p| p.ident == *fname) { - None => vec::push(pats, dummy), - Some(pat) => vec::push(pats, pat.pat) + None => pats.push(dummy), + Some(pat) => pats.push(pat.pat) } } Some(pats) @@ -514,7 +514,7 @@ fn enter_region(bcx: block, dm: DefMap, m: &[@Match/&r], fn get_options(ccx: @crate_ctxt, m: &[@Match], col: uint) -> ~[Opt] { fn add_to_set(tcx: ty::ctxt, set: &DVec, val: Opt) { - if set.any(|l| opt_eq(tcx, &l, &val)) {return;} + if set.any(|l| opt_eq(tcx, l, &val)) {return;} set.push(val); } @@ -581,8 +581,8 @@ fn collect_record_or_struct_fields(m: &[@Match], col: uint) -> ~[ast::ident] { fn extend(idents: &mut ~[ast::ident], field_pats: &[ast::field_pat]) { for field_pats.each |field_pat| { let field_ident = field_pat.ident; - if !vec::any(*idents, |x| x == field_ident) { - vec::push(*idents, field_ident); + if !vec::any(*idents, |x| *x == field_ident) { + idents.push(field_ident); } } } @@ -1162,9 +1162,9 @@ fn trans_alt_inner(scope_cx: block, let arm_data = @ArmData {bodycx: body, arm: arm, bindings_map: bindings_map}; - vec::push(arm_datas, arm_data); + arm_datas.push(arm_data); for vec::each(arm.pats) |p| { - vec::push(matches, @Match {pats: ~[*p], data: arm_data}); + matches.push(@Match {pats: ~[*p], data: arm_data}); } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 65a788991bfc..0631d7b1ea4d 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -57,7 +57,7 @@ struct icx_popper { ccx: @crate_ctxt, drop { if self.ccx.sess.count_llvm_insns() { - vec::pop(*(self.ccx.stats.llvm_insn_ctxt)); + self.ccx.stats.llvm_insn_ctxt.pop(); } } } @@ -76,7 +76,7 @@ impl @crate_ctxt: get_insn_ctxt { fn insn_ctxt(s: &str) -> icx_popper { debug!("new insn_ctxt: %s", s); if self.sess.count_llvm_insns() { - vec::push(*self.stats.llvm_insn_ctxt, str::from_slice(s)); + self.stats.llvm_insn_ctxt.push(str::from_slice(s)); } icx_popper(self) } @@ -98,7 +98,7 @@ fn log_fn_time(ccx: @crate_ctxt, name: ~str, start: time::Timespec, end: time::Timespec) { let elapsed = 1000 * ((end.sec - start.sec) as int) + ((end.nsec as int) - (start.nsec as int)) / 1000000; - vec::push(*ccx.stats.fn_times, {ident: name, time: elapsed}); + ccx.stats.fn_times.push({ident: name, time: elapsed}); } fn decl_fn(llmod: ModuleRef, name: ~str, cc: lib::llvm::CallConv, @@ -383,7 +383,7 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, parent_id: ast::def_id, substs: ~[ty::t]) -> ValueRef { let _icx = ccx.insn_ctxt("trans_res_dtor"); - if (substs.len() > 0u) { + if (substs.is_not_empty()) { let did = if did.crate != ast::local_crate { inline::maybe_instantiate_inline(ccx, did) } else { did }; @@ -1153,7 +1153,7 @@ fn cleanup_and_leave(bcx: block, upto: Option, } let sub_cx = sub_block(bcx, ~"cleanup"); Br(bcx, sub_cx.llbb); - vec::push(inf.cleanup_paths, {target: leave, dest: sub_cx.llbb}); + inf.cleanup_paths.push({target: leave, dest: sub_cx.llbb}); bcx = trans_block_cleanups_(sub_cx, block_cleanups(cur), is_lpad); } _ => () @@ -1252,7 +1252,7 @@ fn alloc_local(cx: block, local: @ast::local) -> block { let val = alloc_ty(cx, t); if cx.sess().opts.debuginfo { do option::iter(&simple_name) |name| { - str::as_c_str(cx.ccx().sess.str_of(name), |buf| { + str::as_c_str(cx.ccx().sess.str_of(*name), |buf| { llvm::LLVMSetValueName(val, buf) }); } @@ -1406,9 +1406,9 @@ fn new_fn_ctxt_w_id(ccx: @crate_ctxt, path: path, mut llself: None, mut personality: None, mut loop_ret: None, - llargs: HashMap::(), - lllocals: HashMap::(), - llupvars: HashMap::(), + llargs: HashMap(), + lllocals: HashMap(), + llupvars: HashMap(), id: id, param_substs: param_substs, span: sp, @@ -1496,7 +1496,7 @@ fn copy_args_to_allocas(fcx: fn_ctxt, // For certain mode/type combinations, the raw llarg values are passed // by value. However, within the fn body itself, we want to always - // have all locals and argumenst be by-ref so that we can cancel the + // have all locals and arguments be by-ref so that we can cancel the // cleanup and for better interaction with LLVM's debug info. So, if // the argument would be passed by value, we store it into an alloca. // This alloca should be optimized away by LLVM's mem-to-reg pass in @@ -1767,9 +1767,7 @@ fn trans_class_dtor(ccx: @crate_ctxt, path: path, /* The dtor takes a (null) output pointer, and a self argument, and returns () */ - let lldty = T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(tcx))), - T_ptr(type_of(ccx, class_ty))], - llvm::LLVMVoidType()); + let lldty = type_of_dtor(ccx, class_ty); let s = get_dtor_symbol(ccx, path, dtor_id, psubsts); @@ -1780,7 +1778,7 @@ fn trans_class_dtor(ccx: @crate_ctxt, path: path, /* If we're monomorphizing, register the monomorphized decl for the dtor */ do option::iter(&hash_id) |h_id| { - ccx.monomorphized.insert(h_id, lldecl); + ccx.monomorphized.insert(*h_id, lldecl); } /* Translate the dtor body */ trans_fn(ccx, path, ast_util::dtor_dec(), @@ -1833,7 +1831,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) { *path, ~[path_name(item.ident)]), decl, body, llfndecl, item.id); - } else if tps.len() == 0u { + } else if tps.is_empty() { let llfndecl = get_item_val(ccx, item.id); trans_fn(ccx, vec::append(*path, ~[path_name(item.ident)]), @@ -2001,7 +1999,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, let llenvarg = llvm::LLVMGetParam(llfdecl, 1 as c_uint); let mut args = ~[lloutputarg, llenvarg]; if takes_argv { - vec::push(args, llvm::LLVMGetParam(llfdecl, 2 as c_uint)); + args.push(llvm::LLVMGetParam(llfdecl, 2 as c_uint)); } Call(bcx, main_llfn, args); @@ -2315,7 +2313,7 @@ fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> { let frameaddress = decl_cdecl_fn(llmod, ~"llvm.frameaddress", T_fn(T_frameaddress_args, T_ptr(T_i8()))); - let intrinsics = HashMap::<~str,ValueRef>(); + let intrinsics = HashMap(); intrinsics.insert(~"llvm.gcroot", gcroot); intrinsics.insert(~"llvm.gcread", gcread); intrinsics.insert(~"llvm.memmove.p0i8.p0i8.i32", memmove32); @@ -2349,10 +2347,15 @@ fn trap(bcx: block) { } fn push_rtcall(ccx: @crate_ctxt, name: ~str, did: ast::def_id) { - if ccx.rtcalls.contains_key(name) { - fail fmt!("multiple definitions for runtime call %s", name); + match ccx.rtcalls.find(name) { + Some(existing_did) if did != existing_did => { + ccx.sess.fatal(fmt!("multiple definitions for runtime call %s", + name)); + } + Some(_) | None => { + ccx.rtcalls.insert(name, did); + } } - ccx.rtcalls.insert(name, did); } fn gather_local_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) { @@ -2451,10 +2454,10 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef { for ccx.module_data.each |key, val| { let elt = C_struct(~[p2i(ccx, C_cstr(ccx, key)), p2i(ccx, val)]); - vec::push(elts, elt); + elts.push(elt); } let term = C_struct(~[C_int(ccx, 0), C_int(ccx, 0)]); - vec::push(elts, term); + elts.push(term); llvm::LLVMSetInitializer(map, C_array(elttype, elts)); return map; } @@ -2492,10 +2495,10 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) { let cr = str::as_c_str(nm, |buf| { llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) }); - vec::push(subcrates, p2i(ccx, cr)); + subcrates.push(p2i(ccx, cr)); i += 1; } - vec::push(subcrates, C_int(ccx, 0)); + subcrates.push(C_int(ccx, 0)); let llannihilatefn; let annihilate_def_id = ccx.tcx.lang_items.annihilate_fn.get(); @@ -2627,17 +2630,17 @@ fn trans_crate(sess: session::session, llmod: llmod, td: td, tn: tn, - externs: HashMap::<~str,ValueRef>(), + externs: HashMap(), intrinsics: intrinsics, - item_vals: HashMap::(), + item_vals: HashMap(), exp_map2: emap2, reachable: reachable, - item_symbols: HashMap::(), + item_symbols: HashMap(), mut main_fn: None::, link_meta: link_meta, enum_sizes: ty::new_ty_hash(), discrims: HashMap(), - discrim_symbols: HashMap::(), + discrim_symbols: HashMap(), tydescs: ty::new_ty_hash(), mut finished_tydescs: false, external: HashMap(), @@ -2646,15 +2649,15 @@ fn trans_crate(sess: session::session, type_use_cache: HashMap(), vtables: map::HashMap(), const_cstr_cache: HashMap(), - const_globals: HashMap::(), - module_data: HashMap::<~str,ValueRef>(), + const_globals: HashMap(), + module_data: HashMap(), lltypes: ty::new_ty_hash(), names: new_namegen(sess.parse_sess.interner), next_addrspace: new_addrspace_gen(), symbol_hasher: symbol_hasher, type_hashcodes: ty::new_ty_hash(), type_short_names: ty::new_ty_hash(), - all_llvm_symbols: HashMap::<~str,()>(), + all_llvm_symbols: HashMap(), tcx: tcx, maps: maps, stats: @@ -2672,7 +2675,7 @@ fn trans_crate(sess: session::session, upcalls: upcall::declare_upcalls(targ_cfg, tn, tydesc_type, llmod), - rtcalls: HashMap::<~str,ast::def_id>(), + rtcalls: HashMap(), tydesc_type: tydesc_type, int_type: int_type, float_type: float_type, @@ -2683,7 +2686,7 @@ fn trans_crate(sess: session::session, crate_map: crate_map, mut uses_gc: false, dbg_cx: dbg_cx, - class_ctors: HashMap::(), + class_ctors: HashMap(), mut do_not_commit_warning_issued: false}; @@ -2701,11 +2704,7 @@ fn trans_crate(sess: session::session, decl_gc_metadata(ccx, llmod_id); fill_crate_map(ccx, crate_map); - // NB: Must call force_declare_tydescs before emit_tydescs to break - // cyclical dependency with shape code! See shape.rs for details. - force_declare_tydescs(ccx); glue::emit_tydescs(ccx); - gen_shape_tables(ccx); write_abi_version(ccx); // Translate the metadata. diff --git a/src/rustc/middle/trans/build.rs b/src/rustc/middle/trans/build.rs index 865374054e65..69de8a2cca3e 100644 --- a/src/rustc/middle/trans/build.rs +++ b/src/rustc/middle/trans/build.rs @@ -134,7 +134,7 @@ fn IndirectBr(cx: block, Addr: ValueRef, NumDests: uint) { // lot more efficient) than doing str::as_c_str("", ...) every time. fn noname() -> *libc::c_char unsafe { const cnull: uint = 0u; - return cast::reinterpret_cast(&ptr::addr_of(cnull)); + return cast::reinterpret_cast(&ptr::addr_of(&cnull)); } fn Invoke(cx: block, Fn: ValueRef, Args: ~[ValueRef], @@ -435,7 +435,7 @@ fn GEP(cx: block, Pointer: ValueRef, Indices: ~[ValueRef]) -> ValueRef { // XXX: Use a small-vector optimization to avoid allocations here. fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef { let mut v: ~[ValueRef] = ~[]; - for vec::each(ixs) |i| { vec::push(v, C_i32(*i as i32)); } + for vec::each(ixs) |i| { v.push(C_i32(*i as i32)); } count_insn(cx, "gepi"); return InBoundsGEP(cx, base, v); } @@ -629,8 +629,8 @@ fn Phi(cx: block, Ty: TypeRef, vals: ~[ValueRef], bbs: ~[BasicBlockRef]) fn AddIncomingToPhi(phi: ValueRef, val: ValueRef, bb: BasicBlockRef) { if llvm::LLVMIsUndef(phi) == lib::llvm::True { return; } unsafe { - let valptr = cast::reinterpret_cast(&ptr::addr_of(val)); - let bbptr = cast::reinterpret_cast(&ptr::addr_of(bb)); + let valptr = cast::reinterpret_cast(&ptr::addr_of(&val)); + let bbptr = cast::reinterpret_cast(&ptr::addr_of(&bb)); llvm::LLVMAddIncoming(phi, valptr, bbptr, 1 as c_uint); } } diff --git a/src/rustc/middle/trans/callee.rs b/src/rustc/middle/trans/callee.rs index 3050297b360f..e7b4dd171e31 100644 --- a/src/rustc/middle/trans/callee.rs +++ b/src/rustc/middle/trans/callee.rs @@ -478,10 +478,10 @@ fn trans_args(cx: block, llenv: ValueRef, args: CallArgs, fn_ty: ty::t, } } }; - vec::push(llargs, llretslot); + llargs.push(llretslot); // Arg 1: Env (closure-bindings / self value) - vec::push(llargs, llenv); + llargs.push(llenv); // ... then explicit args. @@ -497,11 +497,11 @@ fn trans_args(cx: block, llenv: ValueRef, args: CallArgs, fn_ty: ty::t, if i == last { ret_flag } else { None }, autoref_arg) }); - vec::push(llargs, arg_val); + llargs.push(arg_val); } } ArgVals(vs) => { - vec::push_all(llargs, vs); + llargs.push_all(vs); } } @@ -537,7 +537,7 @@ fn trans_arg_expr(bcx: block, ret_flag=%?)", formal_ty.mode, bcx.ty_to_str(formal_ty.ty), bcx.expr_to_str(arg_expr), - ret_flag.map(|v| bcx.val_str(v))); + ret_flag.map(|v| bcx.val_str(*v))); let _indenter = indenter(); // translate the arg expr to a datum @@ -622,7 +622,7 @@ fn trans_arg_expr(bcx: block, // However, we must cleanup should we fail before the // callee is actually invoked. scratch.add_clean(bcx); - vec::push(*temp_cleanups, scratch.val); + temp_cleanups.push(scratch.val); match arg_datum.appropriate_mode() { ByValue => { diff --git a/src/rustc/middle/trans/closure.rs b/src/rustc/middle/trans/closure.rs index 38526c223a1c..1ab25a183293 100644 --- a/src/rustc/middle/trans/closure.rs +++ b/src/rustc/middle/trans/closure.rs @@ -259,16 +259,16 @@ fn build_closure(bcx0: block, match cap_var.mode { capture::cap_ref => { assert ck == ty::ck_block; - vec::push(env_vals, EnvValue {action: EnvRef, - datum: datum}); + env_vals.push(EnvValue {action: EnvRef, + datum: datum}); } capture::cap_copy => { - vec::push(env_vals, EnvValue {action: EnvStore, - datum: datum}); + env_vals.push(EnvValue {action: EnvStore, + datum: datum}); } capture::cap_move => { - vec::push(env_vals, EnvValue {action: EnvMove, - datum: datum}); + env_vals.push(EnvValue {action: EnvMove, + datum: datum}); } capture::cap_drop => { bcx = datum.drop_val(bcx); @@ -281,10 +281,10 @@ fn build_closure(bcx0: block, // variables: do option::iter(&include_ret_handle) |flagptr| { // Flag indicating we have returned (a by-ref bool): - let flag_datum = Datum {val: flagptr, ty: ty::mk_bool(tcx), + let flag_datum = Datum {val: *flagptr, ty: ty::mk_bool(tcx), mode: ByRef, source: FromLvalue}; - vec::push(env_vals, EnvValue {action: EnvRef, - datum: flag_datum}); + env_vals.push(EnvValue {action: EnvRef, + datum: flag_datum}); // Return value (we just pass a by-ref () and cast it later to // the right thing): @@ -295,8 +295,8 @@ fn build_closure(bcx0: block, let ret_casted = PointerCast(bcx, ret_true, T_ptr(T_nil())); let ret_datum = Datum {val: ret_casted, ty: ty::mk_nil(tcx), mode: ByRef, source: FromLvalue}; - vec::push(env_vals, EnvValue {action: EnvRef, - datum: ret_datum}); + env_vals.push(EnvValue {action: EnvRef, + datum: ret_datum}); } return store_environment(bcx, env_vals, ck); @@ -363,7 +363,7 @@ fn trans_expr_fn(bcx: block, let llfnty = type_of_fn_from_ty(ccx, fty); let sub_path = vec::append_one(bcx.fcx.path, path_name(special_idents::anon)); - let s = mangle_internal_name_by_path(ccx, sub_path); + let s = mangle_internal_name_by_path_and_seq(ccx, sub_path, ~"expr_fn"); let llfn = decl_internal_cdecl_fn(ccx.llmod, s, llfnty); let trans_closure_env = fn@(ck: ty::closure_kind) -> Result { diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs index a1ca4287f0ef..6768f3e71a0d 100644 --- a/src/rustc/middle/trans/common.rs +++ b/src/rustc/middle/trans/common.rs @@ -25,9 +25,9 @@ use syntax::parse::token::ident_interner; use syntax::ast::ident; type namegen = fn@(~str) -> ident; -fn new_namegen(intr: ident_interner) -> namegen { +fn new_namegen(intr: @ident_interner) -> namegen { return fn@(prefix: ~str) -> ident { - return intr.gensym(@fmt!("%s_%u", prefix, intr.gensym(@prefix))) + return intr.gensym(@fmt!("%s_%u", prefix, intr.gensym(@prefix).repr)) }; } @@ -348,9 +348,9 @@ fn add_clean(bcx: block, val: ValueRef, t: ty::t) { let {root, rooted} = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); do in_scope_cx(bcx) |info| { - vec::push(info.cleanups, - clean(|a| glue::drop_ty_root(a, root, rooted, t), - cleanup_type)); + info.cleanups.push( + clean(|a| glue::drop_ty_root(a, root, rooted, t), + cleanup_type)); scope_clean_changed(info); } } @@ -362,9 +362,9 @@ fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) { ty_to_str(cx.ccx().tcx, ty)); let cleanup_type = cleanup_type(cx.tcx(), ty); do in_scope_cx(cx) |info| { - vec::push(info.cleanups, - clean_temp(val, |a| glue::drop_ty_immediate(a, val, ty), - cleanup_type)); + info.cleanups.push( + clean_temp(val, |a| glue::drop_ty_immediate(a, val, ty), + cleanup_type)); scope_clean_changed(info); } } @@ -376,9 +376,9 @@ fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { let {root, rooted} = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); do in_scope_cx(bcx) |info| { - vec::push(info.cleanups, - clean_temp(val, |a| glue::drop_ty_root(a, root, rooted, t), - cleanup_type)); + info.cleanups.push( + clean_temp(val, |a| glue::drop_ty_root(a, root, rooted, t), + cleanup_type)); scope_clean_changed(info); } } @@ -388,8 +388,8 @@ fn add_clean_free(cx: block, ptr: ValueRef, heap: heap) { heap_exchange => |a| glue::trans_unique_free(a, ptr) }; do in_scope_cx(cx) |info| { - vec::push(info.cleanups, clean_temp(ptr, free_fn, - normal_exit_and_unwind)); + info.cleanups.push(clean_temp(ptr, free_fn, + normal_exit_and_unwind)); scope_clean_changed(info); } } @@ -402,7 +402,7 @@ fn revoke_clean(cx: block, val: ValueRef) { do in_scope_cx(cx) |info| { let cleanup_pos = vec::position( info.cleanups, - |cu| match cu { + |cu| match *cu { clean_temp(v, _, _) if v == val => true, _ => false }); @@ -472,7 +472,7 @@ type optional_boxed_ast_expr = Option<@ast::expr>; impl optional_boxed_ast_expr: get_node_info { fn info() -> Option { - self.chain(|s| s.info()) + self.chain_ref(|s| s.info()) } } @@ -645,7 +645,7 @@ impl block { fmt!("[block %d]", node_info.id) } None => { - fmt!("[block %x]", ptr::addr_of(*self) as uint) + fmt!("[block %x]", ptr::addr_of(&(*self)) as uint) } } } @@ -1024,7 +1024,7 @@ fn C_cstr(cx: @crate_ctxt, s: ~str) -> ValueRef { llvm::LLVMConstString(buf, str::len(s) as c_uint, False) }; let g = - str::as_c_str(fmt!("str%u", cx.names(~"str")), + str::as_c_str(fmt!("str%u", cx.names(~"str").repr), |buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf)); llvm::LLVMSetInitializer(g, sc); llvm::LLVMSetGlobalConstant(g, True); @@ -1050,7 +1050,7 @@ fn C_postr(s: ~str) -> ValueRef { fn C_zero_byte_arr(size: uint) -> ValueRef unsafe { let mut i = 0u; let mut elts: ~[ValueRef] = ~[]; - while i < size { vec::push(elts, C_u8(0u)); i += 1u; } + while i < size { elts.push(C_u8(0u)); i += 1u; } return llvm::LLVMConstArray(T_i8(), vec::raw::to_ptr(elts), elts.len() as c_uint); } @@ -1086,7 +1086,8 @@ fn C_bytes_plus_null(bytes: ~[u8]) -> ValueRef unsafe { fn C_shape(ccx: @crate_ctxt, bytes: ~[u8]) -> ValueRef { let llshape = C_bytes_plus_null(bytes); - let llglobal = str::as_c_str(fmt!("shape%u", ccx.names(~"shape")), |buf| { + let name = fmt!("shape%u", ccx.names(~"shape").repr); + let llglobal = str::as_c_str(name, |buf| { llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf) }); llvm::LLVMSetInitializer(llglobal, llshape); @@ -1141,7 +1142,7 @@ impl mono_id_ : cmp::Eq { } impl mono_param_id : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { mono_precise(t, mids) => to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), &mids, lsb0, f), @@ -1155,7 +1156,7 @@ impl mono_param_id : to_bytes::IterBytes { } impl mono_id_ : core::to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f); } } @@ -1221,7 +1222,7 @@ fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] { fn node_vtables(bcx: block, id: ast::node_id) -> Option { let raw_vtables = bcx.ccx().maps.vtable_map.find(id); raw_vtables.map( - |vts| meth::resolve_vtables_in_fn_ctxt(bcx.fcx, vts)) + |vts| meth::resolve_vtables_in_fn_ctxt(bcx.fcx, *vts)) } fn resolve_vtables_in_fn_ctxt(fcx: fn_ctxt, vts: typeck::vtable_res) diff --git a/src/rustc/middle/trans/controlflow.rs b/src/rustc/middle/trans/controlflow.rs index 5d8b0fbbbe15..ce32cd0a2dd1 100644 --- a/src/rustc/middle/trans/controlflow.rs +++ b/src/rustc/middle/trans/controlflow.rs @@ -158,7 +158,7 @@ fn trans_log(log_ex: @ast::expr, let modpath = vec::append( ~[path_mod(ccx.sess.ident_of(ccx.link_meta.name))], vec::filter(bcx.fcx.path, |e| - match e { path_mod(_) => true, _ => false } + match *e { path_mod(_) => true, _ => false } )); let modname = path_str(ccx.sess, modpath); @@ -344,3 +344,21 @@ fn trans_fail_value(bcx: block, sp_opt: Option, V_fail_str: ValueRef) Unreachable(bcx); return bcx; } + +fn trans_fail_bounds_check(bcx: block, sp: span, + index: ValueRef, len: ValueRef) -> block { + let _icx = bcx.insn_ctxt("trans_fail_bounds_check"); + let ccx = bcx.ccx(); + + let loc = codemap::lookup_char_pos(bcx.sess().parse_sess.cm, sp.lo); + let line = C_int(ccx, loc.line as int); + let filename_cstr = C_cstr(bcx.ccx(), loc.file.name); + let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8())); + + let args = ~[filename, line, index, len]; + let bcx = callee::trans_rtcall(bcx, ~"fail_bounds_check", args, + expr::Ignore); + Unreachable(bcx); + return bcx; +} + diff --git a/src/rustc/middle/trans/datum.rs b/src/rustc/middle/trans/datum.rs index 3f2705a9bcc5..241fa5e53afb 100644 --- a/src/rustc/middle/trans/datum.rs +++ b/src/rustc/middle/trans/datum.rs @@ -146,7 +146,7 @@ impl DatumMode: cmp::Eq { } impl DatumMode: to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as uint).iter_bytes(lsb0, f) } } @@ -204,7 +204,7 @@ fn appropriate_mode(ty: ty::t) -> DatumMode { * * Indicates the "appropriate" mode for this value, * which is either by ref or by value, depending - * on whether type is iimmediate or what. */ + * on whether type is immediate or not. */ if ty::type_is_nil(ty) || ty::type_is_bot(ty) { ByValue diff --git a/src/rustc/middle/trans/debuginfo.rs b/src/rustc/middle/trans/debuginfo.rs index 9944daefea40..6cd4b49fa3b3 100644 --- a/src/rustc/middle/trans/debuginfo.rs +++ b/src/rustc/middle/trans/debuginfo.rs @@ -90,7 +90,7 @@ type debug_ctxt = { crate_file: ~str }; -fn mk_ctxt(crate: ~str, intr: ident_interner) -> debug_ctxt { +fn mk_ctxt(crate: ~str, intr: @ident_interner) -> debug_ctxt { {llmetadata: map::HashMap(), names: new_namegen(intr), crate_file: crate} @@ -383,7 +383,7 @@ fn create_derived_type(type_tag: int, file: ValueRef, name: ~str, line: int, fn add_member(cx: @struct_ctxt, name: ~str, line: int, size: int, align: int, ty: ValueRef) { - vec::push(cx.members, create_derived_type(MemberTag, cx.file, name, line, + cx.members.push(create_derived_type(MemberTag, cx.file, name, line, size * 8, align * 8, cx.total_size, ty)); cx.total_size += size * 8; @@ -529,7 +529,7 @@ fn create_ty(_cx: @crate_ctxt, _t: ty::t, _ty: @ast::ty) ty::ty_rec(fields) { let fs = ~[]; for field in fields { - vec::push(fs, {node: {ident: field.ident, + fs.push({node: {ident: field.ident, mt: {ty: t_to_ty(cx, field.mt.ty, span), mutbl: field.mt.mutbl}}, span: span}); diff --git a/src/rustc/middle/trans/expr.rs b/src/rustc/middle/trans/expr.rs index 0a38e19a26c5..57439daca2f2 100644 --- a/src/rustc/middle/trans/expr.rs +++ b/src/rustc/middle/trans/expr.rs @@ -813,7 +813,7 @@ fn trans_local_var(bcx: block, ref_id: ast::node_id, def: ast::def) -> Datum { nid: ast::node_id) -> Datum { let is_last_use = match bcx.ccx().maps.last_use_map.find(ref_id) { None => false, - Some(vars) => (*vars).contains(nid) + Some(vars) => (*vars).contains(&nid) }; let source = if is_last_use {FromLastUseLvalue} else {FromLvalue}; @@ -946,7 +946,9 @@ fn trans_index(bcx: block, let bounds_check = ICmp(bcx, lib::llvm::IntUGE, scaled_ix, len); let bcx = do with_cond(bcx, bounds_check) |bcx| { - controlflow::trans_fail(bcx, Some(index_expr.span), ~"bounds check") + let unscaled_len = UDiv(bcx, len, vt.llunit_size); + controlflow::trans_fail_bounds_check(bcx, index_expr.span, + ix_val, unscaled_len) }; let elt = InBoundsGEP(bcx, base, ~[ix_val]); let elt = PointerCast(bcx, elt, T_ptr(vt.llunit_ty)); @@ -993,7 +995,7 @@ fn trans_rec_or_struct(bcx: block, let dest = GEPi(bcx, addr, struct_field(ix)); bcx = trans_into(bcx, field.node.expr, SaveIn(dest)); add_clean_temp_mem(bcx, dest, field_tys[ix].mt.ty); - vec::push(temp_cleanups, dest); + temp_cleanups.push(dest); } // copy over any remaining fields from the base (for @@ -1046,7 +1048,7 @@ fn trans_tup(bcx: block, elts: ~[@ast::expr], dest: Dest) -> block { let e_ty = expr_ty(bcx, *e); bcx = trans_into(bcx, *e, SaveIn(dest)); add_clean_temp_mem(bcx, dest, e_ty); - vec::push(temp_cleanups, dest); + temp_cleanups.push(dest); } for vec::each(temp_cleanups) |cleanup| { revoke_clean(bcx, *cleanup); diff --git a/src/rustc/middle/trans/foreign.rs b/src/rustc/middle/trans/foreign.rs index e775b3fd746f..74dadd2cab49 100644 --- a/src/rustc/middle/trans/foreign.rs +++ b/src/rustc/middle/trans/foreign.rs @@ -92,7 +92,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { Double => 8, Struct => { do vec::foldl(0, struct_tys(ty)) |a, t| { - uint::max(a, ty_align(t)) + uint::max(a, ty_align(*t)) } } Array => { @@ -113,7 +113,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { Double => 8, Struct => { do vec::foldl(0, struct_tys(ty)) |s, t| { - s + ty_size(t) + s + ty_size(*t) } } Array => { @@ -297,21 +297,21 @@ fn llreg_ty(cls: ~[x86_64_reg_class]) -> TypeRef { while i < e { match cls[i] { integer_class => { - vec::push(tys, T_i64()); + tys.push(T_i64()); } sse_fv_class => { let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; let vec_ty = llvm::LLVMVectorType(T_f32(), vec_len as c_uint); - vec::push(tys, vec_ty); + tys.push(vec_ty); i += vec_len; loop; } sse_fs_class => { - vec::push(tys, T_f32()); + tys.push(T_f32()); } sse_ds_class => { - vec::push(tys, T_f64()); + tys.push(T_f64()); } _ => fail ~"llregtype: unhandled class" } @@ -378,8 +378,8 @@ fn x86_64_tys(atys: ~[TypeRef], let mut attrs = ~[]; for vec::each(atys) |t| { let (ty, attr) = x86_64_ty(*t, is_pass_byval, ByValAttribute); - vec::push(arg_tys, ty); - vec::push(attrs, attr); + arg_tys.push(ty); + attrs.push(attr); } let mut (ret_ty, ret_attr) = x86_64_ty(rty, is_ret_bysret, StructRetAttribute); @@ -619,7 +619,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt, } else { load_inbounds(bcx, llargbundle, [0u, i]) }; - vec::push(llargvals, llargval); + llargvals.push(llargval); i += 1u; } } @@ -627,7 +627,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt, while i < n { let llargval = load_inbounds(bcx, llargbundle, [0u, i]); - vec::push(llargvals, llargval); + llargvals.push(llargval); i += 1u; } } @@ -1041,12 +1041,12 @@ fn trans_foreign_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl, let mut i = 0u; let n = vec::len(tys.arg_tys); let llretptr = load_inbounds(bcx, llargbundle, ~[0u, n]); - vec::push(llargvals, llretptr); + llargvals.push(llretptr); let llenvptr = C_null(T_opaque_box_ptr(bcx.ccx())); - vec::push(llargvals, llenvptr); + llargvals.push(llenvptr); while i < n { let llargval = load_inbounds(bcx, llargbundle, ~[0u, i]); - vec::push(llargvals, llargval); + llargvals.push(llargval); i += 1u; } return llargvals; diff --git a/src/rustc/middle/trans/glue.rs b/src/rustc/middle/trans/glue.rs index 8ac42bc22846..a8a750cd4be4 100644 --- a/src/rustc/middle/trans/glue.rs +++ b/src/rustc/middle/trans/glue.rs @@ -192,16 +192,16 @@ fn lazily_emit_simplified_tydesc_glue(ccx: @crate_ctxt, field: uint, lazily_emit_tydesc_glue(ccx, field, simpl_ti); if field == abi::tydesc_field_take_glue { ti.take_glue = - simpl_ti.take_glue.map(|v| cast_glue(ccx, ti, v)); + simpl_ti.take_glue.map(|v| cast_glue(ccx, ti, *v)); } else if field == abi::tydesc_field_drop_glue { ti.drop_glue = - simpl_ti.drop_glue.map(|v| cast_glue(ccx, ti, v)); + simpl_ti.drop_glue.map(|v| cast_glue(ccx, ti, *v)); } else if field == abi::tydesc_field_free_glue { ti.free_glue = - simpl_ti.free_glue.map(|v| cast_glue(ccx, ti, v)); + simpl_ti.free_glue.map(|v| cast_glue(ccx, ti, *v)); } else if field == abi::tydesc_field_visit_glue { ti.visit_glue = - simpl_ti.visit_glue.map(|v| cast_glue(ccx, ti, v)); + simpl_ti.visit_glue.map(|v| cast_glue(ccx, ti, *v)); } return true; } @@ -398,7 +398,7 @@ fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { ty::ty_class(did, ref substs) => { // Call the dtor if there is one do option::map_default(&ty::ty_dtor(bcx.tcx(), did), bcx) |dt_id| { - trans_class_drop(bcx, v, dt_id, did, substs) + trans_class_drop(bcx, v, *dt_id, did, substs) } } _ => bcx @@ -426,8 +426,8 @@ fn trans_class_drop(bcx: block, // Class dtors have no explicit args, so the params should // just consist of the output pointer and the environment // (self) - assert(params.len() == 2u); - let self_arg = PointerCast(bcx, v0, params[1u]); + assert(params.len() == 2); + let self_arg = PointerCast(bcx, v0, params[1]); let args = ~[bcx.fcx.llretptr, self_arg]; Call(bcx, dtor_addr, args); @@ -440,7 +440,7 @@ fn trans_class_drop(bcx: block, bcx = drop_ty(bcx, llfld_a, fld.mt.ty); } - Store(bcx, C_u8(0u), drop_flag); + Store(bcx, C_u8(0), drop_flag); bcx } } @@ -679,7 +679,7 @@ fn emit_tydescs(ccx: @crate_ctxt) { let _icx = ccx.insn_ctxt("emit_tydescs"); // As of this point, allow no more tydescs to be created. ccx.finished_tydescs = true; - for ccx.tydescs.each |key, val| { + for ccx.tydescs.each |_key, val| { let glue_fn_ty = T_ptr(T_generic_glue_fn(ccx)); let ti = val; @@ -720,10 +720,8 @@ fn emit_tydescs(ccx: @crate_ctxt) { } }; - let shape = shape_of(ccx, key); - let shape_tables = - llvm::LLVMConstPointerCast(ccx.shape_cx.llshapetables, - T_ptr(T_i8())); + let shape = C_null(T_ptr(T_i8())); + let shape_tables = C_null(T_ptr(T_i8())); let tydesc = C_named_struct(ccx.tydesc_type, @@ -733,7 +731,7 @@ fn emit_tydescs(ccx: @crate_ctxt) { drop_glue, // drop_glue free_glue, // free_glue visit_glue, // visit_glue - C_shape(ccx, shape), // shape + shape, // shape shape_tables]); // shape_tables let gvar = ti.tydesc; diff --git a/src/rustc/middle/trans/inline.rs b/src/rustc/middle/trans/inline.rs index 08e9cde6ac53..76888471bf97 100644 --- a/src/rustc/middle/trans/inline.rs +++ b/src/rustc/middle/trans/inline.rs @@ -49,7 +49,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id) ast::item_enum(_, _) => { let vs_here = ty::enum_variants(ccx.tcx, local_def(item.id)); let vs_there = ty::enum_variants(ccx.tcx, parent_id); - do vec::iter2(*vs_here, *vs_there) |here, there| { + for vec::each2(*vs_here, *vs_there) |here, there| { if there.id == fn_id { my_id = here.id.node; } ccx.external.insert(there.id, Some(here.id.node)); } diff --git a/src/rustc/middle/trans/machine.rs b/src/rustc/middle/trans/machine.rs new file mode 100644 index 000000000000..5515d80f4bde --- /dev/null +++ b/src/rustc/middle/trans/machine.rs @@ -0,0 +1,148 @@ +// Information concerning the machine representation of various types. + +use middle::trans::common::*; + +// Creates a simpler, size-equivalent type. The resulting type is guaranteed +// to have (a) the same size as the type that was passed in; (b) to be non- +// recursive. This is done by replacing all boxes in a type with boxed unit +// types. +// This should reduce all pointers to some simple pointer type, to +// ensure that we don't recurse endlessly when computing the size of a +// nominal type that has pointers to itself in it. +pub fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t { + fn nilptr(tcx: ty::ctxt) -> ty::t { + ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx), mutbl: ast::m_imm}) + } + fn simplifier(tcx: ty::ctxt, typ: ty::t) -> ty::t { + match ty::get(typ).sty { + ty::ty_box(_) | ty::ty_opaque_box | ty::ty_uniq(_) | + ty::ty_evec(_, ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_box) | + ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) | + ty::ty_ptr(_) | ty::ty_rptr(_,_) => nilptr(tcx), + ty::ty_fn(_) => ty::mk_tup(tcx, ~[nilptr(tcx), nilptr(tcx)]), + ty::ty_evec(_, ty::vstore_slice(_)) | + ty::ty_estr(ty::vstore_slice(_)) => { + ty::mk_tup(tcx, ~[nilptr(tcx), ty::mk_int(tcx)]) + } + // Reduce a class type to a record type in which all the fields are + // simplified + ty::ty_class(did, ref substs) => { + let simpl_fields = (if ty::ty_dtor(tcx, did).is_some() { + // remember the drop flag + ~[{ident: syntax::parse::token::special_idents::dtor, + mt: {ty: ty::mk_u8(tcx), + mutbl: ast::m_mutbl}}] } + else { ~[] }) + + do ty::lookup_class_fields(tcx, did).map |f| { + let t = ty::lookup_field_type(tcx, did, f.id, substs); + {ident: f.ident, + mt: {ty: simplify_type(tcx, t), mutbl: ast::m_const}} + }; + ty::mk_rec(tcx, simpl_fields) + } + _ => typ + } + } + ty::fold_ty(tcx, typ, |t| simplifier(tcx, t)) +} + +// ______________________________________________________________________ +// compute sizeof / alignof + +pub type metrics = { + bcx: block, + sz: ValueRef, + align: ValueRef +}; + +pub type tag_metrics = { + bcx: block, + sz: ValueRef, + align: ValueRef, + payload_align: ValueRef +}; + +// Returns the number of bytes clobbered by a Store to this type. +pub fn llsize_of_store(cx: @crate_ctxt, t: TypeRef) -> uint { + return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint; +} + +// Returns the number of bytes between successive elements of type T in an +// array of T. This is the "ABI" size. It includes any ABI-mandated padding. +pub fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint { + return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint; +} + +// Returns, as near as we can figure, the "real" size of a type. As in, the +// bits in this number of bytes actually carry data related to the datum +// with the type. Not junk, padding, accidentally-damaged words, or +// whatever. Rounds up to the nearest byte though, so if you have a 1-bit +// value, we return 1 here, not 0. Most of rustc works in bytes. +pub fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint { + let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint; + if nbits & 7u != 0u { + // Not an even number of bytes, spills into "next" byte. + 1u + (nbits >> 3) + } else { + nbits >> 3 + } +} + +// Returns the "default" size of t, which is calculated by casting null to a +// *T and then doing gep(1) on it and measuring the result. Really, look in +// the LLVM sources. It does that. So this is likely similar to the ABI size +// (i.e. including alignment-padding), but goodness knows which alignment it +// winds up using. Probably the ABI one? Not recommended. +pub fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { + return llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t), cx.int_type, + False); +} + +// Returns the preferred alignment of the given type for the current target. +// The preffered alignment may be larger than the alignment used when +// packing the type into structs. This will be used for things like +// allocations inside a stack frame, which LLVM has a free hand in. +pub fn llalign_of_pref(cx: @crate_ctxt, t: TypeRef) -> uint { + return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint; +} + +// Returns the minimum alignment of a type required by the plattform. +// This is the alignment that will be used for struct fields, arrays, +// and similar ABI-mandated things. +pub fn llalign_of_min(cx: @crate_ctxt, t: TypeRef) -> uint { + return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint; +} + +// Returns the "default" alignment of t, which is calculated by casting +// null to a record containing a single-bit followed by a t value, then +// doing gep(0,1) to get at the trailing (and presumably padded) t cell. +pub fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { + return llvm::LLVMConstIntCast( + lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False); +} + +// Computes the size of the data part of an enum. +pub fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint { + if cx.enum_sizes.contains_key(t) { return cx.enum_sizes.get(t); } + match ty::get(t).sty { + ty::ty_enum(tid, ref substs) => { + // Compute max(variant sizes). + let mut max_size = 0u; + let variants = ty::enum_variants(cx.tcx, tid); + for vec::each(*variants) |variant| { + let tup_ty = simplify_type(cx.tcx, + ty::mk_tup(cx.tcx, variant.args)); + // Perform any type parameter substitutions. + let tup_ty = ty::subst(cx.tcx, substs, tup_ty); + // Here we possibly do a recursive call. + let this_size = + llsize_of_real(cx, type_of::type_of(cx, tup_ty)); + if max_size < this_size { max_size = this_size; } + } + cx.enum_sizes.insert(t, max_size); + return max_size; + } + _ => cx.sess.bug(~"static_size_of_enum called on non-enum") + } +} + diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs index 33df35cca52b..a94519306a48 100644 --- a/src/rustc/middle/trans/meth.rs +++ b/src/rustc/middle/trans/meth.rs @@ -364,8 +364,8 @@ fn combine_impl_and_methods_origins(bcx: block, // Flatten out to find the number of vtables the method expects. let m_vtables = m_boundss.foldl(0, |sum, m_bounds| { - m_bounds.foldl(sum, |sum, m_bound| { - sum + match m_bound { + m_bounds.foldl(*sum, |sum, m_bound| { + (*sum) + match (*m_bound) { ty::bound_copy | ty::bound_owned | ty::bound_send | ty::bound_const => 0, ty::bound_trait(_) => 1 @@ -536,6 +536,7 @@ fn trans_trait_cast(bcx: block, dest: expr::Dest) -> block { + let mut bcx = bcx; let _icx = bcx.insn_ctxt("impl::trans_cast"); let lldest = match dest { @@ -548,16 +549,23 @@ fn trans_trait_cast(bcx: block, let ccx = bcx.ccx(); let v_ty = expr_ty(bcx, val); - // Allocate an @ box and store the value into it - let {bcx: bcx, box: llbox, body: body} = malloc_boxed(bcx, v_ty); - add_clean_free(bcx, llbox, heap_shared); - let bcx = expr::trans_into(bcx, val, SaveIn(body)); - revoke_clean(bcx, llbox); + let mut llboxdest = GEPi(bcx, lldest, [0u, 1u]); + if bcx.tcx().legacy_boxed_traits.contains_key(id) { + // Allocate an @ box and store the value into it + let {bcx: new_bcx, box: llbox, body: body} = malloc_boxed(bcx, v_ty); + bcx = new_bcx; + add_clean_free(bcx, llbox, heap_shared); + bcx = expr::trans_into(bcx, val, SaveIn(body)); + revoke_clean(bcx, llbox); - // Store the @ box into the pair - Store(bcx, llbox, PointerCast(bcx, - GEPi(bcx, lldest, [0u, 1u]), - T_ptr(val_ty(llbox)))); + // Store the @ box into the pair + Store(bcx, llbox, PointerCast(bcx, llboxdest, T_ptr(val_ty(llbox)))); + } else { + // Just store the @ box into the pair. + llboxdest = PointerCast(bcx, llboxdest, + T_ptr(type_of::type_of(bcx.ccx(), v_ty))); + bcx = expr::trans_into(bcx, val, SaveIn(llboxdest)); + } // Store the vtable into the pair let orig = ccx.maps.vtable_map.get(id)[0]; diff --git a/src/rustc/middle/trans/monomorphize.rs b/src/rustc/middle/trans/monomorphize.rs index 8a68ef4823b4..cd8cffa297a6 100644 --- a/src/rustc/middle/trans/monomorphize.rs +++ b/src/rustc/middle/trans/monomorphize.rs @@ -33,7 +33,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, let param_uses = type_use::type_uses_for(ccx, fn_id, substs.len()); let hash_id = make_mono_id(ccx, fn_id, substs, vtables, Some(param_uses)); if vec::any(hash_id.params, - |p| match p { mono_precise(_, _) => false, _ => true }) { + |p| match *p { mono_precise(_, _) => false, _ => true }) { must_cast = true; } @@ -103,11 +103,11 @@ fn monomorphic_fn(ccx: @crate_ctxt, // Random cut-off -- code that needs to instantiate the same function // recursively more than ten times can probably safely be assumed to be // causing an infinite expansion. - if depth > 10u { + if depth > 10 { ccx.sess.span_fatal( span, ~"overly deep expansion of inlined function"); } - ccx.monomorphizing.insert(fn_id, depth + 1u); + ccx.monomorphizing.insert(fn_id, depth + 1); let pt = vec::append(*pt, ~[path_name(ccx.names(ccx.sess.str_of(name)))]); @@ -243,16 +243,16 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t], let mut i = 0u; vec::map2(*bounds, substs, |bounds, subst| { let mut v = ~[]; - for vec::each(*bounds) |bound| { + for bounds.each |bound| { match *bound { ty::bound_trait(_) => { - vec::push(v, meth::vtable_id(ccx, vts[i])); + v.push(meth::vtable_id(ccx, vts[i])); i += 1u; } _ => () } } - (subst, if v.len() > 0u { Some(v) } else { None }) + (*subst, if v.len() > 0u { Some(v) } else { None }) }) } None => { @@ -262,12 +262,12 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t], let param_ids = match param_uses { Some(uses) => { vec::map2(precise_param_ids, uses, |id, uses| { - match id { + match *id { (a, b@Some(_)) => mono_precise(a, b), (subst, None) => { - if uses == 0u { + if *uses == 0u { mono_any - } else if uses == type_use::use_repr && + } else if *uses == type_use::use_repr && !ty::type_needs_drop(ccx.tcx, subst) { let llty = type_of::type_of(ccx, subst); diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs index e09e3d9493d7..cf58b5b51c4c 100644 --- a/src/rustc/middle/trans/shape.rs +++ b/src/rustc/middle/trans/shape.rs @@ -7,6 +7,7 @@ use driver::session; use driver::session::session; use trans::base; use middle::trans::common::*; +use middle::trans::machine::*; use back::abi; use middle::ty; use middle::ty::field; @@ -22,92 +23,13 @@ use option::is_some; use ty_ctxt = middle::ty::ctxt; -type nominal_id_ = {did: ast::def_id, parent_id: Option, - tps: ~[ty::t]}; -type nominal_id = @nominal_id_; - -impl nominal_id_ : core::cmp::Eq { - pure fn eq(other: &nominal_id_) -> bool { - if self.did != other.did || - self.parent_id != other.parent_id { - false - } else { - do vec::all2(self.tps, other.tps) |m_tp, n_tp| { - ty::type_id(m_tp) == ty::type_id(n_tp) - } - } - } - pure fn ne(other: &nominal_id_) -> bool { - ! (self == *other) - } -} - -impl nominal_id_ : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { - to_bytes::iter_bytes_2(&self.did, &self.parent_id, lsb0, f); - for self.tps.each |t| { - ty::type_id(*t).iter_bytes(lsb0, f); - } - } -} - -fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id, - parent_id: Option, - tps: ~[ty::t]) -> nominal_id { - let tps_norm = tps.map(|t| ty::normalize_ty(tcx, *t)); - @{did: did, parent_id: parent_id, tps: tps_norm} -} - -fn new_nominal_id_hash() -> HashMap { - return HashMap(); -} - -type enum_data = {did: ast::def_id, substs: ty::substs}; - -type ctxt = - {mut next_tag_id: u16, - pad: u16, - tag_id_to_index: HashMap, - tag_order: DVec, - resources: interner::interner, - llshapetablesty: TypeRef, - llshapetables: ValueRef}; - -const shape_u8: u8 = 0u8; -const shape_u16: u8 = 1u8; -const shape_u32: u8 = 2u8; -const shape_u64: u8 = 3u8; -const shape_i8: u8 = 4u8; -const shape_i16: u8 = 5u8; -const shape_i32: u8 = 6u8; -const shape_i64: u8 = 7u8; -const shape_f32: u8 = 8u8; -const shape_f64: u8 = 9u8; -const shape_box: u8 = 10u8; -const shape_enum: u8 = 12u8; -const shape_struct: u8 = 17u8; -const shape_box_fn: u8 = 18u8; -const shape_res: u8 = 20u8; -const shape_uniq: u8 = 22u8; -const shape_opaque_closure_ptr: u8 = 23u8; // the closure itself. -const shape_uniq_fn: u8 = 25u8; -const shape_stack_fn: u8 = 26u8; -const shape_bare_fn: u8 = 27u8; -const shape_tydesc: u8 = 28u8; -const shape_send_tydesc: u8 = 29u8; -const shape_rptr: u8 = 31u8; -const shape_fixedvec: u8 = 32u8; -const shape_slice: u8 = 33u8; -const shape_unboxed_vec: u8 = 34u8; +type ctxt = {mut next_tag_id: u16, pad: u16, pad2: u32}; fn mk_global(ccx: @crate_ctxt, name: ~str, llval: ValueRef, internal: bool) -> ValueRef { - let llglobal = - str::as_c_str(name, - |buf| { - lib::llvm::llvm::LLVMAddGlobal(ccx.llmod, - val_ty(llval), buf) - }); + let llglobal = do str::as_c_str(name) |buf| { + lib::llvm::llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf) + }; lib::llvm::llvm::LLVMSetInitializer(llglobal, llval); lib::llvm::llvm::LLVMSetGlobalConstant(llglobal, True); @@ -118,91 +40,13 @@ fn mk_global(ccx: @crate_ctxt, name: ~str, llval: ValueRef, internal: bool) -> return llglobal; } - -// Computes a set of variants of a enum that are guaranteed to have size and -// alignment at least as large as any other variant of the enum. This is an -// important performance optimization. - -fn round_up(size: u16, align: u8) -> u16 { - assert (align >= 1u8); - let alignment = align as u16; - return size - 1u16 + alignment & !(alignment - 1u16); -} - -type size_align = {size: u16, align: u8}; - -enum enum_kind { - tk_unit, // 1 variant, no data - tk_enum, // N variants, no data - tk_newtype, // 1 variant, data - tk_complex // N variants, no data -} - -fn enum_kind(ccx: @crate_ctxt, did: ast::def_id) -> enum_kind { - let variants = ty::enum_variants(ccx.tcx, did); - if vec::any(*variants, |v| vec::len(v.args) > 0u) { - if vec::len(*variants) == 1u { tk_newtype } - else { tk_complex } - } else { - if vec::len(*variants) <= 1u { tk_unit } - else { tk_enum } - } -} - -// Returns the code corresponding to the pointer size on this architecture. -fn s_int(tcx: ty_ctxt) -> u8 { - return match tcx.sess.targ_cfg.arch { - session::arch_x86 => shape_i32, - session::arch_x86_64 => shape_i64, - session::arch_arm => shape_i32 - }; -} - -fn s_uint(tcx: ty_ctxt) -> u8 { - return match tcx.sess.targ_cfg.arch { - session::arch_x86 => shape_u32, - session::arch_x86_64 => shape_u64, - session::arch_arm => shape_u32 - }; -} - -fn s_float(tcx: ty_ctxt) -> u8 { - return match tcx.sess.targ_cfg.arch { - session::arch_x86 => shape_f64, - session::arch_x86_64 => shape_f64, - session::arch_arm => shape_f64 - }; -} - -fn s_variant_enum_t(tcx: ty_ctxt) -> u8 { - return s_int(tcx); -} - -fn s_tydesc(_tcx: ty_ctxt) -> u8 { - return shape_tydesc; -} - -fn s_send_tydesc(_tcx: ty_ctxt) -> u8 { - return shape_send_tydesc; -} - fn mk_ctxt(llmod: ModuleRef) -> ctxt { let llshapetablesty = trans::common::T_named_struct(~"shapes"); - let llshapetables = str::as_c_str(~"shapes", |buf| { + let _llshapetables = str::as_c_str(~"shapes", |buf| { lib::llvm::llvm::LLVMAddGlobal(llmod, llshapetablesty, buf) }); - return {mut next_tag_id: 0u16, - pad: 0u16, - tag_id_to_index: new_nominal_id_hash(), - tag_order: DVec(), - resources: interner::mk(), - llshapetablesty: llshapetablesty, - llshapetables: llshapetables}; -} - -fn add_bool(&dest: ~[u8], val: bool) { - dest += ~[if val { 1u8 } else { 0u8 }]; + return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32}; } fn add_u16(&dest: ~[u8], val: u16) { @@ -214,571 +58,3 @@ fn add_substr(&dest: ~[u8], src: ~[u8]) { dest += src; } -fn shape_of(ccx: @crate_ctxt, t: ty::t) -> ~[u8] { - match ty::get(t).sty { - ty::ty_nil | ty::ty_bool | ty::ty_uint(ast::ty_u8) | - ty::ty_bot => ~[shape_u8], - ty::ty_int(ast::ty_i) => ~[s_int(ccx.tcx)], - ty::ty_float(ast::ty_f) => ~[s_float(ccx.tcx)], - ty::ty_uint(ast::ty_u) | ty::ty_ptr(_) => ~[s_uint(ccx.tcx)], - ty::ty_type => ~[s_tydesc(ccx.tcx)], - ty::ty_int(ast::ty_i8) => ~[shape_i8], - ty::ty_uint(ast::ty_u16) => ~[shape_u16], - ty::ty_int(ast::ty_i16) => ~[shape_i16], - ty::ty_uint(ast::ty_u32) => ~[shape_u32], - ty::ty_int(ast::ty_i32) | ty::ty_int(ast::ty_char) => ~[shape_i32], - ty::ty_uint(ast::ty_u64) => ~[shape_u64], - ty::ty_int(ast::ty_i64) => ~[shape_i64], - ty::ty_float(ast::ty_f32) => ~[shape_f32], - ty::ty_float(ast::ty_f64) => ~[shape_f64], - ty::ty_estr(ty::vstore_uniq) => { - shape_of(ccx, tvec::expand_boxed_vec_ty(ccx.tcx, t)) - } - ty::ty_enum(did, substs) => { - match enum_kind(ccx, did) { - tk_unit => ~[s_variant_enum_t(ccx.tcx)], - tk_enum => ~[s_variant_enum_t(ccx.tcx)], - tk_newtype | tk_complex => { - let mut s = ~[shape_enum], id; - let nom_id = mk_nominal_id(ccx.tcx, did, - None, substs.tps); - match ccx.shape_cx.tag_id_to_index.find(nom_id) { - None => { - id = ccx.shape_cx.next_tag_id; - ccx.shape_cx.tag_id_to_index.insert(nom_id, id); - ccx.shape_cx.tag_order.push({did: did, - substs: substs}); - ccx.shape_cx.next_tag_id += 1u16; - } - Some(existing_id) => id = existing_id, - } - add_u16(s, id as u16); - - s - } - } - } - ty::ty_estr(ty::vstore_box) | - ty::ty_evec(_, ty::vstore_box) | - ty::ty_box(_) | ty::ty_opaque_box => ~[shape_box], - ty::ty_uniq(mt) => { - let mut s = ~[shape_uniq]; - add_substr(s, shape_of(ccx, mt.ty)); - s - } - ty::ty_unboxed_vec(mt) => { - let mut s = ~[shape_unboxed_vec]; - add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty)); - add_substr(s, shape_of(ccx, mt.ty)); - s - } - ty::ty_evec(_, ty::vstore_uniq) => { - shape_of(ccx, tvec::expand_boxed_vec_ty(ccx.tcx, t)) - } - - ty::ty_estr(ty::vstore_fixed(n)) => { - let mut s = ~[shape_fixedvec]; - let u8_t = ty::mk_mach_uint(ccx.tcx, ast::ty_u8); - assert (n + 1u) <= 0xffffu; - add_u16(s, (n + 1u) as u16); - add_bool(s, true); - add_substr(s, shape_of(ccx, u8_t)); - s - } - - ty::ty_evec(mt, ty::vstore_fixed(n)) => { - let mut s = ~[shape_fixedvec]; - assert n <= 0xffffu; - add_u16(s, n as u16); - add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty)); - add_substr(s, shape_of(ccx, mt.ty)); - s - } - - ty::ty_estr(ty::vstore_slice(_)) => { - let mut s = ~[shape_slice]; - let u8_t = ty::mk_mach_uint(ccx.tcx, ast::ty_u8); - add_bool(s, true); // is_pod - add_bool(s, true); // is_str - add_substr(s, shape_of(ccx, u8_t)); - s - } - - ty::ty_evec(mt, ty::vstore_slice(_)) => { - let mut s = ~[shape_slice]; - add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty)); - add_bool(s, false); // is_str - add_substr(s, shape_of(ccx, mt.ty)); - s - } - - ty::ty_rec(fields) => { - let mut s = ~[shape_struct], sub = ~[]; - for vec::each(fields) |f| { - sub += shape_of(ccx, f.mt.ty); - } - add_substr(s, sub); - s - } - ty::ty_tup(elts) => { - let mut s = ~[shape_struct], sub = ~[]; - for vec::each(elts) |elt| { - sub += shape_of(ccx, *elt); - } - add_substr(s, sub); - s - } - ty::ty_trait(_, _, _) => ~[shape_box_fn], - ty::ty_class(did, ref substs) => { - // same as records, unless there's a dtor - let tps = substs.tps; - let m_dtor_did = ty::ty_dtor(ccx.tcx, did); - let mut s = if m_dtor_did.is_some() { - ~[shape_res] - } - else { ~[shape_struct] }, sub = ~[]; - do m_dtor_did.iter |dtor_did| { - let ri = @{did: dtor_did, parent_id: Some(did), tps: tps}; - let id = ccx.shape_cx.resources.intern(ri); - add_u16(s, id as u16); - }; - for ty::class_items_as_mutable_fields(ccx.tcx, did, - substs).each |f| { - sub += shape_of(ccx, f.mt.ty); - } - add_substr(s, sub); - s - } - ty::ty_rptr(_, mt) => { - let mut s = ~[shape_rptr]; - add_substr(s, shape_of(ccx, mt.ty)); - s - } - ty::ty_param(*) => { - ccx.tcx.sess.bug(~"non-monomorphized type parameter"); - } - ty::ty_fn(ref fn_ty) => { - match fn_ty.meta.proto { - ty::proto_vstore(ty::vstore_box) => ~[shape_box_fn], - ty::proto_vstore(ty::vstore_uniq) => ~[shape_uniq_fn], - ty::proto_vstore(ty::vstore_slice(_)) => ~[shape_stack_fn], - ty::proto_bare => ~[shape_bare_fn], - ty::proto_vstore(ty::vstore_fixed(_)) => - fail ~"fixed vstore is impossible", - } - } - ty::ty_opaque_closure_ptr(_) => ~[shape_opaque_closure_ptr], - ty::ty_infer(_) | ty::ty_self => { - ccx.sess.bug(~"shape_of: unexpected type struct found") - } - } -} - -fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info) -> ~[u8] { - let mut s = ~[]; - for vec::each(v.args) |t| { s += shape_of(ccx, *t); } - return s; -} - -fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef { - // Loop over all the enum variants and write their shapes into a - // data buffer. As we do this, it's possible for us to discover - // new enums, so we must do this first. - let mut data = ~[]; - let mut offsets = ~[]; - let mut i = 0u; - let mut enum_variants = ~[]; - while i < ccx.shape_cx.tag_order.len() { - let {did, substs} = ccx.shape_cx.tag_order[i]; - let variants = @ty::substd_enum_variants(ccx.tcx, did, &substs); - for vec::each(*variants) |v| { - offsets += ~[vec::len(data) as u16]; - - let variant_shape = shape_of_variant(ccx, *v); - add_substr(data, variant_shape); - - let zname = str::to_bytes(ccx.sess.str_of(v.name)) + ~[0u8]; - add_substr(data, zname); - } - enum_variants += ~[variants]; - i += 1u; - } - - // Now calculate the sizes of the header space (which contains offsets to - // info records for each enum) and the info space (which contains offsets - // to each variant shape). As we do so, build up the header. - - let mut header = ~[]; - let mut inf = ~[]; - let header_sz = 2u16 * ccx.shape_cx.next_tag_id; - let data_sz = vec::len(data) as u16; - - let mut inf_sz = 0u16; - for enum_variants.each |variants| { - let num_variants = vec::len(**variants) as u16; - add_u16(header, header_sz + inf_sz); - inf_sz += 2u16 * (num_variants + 2u16) + 3u16; - } - - // Construct the info tables, which contain offsets to the shape of each - // variant. Also construct the largest-variant table for each enum, which - // contains the variants that the size-of operation needs to look at. - - let mut lv_table = ~[]; - let mut i = 0u; - for enum_variants.each |variants| { - add_u16(inf, vec::len(**variants) as u16); - - // Construct the largest-variants table. - add_u16(inf, - header_sz + inf_sz + data_sz + (vec::len(lv_table) as u16)); - - let lv = largest_variants(ccx, *variants); - add_u16(lv_table, vec::len(lv) as u16); - for vec::each(lv) |v| { add_u16(lv_table, *v as u16); } - - // Determine whether the enum has dynamic size. - assert !variants.any(|v| v.args.any(|t| ty::type_has_params(t))); - - // If we can, write in the static size and alignment of the enum. - // Otherwise, write a placeholder. - let size_align = compute_static_enum_size(ccx, lv, *variants); - - // Write in the static size and alignment of the enum. - add_u16(inf, size_align.size); - inf += ~[size_align.align]; - - // Now write in the offset of each variant. - for variants.each |_v| { - add_u16(inf, header_sz + inf_sz + offsets[i]); - i += 1u; - } - } - - assert (i == vec::len(offsets)); - assert (header_sz == vec::len(header) as u16); - assert (inf_sz == vec::len(inf) as u16); - assert (data_sz == vec::len(data) as u16); - - header += inf; - header += data; - header += lv_table; - - return mk_global(ccx, ~"tag_shapes", C_bytes(header), true); - -/* tjc: Not annotating FIXMEs in this module because of #1498 */ - fn largest_variants(ccx: @crate_ctxt, - variants: @~[ty::variant_info]) -> ~[uint] { - // Compute the minimum and maximum size and alignment for each - // variant. - // - // NB: We could do better here; e.g. we know that any - // variant that contains (T,T) must be as least as large as - // any variant that contains just T. - let mut ranges = ~[]; - for vec::each(*variants) |variant| { - let mut bounded = true; - let mut min_size = 0u, min_align = 0u; - for vec::each(variant.args) |elem_t| { - if ty::type_has_params(*elem_t) { - // NB: We could do better here; this causes us to - // conservatively assume that (int, T) has minimum size 0, - // when in fact it has minimum size sizeof(int). - bounded = false; - } else { - let llty = type_of::type_of(ccx, *elem_t); - min_size += llsize_of_real(ccx, llty); - min_align += llalign_of_pref(ccx, llty); - } - } - - ranges += - ~[{size: {min: min_size, bounded: bounded}, - align: {min: min_align, bounded: bounded}}]; - } - - // Initialize the candidate set to contain all variants. - let mut candidates = ~[mut]; - for vec::each(*variants) |_v| { candidates += ~[mut true]; } - - // Do a pairwise comparison among all variants still in the - // candidate set. Throw out any variant that we know has size - // and alignment at least as small as some other variant. - let mut i = 0u; - while i < vec::len(ranges) - 1u { - if candidates[i] { - let mut j = i + 1u; - while j < vec::len(ranges) { - if candidates[j] { - if ranges[i].size.bounded && - ranges[i].align.bounded && - ranges[j].size.bounded && - ranges[j].align.bounded { - if ranges[i].size.min >= ranges[j].size.min && - ranges[i].align.min >= ranges[j].align.min { - // Throw out j. - candidates[j] = false; - } else if ranges[j].size.min >= - ranges[i].size.min && - ranges[j].align.min >= - ranges[j].align.min { - // Throw out i. - candidates[i] = false; - } - } - } - j += 1u; - } - } - i += 1u; - } - - // Return the resulting set. - let mut result = ~[]; - let mut i = 0u; - while i < vec::len(candidates) { - if candidates[i] { vec::push(result, i); } - i += 1u; - } - return result; - } - - fn compute_static_enum_size(ccx: @crate_ctxt, largest_variants: ~[uint], - variants: @~[ty::variant_info]) - -> size_align { - let mut max_size = 0u16; - let mut max_align = 1u8; - for vec::each(largest_variants) |vid| { - // We increment a "virtual data pointer" to compute the size. - let mut lltys = ~[]; - for vec::each(variants[*vid].args) |typ| { - lltys += ~[type_of::type_of(ccx, *typ)]; - } - - let llty = trans::common::T_struct(lltys); - let dp = llsize_of_real(ccx, llty) as u16; - let variant_align = llalign_of_pref(ccx, llty) as u8; - - if max_size < dp { max_size = dp; } - if max_align < variant_align { max_align = variant_align; } - } - - // Add space for the enum if applicable. - // FIXME (issue #792): This is wrong. If the enum starts with an - // 8 byte aligned quantity, we don't align it. - if vec::len(*variants) > 1u { - let variant_t = T_enum_discrim(ccx); - max_size += llsize_of_real(ccx, variant_t) as u16; - let align = llalign_of_pref(ccx, variant_t) as u8; - if max_align < align { max_align = align; } - } - - return {size: max_size, align: max_align}; - } -} - -fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef { - let mut dtors = ~[]; - let len = ccx.shape_cx.resources.len(); - for uint::range(0u, len) |i| { - let ri = ccx.shape_cx.resources.get(i); - for ri.tps.each() |s| { assert !ty::type_has_params(*s); } - do ri.parent_id.iter |id| { - dtors += ~[trans::base::get_res_dtor(ccx, ri.did, id, ri.tps)]; - } - } - return mk_global(ccx, ~"resource_shapes", C_struct(dtors), true); -} - -// This function serves to break a cyclical dependence between -// emit_tydescs and gen_shape_tables. -// -// * emit_tydescs calls shape_of, which causes changes to the shape -// tables -// * gen_shape_tables transitively calls get_tydesc, which causes new -// tydescs to be created -// -// We force those tydescs to be emitted now, thus breaking the -// dependency. -fn force_declare_tydescs(ccx: @crate_ctxt) { - // Walk all known tydescs first to force shape code to declare - // dependencies. - for ccx.tydescs.each |key, _val| { - shape_of(ccx, key); - } - - // Then walk all resource shapes to force emit all dtors. - let len = ccx.shape_cx.resources.len(); - for uint::range(0u, len) |i| { - let ri = ccx.shape_cx.resources.get(i); - for ri.tps.each() |s| { assert !ty::type_has_params(*s); } - do ri.parent_id.iter |id| { - trans::base::get_res_dtor(ccx, ri.did, id, ri.tps); - } - } -} - -fn gen_shape_tables(ccx: @crate_ctxt) { - let lltagstable = gen_enum_shapes(ccx); - let llresourcestable = gen_resource_shapes(ccx); - trans::common::set_struct_body(ccx.shape_cx.llshapetablesty, - ~[val_ty(lltagstable), - val_ty(llresourcestable)]); - - let lltables = - C_named_struct(ccx.shape_cx.llshapetablesty, - ~[lltagstable, llresourcestable]); - lib::llvm::llvm::LLVMSetInitializer(ccx.shape_cx.llshapetables, lltables); - lib::llvm::llvm::LLVMSetGlobalConstant(ccx.shape_cx.llshapetables, True); - lib::llvm::SetLinkage(ccx.shape_cx.llshapetables, - lib::llvm::InternalLinkage); -} - -// ______________________________________________________________________ -// compute sizeof / alignof - -type metrics = { - bcx: block, - sz: ValueRef, - align: ValueRef -}; - -type tag_metrics = { - bcx: block, - sz: ValueRef, - align: ValueRef, - payload_align: ValueRef -}; - -// Returns the number of bytes clobbered by a Store to this type. -fn llsize_of_store(cx: @crate_ctxt, t: TypeRef) -> uint { - return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint; -} - -// Returns the number of bytes between successive elements of type T in an -// array of T. This is the "ABI" size. It includes any ABI-mandated padding. -fn llsize_of_alloc(cx: @crate_ctxt, t: TypeRef) -> uint { - return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint; -} - -// Returns, as near as we can figure, the "real" size of a type. As in, the -// bits in this number of bytes actually carry data related to the datum -// with the type. Not junk, padding, accidentally-damaged words, or -// whatever. Rounds up to the nearest byte though, so if you have a 1-bit -// value, we return 1 here, not 0. Most of rustc works in bytes. -fn llsize_of_real(cx: @crate_ctxt, t: TypeRef) -> uint { - let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint; - if nbits & 7u != 0u { - // Not an even number of bytes, spills into "next" byte. - 1u + (nbits >> 3) - } else { - nbits >> 3 - } -} - -// Returns the "default" size of t, which is calculated by casting null to a -// *T and then doing gep(1) on it and measuring the result. Really, look in -// the LLVM sources. It does that. So this is likely similar to the ABI size -// (i.e. including alignment-padding), but goodness knows which alignment it -// winds up using. Probably the ABI one? Not recommended. -fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { - return llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t), cx.int_type, - False); -} - -// Returns the preferred alignment of the given type for the current target. -// The preffered alignment may be larger than the alignment used when -// packing the type into structs. This will be used for things like -// allocations inside a stack frame, which LLVM has a free hand in. -fn llalign_of_pref(cx: @crate_ctxt, t: TypeRef) -> uint { - return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint; -} - -// Returns the minimum alignment of a type required by the plattform. -// This is the alignment that will be used for struct fields, arrays, -// and similar ABI-mandated things. -fn llalign_of_min(cx: @crate_ctxt, t: TypeRef) -> uint { - return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint; -} - -// Returns the "default" alignment of t, which is calculated by casting -// null to a record containing a single-bit followed by a t value, then -// doing gep(0,1) to get at the trailing (and presumably padded) t cell. -fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { - return llvm::LLVMConstIntCast( - lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False); -} - -// Computes the static size of a enum, without using mk_tup(), which is -// bad for performance. -// -// NB: Migrate trans over to use this. - -// Computes the size of the data part of an enum. -fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint { - if cx.enum_sizes.contains_key(t) { return cx.enum_sizes.get(t); } - match ty::get(t).sty { - ty::ty_enum(tid, ref substs) => { - // Compute max(variant sizes). - let mut max_size = 0u; - let variants = ty::enum_variants(cx.tcx, tid); - for vec::each(*variants) |variant| { - let tup_ty = simplify_type(cx.tcx, - ty::mk_tup(cx.tcx, variant.args)); - // Perform any type parameter substitutions. - let tup_ty = ty::subst(cx.tcx, substs, tup_ty); - // Here we possibly do a recursive call. - let this_size = - llsize_of_real(cx, type_of::type_of(cx, tup_ty)); - if max_size < this_size { max_size = this_size; } - } - cx.enum_sizes.insert(t, max_size); - return max_size; - } - _ => cx.sess.bug(~"static_size_of_enum called on non-enum") - } -} - -// Creates a simpler, size-equivalent type. The resulting type is guaranteed -// to have (a) the same size as the type that was passed in; (b) to be non- -// recursive. This is done by replacing all boxes in a type with boxed unit -// types. -// This should reduce all pointers to some simple pointer type, to -// ensure that we don't recurse endlessly when computing the size of a -// nominal type that has pointers to itself in it. -fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t { - fn nilptr(tcx: ty::ctxt) -> ty::t { - ty::mk_ptr(tcx, {ty: ty::mk_nil(tcx), mutbl: ast::m_imm}) - } - fn simplifier(tcx: ty::ctxt, typ: ty::t) -> ty::t { - match ty::get(typ).sty { - ty::ty_box(_) | ty::ty_opaque_box | ty::ty_uniq(_) | - ty::ty_evec(_, ty::vstore_uniq) | ty::ty_evec(_, ty::vstore_box) | - ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) | - ty::ty_ptr(_) | ty::ty_rptr(_,_) => nilptr(tcx), - ty::ty_fn(_) => ty::mk_tup(tcx, ~[nilptr(tcx), nilptr(tcx)]), - ty::ty_evec(_, ty::vstore_slice(_)) | - ty::ty_estr(ty::vstore_slice(_)) => { - ty::mk_tup(tcx, ~[nilptr(tcx), ty::mk_int(tcx)]) - } - // Reduce a class type to a record type in which all the fields are - // simplified - ty::ty_class(did, ref substs) => { - let simpl_fields = (if ty::ty_dtor(tcx, did).is_some() { - // remember the drop flag - ~[{ident: syntax::parse::token::special_idents::dtor, - mt: {ty: ty::mk_u8(tcx), - mutbl: ast::m_mutbl}}] } - else { ~[] }) + - do ty::lookup_class_fields(tcx, did).map |f| { - let t = ty::lookup_field_type(tcx, did, f.id, substs); - {ident: f.ident, - mt: {ty: simplify_type(tcx, t), mutbl: ast::m_const}} - }; - ty::mk_rec(tcx, simpl_fields) - } - _ => typ - } - } - ty::fold_ty(tcx, typ, |t| simplifier(tcx, t)) -} diff --git a/src/rustc/middle/trans/tvec.rs b/src/rustc/middle/trans/tvec.rs index 10f936262800..e1eae1156945 100644 --- a/src/rustc/middle/trans/tvec.rs +++ b/src/rustc/middle/trans/tvec.rs @@ -332,7 +332,7 @@ fn write_content(bcx: block, bcx = expr::trans_into(bcx, *element, SaveIn(lleltptr)); add_clean_temp_mem(bcx, lleltptr, vt.unit_ty); - vec::push(temp_cleanups, lleltptr); + temp_cleanups.push(lleltptr); } for vec::each(temp_cleanups) |cleanup| { revoke_clean(bcx, *cleanup); @@ -369,7 +369,7 @@ fn write_content(bcx: block, bcx = tmpdatum.move_to(bcx, INIT, lleltptr); } add_clean_temp_mem(bcx, lleltptr, vt.unit_ty); - vec::push(temp_cleanups, lleltptr); + temp_cleanups.push(lleltptr); } for vec::each(temp_cleanups) |cleanup| { diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs index d9032f8ce909..b45da3b27004 100644 --- a/src/rustc/middle/trans/type_of.rs +++ b/src/rustc/middle/trans/type_of.rs @@ -39,13 +39,13 @@ fn type_of_fn(cx: @crate_ctxt, inputs: ~[ty::arg], let mut atys: ~[TypeRef] = ~[]; // Arg 0: Output pointer. - vec::push(atys, T_ptr(type_of(cx, output))); + atys.push(T_ptr(type_of(cx, output))); // Arg 1: Environment - vec::push(atys, T_opaque_box_ptr(cx)); + atys.push(T_opaque_box_ptr(cx)); // ... then explicit args. - vec::push_all(atys, type_of_explicit_args(cx, inputs)); + atys.push_all(type_of_explicit_args(cx, inputs)); return T_fn(atys, llvm::LLVMVoidType()); } @@ -151,7 +151,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { let mut tys: ~[TypeRef] = ~[]; for vec::each(fields) |f| { let mt_ty = f.mt.ty; - vec::push(tys, type_of(cx, mt_ty)); + tys.push(type_of(cx, mt_ty)); } // n.b.: introduce an extra layer of indirection to match @@ -164,7 +164,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { ty::ty_tup(elts) => { let mut tys = ~[]; for vec::each(elts) |elt| { - vec::push(tys, type_of(cx, *elt)); + tys.push(type_of(cx, *elt)); } T_struct(tys) } @@ -254,8 +254,8 @@ fn llvm_type_name(cx: @crate_ctxt, } fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef { - T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))), - T_ptr(type_of(ccx, self_ty))], + T_fn(~[T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))), // output pointer + T_ptr(type_of(ccx, self_ty))], // self arg llvm::LLVMVoidType()) } diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index 8a0873f05851..6bd3c22f626a 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -204,10 +204,10 @@ fn mark_for_expr(cx: ctx, e: @expr) { expr_path(_) => { do cx.ccx.tcx.node_type_substs.find(e.id).iter |ts| { let id = ast_util::def_id_of_def(cx.ccx.tcx.def_map.get(e.id)); - vec::iter2(type_uses_for(cx.ccx, id, ts.len()), ts, - |uses, subst| { - type_needs(cx, uses, subst) - }) + let uses_for_ts = type_uses_for(cx.ccx, id, ts.len()); + for vec::each2(uses_for_ts, *ts) |uses, subst| { + type_needs(cx, *uses, *subst) + } } } expr_fn(*) | expr_fn_block(*) => { @@ -238,8 +238,10 @@ fn mark_for_expr(cx: ctx, e: @expr) { match mth.origin { typeck::method_static(did) => { do cx.ccx.tcx.node_type_substs.find(e.id).iter |ts| { - do vec::iter2(type_uses_for(cx.ccx, did, ts.len()), ts) - |uses, subst| { type_needs(cx, uses, subst)} + let type_uses = type_uses_for(cx.ccx, did, ts.len()); + for vec::each2(type_uses, *ts) |uses, subst| { + type_needs(cx, *uses, *subst) + } } } typeck::method_param({param_num: param, _}) => { diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index f256b4b76cdb..109db9ace099 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -248,7 +248,7 @@ impl creader_cache_key : cmp::Eq { } impl creader_cache_key : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f); } } @@ -263,7 +263,7 @@ impl intern_key : cmp::Eq { } impl intern_key : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.sty, &self.o_def_id, lsb0, f); } } @@ -356,7 +356,8 @@ type ctxt = inferred_modes: HashMap, adjustments: HashMap, normalized_cache: HashMap, - lang_items: middle::lang_items::LanguageItems}; + lang_items: middle::lang_items::LanguageItems, + legacy_boxed_traits: HashMap}; enum tbox_flag { has_params = 1, @@ -406,7 +407,7 @@ enum closure_kind { } impl closure_kind : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } @@ -424,7 +425,7 @@ enum fn_proto { } impl fn_proto : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { proto_bare => 0u8.iter_bytes(lsb0, f), @@ -502,7 +503,7 @@ impl param_ty : cmp::Eq { } impl param_ty : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.idx, &self.def_id, lsb0, f) } } @@ -676,7 +677,7 @@ enum InferTy { } impl InferTy : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { TyVar(ref tv) => to_bytes::iter_bytes_2(&0u8, tv, lsb0, f), IntVar(ref iv) => to_bytes::iter_bytes_2(&1u8, iv, lsb0, f) @@ -685,7 +686,7 @@ impl InferTy : to_bytes::IterBytes { } impl param_bound : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { bound_copy => 0u8.iter_bytes(lsb0, f), bound_owned => 1u8.iter_bytes(lsb0, f), @@ -749,25 +750,25 @@ impl purity: purity_to_str { } impl RegionVid : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } impl TyVid : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } impl IntVid : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } impl FnVid : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } @@ -875,7 +876,8 @@ fn mk_ctxt(s: session::session, inferred_modes: HashMap(), adjustments: HashMap(), normalized_cache: new_ty_hash(), - lang_items: move lang_items} + lang_items: move lang_items, + legacy_boxed_traits: HashMap()} } @@ -902,7 +904,7 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option) -> t { fn sflags(substs: &substs) -> uint { let mut f = 0u; for substs.tps.each |tt| { f |= get(*tt).flags; } - substs.self_r.iter(|r| f |= rflags(r)); + substs.self_r.iter(|r| f |= rflags(*r)); return f; } match st { @@ -1091,12 +1093,15 @@ pure fn mach_sty(cfg: @session::config, t: t) -> sty { } fn default_arg_mode_for_ty(tcx: ctxt, ty: ty::t) -> ast::rmode { - return if type_is_fn(ty) { - // ^^^^^^^^^^^^^^ - // FIXME(#2202) --- We retain by-ref by default to workaround a memory - // leak that otherwise results when @fn is upcast to &fn. - ast::by_ref - } else if tcx.legacy_modes { + // FIXME(#2202) --- We retain by-ref for fn& things to workaround a + // memory leak that otherwise results when @fn is upcast to &fn. + if type_is_fn(ty) { + match ty_fn_proto(ty) { + proto_vstore(vstore_slice(_)) => return ast::by_ref, + _ => () + } + } + return if tcx.legacy_modes { if type_is_borrowed(ty) { // the old mode default was ++ for things like &ptr, but to be // forward-compatible with non-legacy, we should use + @@ -1177,7 +1182,7 @@ fn fold_sty_to_ty(tcx: ty::ctxt, sty: &sty, foldop: fn(t) -> t) -> t { fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty { fn fold_substs(substs: &substs, fldop: fn(t) -> t) -> substs { {self_r: substs.self_r, - self_ty: substs.self_ty.map(|t| fldop(t)), + self_ty: substs.self_ty.map(|t| fldop(*t)), tps: substs.tps.map(|t| fldop(*t))} } @@ -1273,8 +1278,8 @@ fn fold_regions_and_ty( fldr: fn(r: region) -> region, fldt: fn(t: t) -> t) -> substs { - {self_r: substs.self_r.map(|r| fldr(r)), - self_ty: substs.self_ty.map(|t| fldt(t)), + {self_r: substs.self_r.map(|r| fldr(*r)), + self_ty: substs.self_ty.map(|t| fldt(*t)), tps: substs.tps.map(|t| fldt(*t))} } @@ -1403,8 +1408,8 @@ fn substs_is_noop(substs: &substs) -> bool { fn substs_to_str(cx: ctxt, substs: &substs) -> ~str { fmt!("substs(self_r=%s, self_ty=%s, tps=%?)", - substs.self_r.map_default(~"none", |r| region_to_str(cx, r)), - substs.self_ty.map_default(~"none", |t| ty_to_str(cx, t)), + substs.self_r.map_default(~"none", |r| region_to_str(cx, *r)), + substs.self_ty.map_default(~"none", |t| ty_to_str(cx, *t)), tys_to_str(cx, substs.tps)) } @@ -2137,25 +2142,25 @@ fn type_size(cx: ctxt, ty: t) -> uint { } ty_rec(flds) => { - flds.foldl(0, |s, f| s + type_size(cx, f.mt.ty)) + flds.foldl(0, |s, f| *s + type_size(cx, f.mt.ty)) } ty_class(did, ref substs) => { let flds = class_items_as_fields(cx, did, substs); - flds.foldl(0, |s, f| s + type_size(cx, f.mt.ty)) + flds.foldl(0, |s, f| *s + type_size(cx, f.mt.ty)) } ty_tup(tys) => { - tys.foldl(0, |s, t| s + type_size(cx, t)) + tys.foldl(0, |s, t| *s + type_size(cx, *t)) } ty_enum(did, ref substs) => { let variants = substd_enum_variants(cx, did, substs); variants.foldl( // find max size of any variant 0, - |m, v| uint::max(m, + |m, v| uint::max(*m, // find size of this variant: - v.args.foldl(0, |s, a| s + type_size(cx, a)))) + v.args.foldl(0, |s, a| *s + type_size(cx, *a)))) } ty_param(_) | ty_self => { @@ -2238,38 +2243,38 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool { false } - ty_class(did, _) if vec::contains(*seen, did) => { + ty_class(ref did, _) if vec::contains(*seen, did) => { false } ty_class(did, ref substs) => { - vec::push(*seen, did); - let r = vec::any(class_items_as_fields(cx, did, substs), - |f| type_requires(cx, seen, r_ty, f.mt.ty)); - vec::pop(*seen); + seen.push(did); + let r = vec::any(class_items_as_fields(cx, did, substs), + |f| type_requires(cx, seen, r_ty, f.mt.ty)); + seen.pop(); r } ty_tup(ts) => { - vec::any(ts, |t| type_requires(cx, seen, r_ty, t)) + vec::any(ts, |t| type_requires(cx, seen, r_ty, *t)) } - ty_enum(did, _) if vec::contains(*seen, did) => { + ty_enum(ref did, _) if vec::contains(*seen, did) => { false } - ty_enum(did, ref substs) => { - vec::push(*seen, did); - let vs = enum_variants(cx, did); - let r = vec::len(*vs) > 0u && vec::all(*vs, |variant| { - vec::any(variant.args, |aty| { - let sty = subst(cx, substs, aty); - type_requires(cx, seen, r_ty, sty) - }) - }); - vec::pop(*seen); - r - } + ty_enum(did, ref substs) => { + seen.push(did); + let vs = enum_variants(cx, did); + let r = vec::len(*vs) > 0u && vec::all(*vs, |variant| { + vec::any(variant.args, |aty| { + let sty = subst(cx, substs, *aty); + type_requires(cx, seen, r_ty, sty) + }) + }); + seen.pop(); + r + } }; debug!("subtypes_require(%s, %s)? %b", @@ -2505,7 +2510,7 @@ fn index_sty(cx: ctxt, sty: &sty) -> Option { } impl bound_region : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { ty::br_self => 0u8.iter_bytes(lsb0, f), @@ -2522,7 +2527,7 @@ impl bound_region : to_bytes::IterBytes { } impl region : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { re_bound(ref br) => to_bytes::iter_bytes_2(&0u8, br, lsb0, f), @@ -2542,7 +2547,7 @@ impl region : to_bytes::IterBytes { } impl vstore : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { vstore_fixed(ref u) => to_bytes::iter_bytes_2(&0u8, u, lsb0, f), @@ -2557,7 +2562,7 @@ impl vstore : to_bytes::IterBytes { } impl substs : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.self_r, &self.self_ty, &self.tps, lsb0, f) @@ -2565,28 +2570,28 @@ impl substs : to_bytes::IterBytes { } impl mt : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.ty, &self.mutbl, lsb0, f) } } impl field : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.ident, &self.mt, lsb0, f) } } impl arg : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.mode, &self.ty, lsb0, f) } } impl sty : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { ty_nil => 0u8.iter_bytes(lsb0, f), ty_bool => 1u8.iter_bytes(lsb0, f), @@ -3036,7 +3041,7 @@ fn param_tys_in_type(ty: t) -> ~[param_ty] { do walk_ty(ty) |ty| { match get(ty).sty { ty_param(p) => { - vec::push(rslt, p); + rslt.push(p); } _ => () } @@ -3052,7 +3057,7 @@ fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) { let mut rslt = ~[]; do walk_ty(ty) |ty| { match get(ty).sty { - ty_infer(TyVar(v)) => vec::push(rslt, v), + ty_infer(TyVar(v)) => rslt.push(v), _ => () } } @@ -3063,7 +3068,7 @@ fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) { if !type_needs_infer(rt) { return; } // Occurs check! - if vec::contains(vars_in_type(rt), vid) { + if vec::contains(vars_in_type(rt), &vid) { // Maybe this should be span_err -- however, there's an // assertion later on that the type doesn't contain // variables, so in this case we have to be sure to die. @@ -3704,10 +3709,10 @@ fn class_field_tys(fields: ~[@struct_field]) -> ~[field_ty] { for fields.each |field| { match field.node.kind { named_field(ident, mutability, visibility) => { - vec::push(rslt, {ident: ident, - id: ast_util::local_def(field.node.id), - vis: visibility, - mutability: mutability}); + rslt.push({ident: ident, + id: ast_util::local_def(field.node.id), + vis: visibility, + mutability: mutability}); } unnamed_field => {} } @@ -3747,7 +3752,7 @@ fn class_item_fields(cx:ctxt, for lookup_class_fields(cx, did).each |f| { // consider all instance vars mut, because the // constructor may mutate all vars - vec::push(rslt, {ident: f.ident, mt: + rslt.push({ident: f.ident, mt: {ty: lookup_field_type(cx, did, f.id, substs), mutbl: frob_mutability(f.mutability)}}); } diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index 0c4749945536..45a7c22e2f90 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -415,7 +415,7 @@ fn ty_of_arg( let mode = { match a.mode { ast::infer(_) if expected_ty.is_some() => { - result::get(ty::unify_mode( + result::get(&ty::unify_mode( self.tcx(), ty::expected_found {expected: expected_ty.get().mode, found: a.mode})) @@ -434,7 +434,7 @@ fn ty_of_arg( _ => { let m1 = ast::expl(ty::default_arg_mode_for_ty(self.tcx(), ty)); - result::get(ty::unify_mode( + result::get(&ty::unify_mode( self.tcx(), ty::expected_found {expected: m1, found: a.mode})) @@ -484,7 +484,7 @@ fn ty_of_fn_decl( let rb = in_binding_rscope(rscope); let input_tys = do decl.inputs.mapi |i, a| { - let expected_arg_ty = do expected_tys.chain |e| { + let expected_arg_ty = do expected_tys.chain_ref |e| { // no guarantee that the correct number of expected args // were supplied if i < e.inputs.len() {Some(e.inputs[i])} else {None} diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 8d2384cd5306..368b69cafaba 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -181,7 +181,7 @@ impl isr_alist: get_and_find_region { fn find(br: ty::bound_region) -> Option { for list::each(self) |isr| { - let (isr_br, isr_r) = isr; + let (isr_br, isr_r) = *isr; if isr_br == br { return Some(isr_r); } } return None; @@ -279,7 +279,7 @@ fn check_fn(ccx: @crate_ctxt, // Update the self_info to contain an accurate self type (taking // into account explicit self). - let self_info = do self_info.chain |info| { + let self_info = do self_info.chain_ref |info| { // If the self type is sty_static, we don't have a self ty. if info.explicit_self.node == ast::sty_static { None @@ -288,7 +288,7 @@ fn check_fn(ccx: @crate_ctxt, let ty = method::transform_self_type_for_method( fcx.tcx(), self_region, info.self_ty, info.explicit_self.node); - Some({self_ty: ty,.. info}) + Some({self_ty: ty,.. *info}) } }; @@ -308,8 +308,8 @@ fn check_fn(ccx: @crate_ctxt, for self_info.each |info| { fcx.write_ty(info.self_id, info.self_ty); } - do vec::iter2(decl.inputs, arg_tys) |input, arg| { - fcx.write_ty(input.id, arg); + for vec::each2(decl.inputs, arg_tys) |input, arg| { + fcx.write_ty(input.id, *arg); } // If we don't have any enclosing function scope, it is time to @@ -351,8 +351,8 @@ fn check_fn(ccx: @crate_ctxt, } // Add formal parameters. - do vec::iter2(arg_tys, decl.inputs) |arg_ty, input| { - assign(input.ty.span, input.id, Some(arg_ty)); + for vec::each2(arg_tys, decl.inputs) |arg_ty, input| { + assign(input.ty.span, input.id, Some(*arg_ty)); debug!("Argument %s is assigned to %s", tcx.sess.str_of(input.ident), fcx.inh.locals.get(input.id).to_str()); @@ -605,7 +605,7 @@ impl @fn_ctxt: region_scope { } impl @fn_ctxt { - fn tag() -> ~str { fmt!("%x", ptr::addr_of(*self) as uint) } + fn tag() -> ~str { fmt!("%x", ptr::addr_of(&(*self)) as uint) } fn expr_to_str(expr: @ast::expr) -> ~str { fmt!("expr(%?:%s)", expr.id, @@ -807,7 +807,7 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> (ty::t, uint) { _ => () } } - ty::ty_enum(did, _) => { + ty::ty_enum(ref did, _) => { // Watch out for a type like `enum t = @t`. Such a // type would otherwise infinitely auto-deref. Only // autoderef loops during typeck (basically, this one @@ -818,7 +818,7 @@ fn do_autoderef(fcx: @fn_ctxt, sp: span, t: ty::t) -> (ty::t, uint) { if vec::contains(enum_dids, did) { return (t1, autoderefs); } - vec::push(enum_dids, did); + enum_dids.push(*did); } _ => { /*ok*/ } } @@ -1864,7 +1864,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, fcx.write_ty(id, typ); } ast::expr_rec(fields, base) => { - option::iter(&base, |b| { check_expr(fcx, b, expected); }); + option::iter(&base, |b| { check_expr(fcx, *b, expected); }); let expected = if expected.is_none() && base.is_some() { Some(fcx.expr_ty(base.get())) } else { expected }; @@ -1872,8 +1872,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, match sty { ty::ty_rec(flds) => Some(flds), _ => None } ); let fields_t = vec::map(fields, |f| { - bot |= check_expr(fcx, f.node.expr, flds.chain(|flds| - vec::find(flds, |tf| tf.ident == f.node.ident) + bot |= check_expr(fcx, f.node.expr, flds.chain_ref(|flds| + vec::find(*flds, |tf| tf.ident == f.node.ident) ).map(|tf| tf.mt.ty)); let expr_t = fcx.expr_ty(f.node.expr); let expr_mt = {ty: expr_t, mutbl: f.node.mutbl}; @@ -2029,8 +2029,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, let name = class_field.ident; let (_, seen) = class_field_map.get(name); if !seen { - vec::push(missing_fields, - ~"`" + tcx.sess.str_of(name) + ~"`"); + missing_fields.push( + ~"`" + tcx.sess.str_of(name) + ~"`"); } } @@ -2294,11 +2294,11 @@ fn check_enum_variants(ccx: @crate_ctxt, } _ => () } - if vec::contains(*disr_vals, *disr_val) { + if vec::contains(*disr_vals, &*disr_val) { ccx.tcx.sess.span_err(v.span, ~"discriminator value already exists"); } - vec::push(*disr_vals, *disr_val); + disr_vals.push(*disr_val); let ctor_ty = ty::node_id_to_type(ccx.tcx, v.node.id); let arg_tys; @@ -2321,7 +2321,8 @@ fn check_enum_variants(ccx: @crate_ctxt, match arg_tys { None => {} Some(arg_tys) => { - vec::push(*variants, @{args: arg_tys, ctor_ty: ctor_ty, + variants.push( + @{args: arg_tys, ctor_ty: ctor_ty, name: v.node.name, id: local_def(v.node.id), disr_val: this_disr_val}); } diff --git a/src/rustc/middle/typeck/check/alt.rs b/src/rustc/middle/typeck/check/alt.rs index 61d85b2dbfa0..0b2e9c8ab3dd 100644 --- a/src/rustc/middle/typeck/check/alt.rs +++ b/src/rustc/middle/typeck/check/alt.rs @@ -164,8 +164,8 @@ fn check_pat_variant(pcx: pat_ctxt, pat: @ast::pat, path: @ast::path, } do subpats.iter() |pats| { - do vec::iter2(pats, arg_types) |subpat, arg_ty| { - check_pat(pcx, subpat, arg_ty); + for vec::each2(*pats, arg_types) |subpat, arg_ty| { + check_pat(pcx, *subpat, *arg_ty); } }; } else if subpats_len > 0u { diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs index 815101a14481..d08d3e9b8478 100644 --- a/src/rustc/middle/typeck/check/method.rs +++ b/src/rustc/middle/typeck/check/method.rs @@ -48,11 +48,12 @@ candidates in the same way. If find no matching candidate at all, we proceed to auto-deref the receiver type and search again. We keep doing that until we cannot -auto-deref any longer. At that point, we will attempt an auto-ref. -If THAT fails, method lookup fails altogether. Autoref itself comes -in two varieties, autoslice and autoptr. The former converts `~[]` to -`&[]` and the latter converts any type `T` to `&mut T`, `&const T`, or -`&T`. +auto-deref any longer. At each step, we also check for candidates +based on "autoptr", which if the current type is `T`, checks for `&mut +T`, `&const T`, and `&T` receivers. Finally, at the very end, we will +also try autoslice, which converts `~[]` to `&[]` (there is no point +at trying autoslice earlier, because no autoderefable type is also +sliceable). ## Why two phases? @@ -159,22 +160,9 @@ impl LookupContext { None => {} } - // some special logic around newtypes: - match ty::get(self_ty).sty { - ty_enum(*) => { - // Note: in general, we prefer not to auto-ref a - // partially autoderef'd type, because it - // seems... crazy. But we have to be careful - // around newtype enums. They can be further - // deref'd, but they may also have intrinsic - // methods hanging off of them with interior type. - match self.search_for_any_autorefd_method(self_ty, - autoderefs) { - Some(move mme) => { return Some(mme); } - None => {} - } - } - _ => {} + match self.search_for_autoptrd_method(self_ty, autoderefs) { + Some(move mme) => { return Some(move mme); } + None => {} } match self.deref(self_ty, &enum_dids) { @@ -186,7 +174,7 @@ impl LookupContext { } } - self.search_for_any_autorefd_method(self_ty, autoderefs) + self.search_for_autosliced_method(self_ty, autoderefs) } fn deref(ty: ty::t, enum_dids: &DVec) -> Option { @@ -194,7 +182,7 @@ impl LookupContext { ty_enum(did, _) => { // Watch out for newtype'd enums like "enum t = @T". // See discussion in typeck::check::do_autoderef(). - if enum_dids.contains(did) { + if enum_dids.contains(&did) { return None; } enum_dids.push(did); @@ -516,30 +504,6 @@ impl LookupContext { } } - fn search_for_any_autorefd_method( - &self, - self_ty: ty::t, - autoderefs: uint) - -> Option - { - /*! - * - * Attempts both auto-slice and auto-ptr, as appropriate. - */ - - match self.search_for_autosliced_method(self_ty, autoderefs) { - Some(move mme) => { return Some(move mme); } - None => {} - } - - match self.search_for_autoptrd_method(self_ty, autoderefs) { - Some(move mme) => { return Some(move mme); } - None => {} - } - - return None; - } - fn search_for_autosliced_method( &self, self_ty: ty::t, @@ -594,13 +558,7 @@ impl LookupContext { let tcx = self.tcx(); match ty::get(self_ty).sty { - ty_box(*) | ty_uniq(*) | ty_rptr(*) => { - // we should be fully autoderef'd - self.bug(fmt!("Receiver type %s should be fully \ - autoderef'd by this point", - self.ty_to_str(self_ty))); - } - + ty_box(*) | ty_uniq(*) | ty_rptr(*) | ty_infer(IntVar(_)) | // FIXME(#3211)---should be resolved ty_self | ty_param(*) | ty_nil | ty_bot | ty_bool | ty_int(*) | ty_uint(*) | diff --git a/src/rustc/middle/typeck/check/regionmanip.rs b/src/rustc/middle/typeck/check/regionmanip.rs index d969ce908f04..4afb3ad78a63 100644 --- a/src/rustc/middle/typeck/check/regionmanip.rs +++ b/src/rustc/middle/typeck/check/regionmanip.rs @@ -27,17 +27,17 @@ fn replace_bound_regions_in_fn_ty( let region = ty::re_bound(ty::br_self); let ty = ty::mk_rptr(tcx, region, { ty: ty::mk_self(tcx), mutbl: m }); - vec::push(all_tys, ty); + all_tys.push(ty); } _ => {} } - for self_ty.each |t| { vec::push(all_tys, *t) } + for self_ty.each |t| { all_tys.push(*t) } debug!("replace_bound_regions_in_fn_ty(self_info.self_ty=%?, fn_ty=%s, \ all_tys=%?)", - self_ty.map(|t| ty_to_str(tcx, t)), + self_ty.map(|t| ty_to_str(tcx, *t)), ty_to_str(tcx, ty::mk_fn(tcx, *fn_ty)), all_tys.map(|t| ty_to_str(tcx, *t))); let _i = indenter(); @@ -50,11 +50,11 @@ fn replace_bound_regions_in_fn_ty( let t_fn = ty::fold_sty_to_ty(tcx, &ty_fn, |t| { replace_bound_regions(tcx, isr, t) }); - let t_self = self_ty.map(|t| replace_bound_regions(tcx, isr, t)); + let t_self = self_ty.map(|t| replace_bound_regions(tcx, isr, *t)); debug!("result of replace_bound_regions_in_fn_ty: self_info.self_ty=%?, \ fn_ty=%s", - t_self.map(|t| ty_to_str(tcx, t)), + t_self.map(|t| ty_to_str(tcx, *t)), ty_to_str(tcx, t_fn)); @@ -111,14 +111,14 @@ fn replace_bound_regions_in_fn_ty( // For each type `ty` in `tys`... do tys.foldl(isr) |isr, ty| { - let mut isr = isr; + let mut isr = *isr; // Using fold_regions is inefficient, because it // constructs new types, but it avoids code duplication in // terms of locating all the regions within the various // kinds of types. This had already caused me several // bugs so I decided to switch over. - do ty::fold_regions(tcx, ty) |r, in_fn| { + do ty::fold_regions(tcx, *ty) |r, in_fn| { if !in_fn { isr = append_isr(isr, to_r, r); } r }; diff --git a/src/rustc/middle/typeck/check/vtable.rs b/src/rustc/middle/typeck/check/vtable.rs index d48f5b9c070f..e8595b2f50a1 100644 --- a/src/rustc/middle/typeck/check/vtable.rs +++ b/src/rustc/middle/typeck/check/vtable.rs @@ -23,8 +23,8 @@ use util::common::indenter; fn has_trait_bounds(tps: ~[ty::param_bounds]) -> bool { vec::any(tps, |bs| { - vec::any(*bs, |b| { - match b { ty::bound_trait(_) => true, _ => false } + bs.any(|b| { + match b { &ty::bound_trait(_) => true, _ => false } }) }) } @@ -51,8 +51,18 @@ fn lookup_vtables(fcx: @fn_ctxt, match *bound { ty::bound_trait(i_ty) => { let i_ty = ty::subst(tcx, substs, i_ty); - vec::push(result, lookup_vtable(fcx, expr, *ty, i_ty, - allow_unsafe, is_early)); + match lookup_vtable(fcx, expr, *ty, i_ty, allow_unsafe, + is_early) { + Some(vtable) => result.push(vtable), + None => { + fcx.tcx().sess.span_fatal( + expr.span, + fmt!("failed to find an implementation of trait \ + %s for %s", + ty_to_str(fcx.tcx(), i_ty), + ty_to_str(fcx.tcx(), *ty))); + } + } } _ => () } @@ -69,7 +79,7 @@ fn fixup_substs(fcx: @fn_ctxt, expr: @ast::expr, // use a dummy type just to package up the substs that need fixing up let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static)); do fixup_ty(fcx, expr, t, is_early).map |t_f| { - match ty::get(t_f).sty { + match ty::get(*t_f).sty { ty::ty_trait(_, substs_f, _) => substs_f, _ => fail ~"t_f should be a trait" } @@ -91,7 +101,7 @@ fn lookup_vtable(fcx: @fn_ctxt, trait_ty: ty::t, allow_unsafe: bool, is_early: bool) - -> vtable_origin + -> Option { debug!("lookup_vtable(ty=%s, trait_ty=%s)", @@ -113,7 +123,7 @@ fn lookup_vtable(fcx: @fn_ctxt, // The type has unconstrained type variables in it, so we can't // do early resolution on it. Return some completely bogus vtable // information: we aren't storing it anyways. - return vtable_param(0, 0); + return Some(vtable_param(0, 0)); } }; @@ -135,7 +145,7 @@ fn lookup_vtable(fcx: @fn_ctxt, idid); relate_trait_tys(fcx, expr, trait_ty, ity); - return vtable_param(n, n_bound); + return Some(vtable_param(n, n_bound)); } } _ => tcx.sess.impossible_case( @@ -170,7 +180,7 @@ fn lookup_vtable(fcx: @fn_ctxt, } } } - return vtable_trait(did, substs.tps); + return Some(vtable_trait(did, substs.tps)); } _ => { @@ -303,7 +313,7 @@ fn lookup_vtable(fcx: @fn_ctxt, None => { assert is_early; // Bail out with a bogus answer - return vtable_param(0, 0); + return Some(vtable_param(0, 0)); } }; @@ -331,9 +341,9 @@ fn lookup_vtable(fcx: @fn_ctxt, // the impl as well as the resolved list // of type substitutions for the target // trait. - vec::push(found, - vtable_static(im.did, substs_f.tps, - subres)); + found.push( + vtable_static(im.did, substs_f.tps, + subres)); } } } @@ -341,23 +351,20 @@ fn lookup_vtable(fcx: @fn_ctxt, match found.len() { 0 => { /* fallthrough */ } - 1 => { return found[0]; } + 1 => { return Some(found[0]); } _ => { if !is_early { fcx.ccx.tcx.sess.span_err( expr.span, ~"multiple applicable methods in scope"); } - return found[0]; + return Some(found[0]); } } } } - tcx.sess.span_fatal( - expr.span, - fmt!("failed to find an implementation of trait %s for %s", - ty_to_str(tcx, trait_ty), ty_to_str(tcx, ty))); + return None; } fn fixup_ty(fcx: @fn_ctxt, @@ -392,8 +399,9 @@ fn connect_trait_tps(fcx: @fn_ctxt, expr: @ast::expr, impl_tys: ~[ty::t], ty::get(trait_ty).sty, impl_did); match ty::get(trait_ty).sty { ty::ty_trait(_, substs, _) => { - vec::iter2(substs.tps, trait_tys, - |a, b| demand::suptype(fcx, expr.span, a, b)); + for vec::each2(substs.tps, trait_tys) |a, b| { + demand::suptype(fcx, expr.span, *a, *b) + } } _ => tcx.sess.impossible_case(expr.span, "connect_trait_tps: \ don't know how to handle a non-trait ty") @@ -458,13 +466,55 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) { Look up vtables for the type we're casting to, passing in the source and target type */ - let vtable = lookup_vtable(fcx, ex, fcx.expr_ty(src), - target_ty, true, is_early); - /* - Map this expression to that vtable (that is: "ex has - vtable ") - */ - if !is_early { cx.vtable_map.insert(ex.id, @~[vtable]); } + let ty = fcx.expr_ty(src); + let vtable_opt = lookup_vtable(fcx, ex, ty, target_ty, true, + is_early); + match vtable_opt { + None => { + // Try the new-style boxed trait; "@int as @Trait". + let mut err = false; + let ty = structurally_resolved_type(fcx, ex.span, ty); + match ty::get(ty).sty { + ty::ty_box(boxed_ty) => { + let vtable_opt = lookup_vtable(fcx, ex, + boxed_ty.ty, + target_ty, true, + is_early); + match vtable_opt { + Some(vtable) => { + /* + Map this expression to that vtable (that + is: "ex has vtable ") + */ + if !is_early { + cx.vtable_map.insert(ex.id, + @~[vtable]); + } + } + None => err = true + } + } + _ => err = true + } + + if err { + fcx.tcx().sess.span_fatal( + ex.span, + fmt!("failed to find an implementation of trait \ + %s for %s", + ty_to_str(fcx.tcx(), target_ty), + ty_to_str(fcx.tcx(), ty))); + } + } + Some(vtable) => { + /* + Map this expression to that vtable (that is: "ex has + vtable ") + */ + if !is_early { cx.vtable_map.insert(ex.id, @~[vtable]); } + fcx.tcx().legacy_boxed_traits.insert(ex.id, ()); + } + } } _ => () } diff --git a/src/rustc/middle/typeck/check/writeback.rs b/src/rustc/middle/typeck/check/writeback.rs index a70e5f600d35..33a26c8daf49 100644 --- a/src/rustc/middle/typeck/check/writeback.rs +++ b/src/rustc/middle/typeck/check/writeback.rs @@ -94,7 +94,7 @@ fn resolve_type_vars_for_node(wbcx: wb_ctxt, sp: span, id: ast::node_id) let mut new_tps = ~[]; for substs.tps.each |subst| { match resolve_type_vars_in_type(fcx, sp, *subst) { - Some(t) => vec::push(new_tps, t), + Some(t) => new_tps.push(t), None => { wbcx.success = false; return None; } } } diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs index 17d5f81993df..e9238e30c663 100644 --- a/src/rustc/middle/typeck/coherence.rs +++ b/src/rustc/middle/typeck/coherence.rs @@ -198,7 +198,7 @@ impl CoherenceChecker { existing trait", sess.str_of(mi.ident)); let mut method_infos = mis; - push(method_infos, mi); + method_infos.push(mi); pmm.insert(item.id, method_infos); } None => { @@ -484,7 +484,7 @@ impl CoherenceChecker { let trait_def_id = self.trait_ref_to_trait_def_id( - trait_ref); + *trait_ref); if trait_def_id.crate != local_crate { let session = @@ -547,7 +547,7 @@ impl CoherenceChecker { debug!( "(creating impl) adding provided method `%s` to impl", sess.str_of(provided_method.ident)); - push(methods, *provided_method); + methods.push(*provided_method); } } @@ -559,8 +559,7 @@ impl CoherenceChecker { let mut methods = ~[]; for ast_methods.each |ast_method| { - push(methods, - method_to_MethodInfo(*ast_method)); + methods.push(method_to_MethodInfo(*ast_method)); } // For each trait that the impl implements, see what @@ -619,7 +618,7 @@ impl CoherenceChecker { -> @Impl { let mut methods = ~[]; for struct_def.methods.each |ast_method| { - push(methods, @{ + methods.push(@{ did: local_def(ast_method.id), n_tps: ast_method.tps.len(), ident: ast_method.ident, @@ -654,6 +653,10 @@ impl CoherenceChecker { module_def_id, None); for (*implementations).each |implementation| { + debug!("coherence: adding impl from external crate: %s", + ty::item_path_str(self.crate_context.tcx, + implementation.did)); + // Make sure we don't visit the same implementation // multiple times. match impls_seen.find(implementation.did) { diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index 630ac8c13a19..18e29981af30 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -725,7 +725,7 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item) fn compute_bounds(ccx: @crate_ctxt, ast_bounds: @~[ast::ty_param_bound]) -> ty::param_bounds { @do vec::flat_map(*ast_bounds) |b| { - match b { + match *b { ast::bound_send => ~[ty::bound_send], ast::bound_copy => ~[ty::bound_copy], ast::bound_const => ~[ty::bound_const], diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs index a0bb828e4122..e5aa0debfe17 100644 --- a/src/rustc/middle/typeck/infer.rs +++ b/src/rustc/middle/typeck/infer.rs @@ -507,7 +507,7 @@ fn rollback_to( vb: &vals_and_bindings, len: uint) { while vb.bindings.len() != len { - let (vid, old_v) = vec::pop(vb.bindings); + let (vid, old_v) = vb.bindings.pop(); vb.vals.insert(vid.to_uint(), old_v); } } diff --git a/src/rustc/middle/typeck/infer/combine.rs b/src/rustc/middle/typeck/infer/combine.rs index 84791b59b329..db65bff9bfec 100644 --- a/src/rustc/middle/typeck/infer/combine.rs +++ b/src/rustc/middle/typeck/infer/combine.rs @@ -221,7 +221,7 @@ fn super_tps( if vec::same_length(as_, bs) { iter_vec2(as_, bs, |a, b| { - eq_tys(self, a, b) + eq_tys(self, *a, *b) }).then(|| Ok(as_.to_vec()) ) } else { Err(ty::terr_ty_param_size( @@ -327,7 +327,7 @@ fn super_fn_sigs( b_args: ~[ty::arg]) -> cres<~[ty::arg]> { if vec::same_length(a_args, b_args) { - map_vec2(a_args, b_args, |a, b| self.args(a, b)) + map_vec2(a_args, b_args, |a, b| self.args(*a, *b)) } else { Err(ty::terr_arg_count) } @@ -474,7 +474,7 @@ fn super_tys( (ty::ty_rec(as_), ty::ty_rec(bs)) => { if vec::same_length(as_, bs) { map_vec2(as_, bs, |a,b| { - self.flds(a, b) + self.flds(*a, *b) }).chain(|flds| Ok(ty::mk_rec(tcx, flds)) ) } else { Err(ty::terr_record_size(expected_found(self, as_.len(), @@ -484,7 +484,7 @@ fn super_tys( (ty::ty_tup(as_), ty::ty_tup(bs)) => { if vec::same_length(as_, bs) { - map_vec2(as_, bs, |a, b| self.tys(a, b) ) + map_vec2(as_, bs, |a, b| self.tys(*a, *b) ) .chain(|ts| Ok(ty::mk_tup(tcx, ts)) ) } else { Err(ty::terr_tuple_size( diff --git a/src/rustc/middle/typeck/infer/region_var_bindings.rs b/src/rustc/middle/typeck/infer/region_var_bindings.rs index c03128724884..8bbdab74d230 100644 --- a/src/rustc/middle/typeck/infer/region_var_bindings.rs +++ b/src/rustc/middle/typeck/infer/region_var_bindings.rs @@ -350,7 +350,7 @@ impl Constraint : cmp::Eq { } impl Constraint : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { ConstrainVarSubVar(ref v0, ref v1) => to_bytes::iter_bytes_3(&0u8, v0, v1, lsb0, f), @@ -377,7 +377,7 @@ impl TwoRegions : cmp::Eq { } impl TwoRegions : to_bytes::IterBytes { - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.a, &self.b, lsb0, f) } } @@ -830,7 +830,7 @@ impl RegionVarBindings { // It would be nice to write this using map(): let mut edges = vec::with_capacity(num_edges); for self.constraints.each_ref |constraint, span| { - vec::push(edges, GraphEdge { + edges.push(GraphEdge { next_edge: [mut uint::max_value, uint::max_value], constraint: *constraint, span: *span @@ -1192,7 +1192,7 @@ impl RegionVarBindings { set.insert(*orig_node_idx, ()); let mut result = ~[]; while !vec::is_empty(stack) { - let node_idx = vec::pop(stack); + let node_idx = stack.pop(); for self.each_edge(graph, node_idx, dir) |edge| { match edge.constraint { ConstrainVarSubVar(from_vid, to_vid) => { @@ -1201,13 +1201,13 @@ impl RegionVarBindings { Outgoing => to_vid }; if set.insert(*vid, ()) { - vec::push(stack, vid); + stack.push(vid); } } ConstrainRegSubVar(region, _) => { assert dir == Incoming; - vec::push(result, SpannedRegion { + result.push(SpannedRegion { region: region, span: edge.span }); @@ -1215,7 +1215,7 @@ impl RegionVarBindings { ConstrainVarSubReg(_, region) => { assert dir == Outgoing; - vec::push(result, SpannedRegion { + result.push(SpannedRegion { region: region, span: edge.span }); diff --git a/src/rustc/middle/typeck/infer/resolve.rs b/src/rustc/middle/typeck/infer/resolve.rs index 5d748efc332d..2a851a5f7bb2 100644 --- a/src/rustc/middle/typeck/infer/resolve.rs +++ b/src/rustc/middle/typeck/infer/resolve.rs @@ -170,11 +170,11 @@ impl resolve_state { } fn resolve_ty_var(vid: TyVid) -> ty::t { - if vec::contains(self.v_seen, vid) { + if vec::contains(self.v_seen, &vid) { self.err = Some(cyclic_ty(vid)); return ty::mk_var(self.infcx.tcx, vid); } else { - vec::push(self.v_seen, vid); + self.v_seen.push(vid); let tcx = self.infcx.tcx; // Nonobvious: prefer the most specific type @@ -197,7 +197,7 @@ impl resolve_state { ty::mk_var(tcx, vid) } }; - vec::pop(self.v_seen); + self.v_seen.pop(); return t1; } } diff --git a/src/rustc/middle/typeck/infer/unify.rs b/src/rustc/middle/typeck/infer/unify.rs index 500a4d5b419f..7ccbaa40ada1 100644 --- a/src/rustc/middle/typeck/infer/unify.rs +++ b/src/rustc/middle/typeck/infer/unify.rs @@ -51,7 +51,7 @@ impl infer_ctxt { +new_v: var_value) { let old_v = vb.vals.get(vid.to_uint()); - vec::push(vb.bindings, (vid, old_v)); + vb.bindings.push((vid, old_v)); vb.vals.insert(vid.to_uint(), new_v); debug!("Updating variable %s from %s to %s", diff --git a/src/rustc/rustc.rc b/src/rustc/rustc.rc index d34ae4e35f38..dad27b706e60 100644 --- a/src/rustc/rustc.rc +++ b/src/rustc/rustc.rc @@ -12,10 +12,12 @@ #[no_core]; #[legacy_modes]; +#[legacy_exports]; #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; -// #[warn(deprecated_pattern)]; +#[allow(deprecated_mode)]; +#[allow(deprecated_pattern)]; extern mod core(vers = "0.4"); extern mod std(vers = "0.4"); @@ -86,6 +88,7 @@ mod middle { mod type_use; #[legacy_exports] mod reachable; + mod machine; } #[legacy_exports] mod ty; diff --git a/src/rustc/util/common.rs b/src/rustc/util/common.rs index 4c033515b9a9..37cc016e8ea0 100644 --- a/src/rustc/util/common.rs +++ b/src/rustc/util/common.rs @@ -36,7 +36,7 @@ fn field_expr(f: ast::field) -> @ast::expr { return f.node.expr; } fn field_exprs(fields: ~[ast::field]) -> ~[@ast::expr] { let mut es = ~[]; - for fields.each |f| { vec::push(es, f.node.expr); } + for fields.each |f| { es.push(f.node.expr); } return es; } diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs index 9ade20c55682..0df5827ed3d8 100644 --- a/src/rustc/util/ppaux.rs +++ b/src/rustc/util/ppaux.rs @@ -261,7 +261,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str { m == ty::default_arg_mode_for_ty(cx, ty) { ~"" } else { - mode_to_str(ast::expl(m)) + mode_to_str(ast::expl(m)) + ":" } } }; @@ -286,7 +286,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str { } s += ~"("; let mut strs = ~[]; - for inputs.each |a| { vec::push(strs, fn_input_to_str(cx, *a)); } + for inputs.each |a| { strs.push(fn_input_to_str(cx, *a)); } s += str::connect(strs, ~", "); s += ~")"; if ty::get(output).sty != ty_nil { @@ -342,12 +342,12 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str { ty_type => ~"type", ty_rec(elems) => { let mut strs: ~[~str] = ~[]; - for elems.each |fld| { vec::push(strs, field_to_str(cx, *fld)); } + for elems.each |fld| { strs.push(field_to_str(cx, *fld)); } ~"{" + str::connect(strs, ~",") + ~"}" } ty_tup(elems) => { let mut strs = ~[]; - for elems.each |elem| { vec::push(strs, ty_to_str(cx, *elem)); } + for elems.each |elem| { strs.push(ty_to_str(cx, *elem)); } ~"(" + str::connect(strs, ~",") + ~")" } ty_fn(ref f) => { diff --git a/src/rustdoc/astsrv.rs b/src/rustdoc/astsrv.rs index 2ae641a73bbf..ab6b348c04a2 100644 --- a/src/rustdoc/astsrv.rs +++ b/src/rustdoc/astsrv.rs @@ -145,25 +145,25 @@ fn build_error_handlers( }; impl DiagnosticHandler: diagnostic::handler { - fn fatal(msg: ~str) -> ! { self.inner.fatal(msg) } - fn err(msg: ~str) { self.inner.err(msg) } + fn fatal(msg: &str) -> ! { self.inner.fatal(msg) } + fn err(msg: &str) { self.inner.err(msg) } fn bump_err_count() { self.inner.bump_err_count(); } fn has_errors() -> bool { self.inner.has_errors() } fn abort_if_errors() { self.inner.abort_if_errors() } - fn warn(msg: ~str) { self.inner.warn(msg) } - fn note(msg: ~str) { self.inner.note(msg) } - fn bug(msg: ~str) -> ! { self.inner.bug(msg) } - fn unimpl(msg: ~str) -> ! { self.inner.unimpl(msg) } + fn warn(msg: &str) { self.inner.warn(msg) } + fn note(msg: &str) { self.inner.note(msg) } + fn bug(msg: &str) -> ! { self.inner.bug(msg) } + fn unimpl(msg: &str) -> ! { self.inner.unimpl(msg) } fn emit(cmsp: Option<(codemap::codemap, codemap::span)>, - msg: ~str, lvl: diagnostic::level) { + msg: &str, lvl: diagnostic::level) { self.inner.emit(cmsp, msg, lvl) } } let emitter = fn@(cmsp: Option<(codemap::codemap, codemap::span)>, - msg: ~str, lvl: diagnostic::level) { + msg: &str, lvl: diagnostic::level) { diagnostic::emit(cmsp, msg, lvl); }; let inner_handler = diagnostic::mk_handler(Some(emitter)); diff --git a/src/rustdoc/attr_pass.rs b/src/rustdoc/attr_pass.rs index b3ba7f141097..d5f0ca9f507b 100644 --- a/src/rustdoc/attr_pass.rs +++ b/src/rustdoc/attr_pass.rs @@ -144,6 +144,7 @@ fn fold_enum( { variants: do par::map(doc.variants) |variant| { + let variant = *variant; let desc = do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get(doc_id) { ast_map::node_item(@{ @@ -236,7 +237,7 @@ fn merge_method_attrs( { desc: desc, - .. doc + ..*doc } } } diff --git a/src/rustdoc/config.rs b/src/rustdoc/config.rs index b95e16570435..d601d6d92d1e 100644 --- a/src/rustdoc/config.rs +++ b/src/rustdoc/config.rs @@ -141,7 +141,7 @@ fn config_from_opts( let result = result::Ok(config); let result = do result::chain(result) |config| { let output_dir = getopts::opt_maybe_str(matches, opt_output_dir()); - let output_dir = output_dir.map(|s| Path(s)); + let output_dir = output_dir.map(|s| Path(*s)); result::Ok({ output_dir: output_dir.get_default(config.output_dir), .. config @@ -152,7 +152,7 @@ fn config_from_opts( matches, opt_output_format()); do output_format.map_default(result::Ok(config)) |output_format| { - do result::chain(parse_output_format(output_format)) + do result::chain(parse_output_format(*output_format)) |output_format| { result::Ok({ @@ -167,7 +167,7 @@ fn config_from_opts( getopts::opt_maybe_str(matches, opt_output_style()); do output_style.map_default(result::Ok(config)) |output_style| { - do result::chain(parse_output_style(output_style)) + do result::chain(parse_output_style(*output_style)) |output_style| { result::Ok({ output_style: output_style, @@ -228,8 +228,8 @@ fn maybe_find_pandoc( }; let pandoc = do vec::find(possible_pandocs) |pandoc| { - let output = program_output(pandoc, ~[~"--version"]); - debug!("testing pandoc cmd %s: %?", pandoc, output); + let output = program_output(*pandoc, ~[~"--version"]); + debug!("testing pandoc cmd %s: %?", *pandoc, output); output.status == 0 }; @@ -285,20 +285,20 @@ mod test { #[test] fn should_error_with_no_crates() { let config = test::parse_config(~[~"rustdoc"]); - assert result::get_err(config) == ~"no crates specified"; + assert config.get_err() == ~"no crates specified"; } #[test] fn should_error_with_multiple_crates() { let config = test::parse_config(~[~"rustdoc", ~"crate1.rc", ~"crate2.rc"]); - assert result::get_err(config) == ~"multiple crates specified"; + assert config.get_err() == ~"multiple crates specified"; } #[test] fn should_set_output_dir_to_cwd_if_not_provided() { let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]); - assert result::get(config).output_dir == Path("."); + assert config.get().output_dir == Path("."); } #[test] @@ -306,13 +306,13 @@ fn should_set_output_dir_if_provided() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles" ]); - assert result::get(config).output_dir == Path("snuggles"); + assert config.get().output_dir == Path("snuggles"); } #[test] fn should_set_output_format_to_pandoc_html_if_not_provided() { let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]); - assert result::get(config).output_format == PandocHtml; + assert config.get().output_format == PandocHtml; } #[test] @@ -320,7 +320,7 @@ fn should_set_output_format_to_markdown_if_requested() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--output-format", ~"markdown" ]); - assert result::get(config).output_format == Markdown; + assert config.get().output_format == Markdown; } #[test] @@ -328,7 +328,7 @@ fn should_set_output_format_to_pandoc_html_if_requested() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--output-format", ~"html" ]); - assert result::get(config).output_format == PandocHtml; + assert config.get().output_format == PandocHtml; } #[test] @@ -336,13 +336,13 @@ fn should_error_on_bogus_format() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--output-format", ~"bogus" ]); - assert result::get_err(config) == ~"unknown output format 'bogus'"; + assert config.get_err() == ~"unknown output format 'bogus'"; } #[test] fn should_set_output_style_to_doc_per_mod_by_default() { let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]); - assert result::get(config).output_style == DocPerMod; + assert config.get().output_style == DocPerMod; } #[test] @@ -350,7 +350,7 @@ fn should_set_output_style_to_one_doc_if_requested() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-crate" ]); - assert result::get(config).output_style == DocPerCrate; + assert config.get().output_style == DocPerCrate; } #[test] @@ -358,7 +358,7 @@ fn should_set_output_style_to_doc_per_mod_if_requested() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-mod" ]); - assert result::get(config).output_style == DocPerMod; + assert config.get().output_style == DocPerMod; } #[test] @@ -366,7 +366,7 @@ fn should_error_on_bogus_output_style() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--output-style", ~"bogus" ]); - assert result::get_err(config) == ~"unknown output style 'bogus'"; + assert config.get_err() == ~"unknown output style 'bogus'"; } #[test] @@ -374,11 +374,11 @@ fn should_set_pandoc_command_if_requested() { let config = test::parse_config(~[ ~"rustdoc", ~"crate.rc", ~"--pandoc-cmd", ~"panda-bear-doc" ]); - assert result::get(config).pandoc_cmd == Some(~"panda-bear-doc"); + assert config.get().pandoc_cmd == Some(~"panda-bear-doc"); } #[test] fn should_set_pandoc_command_when_using_pandoc() { let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]); - assert result::get(config).pandoc_cmd == Some(~"pandoc"); + assert config.get().pandoc_cmd == Some(~"pandoc"); } diff --git a/src/rustdoc/desc_to_brief_pass.rs b/src/rustdoc/desc_to_brief_pass.rs index b517c2f24091..b8946ce17b0d 100644 --- a/src/rustdoc/desc_to_brief_pass.rs +++ b/src/rustdoc/desc_to_brief_pass.rs @@ -44,7 +44,7 @@ fn fold_trait(fold: fold::Fold<()>, doc: doc::TraitDoc) -> doc::TraitDoc { { methods: par::map(doc.methods, |doc| { brief: extract(doc.desc), - .. doc + .. *doc }), .. doc } @@ -56,7 +56,7 @@ fn fold_impl(fold: fold::Fold<()>, doc: doc::ImplDoc) -> doc::ImplDoc { { methods: par::map(doc.methods, |doc| { brief: extract(doc.desc), - .. doc + .. *doc }), .. doc } @@ -165,7 +165,7 @@ fn paragraphs(s: ~str) -> ~[~str] { let paras = do vec::foldl(~[], lines) |paras, line| { let mut res = paras; - if str::is_whitespace(line) { + if str::is_whitespace(*line) { whitespace_lines += 1; } else { if whitespace_lines > 0 { @@ -178,9 +178,9 @@ fn paragraphs(s: ~str) -> ~[~str] { whitespace_lines = 0; accum = if str::is_empty(accum) { - line + *line } else { - accum + ~"\n" + line + accum + ~"\n" + *line } } diff --git a/src/rustdoc/doc.rs b/src/rustdoc/doc.rs index 82bddf11d161..0764d9e24326 100644 --- a/src/rustdoc/doc.rs +++ b/src/rustdoc/doc.rs @@ -378,7 +378,7 @@ impl IndexEntry : cmp::Eq { impl Doc { fn CrateDoc() -> CrateDoc { option::get(&vec::foldl(None, self.pages, |_m, page| { - match page { + match *page { doc::CratePage(doc) => Some(doc), _ => None } @@ -395,7 +395,7 @@ impl ModDoc { fn mods() -> ~[ModDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { ModTag(ModDoc) => Some(ModDoc), _ => None } @@ -404,7 +404,7 @@ impl ModDoc { fn nmods() -> ~[NmodDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { NmodTag(nModDoc) => Some(nModDoc), _ => None } @@ -413,7 +413,7 @@ impl ModDoc { fn fns() -> ~[FnDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { FnTag(FnDoc) => Some(FnDoc), _ => None } @@ -422,7 +422,7 @@ impl ModDoc { fn consts() -> ~[ConstDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { ConstTag(ConstDoc) => Some(ConstDoc), _ => None } @@ -431,7 +431,7 @@ impl ModDoc { fn enums() -> ~[EnumDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { EnumTag(EnumDoc) => Some(EnumDoc), _ => None } @@ -440,7 +440,7 @@ impl ModDoc { fn traits() -> ~[TraitDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { TraitTag(TraitDoc) => Some(TraitDoc), _ => None } @@ -449,7 +449,7 @@ impl ModDoc { fn impls() -> ~[ImplDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { ImplTag(ImplDoc) => Some(ImplDoc), _ => None } @@ -458,7 +458,7 @@ impl ModDoc { fn types() -> ~[TyDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { TyTag(TyDoc) => Some(TyDoc), _ => None } @@ -467,7 +467,7 @@ impl ModDoc { fn structs() -> ~[StructDoc] { do vec::filter_map(self.items) |itemtag| { - match itemtag { + match *itemtag { StructTag(StructDoc) => Some(StructDoc), _ => None } @@ -490,7 +490,7 @@ impl ~[Page]: PageUtils { fn mods() -> ~[ModDoc] { do vec::filter_map(self) |page| { - match page { + match *page { ItemPage(ModTag(ModDoc)) => Some(ModDoc), _ => None } @@ -499,7 +499,7 @@ impl ~[Page]: PageUtils { fn nmods() -> ~[NmodDoc] { do vec::filter_map(self) |page| { - match page { + match *page { ItemPage(NmodTag(nModDoc)) => Some(nModDoc), _ => None } @@ -508,7 +508,7 @@ impl ~[Page]: PageUtils { fn fns() -> ~[FnDoc] { do vec::filter_map(self) |page| { - match page { + match *page { ItemPage(FnTag(FnDoc)) => Some(FnDoc), _ => None } @@ -517,7 +517,7 @@ impl ~[Page]: PageUtils { fn consts() -> ~[ConstDoc] { do vec::filter_map(self) |page| { - match page { + match *page { ItemPage(ConstTag(ConstDoc)) => Some(ConstDoc), _ => None } @@ -526,7 +526,7 @@ impl ~[Page]: PageUtils { fn enums() -> ~[EnumDoc] { do vec::filter_map(self) |page| { - match page { + match *page { ItemPage(EnumTag(EnumDoc)) => Some(EnumDoc), _ => None } @@ -535,7 +535,7 @@ impl ~[Page]: PageUtils { fn traits() -> ~[TraitDoc] { do vec::filter_map(self) |page| { - match page { + match *page { ItemPage(TraitTag(TraitDoc)) => Some(TraitDoc), _ => None } @@ -544,7 +544,7 @@ impl ~[Page]: PageUtils { fn impls() -> ~[ImplDoc] { do vec::filter_map(self) |page| { - match page { + match *page { ItemPage(ImplTag(ImplDoc)) => Some(ImplDoc), _ => None } @@ -553,7 +553,7 @@ impl ~[Page]: PageUtils { fn types() -> ~[TyDoc] { do vec::filter_map(self) |page| { - match page { + match *page { ItemPage(TyTag(TyDoc)) => Some(TyDoc), _ => None } diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs index b8a13b712e58..7b34a327bee2 100644 --- a/src/rustdoc/extract.rs +++ b/src/rustdoc/extract.rs @@ -21,7 +21,7 @@ fn to_str(id: ast::ident) -> ~str { return *(*intr.get()).get(id); } -fn interner() -> syntax::parse::token::ident_interner { +fn interner() -> @syntax::parse::token::ident_interner { return *(unsafe{ local_data_get(interner_key!()) }).get(); } @@ -140,7 +140,7 @@ fn nmoddoc_from_mod( let ItemDoc = mk_itemdoc(item.id, to_str(item.ident)); match item.node { ast::foreign_item_fn(*) => { - vec::push(fns, fndoc_from_fn(ItemDoc)); + fns.push(fndoc_from_fn(ItemDoc)); } ast::foreign_item_const(*) => {} // XXX: Not implemented. } diff --git a/src/rustdoc/fold.rs b/src/rustdoc/fold.rs index 5d2d5d1f8b90..28dbdaeea801 100644 --- a/src/rustdoc/fold.rs +++ b/src/rustdoc/fold.rs @@ -179,7 +179,7 @@ fn default_any_fold_mod( doc::ModDoc_({ item: fold.fold_item(fold, doc.item), items: par::map(doc.items, |ItemTag, copy fold| { - fold_ItemTag(fold, ItemTag) + fold_ItemTag(fold, *ItemTag) }), .. *doc }) @@ -205,7 +205,7 @@ fn default_par_fold_mod( doc::ModDoc_({ item: fold.fold_item(fold, doc.item), items: par::map(doc.items, |ItemTag, copy fold| { - fold_ItemTag(fold, ItemTag) + fold_ItemTag(fold, *ItemTag) }), .. *doc }) @@ -218,7 +218,7 @@ fn default_any_fold_nmod( { item: fold.fold_item(fold, doc.item), fns: par::map(doc.fns, |FnDoc, copy fold| { - fold.fold_fn(fold, FnDoc) + fold.fold_fn(fold, *FnDoc) }), .. doc } @@ -244,7 +244,7 @@ fn default_par_fold_nmod( { item: fold.fold_item(fold, doc.item), fns: par::map(doc.fns, |FnDoc, copy fold| { - fold.fold_fn(fold, FnDoc) + fold.fold_fn(fold, *FnDoc) }), .. doc } diff --git a/src/rustdoc/markdown_index_pass.rs b/src/rustdoc/markdown_index_pass.rs index 8ebe401dc14a..3bd74d6ffe2e 100644 --- a/src/rustdoc/markdown_index_pass.rs +++ b/src/rustdoc/markdown_index_pass.rs @@ -58,7 +58,7 @@ fn build_mod_index( ) -> doc::Index { { entries: par::map(doc.items, |doc| { - item_to_entry(doc, config) + item_to_entry(*doc, config) }) } } @@ -69,7 +69,7 @@ fn build_nmod_index( ) -> doc::Index { { entries: par::map(doc.fns, |doc| { - item_to_entry(doc::FnTag(doc), config) + item_to_entry(doc::FnTag(*doc), config) }) } } diff --git a/src/rustdoc/page_pass.rs b/src/rustdoc/page_pass.rs index 8710792f0e47..ad3f679a97cb 100644 --- a/src/rustdoc/page_pass.rs +++ b/src/rustdoc/page_pass.rs @@ -105,7 +105,7 @@ fn fold_mod( fn strip_mod(doc: doc::ModDoc) -> doc::ModDoc { doc::ModDoc_({ items: do vec::filter(doc.items) |item| { - match item { + match *item { doc::ModTag(_) => false, doc::NmodTag(_) => false, _ => true diff --git a/src/rustdoc/path_pass.rs b/src/rustdoc/path_pass.rs index 84b542f6bf0d..f6a241fdac84 100644 --- a/src/rustdoc/path_pass.rs +++ b/src/rustdoc/path_pass.rs @@ -43,9 +43,9 @@ fn fold_item(fold: fold::Fold, doc: doc::ItemDoc) -> doc::ItemDoc { fn fold_mod(fold: fold::Fold, doc: doc::ModDoc) -> doc::ModDoc { let is_topmod = doc.id() == ast::crate_node_id; - if !is_topmod { vec::push(fold.ctxt.path, doc.name()); } + if !is_topmod { fold.ctxt.path.push(doc.name()); } let doc = fold::default_any_fold_mod(fold, doc); - if !is_topmod { vec::pop(fold.ctxt.path); } + if !is_topmod { fold.ctxt.path.pop(); } doc::ModDoc_({ item: fold.fold_item(fold, doc.item), @@ -54,9 +54,9 @@ fn fold_mod(fold: fold::Fold, doc: doc::ModDoc) -> doc::ModDoc { } fn fold_nmod(fold: fold::Fold, doc: doc::NmodDoc) -> doc::NmodDoc { - vec::push(fold.ctxt.path, doc.name()); + fold.ctxt.path.push(doc.name()); let doc = fold::default_seq_fold_nmod(fold, doc); - vec::pop(fold.ctxt.path); + fold.ctxt.path.pop(); { item: fold.fold_item(fold, doc.item), diff --git a/src/rustdoc/rustdoc.rc b/src/rustdoc/rustdoc.rc index 1686f56e3f17..f8714b0e9bac 100644 --- a/src/rustdoc/rustdoc.rc +++ b/src/rustdoc/rustdoc.rc @@ -15,6 +15,8 @@ #[allow(vecs_implicitly_copyable)]; #[allow(non_implicitly_copyable_typarams)]; +#[allow(deprecated_mode)]; +#[allow(deprecated_pattern)]; extern mod core(vers = "0.4"); extern mod std(vers = "0.4"); diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs index 648d1d7a3221..50ebef05afbe 100755 --- a/src/rustdoc/rustdoc.rs +++ b/src/rustdoc/rustdoc.rs @@ -5,7 +5,7 @@ use config::Config; fn main(args: ~[~str]) { - if args.contains(~"-h") || args.contains(~"--help") { + if args.contains(&~"-h") || args.contains(&~"--help") { config::usage(); return; } diff --git a/src/rustdoc/sectionalize_pass.rs b/src/rustdoc/sectionalize_pass.rs index 2203707ed213..088ca4d51bd0 100644 --- a/src/rustdoc/sectionalize_pass.rs +++ b/src/rustdoc/sectionalize_pass.rs @@ -42,7 +42,7 @@ fn fold_trait(fold: fold::Fold<()>, doc: doc::TraitDoc) -> doc::TraitDoc { { desc: desc, sections: sections, - ..method + .. *method } }, .. doc @@ -59,7 +59,7 @@ fn fold_impl(fold: fold::Fold<()>, doc: doc::ImplDoc) -> doc::ImplDoc { { desc: desc, sections: sections, - .. method + .. *method } }, .. doc diff --git a/src/rustdoc/text_pass.rs b/src/rustdoc/text_pass.rs index 76ae3192cef9..b929cd0aa91a 100644 --- a/src/rustdoc/text_pass.rs +++ b/src/rustdoc/text_pass.rs @@ -32,7 +32,7 @@ fn run( } fn maybe_apply_op(op: Op, s: Option<~str>) -> Option<~str> { - s.map(|s| op(s) ) + s.map(|s| op(*s) ) } fn fold_item(fold: fold::Fold, doc: doc::ItemDoc) -> doc::ItemDoc { @@ -60,7 +60,7 @@ fn fold_enum(fold: fold::Fold, doc: doc::EnumDoc) -> doc::EnumDoc { variants: do par::map(doc.variants) |variant, copy fold| { { desc: maybe_apply_op(fold.ctxt, variant.desc), - .. variant + .. *variant } }, .. doc @@ -82,7 +82,7 @@ fn apply_to_methods(op: Op, docs: ~[doc::MethodDoc]) -> ~[doc::MethodDoc] { brief: maybe_apply_op(op, doc.brief), desc: maybe_apply_op(op, doc.desc), sections: apply_to_sections(op, doc.sections), - .. doc + .. *doc } } } diff --git a/src/rustdoc/tystr_pass.rs b/src/rustdoc/tystr_pass.rs index 62db53b76009..08ad3ea3ecf4 100644 --- a/src/rustdoc/tystr_pass.rs +++ b/src/rustdoc/tystr_pass.rs @@ -112,6 +112,7 @@ fn fold_enum( { variants: do par::map(doc.variants) |variant| { + let variant = *variant; let sig = do astsrv::exec(srv) |ctxt| { match ctxt.ast_map.get(doc_id) { ast_map::node_item(@{ @@ -161,7 +162,7 @@ fn merge_methods( do par::map(docs) |doc| { { sig: get_method_sig(srv, item_id, doc.name), - .. doc + .. *doc } } } @@ -177,7 +178,7 @@ fn get_method_sig( node: ast::item_trait(_, _, methods), _ }, _) => { match vec::find(methods, |method| { - match method { + match *method { ast::required(ty_m) => to_str(ty_m.ident) == method_name, ast::provided(m) => to_str(m.ident) == method_name, } diff --git a/src/rustdoc/unindent_pass.rs b/src/rustdoc/unindent_pass.rs index 42c9e80ab7bb..2f38c20e900f 100644 --- a/src/rustdoc/unindent_pass.rs +++ b/src/rustdoc/unindent_pass.rs @@ -29,7 +29,7 @@ fn unindent(s: ~str) -> ~str { let ignore_previous_indents = saw_first_line && !saw_second_line && - !str::is_whitespace(line); + !str::is_whitespace(*line); let min_indent = if ignore_previous_indents { uint::max_value @@ -41,12 +41,12 @@ fn unindent(s: ~str) -> ~str { saw_second_line = true; } - if str::is_whitespace(line) { + if str::is_whitespace(*line) { min_indent } else { saw_first_line = true; let mut spaces = 0; - do str::all(line) |char| { + do str::all(*line) |char| { // Only comparing against space because I wouldn't // know what to do with mixed whitespace chars if char == ' ' { @@ -63,11 +63,11 @@ fn unindent(s: ~str) -> ~str { if vec::is_not_empty(lines) { let unindented = ~[str::trim(vec::head(lines))] + do par::map(vec::tail(lines)) |line| { - if str::is_whitespace(line) { - line + if str::is_whitespace(*line) { + *line } else { - assert str::len(line) >= min_indent; - str::slice(line, min_indent, str::len(line)) + assert str::len(*line) >= min_indent; + str::slice(*line, min_indent, str::len(*line)) } }; str::connect(unindented, ~"\n") diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 6ea433e6f1f0..fc2049507eed 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -20,6 +20,7 @@ #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/IPO.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/Assembly/Parser.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Support/FormattedStream.h" @@ -42,7 +43,6 @@ #include "llvm-c/Core.h" #include "llvm-c/BitReader.h" #include "llvm-c/Object.h" -#include // Used by RustMCJITMemoryManager::getPointerToNamedFunction() // to get around glibc issues. See the function for more information. @@ -53,6 +53,7 @@ #endif using namespace llvm; +using namespace llvm::sys; static const char *LLVMRustError; @@ -100,18 +101,6 @@ void LLVMRustInitializeTargets() { LLVMInitializeX86AsmParser(); } -extern "C" bool -LLVMRustLoadLibrary(const char* file) { - std::string err; - - if(llvm::sys::DynamicLibrary::LoadLibraryPermanently(file, &err)) { - LLVMRustError = err.c_str(); - return false; - } - - return true; -} - // Custom memory manager for MCJITting. It needs special features // that the generic JIT memory manager doesn't entail. Based on // code from LLI, change where needed for Rust. @@ -121,10 +110,13 @@ public: SmallVector AllocatedCodeMem; SmallVector FreeCodeMem; void* __morestack; + DenseSet crates; RustMCJITMemoryManager(void* sym) : __morestack(sym) { } ~RustMCJITMemoryManager(); + bool loadCrate(const char*, std::string*); + virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID); @@ -197,6 +189,19 @@ public: } }; +bool RustMCJITMemoryManager::loadCrate(const char* file, std::string* err) { + DynamicLibrary crate = DynamicLibrary::getPermanentLibrary(file, + err); + + if(crate.isValid()) { + crates.insert(&crate); + + return true; + } + + return false; +} + uint8_t *RustMCJITMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { @@ -276,6 +281,9 @@ void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name, if (Name == "__morestack") return &__morestack; const char *NameStr = Name.c_str(); + + // Look through loaded crates and main for symbols. + void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr); if (Ptr) return Ptr; @@ -293,21 +301,49 @@ RustMCJITMemoryManager::~RustMCJITMemoryManager() { } extern "C" void* -LLVMRustJIT(void* __morestack, - LLVMPassManagerRef PMR, - LLVMModuleRef M, - CodeGenOpt::Level OptLevel, - bool EnableSegmentedStacks) { +LLVMRustPrepareJIT(void* __morestack) { + // An execution engine will take ownership of this later + // and clean it up for us. + + return (void*) new RustMCJITMemoryManager(__morestack); +} + +extern "C" bool +LLVMRustLoadCrate(void* mem, const char* crate) { + RustMCJITMemoryManager* manager = (RustMCJITMemoryManager*) mem; + std::string Err; + + assert(manager); + + if(!manager->loadCrate(crate, &Err)) { + LLVMRustError = Err.c_str(); + return false; + } + + return true; +} + +extern "C" void* +LLVMRustExecuteJIT(void* mem, + LLVMPassManagerRef PMR, + LLVMModuleRef M, + CodeGenOpt::Level OptLevel, + bool EnableSegmentedStacks) { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); + InitializeNativeTargetAsmParser(); std::string Err; TargetOptions Options; + Options.JITExceptionHandling = true; Options.JITEmitDebugInfo = true; Options.NoFramePointerElim = true; Options.EnableSegmentedStacks = EnableSegmentedStacks; PassManager *PM = unwrap(PMR); + RustMCJITMemoryManager* MM = (RustMCJITMemoryManager*) mem; + + assert(MM); PM->add(createBasicAliasAnalysisPass()); PM->add(createInstructionCombiningPass()); @@ -318,8 +354,8 @@ LLVMRustJIT(void* __morestack, PM->add(createPromoteMemoryToRegisterPass()); PM->run(*unwrap(M)); - RustMCJITMemoryManager* MM = new RustMCJITMemoryManager(__morestack); ExecutionEngine* EE = EngineBuilder(unwrap(M)) + .setErrorStr(&Err) .setTargetOptions(Options) .setJITMemoryManager(MM) .setOptLevel(OptLevel) diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 1de1e3ba58f2..36833e5175e6 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -4,8 +4,9 @@ LLVMRustWriteOutputFile LLVMRustGetLastError LLVMRustConstSmallInt LLVMRustConstInt -LLVMRustLoadLibrary -LLVMRustJIT +LLVMRustLoadCrate +LLVMRustPrepareJIT +LLVMRustExecuteJIT LLVMRustParseBitcode LLVMRustParseAssemblyFile LLVMRustPrintPassTimings diff --git a/src/snapshots.txt b/src/snapshots.txt index a978f9cc73b8..7464d18247d9 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -1,3 +1,35 @@ +S 2012-10-02 4d30b34 + macos-i386 2bcce3cde8a7e53df202972cda85b0b59ce4e50d + macos-x86_64 fc5592828392f9eabe8b51cc59639be6d709cc26 + freebsd-x86_64 5e09dad0800f16f5d79286330bcb82b6d2b8782e + linux-i386 92fc541d4dde19fe2af5930d72a5a50ca67bad60 + linux-x86_64 1067a27ba6e22011c199ddabe41f2769e3a18228 + winnt-i386 40029da1ea0b2fb8b8fbc24182eb24dbc680e512 + +S 2012-09-29 2f95f7d + macos-i386 e73ea6685a7d70647c127c2ab5b57c12d84ee0d6 + macos-x86_64 7454e7872d772040c46cb0c7d65d68596143ac1f + freebsd-x86_64 37227d6ed35b72b12293615aa845c3c0aa0ced32 + linux-i386 dc530df77174c022b53c51eef7879659f68e9633 + linux-x86_64 e99179e93798dc4c1bed53d9fefe043b51b7b43d + winnt-i386 794f40a0e5422aedd56e383ff532d8f2e3ae0c9d + +S 2012-09-28 d0333a8 + macos-i386 fd57e38d5fa9cd25dbe72c3ae0dd500f48ba7026 + macos-x86_64 bc5a204e56348d4ea2b37e64bcd746f6cec75f9a + freebsd-x86_64 2015128280bf85a02aef8ad1c387c1459cd9d8a3 + linux-i386 8106f24abeb0822afc0ff6bb08288de7cb286a36 + linux-x86_64 ae7147c5c810548bc3c5b423d765792015ded1f7 + winnt-i386 e4772c3dceb12d7724180371262a0d7ee3739eb5 + +S 2012-09-26 010f805 + macos-i386 847b1cda4780badb9529a73aa00adfd907f69106 + macos-x86_64 6645c4302bcc04c76fae92fb0b3703b5b5310d17 + freebsd-x86_64 f951bc129a20a5c360cd318da71d849baba9cb27 + linux-i386 c2993f34ba8469f37f94939fef80c36bfbf6a7df + linux-x86_64 862850a54364de970d0f77cc091d631d343730e7 + winnt-i386 f497329c7e254de7e23f43daf62e38ee562fc92c + S 2012-09-23 92752a4 macos-i386 0d5130364e8610413c9da965ca5ce6967f32ab3d macos-x86_64 a0bc17c9025c509b0ecfb35d04e35b8b232f2687 diff --git a/src/test/auxiliary/cci_class.rs b/src/test/auxiliary/cci_class.rs index 8f4055cd415f..bb286f956bcd 100644 --- a/src/test/auxiliary/cci_class.rs +++ b/src/test/auxiliary/cci_class.rs @@ -1,3 +1,4 @@ +#[legacy_exports]; mod kitties { #[legacy_exports]; diff --git a/src/test/auxiliary/cci_class_2.rs b/src/test/auxiliary/cci_class_2.rs index e572f41322c4..186f021a81f9 100644 --- a/src/test/auxiliary/cci_class_2.rs +++ b/src/test/auxiliary/cci_class_2.rs @@ -1,3 +1,5 @@ +#[legacy_exports]; + mod kitties { #[legacy_exports]; diff --git a/src/test/auxiliary/cci_class_3.rs b/src/test/auxiliary/cci_class_3.rs index 79583a6134ce..dbae452a8f90 100644 --- a/src/test/auxiliary/cci_class_3.rs +++ b/src/test/auxiliary/cci_class_3.rs @@ -1,3 +1,5 @@ +#[legacy_exports]; + mod kitties { #[legacy_exports]; diff --git a/src/test/auxiliary/cci_class_4.rs b/src/test/auxiliary/cci_class_4.rs index 57c6f2f4b521..436f92e5e781 100644 --- a/src/test/auxiliary/cci_class_4.rs +++ b/src/test/auxiliary/cci_class_4.rs @@ -1,3 +1,4 @@ +#[legacy_exports]; mod kitties { #[legacy_exports]; diff --git a/src/test/auxiliary/cci_class_6.rs b/src/test/auxiliary/cci_class_6.rs index 72262781222c..6cf86aff055e 100644 --- a/src/test/auxiliary/cci_class_6.rs +++ b/src/test/auxiliary/cci_class_6.rs @@ -1,3 +1,5 @@ +#[legacy_exports]; + mod kitties { #[legacy_exports]; diff --git a/src/test/auxiliary/cci_class_cast.rs b/src/test/auxiliary/cci_class_cast.rs index 550dfb6886ab..288fe66dd205 100644 --- a/src/test/auxiliary/cci_class_cast.rs +++ b/src/test/auxiliary/cci_class_cast.rs @@ -1,3 +1,5 @@ +#[legacy_exports]; + use to_str::*; use to_str::ToStr; diff --git a/src/test/auxiliary/crateresolve7x.rs b/src/test/auxiliary/crateresolve7x.rs index 520a207345f0..e7bf211d3f0e 100644 --- a/src/test/auxiliary/crateresolve7x.rs +++ b/src/test/auxiliary/crateresolve7x.rs @@ -3,6 +3,7 @@ // aux-build:crateresolve_calories-2.rs // These both have the same version but differ in other metadata +#[legacy_exports]; mod a { #[legacy_exports]; extern mod cr_1 (name = "crateresolve_calories", vers = "0.1", calories="100"); diff --git a/src/test/auxiliary/foreign_lib.rs b/src/test/auxiliary/foreign_lib.rs index 6ea28255421b..bb6d425de344 100644 --- a/src/test/auxiliary/foreign_lib.rs +++ b/src/test/auxiliary/foreign_lib.rs @@ -1,4 +1,5 @@ #[link(name="foreign_lib", vers="0.0")]; +#[legacy_exports]; extern mod rustrt { #[legacy_exports]; diff --git a/src/test/auxiliary/issue-3012-1.rs b/src/test/auxiliary/issue-3012-1.rs index a9d371321f88..d774669cd132 100644 --- a/src/test/auxiliary/issue-3012-1.rs +++ b/src/test/auxiliary/issue-3012-1.rs @@ -1,5 +1,6 @@ #[link(name="socketlib", vers="0.0")]; #[crate_type = "lib"]; +#[legacy_exports]; mod socket { #[legacy_exports]; diff --git a/src/test/auxiliary/test_comm.rs b/src/test/auxiliary/test_comm.rs index b150b58c638f..77f107fda090 100644 --- a/src/test/auxiliary/test_comm.rs +++ b/src/test/auxiliary/test_comm.rs @@ -34,7 +34,7 @@ struct port_ptr { debug!("in the port_ptr destructor"); do task::unkillable { let yield = 0u; - let yieldp = ptr::addr_of(yield); + let yieldp = ptr::addr_of(&yield); rustrt::rust_port_begin_detach(self.po, yieldp); if yield != 0u { task::yield(); @@ -66,10 +66,10 @@ fn recv(p: port) -> T { recv_((**p).po) } /// Receive on a raw port pointer fn recv_(p: *rust_port) -> T { let yield = 0u; - let yieldp = ptr::addr_of(yield); + let yieldp = ptr::addr_of(&yield); let mut res; res = rusti::init::(); - rustrt::port_recv(ptr::addr_of(res) as *uint, p, yieldp); + rustrt::port_recv(ptr::addr_of(&res) as *uint, p, yieldp); if yield != 0u { // Data isn't available yet, so res has not been initialized. diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index 279905fe3f18..afd9b2ccc9ca 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -154,7 +154,7 @@ fn main(++args: ~[~str]) { let seed = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; { - let rng = rand::seeded_rng(copy seed); + let rng = rand::seeded_rng(&seed); let mut results = empty_results(); int_benchmarks::>( map::HashMap, rng, num_keys, &mut results); @@ -164,7 +164,7 @@ fn main(++args: ~[~str]) { } { - let rng = rand::seeded_rng(copy seed); + let rng = rand::seeded_rng(&seed); let mut results = empty_results(); int_benchmarks::<@Mut>>( || @Mut(LinearMap()), diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index a88793705a6b..cf44d4783562 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -30,7 +30,7 @@ fn maybe_run_test(argv: &[~str], name: ~str, test: fn()) { if os::getenv(~"RUST_BENCH").is_some() { run_test = true } else if argv.len() > 0 { - run_test = argv.contains(~"all") || argv.contains(name) + run_test = argv.contains(&~"all") || argv.contains(&name) } if !run_test { return } @@ -47,7 +47,7 @@ fn shift_push() { let mut v2 = ~[]; while v1.len() > 0 { - vec::push(v2, vec::shift(v1)); + v2.push(v1.shift()); } } @@ -56,7 +56,7 @@ fn read_line() { .push_rel(&Path("src/test/bench/shootout-k-nucleotide.data")); for int::range(0, 3) |_i| { - let reader = result::get(io::file_reader(&path)); + let reader = result::get(&io::file_reader(&path)); while !reader.eof() { reader.read_line(); } @@ -122,11 +122,11 @@ fn vec_push_all() { for uint::range(0, 1500) |i| { let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i); if r.gen_bool() { - vec::push_all(v, rv); + v.push_all(rv); } else { v <-> rv; - vec::push_all(v, rv); + v.push_all(rv); } } } diff --git a/src/test/bench/core-vec-append.rs b/src/test/bench/core-vec-append.rs index d708ac9eaa7b..2b9216876b42 100644 --- a/src/test/bench/core-vec-append.rs +++ b/src/test/bench/core-vec-append.rs @@ -7,7 +7,7 @@ use io::WriterUtil; fn collect_raw(num: uint) -> ~[uint] { let mut result = ~[]; for uint::range(0u, num) |i| { - vec::push(result, i); + result.push(i); } return result; } diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index 89ca8eadde4f..a34fcc89c048 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -97,7 +97,7 @@ fn gen_search_keys(graph: graph, n: uint) -> ~[node_id] { let k = r.gen_uint_range(0u, graph.len()); if graph[k].len() > 0u && vec::any(graph[k], |i| { - i != k as node_id + *i != k as node_id }) { map::set_add(keys, k as node_id); } @@ -160,8 +160,8 @@ fn bfs2(graph: graph, key: node_id) -> bfs_result { } }; - fn is_gray(c: color) -> bool { - match c { + fn is_gray(c: &color) -> bool { + match *c { gray(_) => { true } _ => { false } } @@ -183,7 +183,7 @@ fn bfs2(graph: graph, key: node_id) -> bfs_result { let mut color = white; do neighbors.each() |k| { - if is_gray(colors[*k]) { + if is_gray(&colors[*k]) { color = gray(*k); false } @@ -231,18 +231,18 @@ fn pbfs(&&graph: arc::ARC, key: node_id) -> bfs_result { }; #[inline(always)] - fn is_gray(c: color) -> bool { - match c { + fn is_gray(c: &color) -> bool { + match *c { gray(_) => { true } _ => { false } } } - let mut i = 0u; + let mut i = 0; while par::any(colors, is_gray) { // Do the BFS. log(info, fmt!("PBFS iteration %?", i)); - i += 1u; + i += 1; let old_len = colors.len(); let color = arc::ARC(colors); @@ -251,7 +251,7 @@ fn pbfs(&&graph: arc::ARC, key: node_id) -> bfs_result { colors = do par::mapi_factory(*color_vec) { let colors = arc::clone(&color); let graph = arc::clone(&graph); - fn~(i: uint, c: color) -> color { + fn~(+i: uint, +c: color) -> color { let c : color = c; let colors = arc::get(&colors); let graph = arc::get(&graph); @@ -264,7 +264,7 @@ fn pbfs(&&graph: arc::ARC, key: node_id) -> bfs_result { let mut color = white; do neighbors.each() |k| { - if is_gray(colors[*k]) { + if is_gray(&colors[*k]) { color = gray(*k); false } @@ -282,7 +282,7 @@ fn pbfs(&&graph: arc::ARC, key: node_id) -> bfs_result { // Convert the results. do par::map(colors) |c| { - match c { + match *c { white => { -1i64 } black(parent) => { parent } _ => { fail ~"Found remaining gray nodes in BFS" } @@ -314,11 +314,11 @@ fn validate(edges: ~[(node_id, node_id)], } else { while parent != root { - if vec::contains(path, parent) { + if vec::contains(path, &parent) { status = false; } - vec::push(path, parent); + path.push(parent); parent = tree[parent]; } @@ -336,8 +336,8 @@ fn validate(edges: ~[(node_id, node_id)], log(info, ~"Verifying tree edges..."); let status = do tree.alli() |k, parent| { - if parent != root && parent != -1i64 { - level[parent] == level[k] - 1 + if *parent != root && *parent != -1i64 { + level[*parent] == level[k] - 1 } else { true @@ -352,7 +352,7 @@ fn validate(edges: ~[(node_id, node_id)], log(info, ~"Verifying graph edges..."); let status = do edges.all() |e| { - let (u, v) = e; + let (u, v) = *e; abs(level[u] - level[v]) <= 1 }; @@ -370,11 +370,11 @@ fn validate(edges: ~[(node_id, node_id)], let status = do par::alli(tree) |u, v| { let u = u as node_id; - if v == -1i64 || u == root { + if *v == -1i64 || u == root { true } else { - edges.contains((u, v)) || edges.contains((v, u)) + edges.contains(&(u, *v)) || edges.contains(&(*v, u)) } }; diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 89d339b7a763..0a55e7572db9 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -19,7 +19,7 @@ use io::WriterUtil; use pipes::{Port, Chan, SharedChan}; macro_rules! move_out ( - { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } } + { $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); y } } ) enum request { @@ -60,7 +60,7 @@ fn run(args: &[~str]) { for uint::range(0u, workers) |i| { let to_child = to_child.clone(); do task::task().future_result(|+r| { - vec::push(worker_results, r); + worker_results.push(r); }).spawn { for uint::range(0u, size / workers) |_i| { //error!("worker %?: sending %? bytes", i, num_bytes); diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index babc97694a56..ab67a8c7cb12 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -15,7 +15,7 @@ use io::WriterUtil; use pipes::{Port, PortSet, Chan}; macro_rules! move_out ( - { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } } + { $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); y } } ) enum request { @@ -57,7 +57,7 @@ fn run(args: &[~str]) { let (to_child, from_parent_) = pipes::stream(); from_parent.add(from_parent_); do task::task().future_result(|+r| { - vec::push(worker_results, r); + worker_results.push(r); }).spawn { for uint::range(0u, size / workers) |_i| { //error!("worker %?: sending %? bytes", i, num_bytes); diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index e3d8afce1bf0..ec144b78a10a 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -18,7 +18,7 @@ type pipe = arc::MutexARC<~[uint]>; fn send(p: &pipe, msg: uint) { do p.access_cond |state, cond| { - vec::push(*state, msg); + state.push(msg); cond.signal(); } } @@ -27,7 +27,7 @@ fn recv(p: &pipe) -> uint { while vec::is_empty(*state) { cond.wait(); } - vec::pop(*state) + state.pop() } } @@ -91,7 +91,7 @@ fn main(++args: ~[~str]) { option::unwrap(num_chan), option::unwrap(num_port1)) }); - vec::push(futures, new_future); + futures.push(new_future); num_chan = Some(new_chan); }; diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs index 645aa6547000..119c2065d6bc 100644 --- a/src/test/bench/msgsend-ring-pipes.rs +++ b/src/test/bench/msgsend-ring-pipes.rs @@ -24,7 +24,7 @@ proto! ring ( fn macros() { #macro[ [#move_out[x], - unsafe { let y <- *ptr::addr_of(x); y }] + unsafe { let y <- *ptr::addr_of(&x); y }] ]; } @@ -88,7 +88,7 @@ fn main(++args: ~[~str]) { option::unwrap(num_chan), option::unwrap(num_port1)) }; - vec::push(futures, new_future); + futures.push(new_future); num_chan = Some(new_chan); }; diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs index b4b75adc3b5c..1b857b6caeb8 100644 --- a/src/test/bench/msgsend-ring-rw-arcs.rs +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -18,7 +18,7 @@ type pipe = arc::RWARC<~[uint]>; fn send(p: &pipe, msg: uint) { do p.write_cond |state, cond| { - vec::push(*state, msg); + state.push(msg); cond.signal(); } } @@ -27,7 +27,7 @@ fn recv(p: &pipe) -> uint { while vec::is_empty(*state) { cond.wait(); } - vec::pop(*state) + state.pop() } } @@ -92,7 +92,7 @@ fn main(++args: ~[~str]) { option::unwrap(num_chan), option::unwrap(num_port1)) }; - vec::push(futures, new_future); + futures.push(new_future); num_chan = Some(new_chan); }; diff --git a/src/test/bench/msgsend-ring.rs b/src/test/bench/msgsend-ring.rs index 47ce0d2b91f4..5533aeeeb41b 100644 --- a/src/test/bench/msgsend-ring.rs +++ b/src/test/bench/msgsend-ring.rs @@ -51,7 +51,7 @@ fn main(++args: ~[~str]) { get_chan_chan.send(Chan(p)); thread_ring(i, msg_per_task, num_chan, p) }; - vec::push(futures, new_future); + futures.push(new_future); num_chan = get_chan.recv(); }; diff --git a/src/test/bench/msgsend.rs b/src/test/bench/msgsend.rs index 2790f00d40d1..fb1e3ae92262 100644 --- a/src/test/bench/msgsend.rs +++ b/src/test/bench/msgsend.rs @@ -37,7 +37,7 @@ fn run(args: ~[~str]) { let mut worker_results = ~[]; for uint::range(0u, workers) |_i| { do task::task().future_result(|+r| { - vec::push(worker_results, r); + worker_results.push(r); }).spawn { for uint::range(0u, size / workers) |_i| { comm::send(to_child, bytes(100u)); diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs index 570ec8c0b6bf..70f98934e1bc 100644 --- a/src/test/bench/pingpong.rs +++ b/src/test/bench/pingpong.rs @@ -33,7 +33,7 @@ proto! pingpong_unbounded ( // This stuff should go in libcore::pipes macro_rules! move_it ( - { $x:expr } => { let t <- *ptr::addr_of($x); t } + { $x:expr } => { let t <- *ptr::addr_of(&($x)); t } ) macro_rules! follow ( diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index bdfe4b7b727a..5c7827f5106d 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -163,7 +163,7 @@ fn rendezvous(nn: uint, set: ~[color]) { // save each creature's meeting stats let mut report = ~[]; for vec::each(to_creature) |_to_one| { - vec::push(report, comm::recv(from_creatures_log)); + report.push(comm::recv(from_creatures_log)); } // print each color in the set diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs index a07b29f3dc6f..0c742e16bfa5 100644 --- a/src/test/bench/shootout-fasta.rs +++ b/src/test/bench/shootout-fasta.rs @@ -81,7 +81,7 @@ fn main(++args: ~[~str]) { }; let writer = if os::getenv(~"RUST_BENCH").is_some() { - result::get(io::file_writer(&Path("./shootout-fasta.data"), + result::get(&io::file_writer(&Path("./shootout-fasta.data"), ~[io::Truncate, io::Create])) } else { io::stdout() diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index 21bed9f8790b..85dcdd32e13d 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -41,7 +41,7 @@ fn sort_and_fmt(mm: HashMap<~[u8], uint>, total: uint) -> ~str { // map -> [(k,%)] mm.each(fn&(key: ~[u8], val: uint) -> bool { - vec::push(pairs, (key, pct(val, total))); + pairs.push((key, pct(val, total))); return true; }); @@ -134,7 +134,7 @@ fn main(++args: ~[~str]) { // get to this massive data set, but #include_bin chokes on it (#2598) let path = Path(env!("CFG_SRC_DIR")) .push_rel(&Path("src/test/bench/shootout-k-nucleotide.data")); - result::get(io::file_reader(&path)) + result::get(&io::file_reader(&path)) } else { io::stdin() }; @@ -152,7 +152,7 @@ fn main(++args: ~[~str]) { stream <-> streams[ii]; let (to_parent_, from_child_) = option::unwrap(stream); - vec::push(from_child, from_child_); + from_child.push(from_child_); let (to_child, from_parent) = pipes::stream(); diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index d107db7e6b08..6ba6eb7feadd 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -38,7 +38,7 @@ fn sort_and_fmt(mm: HashMap<~[u8], uint>, total: uint) -> ~str { // map -> [(k,%)] mm.each(fn&(key: ~[u8], val: uint) -> bool { - vec::push(pairs, (key, pct(val, total))); + pairs.push((key, pct(val, total))); return true; }); @@ -131,7 +131,7 @@ fn main(++args: ~[~str]) { // get to this massive data set, but #include_bin chokes on it (#2598) let path = Path(env!("CFG_SRC_DIR")) .push_rel(&Path("src/test/bench/shootout-k-nucleotide.data")); - result::get(io::file_reader(&path)) + result::get(&io::file_reader(&path)) } else { io::stdin() }; diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index f6386a207b11..ee38b957b0cb 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -85,7 +85,7 @@ fn chanmb(i: uint, size: uint, ch: comm::Chan) -> () let xincr = 8f64*incr; for uint::range(0_u, size/8_u) |j| { let x = cmplx {re: xincr*(j as f64) - 1.5f64, im: y}; - vec::push(crv, fillbyte(x, incr)); + crv.push(fillbyte(x, incr)); }; comm::send(ch, {i:i, b:crv}); } @@ -94,7 +94,7 @@ type devnull = {dn: int}; impl devnull: io::Writer { fn write(_b: &[const u8]) {} - fn seek(_i: int, _s: io::SeekStyle) {} + fn seek(+_i: int, +_s: io::SeekStyle) {} fn tell() -> uint {0_u} fn flush() -> int {0} fn get_type() -> io::WriterType { io::File } @@ -114,7 +114,7 @@ fn writer(path: ~str, writech: comm::Chan>, size: uint) } _ => { result::get( - io::file_writer(&Path(path), + &io::file_writer(&Path(path), ~[io::Create, io::Truncate])) } }; diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs index 705679bd4030..90224645f84c 100644 --- a/src/test/bench/shootout-pfib.rs +++ b/src/test/bench/shootout-pfib.rs @@ -73,7 +73,7 @@ fn stress(num_tasks: int) { let mut results = ~[]; for range(0, num_tasks) |i| { do task::task().future_result(|+r| { - vec::push(results, r); + results.push(r); }).spawn { stress_task(i); } diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs index da8b1932f653..c9d4fb6b4d87 100644 --- a/src/test/bench/task-perf-one-million.rs +++ b/src/test/bench/task-perf-one-million.rs @@ -21,7 +21,7 @@ fn calc(children: uint, parent_ch: comm::Chan) { for iter::repeat (children) { match comm::recv(port) { ready(child_ch) => { - vec::push(child_chs, child_ch); + child_chs.push(child_ch); } _ => fail ~"task-perf-one-million failed (port not ready)" } diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs index 73c5dab16d86..626123665243 100644 --- a/src/test/bench/task-perf-word-count-generic.rs +++ b/src/test/bench/task-perf-word-count-generic.rs @@ -20,7 +20,7 @@ use option::None; use std::map; use std::map::HashMap; use hash::Hash; -use io::WriterUtil; +use io::{ReaderUtil, WriterUtil}; use std::time; @@ -32,7 +32,7 @@ use cmp::Eq; use to_bytes::IterBytes; macro_rules! move_out ( - { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } } + { $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); y } } ) trait word_reader { @@ -155,8 +155,8 @@ mod map_reduce { let (ctrl, ctrl_server) = ctrl_proto::init(); let ctrl = box(ctrl); let i = copy *i; - vec::push(tasks, spawn_joinable(|move i| map_task(map, ctrl, i))); - vec::push(ctrls, ctrl_server); + tasks.push(spawn_joinable(|move i| map_task(map, ctrl, i))); + ctrls.push(ctrl_server); } return tasks; } @@ -270,8 +270,7 @@ mod map_reduce { let p = Port(); let ch = Chan(p); let r = reduce, kk = k; - vec::push(tasks, - spawn_joinable(|| reduce_task(r, kk, ch) )); + tasks.push(spawn_joinable(|| reduce_task(r, kk, ch) )); c = recv(p); reducers.insert(k, c); } diff --git a/src/test/compile-fail/block-arg-as-stmt-with-value.rs b/src/test/compile-fail/block-arg-as-stmt-with-value.rs index b8e34aefd6f8..15154ab5a4ec 100644 --- a/src/test/compile-fail/block-arg-as-stmt-with-value.rs +++ b/src/test/compile-fail/block-arg-as-stmt-with-value.rs @@ -2,7 +2,7 @@ fn compute1() -> float { let v = ~[0f, 1f, 2f, 3f]; - do vec::foldl(0f, v) |x, y| { x + y } - 10f + do vec::foldl(0f, v) |x, y| { x + *y } - 10f //~^ ERROR mismatched types: expected `()` } diff --git a/src/test/compile-fail/deprecated-mode-fn-arg.rs b/src/test/compile-fail/deprecated-mode-fn-arg.rs new file mode 100644 index 000000000000..5afffb59dfc3 --- /dev/null +++ b/src/test/compile-fail/deprecated-mode-fn-arg.rs @@ -0,0 +1,9 @@ +#[forbid(deprecated_mode)]; + +fn foo(_f: fn(&i: int)) { //~ ERROR explicit mode +} + +type Bar = fn(&i: int); //~ ERROR explicit mode + +fn main() { +} \ No newline at end of file diff --git a/src/test/compile-fail/issue-3096-2.rs b/src/test/compile-fail/issue-3096-2.rs index cd3d63b58889..03e13f67a9a9 100644 --- a/src/test/compile-fail/issue-3096-2.rs +++ b/src/test/compile-fail/issue-3096-2.rs @@ -1,6 +1,6 @@ enum bottom { } fn main() { - let x = ptr::addr_of(()) as *bottom; + let x = ptr::p2::addr_of(&()) as *bottom; match x { } //~ ERROR non-exhaustive patterns } diff --git a/src/test/compile-fail/mutable-huh-ptr-assign.rs b/src/test/compile-fail/mutable-huh-ptr-assign.rs index ecfbb9a1f08f..4b680ec8b707 100644 --- a/src/test/compile-fail/mutable-huh-ptr-assign.rs +++ b/src/test/compile-fail/mutable-huh-ptr-assign.rs @@ -7,7 +7,7 @@ fn main() { unsafe { let a = 0; - let v = ptr::mut_addr_of(a); + let v = ptr::mut_addr_of(&a); f(v); } } diff --git a/src/test/compile-fail/mutable-huh-variance-ptr.rs b/src/test/compile-fail/mutable-huh-variance-ptr.rs index c96f3f624f18..e98b9b34c5fc 100644 --- a/src/test/compile-fail/mutable-huh-variance-ptr.rs +++ b/src/test/compile-fail/mutable-huh-variance-ptr.rs @@ -4,7 +4,7 @@ extern mod std; fn main() { let a = ~[0]; - let v: *mut ~[int] = ptr::mut_addr_of(a); + let v: *mut ~[int] = ptr::mut_addr_of(&a); fn f(&&v: *mut ~[const int]) { unsafe { diff --git a/src/test/compile-fail/non-copyable-void.rs b/src/test/compile-fail/non-copyable-void.rs index 59136683e6fb..a00dd7afd6df 100644 --- a/src/test/compile-fail/non-copyable-void.rs +++ b/src/test/compile-fail/non-copyable-void.rs @@ -1,5 +1,5 @@ fn main() { - let x : *~[int] = ptr::addr_of(~[1,2,3]); + let x : *~[int] = ptr::p2::addr_of(&~[1,2,3]); let y : *libc::c_void = x as *libc::c_void; unsafe { let _z = *y; diff --git a/src/test/compile-fail/purity-infer-fail.rs b/src/test/compile-fail/purity-infer-fail.rs index 691829edf597..b7666fa86509 100644 --- a/src/test/compile-fail/purity-infer-fail.rs +++ b/src/test/compile-fail/purity-infer-fail.rs @@ -2,5 +2,5 @@ fn something(f: pure fn()) { f(); } fn main() { let mut x = ~[]; - something(|| vec::push(x, 0) ); //~ ERROR access to impure function prohibited in pure context + something(|| x.push(0) ); //~ ERROR access to impure function prohibited in pure context } diff --git a/src/test/compile-fail/regions-escape-loop-via-vec.rs b/src/test/compile-fail/regions-escape-loop-via-vec.rs index 638f14f87949..276862ce1067 100644 --- a/src/test/compile-fail/regions-escape-loop-via-vec.rs +++ b/src/test/compile-fail/regions-escape-loop-via-vec.rs @@ -7,7 +7,7 @@ fn broken() -> int { y += ~[&mut z]; //~ ERROR illegal borrow x += 1; } - vec::foldl(0, y, |v, p| v + *p ) + vec::foldl(0, y, |v, p| v + **p ) } fn main() { } \ No newline at end of file diff --git a/src/test/compile-fail/unnamed_argument_mode.rs b/src/test/compile-fail/unnamed_argument_mode.rs new file mode 100644 index 000000000000..36e6edc96f99 --- /dev/null +++ b/src/test/compile-fail/unnamed_argument_mode.rs @@ -0,0 +1,14 @@ +//error-pattern: mismatched types + +fn bad(&a: int) { +} + +// unnamed argument &int is now parsed x: &int +// it's not parsed &x: int anymore + +fn called(f: fn(&int)) { +} + +fn main() { +called(bad); +} diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow-2.rs b/src/test/run-fail/bug-2470-bounds-check-overflow-2.rs index 0db43856612a..ef371d07569c 100644 --- a/src/test/run-fail/bug-2470-bounds-check-overflow-2.rs +++ b/src/test/run-fail/bug-2470-bounds-check-overflow-2.rs @@ -1,5 +1,5 @@ // xfail-test -// error-pattern:bounds check +// error-pattern:index out of bounds fn main() { let x = ~[1u,2u,3u]; @@ -14,4 +14,4 @@ fn main() { // This should fail. error!("ov2 0x%x", x[idx]); -} \ No newline at end of file +} diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow-3.rs b/src/test/run-fail/bug-2470-bounds-check-overflow-3.rs index 949d303eb01a..ae3a9c55b931 100644 --- a/src/test/run-fail/bug-2470-bounds-check-overflow-3.rs +++ b/src/test/run-fail/bug-2470-bounds-check-overflow-3.rs @@ -1,5 +1,5 @@ // xfail-test -// error-pattern:bounds check +// error-pattern:index out of bounds #[cfg(target_arch="x86")] fn main() { diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow.rs b/src/test/run-fail/bug-2470-bounds-check-overflow.rs index 924b3dda1497..fdbcb4de2be2 100644 --- a/src/test/run-fail/bug-2470-bounds-check-overflow.rs +++ b/src/test/run-fail/bug-2470-bounds-check-overflow.rs @@ -1,4 +1,4 @@ -// error-pattern:bounds check +// error-pattern:index out of bounds fn main() { diff --git a/src/test/run-fail/issue-2156.rs b/src/test/run-fail/issue-2156.rs index 6b39e323c6e5..57d33c965b0b 100644 --- a/src/test/run-fail/issue-2156.rs +++ b/src/test/run-fail/issue-2156.rs @@ -1,7 +1,7 @@ // error-pattern:explicit failure // Don't double free the string extern mod std; -use io::Reader; +use io::ReaderUtil; fn main() { do io::with_str_reader(~"") |rdr| { diff --git a/src/test/run-fail/result-get-fail.rs b/src/test/run-fail/result-get-fail.rs index fbc8378643b9..2b8712f3d593 100644 --- a/src/test/run-fail/result-get-fail.rs +++ b/src/test/run-fail/result-get-fail.rs @@ -1,4 +1,4 @@ // error-pattern:get called on error result: ~"kitty" fn main() { - log(error, result::get(result::Err::(~"kitty"))); + log(error, result::get(&result::Err::(~"kitty"))); } diff --git a/src/test/run-fail/small-negative-indexing.rs b/src/test/run-fail/small-negative-indexing.rs index 96f0c12c760f..5ba6e9dd27ab 100644 --- a/src/test/run-fail/small-negative-indexing.rs +++ b/src/test/run-fail/small-negative-indexing.rs @@ -1,4 +1,4 @@ -// error-pattern:bounds check +// error-pattern:index out of bounds: the len is 1024 but the index is -1 fn main() { let v = vec::from_fn(1024u, {|n| n}); // this should trip a bounds check diff --git a/src/test/run-fail/str-overrun.rs b/src/test/run-fail/str-overrun.rs index b8bccfe82d47..d9485f3a2896 100644 --- a/src/test/run-fail/str-overrun.rs +++ b/src/test/run-fail/str-overrun.rs @@ -1,6 +1,6 @@ // -*- rust -*- -// error-pattern:bounds check +// error-pattern:index out of bounds: the len is 5 but the index is 5 fn main() { let s: ~str = ~"hello"; diff --git a/src/test/run-fail/vec-overrun.rs b/src/test/run-fail/vec-overrun.rs index 8301a05f76bf..fd3254bc6b13 100644 --- a/src/test/run-fail/vec-overrun.rs +++ b/src/test/run-fail/vec-overrun.rs @@ -1,6 +1,6 @@ // -*- rust -*- -// error-pattern:bounds check +// error-pattern:index out of bounds: the len is 1 but the index is 2 fn main() { let v: ~[int] = ~[10]; let x: int = 0; diff --git a/src/test/run-fail/vec-underrun.rs b/src/test/run-fail/vec-underrun.rs index 1228e95ac1e7..88b29471dac1 100644 --- a/src/test/run-fail/vec-underrun.rs +++ b/src/test/run-fail/vec-underrun.rs @@ -1,6 +1,6 @@ // -*- rust -*- -// error-pattern:bounds check +// error-pattern:index out of bounds: the len is 2 but the index is -1 fn main() { let v: ~[int] = ~[10, 20]; let x: int = 0; diff --git a/src/test/run-fail/zip-different-lengths.rs b/src/test/run-fail/zip-different-lengths.rs index 4e97d2f903f5..c6239c1f657c 100644 --- a/src/test/run-fail/zip-different-lengths.rs +++ b/src/test/run-fail/zip-different-lengths.rs @@ -8,7 +8,7 @@ fn enum_chars(start: u8, end: u8) -> ~[char] { assert start < end; let mut i = start; let mut r = ~[]; - while i <= end { vec::push(r, i as char); i += 1u as u8; } + while i <= end { r.push(i as char); i += 1u as u8; } return r; } @@ -16,7 +16,7 @@ fn enum_uints(start: uint, end: uint) -> ~[uint] { assert start < end; let mut i = start; let mut r = ~[]; - while i <= end { vec::push(r, i); i += 1u; } + while i <= end { r.push(i); i += 1u; } return r; } diff --git a/src/test/run-pass/auto-ref-sliceable.rs b/src/test/run-pass/auto-ref-sliceable.rs index 43d9fa5b14bc..48d83da74adb 100644 --- a/src/test/run-pass/auto-ref-sliceable.rs +++ b/src/test/run-pass/auto-ref-sliceable.rs @@ -4,7 +4,7 @@ trait Pushable { impl ~[T]: Pushable { fn push_val(&mut self, +t: T) { - vec::push(*self, t); + self.push(t); } } diff --git a/src/test/run-pass/auto_serialize2.rs b/src/test/run-pass/auto_serialize2.rs new file mode 100644 index 000000000000..4503ea6c7e01 --- /dev/null +++ b/src/test/run-pass/auto_serialize2.rs @@ -0,0 +1,163 @@ +extern mod std; + +// These tests used to be separate files, but I wanted to refactor all +// the common code. + +use cmp::Eq; +use std::ebml2; +use io::Writer; +use std::serialization2::{Serializable, Deserializable, deserialize}; +use std::prettyprint2; + +fn test_ser_and_deser( + a1: &A, + +expected: ~str +) { + // check the pretty printer: + let s = do io::with_str_writer |w| { + a1.serialize(&prettyprint2::Serializer(w)) + }; + debug!("s == %?", s); + assert s == expected; + + // check the EBML serializer: + let bytes = do io::with_bytes_writer |wr| { + let ebml_w = &ebml2::Serializer(wr); + a1.serialize(ebml_w) + }; + let d = ebml2::Doc(@bytes); + let a2: A = deserialize(&ebml2::Deserializer(d)); + assert *a1 == a2; +} + +#[auto_serialize2] +#[auto_deserialize2] +enum Expr { + Val(uint), + Plus(@Expr, @Expr), + Minus(@Expr, @Expr) +} + +impl Expr : cmp::Eq { + pure fn eq(other: &Expr) -> bool { + match self { + Val(e0a) => { + match *other { + Val(e0b) => e0a == e0b, + _ => false + } + } + Plus(e0a, e1a) => { + match *other { + Plus(e0b, e1b) => e0a == e0b && e1a == e1b, + _ => false + } + } + Minus(e0a, e1a) => { + match *other { + Minus(e0b, e1b) => e0a == e0b && e1a == e1b, + _ => false + } + } + } + } + pure fn ne(other: &Expr) -> bool { !self.eq(other) } +} + +impl AnEnum : cmp::Eq { + pure fn eq(other: &AnEnum) -> bool { + self.v == other.v + } + pure fn ne(other: &AnEnum) -> bool { !self.eq(other) } +} + +impl Point : cmp::Eq { + pure fn eq(other: &Point) -> bool { + self.x == other.x && self.y == other.y + } + pure fn ne(other: &Point) -> bool { !self.eq(other) } +} + +impl Quark : cmp::Eq { + pure fn eq(other: &Quark) -> bool { + match self { + Top(ref q) => { + match *other { + Top(ref r) => q == r, + Bottom(_) => false + } + }, + Bottom(ref q) => { + match *other { + Top(_) => false, + Bottom(ref r) => q == r + } + }, + } + } + pure fn ne(other: &Quark) -> bool { !self.eq(other) } +} + +impl CLike : cmp::Eq { + pure fn eq(other: &CLike) -> bool { + self as int == *other as int + } + pure fn ne(other: &CLike) -> bool { !self.eq(other) } +} + +#[auto_serialize2] +#[auto_deserialize2] +type Spanned = {lo: uint, hi: uint, node: T}; + +impl Spanned : cmp::Eq { + pure fn eq(other: &Spanned) -> bool { + self.lo == other.lo && self.hi == other.hi && self.node == other.node + } + pure fn ne(other: &Spanned) -> bool { !self.eq(other) } +} + +#[auto_serialize2] +#[auto_deserialize2] +type SomeRec = {v: ~[uint]}; + +#[auto_serialize2] +#[auto_deserialize2] +enum AnEnum = SomeRec; + +#[auto_serialize2] +#[auto_deserialize2] +struct Point {x: uint, y: uint} + +#[auto_serialize2] +#[auto_deserialize2] +enum Quark { + Top(T), + Bottom(T) +} + +#[auto_serialize2] +#[auto_deserialize2] +enum CLike { A, B, C } + +fn main() { + test_ser_and_deser(&Plus(@Minus(@Val(3u), @Val(10u)), + @Plus(@Val(22u), @Val(5u))), + ~"Plus(@Minus(@Val(3u), @Val(10u)), \ + @Plus(@Val(22u), @Val(5u)))"); + + test_ser_and_deser(&{lo: 0u, hi: 5u, node: 22u}, + ~"{lo: 0u, hi: 5u, node: 22u}"); + + test_ser_and_deser(&AnEnum({v: ~[1u, 2u, 3u]}), + ~"AnEnum({v: ~[1u, 2u, 3u]})"); + + test_ser_and_deser(&Point {x: 3u, y: 5u}, ~"Point {x: 3u, y: 5u}"); + + test_ser_and_deser(&@[1u, 2u, 3u], ~"@[1u, 2u, 3u]"); + + test_ser_and_deser(&Top(22u), ~"Top(22u)"); + test_ser_and_deser(&Bottom(222u), ~"Bottom(222u)"); + + test_ser_and_deser(&A, ~"A"); + test_ser_and_deser(&B, ~"B"); +} diff --git a/src/test/run-pass/autoref-intermediate-types-issue-3585.rs b/src/test/run-pass/autoref-intermediate-types-issue-3585.rs new file mode 100644 index 000000000000..68e172bacadc --- /dev/null +++ b/src/test/run-pass/autoref-intermediate-types-issue-3585.rs @@ -0,0 +1,20 @@ +trait Foo { + fn foo(&self) -> ~str; +} + +impl @T: Foo { + fn foo(&self) -> ~str { + fmt!("@%s", (**self).foo()) + } +} + +impl uint: Foo { + fn foo(&self) -> ~str { + fmt!("%u", *self) + } +} + +fn main() { + let x = @3u; + assert x.foo() == ~"@3"; +} \ No newline at end of file diff --git a/src/test/run-pass/binops.rs b/src/test/run-pass/binops.rs index 0cc828132c94..cfcb158a990a 100644 --- a/src/test/run-pass/binops.rs +++ b/src/test/run-pass/binops.rs @@ -103,8 +103,8 @@ fn test_class() { unsafe { error!("q = %x, r = %x", - (cast::reinterpret_cast::<*p, uint>(&ptr::addr_of(q))), - (cast::reinterpret_cast::<*p, uint>(&ptr::addr_of(r)))); + (cast::reinterpret_cast::<*p, uint>(&ptr::addr_of(&q))), + (cast::reinterpret_cast::<*p, uint>(&ptr::addr_of(&r)))); } assert(q == r); r.y = 17; diff --git a/src/test/run-pass/block-arg-can-be-followed-by-binop.rs b/src/test/run-pass/block-arg-can-be-followed-by-binop.rs index 53f158471e8b..bab28a06934d 100644 --- a/src/test/run-pass/block-arg-can-be-followed-by-binop.rs +++ b/src/test/run-pass/block-arg-can-be-followed-by-binop.rs @@ -2,7 +2,7 @@ fn main() { let v = ~[-1f, 0f, 1f, 2f, 3f]; // Trailing expressions don't require parentheses: - let y = do vec::foldl(0f, v) |x, y| { x + y } + 10f; + let y = do vec::foldl(0f, v) |x, y| { x + *y } + 10f; assert y == 15f; } diff --git a/src/test/run-pass/block-arg-in-parentheses.rs b/src/test/run-pass/block-arg-in-parentheses.rs index 14b05b29dc36..1121cc4dd2f3 100644 --- a/src/test/run-pass/block-arg-in-parentheses.rs +++ b/src/test/run-pass/block-arg-in-parentheses.rs @@ -1,20 +1,20 @@ fn w_semi(v: ~[int]) -> int { // the semicolon causes compiler not to // complain about the ignored return value: - do vec::foldl(0, v) |x,y| { x+y }; + do vec::foldl(0, v) |x,y| { x+*y }; -10 } fn w_paren1(v: ~[int]) -> int { - (do vec::foldl(0, v) |x,y| { x+y }) - 10 + (do vec::foldl(0, v) |x,y| { x+*y }) - 10 } fn w_paren2(v: ~[int]) -> int { - (do vec::foldl(0, v) |x,y| { x+y} - 10) + (do vec::foldl(0, v) |x,y| { x+*y} - 10) } fn w_ret(v: ~[int]) -> int { - return do vec::foldl(0, v) |x,y| { x+y } - 10; + return do vec::foldl(0, v) |x,y| { x+*y } - 10; } fn main() { diff --git a/src/test/run-pass/block-arg.rs b/src/test/run-pass/block-arg.rs index 5953e0b85fb5..0f77a0e0816f 100644 --- a/src/test/run-pass/block-arg.rs +++ b/src/test/run-pass/block-arg.rs @@ -8,28 +8,28 @@ fn main() { } // Usable at all: - let mut any_negative = do vec::any(v) |e| { float::is_negative(e) }; + let mut any_negative = do vec::any(v) |e| { float::is_negative(*e) }; assert any_negative; // Higher precedence than assignments: - any_negative = do vec::any(v) |e| { float::is_negative(e) }; + any_negative = do vec::any(v) |e| { float::is_negative(*e) }; assert any_negative; // Higher precedence than unary operations: let abs_v = do vec::map(v) |e| { float::abs(*e) }; - assert do vec::all(abs_v) |e| { float::is_nonnegative(e) }; - assert !do vec::any(abs_v) |e| { float::is_negative(e) }; + assert do vec::all(abs_v) |e| { float::is_nonnegative(*e) }; + assert !do vec::any(abs_v) |e| { float::is_negative(*e) }; // Usable in funny statement-like forms: - if !do vec::any(v) |e| { float::is_positive(e) } { + if !do vec::any(v) |e| { float::is_positive(*e) } { assert false; } - match do vec::all(v) |e| { float::is_negative(e) } { + match do vec::all(v) |e| { float::is_negative(*e) } { true => { fail ~"incorrect answer."; } false => { } } match 3 { - _ if do vec::any(v) |e| { float::is_negative(e) } => { + _ if do vec::any(v) |e| { float::is_negative(*e) } => { } _ => { fail ~"wrong answer."; @@ -38,15 +38,15 @@ fn main() { // Lower precedence than binary operations: - let w = do vec::foldl(0f, v) |x, y| { x + y } + 10f; - let y = do vec::foldl(0f, v) |x, y| { x + y } + 10f; - let z = 10f + do vec::foldl(0f, v) |x, y| { x + y }; + let w = do vec::foldl(0f, v) |x, y| { x + *y } + 10f; + let y = do vec::foldl(0f, v) |x, y| { x + *y } + 10f; + let z = 10f + do vec::foldl(0f, v) |x, y| { x + *y }; assert w == y; assert y == z; // In the tail of a block let w = - if true { do vec::any(abs_v) |e| { float::is_nonnegative(e) } } + if true { do vec::any(abs_v) |e| { float::is_nonnegative(*e) } } else { false }; assert w; } diff --git a/src/test/run-pass/block-vec-map2.rs b/src/test/run-pass/block-vec-map2.rs index 332afc65f720..d270800de11e 100644 --- a/src/test/run-pass/block-vec-map2.rs +++ b/src/test/run-pass/block-vec-map2.rs @@ -4,7 +4,7 @@ fn main() { let v = vec::map2(~[1, 2, 3, 4, 5], ~[true, false, false, true, true], - |i, b| if b { -i } else { i } ); + |i, b| if *b { -(*i) } else { *i } ); log(error, v); assert (v == ~[-1, 2, 3, -4, -5]); } diff --git a/src/test/run-pass/borrowck-borrow-from-expr-block.rs b/src/test/run-pass/borrowck-borrow-from-expr-block.rs index ec31225f46bf..d180fc4b8ae5 100644 --- a/src/test/run-pass/borrowck-borrow-from-expr-block.rs +++ b/src/test/run-pass/borrowck-borrow-from-expr-block.rs @@ -7,7 +7,7 @@ fn borrow(x: &int, f: fn(x: &int)) { fn test1(x: @~int) { // Right now, at least, this induces a copy of the unique pointer: do borrow({*x}) |p| { - let x_a = ptr::addr_of(**x); + let x_a = ptr::addr_of(&(**x)); assert (x_a as uint) != to_uint(p); assert unsafe{*x_a} == *p; } diff --git a/src/test/run-pass/borrowck-mut-uniq.rs b/src/test/run-pass/borrowck-mut-uniq.rs index 6db380735cba..2d1833c07367 100644 --- a/src/test/run-pass/borrowck-mut-uniq.rs +++ b/src/test/run-pass/borrowck-mut-uniq.rs @@ -4,7 +4,7 @@ fn add_int(x: &mut ints, v: int) { *x.sum += v; let mut values = ~[]; x.values <-> values; - vec::push(values, v); + values.push(v); x.values <- values; } diff --git a/src/test/run-pass/borrowck-preserve-box-in-discr.rs b/src/test/run-pass/borrowck-preserve-box-in-discr.rs index 373830d77afd..5ed78488b356 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-discr.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-discr.rs @@ -5,13 +5,13 @@ fn main() { match *x { {f: b_x} => { assert *b_x == 3; - assert ptr::addr_of(*x.f) == ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) == ptr::addr_of(&(*b_x)); x = @{f: ~4}; - debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(*b_x) as uint); + debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(&(*b_x)) as uint); assert *b_x == 3; - assert ptr::addr_of(*x.f) != ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) != ptr::addr_of(&(*b_x)); } } } \ No newline at end of file diff --git a/src/test/run-pass/borrowck-preserve-box-in-field.rs b/src/test/run-pass/borrowck-preserve-box-in-field.rs index 7ab2dc4b99da..d7d3aa68fafa 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-field.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-field.rs @@ -11,11 +11,11 @@ fn main() { let mut x = @{f: ~3}; do borrow(x.f) |b_x| { assert *b_x == 3; - assert ptr::addr_of(*x.f) == ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) == ptr::addr_of(&(*b_x)); x = @{f: ~4}; - debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(*b_x) as uint); + debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(&(*b_x)) as uint); assert *b_x == 3; - assert ptr::addr_of(*x.f) != ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) != ptr::addr_of(&(*b_x)); } } \ No newline at end of file diff --git a/src/test/run-pass/borrowck-preserve-box-in-pat.rs b/src/test/run-pass/borrowck-preserve-box-in-pat.rs index 599879f82f1d..f0944ea35444 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-pat.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-pat.rs @@ -5,13 +5,13 @@ fn main() { match x { @@{f: b_x} => { assert *b_x == 3; - assert ptr::addr_of(x.f) == ptr::addr_of(b_x); + assert ptr::addr_of(&(x.f)) == ptr::addr_of(&(b_x)); *x = @{f: ~4}; - debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(*b_x) as uint); + debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(&(*b_x)) as uint); assert *b_x == 3; - assert ptr::addr_of(*x.f) != ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) != ptr::addr_of(&(*b_x)); } } } diff --git a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs index bd43ad65cffb..b0bb4d8d40cc 100644 --- a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs +++ b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs @@ -11,11 +11,11 @@ fn main() { let mut x = ~mut @{f: ~3}; do borrow(x.f) |b_x| { assert *b_x == 3; - assert ptr::addr_of(*x.f) == ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) == ptr::addr_of(&(*b_x)); *x = @{f: ~4}; - debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(*b_x) as uint); + debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(&(*b_x)) as uint); assert *b_x == 3; - assert ptr::addr_of(*x.f) != ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) != ptr::addr_of(&(*b_x)); } } \ No newline at end of file diff --git a/src/test/run-pass/borrowck-preserve-box.rs b/src/test/run-pass/borrowck-preserve-box.rs index 8d59975204b1..88f4b459d361 100644 --- a/src/test/run-pass/borrowck-preserve-box.rs +++ b/src/test/run-pass/borrowck-preserve-box.rs @@ -11,11 +11,11 @@ fn main() { let mut x = @3; do borrow(x) |b_x| { assert *b_x == 3; - assert ptr::addr_of(*x) == ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x)) == ptr::addr_of(&(*b_x)); x = @22; - debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(*b_x) as uint); + debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(&(*b_x)) as uint); assert *b_x == 3; - assert ptr::addr_of(*x) != ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x)) != ptr::addr_of(&(*b_x)); } } \ No newline at end of file diff --git a/src/test/run-pass/borrowck-preserve-expl-deref.rs b/src/test/run-pass/borrowck-preserve-expl-deref.rs index e126ecc4340b..ba525eafc516 100644 --- a/src/test/run-pass/borrowck-preserve-expl-deref.rs +++ b/src/test/run-pass/borrowck-preserve-expl-deref.rs @@ -11,11 +11,11 @@ fn main() { let mut x = @{f: ~3}; do borrow((*x).f) |b_x| { assert *b_x == 3; - assert ptr::addr_of(*x.f) == ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) == ptr::addr_of(&(*b_x)); x = @{f: ~4}; - debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(*b_x) as uint); + debug!("ptr::addr_of(*b_x) = %x", ptr::addr_of(&(*b_x)) as uint); assert *b_x == 3; - assert ptr::addr_of(*x.f) != ptr::addr_of(*b_x); + assert ptr::addr_of(&(*x.f)) != ptr::addr_of(&(*b_x)); } } diff --git a/src/test/run-pass/box-annihilator-shared.rs b/src/test/run-pass/box-annihilator-shared.rs deleted file mode 100644 index 5786b334af72..000000000000 --- a/src/test/run-pass/box-annihilator-shared.rs +++ /dev/null @@ -1,12 +0,0 @@ -extern mod rustrt { - #[legacy_exports]; - fn rust_annihilate_box(ptr: *uint); -} - -fn main() { - unsafe { - let x = @3; - let p: *uint = cast::transmute(x); - rustrt::rust_annihilate_box(p); - } -} diff --git a/src/test/run-pass/box-annihilator-unique-vec.rs b/src/test/run-pass/box-annihilator-unique-vec.rs deleted file mode 100644 index 45449cc63825..000000000000 --- a/src/test/run-pass/box-annihilator-unique-vec.rs +++ /dev/null @@ -1,12 +0,0 @@ -extern mod rustrt { - #[legacy_exports]; - fn rust_annihilate_box(ptr: *uint); -} - -fn main() { - unsafe { - let x = ~[~"a", ~"b", ~"c"]; - let p: *uint = cast::transmute(x); - rustrt::rust_annihilate_box(p); - } -} diff --git a/src/test/run-pass/box-annihilator-unique.rs b/src/test/run-pass/box-annihilator-unique.rs deleted file mode 100644 index a2d11654f9a7..000000000000 --- a/src/test/run-pass/box-annihilator-unique.rs +++ /dev/null @@ -1,12 +0,0 @@ -extern mod rustrt { - #[legacy_exports]; - fn rust_annihilate_box(ptr: *uint); -} - -fn main() { - unsafe { - let x = ~3; - let p: *uint = cast::transmute(x); - rustrt::rust_annihilate_box(p); - } -} diff --git a/src/test/run-pass/cap-clause-move.rs b/src/test/run-pass/cap-clause-move.rs index 260c1d45b76b..0561af6ca6d3 100644 --- a/src/test/run-pass/cap-clause-move.rs +++ b/src/test/run-pass/cap-clause-move.rs @@ -1,29 +1,29 @@ fn main() { let x = ~1; - let y = ptr::addr_of(*x) as uint; - let lam_copy = fn@(copy x) -> uint { ptr::addr_of(*x) as uint }; - let lam_move = fn@(move x) -> uint { ptr::addr_of(*x) as uint }; + let y = ptr::addr_of(&(*x)) as uint; + let lam_copy = fn@(copy x) -> uint { ptr::addr_of(&(*x)) as uint }; + let lam_move = fn@(move x) -> uint { ptr::addr_of(&(*x)) as uint }; assert lam_copy() != y; assert lam_move() == y; let x = ~2; - let y = ptr::addr_of(*x) as uint; - let lam_copy: fn@() -> uint = |copy x| ptr::addr_of(*x) as uint; - let lam_move: fn@() -> uint = |move x| ptr::addr_of(*x) as uint; + let y = ptr::addr_of(&(*x)) as uint; + let lam_copy: fn@() -> uint = |copy x| ptr::addr_of(&(*x)) as uint; + let lam_move: fn@() -> uint = |move x| ptr::addr_of(&(*x)) as uint; assert lam_copy() != y; assert lam_move() == y; let x = ~3; - let y = ptr::addr_of(*x) as uint; - let snd_copy = fn~(copy x) -> uint { ptr::addr_of(*x) as uint }; - let snd_move = fn~(move x) -> uint { ptr::addr_of(*x) as uint }; + let y = ptr::addr_of(&(*x)) as uint; + let snd_copy = fn~(copy x) -> uint { ptr::addr_of(&(*x)) as uint }; + let snd_move = fn~(move x) -> uint { ptr::addr_of(&(*x)) as uint }; assert snd_copy() != y; assert snd_move() == y; let x = ~4; - let y = ptr::addr_of(*x) as uint; - let lam_copy: fn~() -> uint = |copy x| ptr::addr_of(*x) as uint; - let lam_move: fn~() -> uint = |move x| ptr::addr_of(*x) as uint; + let y = ptr::addr_of(&(*x)) as uint; + let lam_copy: fn~() -> uint = |copy x| ptr::addr_of(&(*x)) as uint; + let lam_move: fn~() -> uint = |move x| ptr::addr_of(&(*x)) as uint; assert lam_copy() != y; assert lam_move() == y; } diff --git a/src/test/run-pass/cleanup-copy-mode.rs b/src/test/run-pass/cleanup-copy-mode.rs index 2cf1276887e8..e4bfa54c4104 100644 --- a/src/test/run-pass/cleanup-copy-mode.rs +++ b/src/test/run-pass/cleanup-copy-mode.rs @@ -2,7 +2,7 @@ fn adder(+x: @int, +y: @int) -> int { return *x + *y; } fn failer() -> @int { fail; } fn main() { - assert(result::is_err(task::try(|| { + assert(result::is_err(&task::try(|| { adder(@2, failer()); () }))); } diff --git a/src/test/run-pass/early-vtbl-resolution.rs b/src/test/run-pass/early-vtbl-resolution.rs index 24faa53fda42..2bbbbf7ef178 100644 --- a/src/test/run-pass/early-vtbl-resolution.rs +++ b/src/test/run-pass/early-vtbl-resolution.rs @@ -9,7 +9,7 @@ fn foo_func>(x: B) -> Option { x.foo() } fn main() { - for iter::eachi(Some({a: 0})) |i, a| { + for iter::eachi(&(Some({a: 0}))) |i, a| { #debug["%u %d", i, a.a]; } diff --git a/src/test/run-pass/enum-export-inheritance.rs b/src/test/run-pass/enum-export-inheritance.rs new file mode 100644 index 000000000000..1fddddba331b --- /dev/null +++ b/src/test/run-pass/enum-export-inheritance.rs @@ -0,0 +1,12 @@ +mod a { + pub enum Foo { + Bar, + Baz, + Boo + } +} + +fn main() { + let x = a::Bar; +} + diff --git a/src/test/run-pass/hello.rs b/src/test/run-pass/hello.rs index 5f61c554992d..5b0664f400b1 100644 --- a/src/test/run-pass/hello.rs +++ b/src/test/run-pass/hello.rs @@ -1,5 +1,5 @@ - - - // -*- rust -*- -fn main() { debug!("hello, world."); } + +fn main() { + io::println("hello, world"); +} diff --git a/src/test/run-pass/issue-2611.rs b/src/test/run-pass/issue-2611.rs index cc2e89c76ead..8fb5a0d6e04c 100644 --- a/src/test/run-pass/issue-2611.rs +++ b/src/test/run-pass/issue-2611.rs @@ -4,12 +4,12 @@ use iter::BaseIter; trait FlatMapToVec { - fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B]; + fn flat_map_to_vec>(op: fn(+a: A) -> IB) -> ~[B]; } impl BaseIter: FlatMapToVec { - fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] { - iter::flat_map_to_vec(self, op) + fn flat_map_to_vec>(op: fn(+a: A) -> IB) -> ~[B] { + iter::flat_map_to_vec(&self, op) } } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 6da4349ba5fc..b887b86cf2f3 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -201,7 +201,7 @@ mod pingpong { fn liberate_ping(-p: ping) -> pipes::send_packet unsafe { let addr : *pipes::send_packet = match p { - ping(x) => { cast::transmute(ptr::addr_of(x)) } + ping(x) => { cast::transmute(ptr::addr_of(&x)) } }; let liberated_value <- *addr; cast::forget(p); @@ -210,7 +210,7 @@ mod pingpong { fn liberate_pong(-p: pong) -> pipes::send_packet unsafe { let addr : *pipes::send_packet = match p { - pong(x) => { cast::transmute(ptr::addr_of(x)) } + pong(x) => { cast::transmute(ptr::addr_of(&x)) } }; let liberated_value <- *addr; cast::forget(p); diff --git a/src/test/run-pass/issue-2804.rs b/src/test/run-pass/issue-2804.rs index 9088f6e3584c..7ef4ef225604 100644 --- a/src/test/run-pass/issue-2804.rs +++ b/src/test/run-pass/issue-2804.rs @@ -1,6 +1,7 @@ extern mod std; use io::WriterUtil; use std::map::HashMap; +use std::json; enum object { @@ -8,13 +9,13 @@ enum object int_value(i64), } -fn lookup(table: std::map::HashMap<~str, std::json::Json>, key: ~str, default: ~str) -> ~str +fn lookup(table: ~json::Object, key: ~str, default: ~str) -> ~str { - match table.find(key) + match table.find(&key) { option::Some(std::json::String(s)) => { - *s + s } option::Some(value) => { @@ -32,7 +33,7 @@ fn add_interface(store: int, managed_ip: ~str, data: std::json::Json) -> (~str, { match data { - std::json::Dict(interface) => + std::json::Object(interface) => { let name = lookup(interface, ~"ifDescr", ~""); let label = fmt!("%s-%s", managed_ip, name); @@ -53,7 +54,7 @@ fn add_interfaces(store: int, managed_ip: ~str, device: std::map::HashMap<~str, { std::json::List(interfaces) => { - do vec::map(*interfaces) |interface| { + do vec::map(interfaces) |interface| { add_interface(store, managed_ip, *interface) } } diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs index 704e8f79fb11..6d771dc7386e 100644 --- a/src/test/run-pass/issue-2904.rs +++ b/src/test/run-pass/issue-2904.rs @@ -1,5 +1,7 @@ /// Map representation +use io::ReaderUtil; + extern mod std; enum square { @@ -50,10 +52,10 @@ fn read_board_grid(+in: rdr) -> ~[~[square]] { let mut grid = ~[]; for in.each_line |line| { let mut row = ~[]; - for line.each_char |c| { - vec::push(row, square_from_char(c)) + for str::each_char(line) |c| { + row.push(square_from_char(c)) } - vec::push(grid, row) + grid.push(row) } let width = grid[0].len(); for grid.each |row| { assert row.len() == width } diff --git a/src/test/run-pass/issue-783.rs b/src/test/run-pass/issue-783.rs index 752101e651b9..a9c6fed8ecae 100644 --- a/src/test/run-pass/issue-783.rs +++ b/src/test/run-pass/issue-783.rs @@ -1,6 +1,6 @@ extern mod std; use comm::*; -use task::*; +use task::spawn; fn a() { fn doit() { diff --git a/src/test/run-pass/iter-all.rs b/src/test/run-pass/iter-all.rs index eb5dbd6aa5cf..75334db86cc6 100644 --- a/src/test/run-pass/iter-all.rs +++ b/src/test/run-pass/iter-all.rs @@ -1,4 +1,4 @@ -fn is_even(&&x: uint) -> bool { (x % 2u) == 0u } +fn is_even(x: &uint) -> bool { (*x % 2) == 0 } fn main() { assert ![1u, 2u]/_.all(is_even); diff --git a/src/test/run-pass/iter-any.rs b/src/test/run-pass/iter-any.rs index d672df09c247..22057b74a414 100644 --- a/src/test/run-pass/iter-any.rs +++ b/src/test/run-pass/iter-any.rs @@ -1,11 +1,11 @@ -fn is_even(&&x: uint) -> bool { (x % 2u) == 0u } +fn is_even(x: &uint) -> bool { (*x % 2) == 0 } fn main() { assert ![1u, 3u]/_.any(is_even); assert [1u, 2u]/_.any(is_even); assert ![]/_.any(is_even); - assert !Some(1u).any(is_even); - assert Some(2u).any(is_even); + assert !Some(1).any(is_even); + assert Some(2).any(is_even); assert !None.any(is_even); } diff --git a/src/test/run-pass/iter-contains.rs b/src/test/run-pass/iter-contains.rs index 43bce3e7dcbb..6036b5b2d24b 100644 --- a/src/test/run-pass/iter-contains.rs +++ b/src/test/run-pass/iter-contains.rs @@ -1,10 +1,10 @@ fn main() { - assert []/_.contains(22u) == false; - assert [1u, 3u]/_.contains(22u) == false; - assert [22u, 1u, 3u]/_.contains(22u) == true; - assert [1u, 22u, 3u]/_.contains(22u) == true; - assert [1u, 3u, 22u]/_.contains(22u) == true; - assert None.contains(22u) == false; - assert Some(1u).contains(22u) == false; - assert Some(22u).contains(22u) == true; + assert []/_.contains(&22u) == false; + assert [1u, 3u]/_.contains(&22u) == false; + assert [22u, 1u, 3u]/_.contains(&22u) == true; + assert [1u, 22u, 3u]/_.contains(&22u) == true; + assert [1u, 3u, 22u]/_.contains(&22u) == true; + assert None.contains(&22u) == false; + assert Some(1u).contains(&22u) == false; + assert Some(22u).contains(&22u) == true; } diff --git a/src/test/run-pass/iter-count.rs b/src/test/run-pass/iter-count.rs index ba22cc7710bc..0b6f94367be3 100644 --- a/src/test/run-pass/iter-count.rs +++ b/src/test/run-pass/iter-count.rs @@ -1,9 +1,9 @@ fn main() { - assert []/_.count(22u) == 0u; - assert [1u, 3u]/_.count(22u) == 0u; - assert [22u, 1u, 3u]/_.count(22u) == 1u; - assert [22u, 1u, 22u]/_.count(22u) == 2u; - assert None.count(22u) == 0u; - assert Some(1u).count(22u) == 0u; - assert Some(22u).count(22u) == 1u; + assert []/_.count(&22u) == 0u; + assert [1u, 3u]/_.count(&22u) == 0u; + assert [22u, 1u, 3u]/_.count(&22u) == 1u; + assert [22u, 1u, 22u]/_.count(&22u) == 2u; + assert None.count(&22u) == 0u; + assert Some(1u).count(&22u) == 0u; + assert Some(22u).count(&22u) == 1u; } diff --git a/src/test/run-pass/iter-filter-to-vec.rs b/src/test/run-pass/iter-filter-to-vec.rs index 8cb9e0e9d536..f96b18f140a4 100644 --- a/src/test/run-pass/iter-filter-to-vec.rs +++ b/src/test/run-pass/iter-filter-to-vec.rs @@ -1,9 +1,9 @@ -fn is_even(&&x: uint) -> bool { (x % 2u) == 0u } +fn is_even(+x: uint) -> bool { (x % 2) == 0 } fn main() { - assert [1u, 3u]/_.filter_to_vec(is_even) == ~[]; - assert [1u, 2u, 3u]/_.filter_to_vec(is_even) == ~[2u]; + assert [1, 3]/_.filter_to_vec(is_even) == ~[]; + assert [1, 2, 3]/_.filter_to_vec(is_even) == ~[2]; assert None.filter_to_vec(is_even) == ~[]; - assert Some(1u).filter_to_vec(is_even) == ~[]; - assert Some(2u).filter_to_vec(is_even) == ~[2u]; + assert Some(1).filter_to_vec(is_even) == ~[]; + assert Some(2).filter_to_vec(is_even) == ~[2]; } diff --git a/src/test/run-pass/iter-foldl.rs b/src/test/run-pass/iter-foldl.rs index 41bb6b82ddd7..bbc1673f6864 100644 --- a/src/test/run-pass/iter-foldl.rs +++ b/src/test/run-pass/iter-foldl.rs @@ -1,4 +1,4 @@ -fn add(&&x: float, &&y: uint) -> float { x + (y as float) } +fn add(x: &float, y: &uint) -> float { *x + ((*y) as float) } fn main() { assert [1u, 3u]/_.foldl(20f, add) == 24f; diff --git a/src/test/run-pass/iter-map-to-vec.rs b/src/test/run-pass/iter-map-to-vec.rs index 11f2cc1efb17..2f5359f197f1 100644 --- a/src/test/run-pass/iter-map-to-vec.rs +++ b/src/test/run-pass/iter-map-to-vec.rs @@ -1,9 +1,9 @@ -fn inc(x: &uint) -> uint { *x + 1u } +fn inc(+x: uint) -> uint { x + 1 } fn main() { - assert [1u, 3u]/_.map_to_vec(inc) == ~[2u, 4u]; - assert [1u, 2u, 3u]/_.map_to_vec(inc) == ~[2u, 3u, 4u]; + assert [1, 3]/_.map_to_vec(inc) == ~[2, 4]; + assert [1, 2, 3]/_.map_to_vec(inc) == ~[2, 3, 4]; assert None.map_to_vec(inc) == ~[]; - assert Some(1u).map_to_vec(inc) == ~[2u]; - assert Some(2u).map_to_vec(inc) == ~[3u]; + assert Some(1).map_to_vec(inc) == ~[2]; + assert Some(2).map_to_vec(inc) == ~[3]; } diff --git a/src/test/run-pass/last-use-corner-cases.rs b/src/test/run-pass/last-use-corner-cases.rs index 2d8e3aa7b8c0..a3088a2c1256 100644 --- a/src/test/run-pass/last-use-corner-cases.rs +++ b/src/test/run-pass/last-use-corner-cases.rs @@ -4,14 +4,14 @@ fn main() { // Make sure closing over can be a last use let q = ~10; - let addr = ptr::addr_of(*q); - let f = fn@() -> *int { ptr::addr_of(*q) }; + let addr = ptr::addr_of(&(*q)); + let f = fn@() -> *int { ptr::addr_of(&(*q)) }; assert addr == f(); // But only when it really is the last use let q = ~20; - let f = fn@() -> *int { ptr::addr_of(*q) }; - assert ptr::addr_of(*q) != f(); + let f = fn@() -> *int { ptr::addr_of(&(*q)) }; + assert ptr::addr_of(&(*q)) != f(); // Ensure function arguments and box arguments interact sanely. fn call_me(x: fn() -> int, y: ~int) { assert x() == *y; } diff --git a/src/test/run-pass/numeric-method-autoexport.rs b/src/test/run-pass/numeric-method-autoexport.rs index 6a3676227cc0..f2882b919838 100644 --- a/src/test/run-pass/numeric-method-autoexport.rs +++ b/src/test/run-pass/numeric-method-autoexport.rs @@ -5,11 +5,11 @@ fn main() { // ints // num - assert 15.add(6) == 21; - assert 15i8.add(6i8) == 21i8; - assert 15i16.add(6i16) == 21i16; - assert 15i32.add(6i32) == 21i32; - assert 15i64.add(6i64) == 21i64; + assert 15.add(&6) == 21; + assert 15i8.add(&6i8) == 21i8; + assert 15i16.add(&6i16) == 21i16; + assert 15i32.add(&6i32) == 21i32; + assert 15i64.add(&6i64) == 21i64; // times 15.times(|| false); 15i8.times(|| false); @@ -19,11 +19,11 @@ fn main() { // uints // num - assert 15u.add(6u) == 21u; - assert 15u8.add(6u8) == 21u8; - assert 15u16.add(6u16) == 21u16; - assert 15u32.add(6u32) == 21u32; - assert 15u64.add(6u64) == 21u64; + assert 15u.add(&6u) == 21u; + assert 15u8.add(&6u8) == 21u8; + assert 15u16.add(&6u16) == 21u16; + assert 15u32.add(&6u32) == 21u32; + assert 15u64.add(&6u64) == 21u64; // times 15u.times(|| false); 15u8.times(|| false); diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs index d5af5a54377d..2215b49937fd 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/run-pass/operator-overloading.rs @@ -25,7 +25,7 @@ impl Point : ops::Neg { } impl Point : ops::Index { - pure fn index(&&x: bool) -> int { + pure fn index(+x: bool) -> int { if x { self.x } else { self.y } } } diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs index 8ac76293284b..899b74b2866e 100644 --- a/src/test/run-pass/pipe-bank-proto.rs +++ b/src/test/run-pass/pipe-bank-proto.rs @@ -33,7 +33,7 @@ proto! bank ( ) macro_rules! move_it ( - { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } } + { $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); y } } ) fn switch(+endp: pipes::RecvPacket, diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs index f9f091131ab7..9bfbbe338e76 100644 --- a/src/test/run-pass/pipe-pingpong-bounded.rs +++ b/src/test/run-pass/pipe-pingpong-bounded.rs @@ -28,7 +28,7 @@ mod pingpong { do pipes::entangle_buffer(buffer) |buffer, data| { data.ping.set_buffer_(buffer); data.pong.set_buffer_(buffer); - ptr::addr_of(data.ping) + ptr::addr_of(&(data.ping)) } } enum ping = server::pong; @@ -38,8 +38,8 @@ mod pingpong { fn ping(+pipe: ping) -> pong { { let b = pipe.reuse_buffer(); - let s = SendPacketBuffered(ptr::addr_of(b.buffer.data.pong)); - let c = RecvPacketBuffered(ptr::addr_of(b.buffer.data.pong)); + let s = SendPacketBuffered(ptr::addr_of(&(b.buffer.data.pong))); + let c = RecvPacketBuffered(ptr::addr_of(&(b.buffer.data.pong))); let message = pingpong::ping(s); pipes::send(pipe, message); c @@ -57,8 +57,8 @@ mod pingpong { fn pong(+pipe: pong) -> ping { { let b = pipe.reuse_buffer(); - let s = SendPacketBuffered(ptr::addr_of(b.buffer.data.ping)); - let c = RecvPacketBuffered(ptr::addr_of(b.buffer.data.ping)); + let s = SendPacketBuffered(ptr::addr_of(&(b.buffer.data.ping))); + let c = RecvPacketBuffered(ptr::addr_of(&(b.buffer.data.ping))); let message = pingpong::pong(s); pipes::send(pipe, message); c diff --git a/src/test/run-pass/reexport-star.rs b/src/test/run-pass/reexport-star.rs new file mode 100644 index 000000000000..1709ddc70f2d --- /dev/null +++ b/src/test/run-pass/reexport-star.rs @@ -0,0 +1,14 @@ +mod a { + pub fn f() {} + pub fn g() {} +} + +mod b { + pub use a::*; +} + +fn main() { + b::f(); + b::g(); +} + diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs index affd0ef61625..e27aaa618aca 100644 --- a/src/test/run-pass/reflect-visit-data.rs +++ b/src/test/run-pass/reflect-visit-data.rs @@ -612,7 +612,7 @@ fn get_tydesc_for(&&_t: T) -> *TyDesc { fn main() { let r = (1,2,3,true,false,{x:5,y:4,z:3}); - let p = ptr::addr_of(r) as *c_void; + let p = ptr::addr_of(&r) as *c_void; let u = my_visitor(@{mut ptr1: p, mut ptr2: p, mut vals: ~[]}); diff --git a/src/test/run-pass/resource-cycle.rs b/src/test/run-pass/resource-cycle.rs index 9e0a2c35e2f0..26e19ee1b0c6 100644 --- a/src/test/run-pass/resource-cycle.rs +++ b/src/test/run-pass/resource-cycle.rs @@ -4,8 +4,8 @@ struct r { v: *int, drop unsafe { debug!("r's dtor: self = %x, self.v = %x, self.v's value = %x", - cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(self)), - cast::reinterpret_cast::<**int, uint>(&ptr::addr_of(self.v)), + cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&self)), + cast::reinterpret_cast::<**int, uint>(&ptr::addr_of(&(self.v))), cast::reinterpret_cast::<*int, uint>(&self.v)); let v2: ~int = cast::reinterpret_cast(&self.v); } } @@ -34,27 +34,27 @@ fn main() unsafe { r: { let rs = r(i1p); debug!("r = %x", - cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(rs))); + cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&rs))); rs } }); debug!("x1 = %x, x1.r = %x", cast::reinterpret_cast::<@t, uint>(&x1), - cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(x1.r))); + cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&(x1.r)))); let x2 = @t({ mut next: None, r: { let rs = r(i2p); debug!("r2 = %x", - cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(rs))); + cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&rs))); rs } }); debug!("x2 = %x, x2.r = %x", cast::reinterpret_cast::<@t, uint>(&x2), - cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(x2.r))); + cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&(x2.r)))); x1.next = Some(x2); x2.next = Some(x1); diff --git a/src/test/run-pass/ret-break-cont-in-block.rs b/src/test/run-pass/ret-break-cont-in-block.rs index 9013842ba8b6..4e7e978cf556 100644 --- a/src/test/run-pass/ret-break-cont-in-block.rs +++ b/src/test/run-pass/ret-break-cont-in-block.rs @@ -43,10 +43,10 @@ fn ret_deep() -> ~str { fn main() { let mut last = 0; for vec::all(~[1, 2, 3, 4, 5, 6, 7]) |e| { - last = e; - if e == 5 { break; } - if e % 2 == 1 { loop; } - assert e % 2 == 0; + last = *e; + if *e == 5 { break; } + if *e % 2 == 1 { loop; } + assert *e % 2 == 0; }; assert last == 5; diff --git a/src/test/run-pass/rt-sched-1.rs b/src/test/run-pass/rt-sched-1.rs index 9604dff64d7e..15207b668fef 100644 --- a/src/test/run-pass/rt-sched-1.rs +++ b/src/test/run-pass/rt-sched-1.rs @@ -33,7 +33,7 @@ fn main() unsafe { assert child_sched_id == new_sched_id; comm::send(ch, ()); }; - let fptr = cast::reinterpret_cast(&ptr::addr_of(f)); + let fptr = cast::reinterpret_cast(&ptr::addr_of(&f)); rustrt::start_task(new_task_id, fptr); cast::forget(f); comm::recv(po); diff --git a/src/test/run-pass/select-macro.rs b/src/test/run-pass/select-macro.rs index 15dd56e46c50..78bddffcc1d4 100644 --- a/src/test/run-pass/select-macro.rs +++ b/src/test/run-pass/select-macro.rs @@ -28,7 +28,7 @@ macro_rules! select_if ( match move pipes::try_recv($port) { $(Some($message($($(ref $x,)+)* ref next)) => { // FIXME (#2329) we really want move out of enum here. - let $next = unsafe { let x <- *ptr::addr_of(*next); x }; + let $next = unsafe { let x <- *ptr::addr_of(&(*next)); x }; $e })+ _ => fail diff --git a/src/test/run-pass/stable-addr-of.rs b/src/test/run-pass/stable-addr-of.rs index 060994ed48f0..dceb80331b4d 100644 --- a/src/test/run-pass/stable-addr-of.rs +++ b/src/test/run-pass/stable-addr-of.rs @@ -2,5 +2,5 @@ fn main() { let foo = 1; - assert ptr::addr_of(foo) == ptr::addr_of(foo); + assert ptr::addr_of(&foo) == ptr::addr_of(&foo); } diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs index dd2dd5e54d46..4faac4fdac19 100644 --- a/src/test/run-pass/task-comm-3.rs +++ b/src/test/run-pass/task-comm-3.rs @@ -34,7 +34,7 @@ fn test00() { while i < number_of_tasks { let ch = po.chan(); do task::task().future_result(|+r| { - vec::push(results, r); + results.push(r); }).spawn |copy i| { test00_start(ch, i, number_of_messages) } diff --git a/src/test/run-pass/task-comm.rs b/src/test/run-pass/task-comm.rs index a3a6b6efd7f8..8d144b1a3995 100644 --- a/src/test/run-pass/task-comm.rs +++ b/src/test/run-pass/task-comm.rs @@ -40,7 +40,7 @@ fn test00() { while i < number_of_tasks { i = i + 1; do task::task().future_result(|+r| { - vec::push(results, r); + results.push(r); }).spawn |copy i| { test00_start(ch, i, number_of_messages); } @@ -127,7 +127,7 @@ fn test06() { while i < number_of_tasks { i = i + 1; do task::task().future_result(|+r| { - vec::push(results, r); + results.push(r); }).spawn |copy i| { test06_start(i); }; diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index 98d5193c86d6..405ba82b7903 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -10,7 +10,7 @@ struct notify { drop { error!("notify: task=%? v=%x unwinding=%b b=%b", task::get_task(), - ptr::addr_of(*(self.v)) as uint, + ptr::addr_of(&(*(self.v))) as uint, task::failing(), *(self.v)); let b = *(self.v); @@ -30,7 +30,7 @@ fn joinable(+f: fn~()) -> comm::Port { let b = @mut false; error!("wrapper: task=%? allocated v=%x", task::get_task(), - ptr::addr_of(*b) as uint); + ptr::addr_of(&(*b)) as uint); let _r = notify(c, b); f(); *b = true; diff --git a/src/test/run-pass/task-spawn-move-and-copy.rs b/src/test/run-pass/task-spawn-move-and-copy.rs index 9cedfea61300..7316a927751b 100644 --- a/src/test/run-pass/task-spawn-move-and-copy.rs +++ b/src/test/run-pass/task-spawn-move-and-copy.rs @@ -3,16 +3,16 @@ fn main() { let ch = comm::Chan(p); let x = ~1; - let x_in_parent = ptr::addr_of(*x) as uint; + let x_in_parent = ptr::addr_of(&(*x)) as uint; let y = ~2; - let y_in_parent = ptr::addr_of(*y) as uint; + let y_in_parent = ptr::addr_of(&(*y)) as uint; task::spawn(fn~(copy ch, copy y, move x) { - let x_in_child = ptr::addr_of(*x) as uint; + let x_in_child = ptr::addr_of(&(*x)) as uint; comm::send(ch, x_in_child); - let y_in_child = ptr::addr_of(*y) as uint; + let y_in_child = ptr::addr_of(&(*y)) as uint; comm::send(ch, y_in_child); }); // Ensure last-use analysis doesn't move y to child. diff --git a/src/test/run-pass/uniq-cc-generic.rs b/src/test/run-pass/uniq-cc-generic.rs index 18c3db591f65..592d49cc2a87 100644 --- a/src/test/run-pass/uniq-cc-generic.rs +++ b/src/test/run-pass/uniq-cc-generic.rs @@ -9,7 +9,7 @@ type pointy = { }; fn make_uniq_closure(a: A) -> fn~() -> uint { - fn~() -> uint { ptr::addr_of(a) as uint } + fn~() -> uint { ptr::addr_of(&a) as uint } } fn empty_pointy() -> @pointy { diff --git a/src/test/run-pass/unnamed_argument_mode.rs b/src/test/run-pass/unnamed_argument_mode.rs new file mode 100644 index 000000000000..97e7582e142d --- /dev/null +++ b/src/test/run-pass/unnamed_argument_mode.rs @@ -0,0 +1,11 @@ +fn good(a: &int) { +} + +// unnamed argument &int is now parse x: &int + +fn called(f: fn(&int)) { +} + +fn main() { +called(good); +} diff --git a/src/test/run-pass/vec-push.rs b/src/test/run-pass/vec-push.rs index 3e47f7e0a3b3..d4190d413861 100644 --- a/src/test/run-pass/vec-push.rs +++ b/src/test/run-pass/vec-push.rs @@ -1 +1 @@ -fn main() { let mut v = ~[1, 2, 3]; vec::push(v, 1); } +fn main() { let mut v = ~[1, 2, 3]; v.push(1); } diff --git a/src/test/run-pass/zip-same-length.rs b/src/test/run-pass/zip-same-length.rs index 61e359129fe8..9b8304792fa3 100644 --- a/src/test/run-pass/zip-same-length.rs +++ b/src/test/run-pass/zip-same-length.rs @@ -7,7 +7,7 @@ fn enum_chars(start: u8, end: u8) -> ~[char] { assert start < end; let mut i = start; let mut r = ~[]; - while i <= end { vec::push(r, i as char); i += 1u as u8; } + while i <= end { r.push(i as char); i += 1u as u8; } return r; } @@ -15,7 +15,7 @@ fn enum_uints(start: uint, end: uint) -> ~[uint] { assert start < end; let mut i = start; let mut r = ~[]; - while i <= end { vec::push(r, i); i += 1u; } + while i <= end { r.push(i); i += 1u; } return r; }